mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl: implement a new hack UserHacks_UnscaleSprite for opengl
UserHacks_UnscaleSprite = 1 will unscale flat sprites UserHacks_UnscaleSprite = 2 will unscale all sprites (don't work well so far) The idea of the hack is to redo the interpolation of texture coordinate based on the non-upscaled pixel position. It avoids various glitches but sprites aren't upscaled anymore (so no more anti-aliasing, potentially a coefficient can be added).
This commit is contained in:
parent
6124eb844e
commit
31f8c065db
|
@ -116,6 +116,7 @@ GSDeviceOGL::~GSDeviceOGL()
|
|||
|
||||
// Delete HW FX
|
||||
delete m_vs_cb;
|
||||
delete m_gs_cb;
|
||||
delete m_ps_cb;
|
||||
gl_DeleteSamplers(1, &m_palette_ss);
|
||||
m_shader->Delete(m_apitrace);
|
||||
|
@ -668,10 +669,15 @@ GLuint GSDeviceOGL::CompileVS(VSSelector sel, int logz)
|
|||
/* Note: must be here because tfx_glsl is static */
|
||||
GLuint GSDeviceOGL::CompileGS()
|
||||
{
|
||||
// Don't use a dynamic selector to only compile a single GS.
|
||||
// If configuration is updated, shader will be recompiled
|
||||
int unscale_sprite = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_UnscaleSprite", 0) : 0;
|
||||
std::string macro = format("#define GS_SPRITE %d\n", unscale_sprite);
|
||||
|
||||
#ifdef ENABLE_GLES
|
||||
return 0;
|
||||
#else
|
||||
return m_shader->Compile("tfx_vgs.glsl", "gs_main", GL_GEOMETRY_SHADER, tfx_vgs_glsl, "");
|
||||
return m_shader->Compile("tfx_vgs.glsl", "gs_main", GL_GEOMETRY_SHADER, tfx_vgs_glsl, macro);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -697,6 +703,7 @@ GLuint GSDeviceOGL::CompilePS(PSSelector sel)
|
|||
+ format("#define PS_TCOFFSETHACK %d\n", sel.tcoffsethack)
|
||||
+ format("#define PS_POINT_SAMPLER %d\n", sel.point_sampler)
|
||||
+ format("#define PS_IIP %d\n", sel.iip)
|
||||
+ format("#define PS_SPRITE %d\n", sel.sprite)
|
||||
;
|
||||
|
||||
return m_shader->Compile("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, tfx_fs_all_glsl, macro);
|
||||
|
|
|
@ -334,6 +334,31 @@ class GSDeviceOGL : public GSDevice
|
|||
}
|
||||
};
|
||||
|
||||
__aligned(struct, 32) GSConstantBuffer
|
||||
{
|
||||
GSVector4 rt_size;
|
||||
|
||||
GSConstantBuffer()
|
||||
{
|
||||
rt_size = GSVector4::zero();
|
||||
}
|
||||
|
||||
__forceinline bool Update(const GSConstantBuffer* cb)
|
||||
{
|
||||
GSVector4i* a = (GSVector4i*)this;
|
||||
GSVector4i* b = (GSVector4i*)cb;
|
||||
|
||||
if(!(a[0] == b[0]).alltrue())
|
||||
{
|
||||
a[0] = b[0];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct PSSelector
|
||||
{
|
||||
union
|
||||
|
@ -352,6 +377,7 @@ class GSDeviceOGL : public GSDevice
|
|||
uint32 tcoffsethack:1;
|
||||
uint32 point_sampler:1;
|
||||
uint32 iip:1;
|
||||
uint32 sprite:1;
|
||||
// Next param will be handle by subroutine
|
||||
uint32 colclip:2;
|
||||
uint32 atst:3;
|
||||
|
@ -366,7 +392,7 @@ class GSDeviceOGL : public GSDevice
|
|||
uint32 key;
|
||||
};
|
||||
|
||||
operator uint32() {return key & 0x1fffffff;}
|
||||
operator uint32() {return key & 0x3fffffff;}
|
||||
|
||||
PSSelector() : key(0) {}
|
||||
};
|
||||
|
@ -528,9 +554,11 @@ class GSDeviceOGL : public GSDevice
|
|||
GLuint m_rt_ss;
|
||||
|
||||
GSUniformBufferOGL* m_vs_cb;
|
||||
GSUniformBufferOGL* m_gs_cb;
|
||||
GSUniformBufferOGL* m_ps_cb;
|
||||
|
||||
VSConstantBuffer m_vs_cb_cache;
|
||||
GSConstantBuffer m_gs_cb_cache;
|
||||
PSConstantBuffer m_ps_cb_cache;
|
||||
|
||||
GSTexture* CreateSurface(int type, int w, int h, bool msaa, int format);
|
||||
|
@ -624,7 +652,7 @@ class GSDeviceOGL : public GSDevice
|
|||
void SetupVS(VSSelector sel);
|
||||
void SetupGS(bool enable);
|
||||
void SetupPS(PSSelector sel);
|
||||
void SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb);
|
||||
void SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb, const GSConstantBuffer* gs_cb);
|
||||
void SetupSampler(PSSamplerSelector ssel);
|
||||
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
|
||||
GLuint GetSamplerID(PSSamplerSelector ssel);
|
||||
|
|
|
@ -32,6 +32,7 @@ GSRendererOGL::GSRendererOGL()
|
|||
UserHacks_AlphaStencil = !!theApp.GetConfig("UserHacks_AlphaStencil", 0) && !!theApp.GetConfig("UserHacks", 0);
|
||||
UserHacks_DateGL4 = !!theApp.GetConfig("UserHacks_DateGL4", 0);
|
||||
m_pixelcenter = GSVector2(-0.5f, -0.5f);
|
||||
UserHacks_Unscale_sprite = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_UnscaleSprite", 0) : 0;
|
||||
|
||||
UserHacks_TCOffset = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_TCOffset", 0) : 0;
|
||||
UserHacks_TCO_x = (UserHacks_TCOffset & 0xFFFF) / -1000.0f;
|
||||
|
@ -165,10 +166,19 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
|
||||
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
|
||||
|
||||
GSDeviceOGL::VSSelector vs_sel;
|
||||
GSDeviceOGL::VSConstantBuffer vs_cb;
|
||||
|
||||
// Blend
|
||||
GSDeviceOGL::GSConstantBuffer gs_cb;
|
||||
|
||||
GSDeviceOGL::PSSelector ps_sel;
|
||||
GSDeviceOGL::PSConstantBuffer ps_cb;
|
||||
GSDeviceOGL::PSSamplerSelector ps_ssel;
|
||||
|
||||
GSDeviceOGL::OMBlendSelector om_bsel;
|
||||
GSDeviceOGL::OMDepthStencilSelector om_dssel;
|
||||
|
||||
// Blend
|
||||
|
||||
if(!IsOpaque())
|
||||
{
|
||||
|
@ -238,8 +248,6 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
|
||||
// om
|
||||
|
||||
GSDeviceOGL::OMDepthStencilSelector om_dssel;
|
||||
|
||||
if(context->TEST.ZTE)
|
||||
{
|
||||
om_dssel.ztst = context->TEST.ZTST;
|
||||
|
@ -255,9 +263,17 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
om_dssel.fba = context->FBA.FBA;
|
||||
}
|
||||
|
||||
// vs
|
||||
bool hack_enabled = (UserHacks_Unscale_sprite > 1) || ((UserHacks_Unscale_sprite == 1) && !m_vt.IsLinear());
|
||||
if (hack_enabled && (m_vt.m_primclass == GS_SPRITE_CLASS) && GLLoader::found_geometry_shader) {
|
||||
bool blit = tex && (tex->m_texture->GetWidth() == rtsize.x) && (tex->m_texture->GetHeight() == rtsize.y);
|
||||
if (!blit) {
|
||||
ps_sel.sprite = 1;
|
||||
gs_cb.rt_size = GSVector4(rtsize.x / rtscale.x, rtsize.y / rtscale.y) / 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
GSDeviceOGL::VSSelector vs_sel;
|
||||
|
||||
// vs
|
||||
|
||||
vs_sel.tme = PRIM->TME;
|
||||
vs_sel.fst = PRIM->FST;
|
||||
|
@ -298,8 +314,6 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
}
|
||||
|
||||
// FIXME Opengl support half pixel center (as dx10). Code could be easier!!!
|
||||
GSDeviceOGL::VSConstantBuffer vs_cb;
|
||||
|
||||
float sx = 2.0f * rtscale.x / (rtsize.x << 4);
|
||||
float sy = 2.0f * rtscale.y / (rtsize.y << 4);
|
||||
float ox = (float)(int)context->XYOFFSET.OFX;
|
||||
|
@ -323,12 +337,6 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
vs_cb.Vertex_Scale_Offset = GSVector4(sx, sy, ox * sx + ox2 + 1, oy * sy + oy2 + 1);
|
||||
// END of FIXME
|
||||
|
||||
// ps
|
||||
|
||||
GSDeviceOGL::PSSelector ps_sel;
|
||||
GSDeviceOGL::PSSamplerSelector ps_ssel;
|
||||
GSDeviceOGL::PSConstantBuffer ps_cb;
|
||||
|
||||
// GS_SPRITE_CLASS are already flat (either by CPU or the GS)
|
||||
ps_sel.iip = (m_vt.m_primclass == GS_SPRITE_CLASS) ? 1 : PRIM->IIP;
|
||||
|
||||
|
@ -481,7 +489,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
SetupIA();
|
||||
|
||||
dev->SetupOM(om_dssel, om_bsel, afix);
|
||||
dev->SetupCB(&vs_cb, &ps_cb);
|
||||
dev->SetupCB(&vs_cb, &ps_cb, ps_sel.sprite ? &gs_cb : NULL);
|
||||
|
||||
if (advance_DATE) {
|
||||
// Create an r32i image that will contain primitive ID
|
||||
|
|
|
@ -39,6 +39,7 @@ class GSRendererOGL : public GSRendererHW
|
|||
bool UserHacks_AlphaHack;
|
||||
bool UserHacks_AlphaStencil;
|
||||
bool UserHacks_DateGL4;
|
||||
int UserHacks_Unscale_sprite;
|
||||
unsigned int UserHacks_TCOffset;
|
||||
float UserHacks_TCO_x, UserHacks_TCO_y;
|
||||
|
||||
|
|
|
@ -25,10 +25,12 @@
|
|||
|
||||
static const uint32 g_vs_cb_index = 20;
|
||||
static const uint32 g_ps_cb_index = 21;
|
||||
static const uint32 g_gs_cb_index = 22;
|
||||
|
||||
void GSDeviceOGL::CreateTextureFX()
|
||||
{
|
||||
m_vs_cb = new GSUniformBufferOGL(g_vs_cb_index, sizeof(VSConstantBuffer));
|
||||
m_gs_cb = new GSUniformBufferOGL(g_gs_cb_index, sizeof(GSConstantBuffer));
|
||||
m_ps_cb = new GSUniformBufferOGL(g_ps_cb_index, sizeof(PSConstantBuffer));
|
||||
|
||||
// warning 1 sampler by image unit. So you cannot reuse m_ps_ss...
|
||||
|
@ -117,7 +119,7 @@ GSBlendStateOGL* GSDeviceOGL::CreateBlend(OMBlendSelector bsel, uint8 afix)
|
|||
return bs;
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb)
|
||||
void GSDeviceOGL::SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb, const GSConstantBuffer* gs_cb)
|
||||
{
|
||||
if(m_vs_cb_cache.Update(vs_cb)) {
|
||||
m_vs_cb->upload(vs_cb);
|
||||
|
@ -127,6 +129,10 @@ void GSDeviceOGL::SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer*
|
|||
m_ps_cb->upload(ps_cb);
|
||||
}
|
||||
|
||||
if (gs_cb && m_gs_cb_cache.Update(gs_cb)) {
|
||||
m_gs_cb->upload(gs_cb);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupVS(VSSelector sel)
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#define PS_POINT_SAMPLER 0
|
||||
#define PS_TCOFFSETHACK 0
|
||||
#define PS_IIP 1
|
||||
#define PS_SPRITE 0
|
||||
#endif
|
||||
|
||||
#ifdef FRAGMENT_SHADER
|
||||
|
@ -47,6 +48,11 @@ in SHADER
|
|||
vec4 t;
|
||||
vec4 c;
|
||||
flat vec4 fc;
|
||||
#if PS_SPRITE == 1
|
||||
flat vec4 flat_T;
|
||||
flat vec2 flat_P;
|
||||
vec2 alpha;
|
||||
#endif
|
||||
} PSin;
|
||||
|
||||
#define PSin_t (PSin.t)
|
||||
|
@ -430,7 +436,21 @@ void fog(inout vec4 c, float f)
|
|||
|
||||
vec4 ps_color()
|
||||
{
|
||||
vec4 t = sample_color(PSin_t.xy, PSin_t.w);
|
||||
#if PS_SPRITE == 1
|
||||
// Reinterpolate manually the texture coordinate.
|
||||
// trunc => native resolution. Maybe we can add an option to choose a value between
|
||||
// trunc and current.
|
||||
vec2 factor = vec2(trunc(PSin.alpha.x), floor(PSin.alpha.y));
|
||||
//vec2 factor = trunc(PSin.alpha);
|
||||
factor *= PSin.flat_P;
|
||||
vec2 txy;
|
||||
txy.x = mix(PSin.flat_T.x, PSin.flat_T.y, factor.x);
|
||||
txy.y = mix(PSin.flat_T.z, PSin.flat_T.w, factor.y);
|
||||
|
||||
#else
|
||||
vec2 txy = PSin_t.xy;
|
||||
#endif
|
||||
vec4 t = sample_color(txy, PSin_t.w);
|
||||
|
||||
vec4 zero = vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
vec4 one = vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
|
|
@ -7,13 +7,6 @@
|
|||
#define VS_LOGZ 0
|
||||
#endif
|
||||
|
||||
struct vertex
|
||||
{
|
||||
vec4 t;
|
||||
vec4 c;
|
||||
vec4 fc;
|
||||
};
|
||||
|
||||
#ifdef VERTEX_SHADER
|
||||
layout(location = 0) in vec2 i_st;
|
||||
layout(location = 2) in vec4 i_c;
|
||||
|
@ -158,6 +151,11 @@ void vs_main()
|
|||
#endif
|
||||
|
||||
#ifdef GEOMETRY_SHADER
|
||||
|
||||
#ifndef GS_SPRITE
|
||||
#define GS_SPRITE 0
|
||||
#endif
|
||||
|
||||
in gl_PerVertex {
|
||||
invariant vec4 gl_Position;
|
||||
float gl_PointSize;
|
||||
|
@ -188,26 +186,63 @@ out SHADER
|
|||
vec4 t;
|
||||
vec4 c;
|
||||
flat vec4 fc;
|
||||
#if GS_SPRITE > 0
|
||||
flat vec4 flat_T;
|
||||
flat vec2 flat_P;
|
||||
vec2 alpha;
|
||||
#endif
|
||||
} GSout;
|
||||
|
||||
layout(std140, binding = 22) uniform cb22
|
||||
{
|
||||
vec4 rt_size;
|
||||
};
|
||||
|
||||
|
||||
struct vertex
|
||||
{
|
||||
vec4 t;
|
||||
vec4 c;
|
||||
vec2 a;
|
||||
};
|
||||
|
||||
void out_vertex(in vertex v)
|
||||
{
|
||||
GSout.t = v.t;
|
||||
GSout.c = v.c;
|
||||
GSout.fc = v.fc;
|
||||
#if GS_SPRITE > 0
|
||||
GSout.alpha = v.a;
|
||||
#endif
|
||||
gl_PrimitiveID = gl_PrimitiveIDIn;
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
void out_flat(in vec2 dp)
|
||||
{
|
||||
// Flat output
|
||||
GSout.fc = GSin[1].fc;
|
||||
#if GS_SPRITE > 0
|
||||
GSout.flat_T = vec4(GSin[0].t.x, GSin[1].t.x, GSin[0].t.y, GSin[1].t.y);
|
||||
GSout.flat_P = 1.0f / dp;
|
||||
#endif
|
||||
}
|
||||
|
||||
layout(lines) in;
|
||||
layout(triangle_strip, max_vertices = 6) out;
|
||||
|
||||
void gs_main()
|
||||
{
|
||||
// Rescale from -1 1 to 0:1 (require window size)
|
||||
#if GS_SPRITE > 0
|
||||
vec2 dp = (gl_in[1].gl_Position.xy - gl_in[0].gl_Position.xy) * rt_size.xy;
|
||||
#else
|
||||
vec2 dp = vec2(0.0f, 0.0f);
|
||||
#endif
|
||||
|
||||
// left top => GSin[0];
|
||||
// right bottom => GSin[1];
|
||||
vertex rb = vertex(GSin[1].t, GSin[1].c, GSin[1].fc);
|
||||
vertex lt = vertex(GSin[0].t, GSin[0].c, GSin[0].fc);
|
||||
vertex rb = vertex(GSin[1].t, GSin[1].c, dp);
|
||||
vertex lt = vertex(GSin[0].t, GSin[0].c, vec2(0.0f, 0.0f));
|
||||
|
||||
vec4 rb_p = gl_in[1].gl_Position;
|
||||
vec4 lb_p = gl_in[1].gl_Position;
|
||||
|
@ -225,10 +260,12 @@ void gs_main()
|
|||
vertex lb = rb;
|
||||
lb_p.x = lt_p.x;
|
||||
lb.t.x = lt.t.x;
|
||||
lb.a.x = lt.a.x;
|
||||
|
||||
vertex rt = rb;
|
||||
rt_p.y = lt_p.y;
|
||||
rt.t.y = lt.t.y;
|
||||
rt.a.y = lt.a.y;
|
||||
|
||||
// Triangle 1
|
||||
gl_Position = lt_p;
|
||||
|
@ -238,8 +275,8 @@ void gs_main()
|
|||
out_vertex(lb);
|
||||
|
||||
gl_Position = rt_p;
|
||||
out_flat(dp);
|
||||
out_vertex(rt);
|
||||
|
||||
EndPrimitive();
|
||||
|
||||
// Triangle 2
|
||||
|
@ -250,8 +287,8 @@ void gs_main()
|
|||
out_vertex(rt);
|
||||
|
||||
gl_Position = rb_p;
|
||||
out_flat(dp);
|
||||
out_vertex(rb);
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
|
|
|
@ -458,13 +458,6 @@ static const char* tfx_vgs_glsl =
|
|||
"#define VS_LOGZ 0\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"struct vertex\n"
|
||||
"{\n"
|
||||
" vec4 t;\n"
|
||||
" vec4 c;\n"
|
||||
" vec4 fc;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"#ifdef VERTEX_SHADER\n"
|
||||
"layout(location = 0) in vec2 i_st;\n"
|
||||
"layout(location = 2) in vec4 i_c;\n"
|
||||
|
@ -609,6 +602,11 @@ static const char* tfx_vgs_glsl =
|
|||
"#endif\n"
|
||||
"\n"
|
||||
"#ifdef GEOMETRY_SHADER\n"
|
||||
"\n"
|
||||
"#ifndef GS_SPRITE\n"
|
||||
"#define GS_SPRITE 0\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"in gl_PerVertex {\n"
|
||||
" invariant vec4 gl_Position;\n"
|
||||
" float gl_PointSize;\n"
|
||||
|
@ -639,26 +637,63 @@ static const char* tfx_vgs_glsl =
|
|||
" vec4 t;\n"
|
||||
" vec4 c;\n"
|
||||
" flat vec4 fc;\n"
|
||||
"#if GS_SPRITE > 0\n"
|
||||
" flat vec4 flat_T;\n"
|
||||
" flat vec2 flat_P;\n"
|
||||
" vec2 alpha;\n"
|
||||
"#endif\n"
|
||||
"} GSout;\n"
|
||||
"\n"
|
||||
"layout(std140, binding = 22) uniform cb22\n"
|
||||
"{\n"
|
||||
" vec4 rt_size;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"struct vertex\n"
|
||||
"{\n"
|
||||
" vec4 t;\n"
|
||||
" vec4 c;\n"
|
||||
" vec2 a;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"void out_vertex(in vertex v)\n"
|
||||
"{\n"
|
||||
" GSout.t = v.t;\n"
|
||||
" GSout.c = v.c;\n"
|
||||
" GSout.fc = v.fc;\n"
|
||||
"#if GS_SPRITE > 0\n"
|
||||
" GSout.alpha = v.a;\n"
|
||||
"#endif\n"
|
||||
" gl_PrimitiveID = gl_PrimitiveIDIn;\n"
|
||||
" EmitVertex();\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void out_flat(in vec2 dp)\n"
|
||||
"{\n"
|
||||
" // Flat output\n"
|
||||
" GSout.fc = GSin[1].fc;\n"
|
||||
"#if GS_SPRITE > 0\n"
|
||||
" GSout.flat_T = vec4(GSin[0].t.x, GSin[1].t.x, GSin[0].t.y, GSin[1].t.y);\n"
|
||||
" GSout.flat_P = 1.0f / dp;\n"
|
||||
"#endif\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"layout(lines) in;\n"
|
||||
"layout(triangle_strip, max_vertices = 6) out;\n"
|
||||
"\n"
|
||||
"void gs_main()\n"
|
||||
"{\n"
|
||||
" // Rescale from -1 1 to 0:1 (require window size)\n"
|
||||
"#if GS_SPRITE > 0\n"
|
||||
" vec2 dp = (gl_in[1].gl_Position.xy - gl_in[0].gl_Position.xy) * rt_size.xy;\n"
|
||||
"#else\n"
|
||||
" vec2 dp = vec2(0.0f, 0.0f);\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" // left top => GSin[0];\n"
|
||||
" // right bottom => GSin[1];\n"
|
||||
" vertex rb = vertex(GSin[1].t, GSin[1].c, GSin[1].fc);\n"
|
||||
" vertex lt = vertex(GSin[0].t, GSin[0].c, GSin[0].fc);\n"
|
||||
" vertex rb = vertex(GSin[1].t, GSin[1].c, dp);\n"
|
||||
" vertex lt = vertex(GSin[0].t, GSin[0].c, vec2(0.0f, 0.0f));\n"
|
||||
"\n"
|
||||
" vec4 rb_p = gl_in[1].gl_Position;\n"
|
||||
" vec4 lb_p = gl_in[1].gl_Position;\n"
|
||||
|
@ -676,10 +711,12 @@ static const char* tfx_vgs_glsl =
|
|||
" vertex lb = rb;\n"
|
||||
" lb_p.x = lt_p.x;\n"
|
||||
" lb.t.x = lt.t.x;\n"
|
||||
" lb.a.x = lt.a.x;\n"
|
||||
"\n"
|
||||
" vertex rt = rb;\n"
|
||||
" rt_p.y = lt_p.y;\n"
|
||||
" rt.t.y = lt.t.y;\n"
|
||||
" rt.a.y = lt.a.y;\n"
|
||||
"\n"
|
||||
" // Triangle 1\n"
|
||||
" gl_Position = lt_p;\n"
|
||||
|
@ -689,8 +726,8 @@ static const char* tfx_vgs_glsl =
|
|||
" out_vertex(lb);\n"
|
||||
"\n"
|
||||
" gl_Position = rt_p;\n"
|
||||
" out_flat(dp);\n"
|
||||
" out_vertex(rt);\n"
|
||||
"\n"
|
||||
" EndPrimitive();\n"
|
||||
"\n"
|
||||
" // Triangle 2\n"
|
||||
|
@ -701,8 +738,8 @@ static const char* tfx_vgs_glsl =
|
|||
" out_vertex(rt);\n"
|
||||
"\n"
|
||||
" gl_Position = rb_p;\n"
|
||||
" out_flat(dp);\n"
|
||||
" out_vertex(rb);\n"
|
||||
"\n"
|
||||
" EndPrimitive();\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
|
@ -750,6 +787,7 @@ static const char* tfx_fs_all_glsl =
|
|||
"#define PS_POINT_SAMPLER 0\n"
|
||||
"#define PS_TCOFFSETHACK 0\n"
|
||||
"#define PS_IIP 1\n"
|
||||
"#define PS_SPRITE 0\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#ifdef FRAGMENT_SHADER\n"
|
||||
|
@ -759,6 +797,11 @@ static const char* tfx_fs_all_glsl =
|
|||
" vec4 t;\n"
|
||||
" vec4 c;\n"
|
||||
" flat vec4 fc;\n"
|
||||
"#if PS_SPRITE == 1\n"
|
||||
" flat vec4 flat_T;\n"
|
||||
" flat vec2 flat_P;\n"
|
||||
" vec2 alpha;\n"
|
||||
"#endif\n"
|
||||
"} PSin;\n"
|
||||
"\n"
|
||||
"#define PSin_t (PSin.t)\n"
|
||||
|
@ -1142,7 +1185,21 @@ static const char* tfx_fs_all_glsl =
|
|||
"\n"
|
||||
"vec4 ps_color()\n"
|
||||
"{\n"
|
||||
" vec4 t = sample_color(PSin_t.xy, PSin_t.w);\n"
|
||||
"#if PS_SPRITE == 1\n"
|
||||
" // Reinterpolate manually the texture coordinate.\n"
|
||||
" // trunc => native resolution. Maybe we can add an option to choose a value between\n"
|
||||
" // trunc and current.\n"
|
||||
" vec2 factor = vec2(trunc(PSin.alpha.x), floor(PSin.alpha.y));\n"
|
||||
" //vec2 factor = trunc(PSin.alpha);\n"
|
||||
" factor *= PSin.flat_P;\n"
|
||||
" vec2 txy;\n"
|
||||
" txy.x = mix(PSin.flat_T.x, PSin.flat_T.y, factor.x);\n"
|
||||
" txy.y = mix(PSin.flat_T.z, PSin.flat_T.w, factor.y);\n"
|
||||
"\n"
|
||||
"#else\n"
|
||||
" vec2 txy = PSin_t.xy;\n"
|
||||
"#endif\n"
|
||||
" vec4 t = sample_color(txy, PSin_t.w);\n"
|
||||
"\n"
|
||||
" vec4 zero = vec4(0.0f, 0.0f, 0.0f, 0.0f);\n"
|
||||
" vec4 one = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
|
||||
|
|
Loading…
Reference in New Issue