mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-25 07:10:00 -06:00
some work on shadows.
(still need to check opaquePolyID)
This commit is contained in:
@ -76,6 +76,10 @@ PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
|||||||
PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei;
|
PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei;
|
||||||
PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei;
|
PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei;
|
||||||
|
|
||||||
|
PFNGLCOLORMASKIPROC glColorMaski;
|
||||||
|
|
||||||
|
PFNGLMEMORYBARRIERPROC glMemoryBarrier;
|
||||||
|
|
||||||
PFNGLGETSTRINGIPROC glGetStringi;
|
PFNGLGETSTRINGIPROC glGetStringi;
|
||||||
|
|
||||||
|
|
||||||
@ -111,7 +115,7 @@ void main()
|
|||||||
{
|
{
|
||||||
oColor = vec4(uColor).bgra / 31.0;
|
oColor = vec4(uColor).bgra / 31.0;
|
||||||
oAttr.r = uOpaquePolyID;
|
oAttr.r = uOpaquePolyID;
|
||||||
oAttr.g = uFogFlag;
|
oAttr.g = 0;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@ -416,6 +420,7 @@ void main()
|
|||||||
if (col.a < 30.5/31) discard;
|
if (col.a < 30.5/31) discard;
|
||||||
|
|
||||||
oColor = col;
|
oColor = col;
|
||||||
|
oAttr.r = (fPolygonAttr.x >> 24) & 0x3F;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@ -429,6 +434,7 @@ void main()
|
|||||||
if (col.a < 30.5/31) discard;
|
if (col.a < 30.5/31) discard;
|
||||||
|
|
||||||
oColor = col;
|
oColor = col;
|
||||||
|
oAttr.r = (fPolygonAttr.x >> 24) & 0x3F;
|
||||||
gl_FragDepth = fZ;
|
gl_FragDepth = fZ;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -460,21 +466,62 @@ void main()
|
|||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
const char* kRenderFS_ZS = R"(
|
const char* kRenderFS_ZSM = R"(
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
oColor = vec4(0,0,0,1);
|
oColor = vec4(0,0,0,1);
|
||||||
|
oAttr.g = 1;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
const char* kRenderFS_WS = R"(
|
const char* kRenderFS_WSM = R"(
|
||||||
|
|
||||||
smooth in float fZ;
|
smooth in float fZ;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
oColor = vec4(0,0,0,1);
|
oColor = vec4(0,0,0,1);
|
||||||
|
oAttr.g = 1;
|
||||||
|
gl_FragDepth = fZ;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_ZS = R"(
|
||||||
|
|
||||||
|
layout(binding=2) uniform usampler2D iAttrTex;
|
||||||
|
//layout(origin_upper_left) in vec4 gl_FragCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 col = FinalColor();
|
||||||
|
if (col.a < 0.5/31) discard;
|
||||||
|
if (col.a >= 30.5/31) discard;
|
||||||
|
|
||||||
|
uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0);
|
||||||
|
if (iAttr.y != 1) discard;
|
||||||
|
|
||||||
|
oColor = col;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_WS = R"(
|
||||||
|
|
||||||
|
layout(binding=2) uniform usampler2D iAttrTex;
|
||||||
|
//layout(origin_upper_left) in vec4 gl_FragCoord;
|
||||||
|
|
||||||
|
smooth in float fZ;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 col = FinalColor();
|
||||||
|
if (col.a < 0.5/31) discard;
|
||||||
|
if (col.a >= 30.5/31) discard;
|
||||||
|
|
||||||
|
uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0);
|
||||||
|
if (iAttr.y != 1) discard;
|
||||||
|
|
||||||
|
oColor = col;
|
||||||
gl_FragDepth = fZ;
|
gl_FragDepth = fZ;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -485,6 +532,7 @@ enum
|
|||||||
RenderFlag_WBuffer = 0x01,
|
RenderFlag_WBuffer = 0x01,
|
||||||
RenderFlag_Trans = 0x02,
|
RenderFlag_Trans = 0x02,
|
||||||
RenderFlag_ShadowMask = 0x04,
|
RenderFlag_ShadowMask = 0x04,
|
||||||
|
RenderFlag_Shadow = 0x08,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -586,6 +634,10 @@ bool InitGLExtensions()
|
|||||||
LOADPROC(GLBLENDFUNCSEPARATEI, glBlendFuncSeparatei);
|
LOADPROC(GLBLENDFUNCSEPARATEI, glBlendFuncSeparatei);
|
||||||
LOADPROC(GLBLENDEQUATIONSEPARATEI, glBlendEquationSeparatei);
|
LOADPROC(GLBLENDEQUATIONSEPARATEI, glBlendEquationSeparatei);
|
||||||
|
|
||||||
|
LOADPROC(GLCOLORMASKI, glColorMaski);
|
||||||
|
|
||||||
|
LOADPROC(GLMEMORYBARRIER, glMemoryBarrier);
|
||||||
|
|
||||||
LOADPROC(GLGETSTRINGI, glGetStringi);
|
LOADPROC(GLGETSTRINGI, glGetStringi);
|
||||||
|
|
||||||
#undef LOADPROC
|
#undef LOADPROC
|
||||||
@ -750,8 +802,12 @@ bool Init()
|
|||||||
if (!BuildRenderShader(RenderFlag_Trans | RenderFlag_WBuffer,
|
if (!BuildRenderShader(RenderFlag_Trans | RenderFlag_WBuffer,
|
||||||
kRenderVS_W, kRenderFS_WT)) return false;
|
kRenderVS_W, kRenderFS_WT)) return false;
|
||||||
if (!BuildRenderShader(RenderFlag_ShadowMask,
|
if (!BuildRenderShader(RenderFlag_ShadowMask,
|
||||||
kRenderVS_Z, kRenderFS_ZS)) return false;
|
kRenderVS_Z, kRenderFS_ZSM)) return false;
|
||||||
if (!BuildRenderShader(RenderFlag_ShadowMask | RenderFlag_WBuffer,
|
if (!BuildRenderShader(RenderFlag_ShadowMask | RenderFlag_WBuffer,
|
||||||
|
kRenderVS_W, kRenderFS_WSM)) return false;
|
||||||
|
if (!BuildRenderShader(RenderFlag_Shadow,
|
||||||
|
kRenderVS_Z, kRenderFS_ZS)) return false;
|
||||||
|
if (!BuildRenderShader(RenderFlag_Shadow | RenderFlag_WBuffer,
|
||||||
kRenderVS_W, kRenderFS_WS)) return false;
|
kRenderVS_W, kRenderFS_WS)) return false;
|
||||||
|
|
||||||
|
|
||||||
@ -871,6 +927,9 @@ bool Init()
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); // opaque polyID / shadow bits
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,6 +968,8 @@ void SetupPolygon(RendererPolygon* rp, Polygon* polygon)
|
|||||||
{
|
{
|
||||||
if (polygon->Translucent)
|
if (polygon->Translucent)
|
||||||
{
|
{
|
||||||
|
if (polygon->IsShadow) rp->RenderKey |= 0x20000;
|
||||||
|
else rp->RenderKey |= 0x10000;
|
||||||
rp->RenderKey |= (polygon->Attr >> 10) & 0x2; // bit11 - depth write
|
rp->RenderKey |= (polygon->Attr >> 10) & 0x2; // bit11 - depth write
|
||||||
rp->RenderKey |= (polygon->Attr & 0x3F000000) >> 16; // polygon ID
|
rp->RenderKey |= (polygon->Attr & 0x3F000000) >> 16; // polygon ID
|
||||||
}
|
}
|
||||||
@ -918,6 +979,10 @@ void SetupPolygon(RendererPolygon* rp, Polygon* polygon)
|
|||||||
rp->RenderKey |= 0x2;
|
rp->RenderKey |= 0x2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rp->RenderKey |= 0x30000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildPolygons(RendererPolygon* polygons, int npolys)
|
void BuildPolygons(RendererPolygon* polygons, int npolys)
|
||||||
@ -1029,6 +1094,8 @@ void RenderFrame()
|
|||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
glColorMaski(1, GL_TRUE, GL_TRUE, GL_FALSE, GL_FALSE);
|
||||||
|
|
||||||
// clear buffers
|
// clear buffers
|
||||||
// TODO: clear bitmap
|
// TODO: clear bitmap
|
||||||
@ -1064,6 +1131,8 @@ void RenderFrame()
|
|||||||
glDrawArrays(GL_TRIANGLES, 0, 2*3);
|
glDrawArrays(GL_TRIANGLES, 0, 2*3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glColorMaski(1, GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
|
||||||
if (RenderNumPolygons)
|
if (RenderNumPolygons)
|
||||||
{
|
{
|
||||||
// render shit here
|
// render shit here
|
||||||
@ -1106,10 +1175,12 @@ void RenderFrame()
|
|||||||
|
|
||||||
u16* iptr;
|
u16* iptr;
|
||||||
u32 curkey;
|
u32 curkey;
|
||||||
bool lastwasshadow;
|
bool lastwasshadow;bool darp;
|
||||||
|
//printf("morp %08X\n", RenderClearAttr1);
|
||||||
if (firsttrans > -1)
|
if (firsttrans > -1)
|
||||||
{
|
{
|
||||||
|
glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
if (PolygonList[firsttrans].PolyData->IsShadow) printf("!! GLORG!!! %08X\n", PolygonList[firsttrans].PolyData->Attr);
|
||||||
// pass 2: if needed, render translucent pixels that are against background pixels
|
// pass 2: if needed, render translucent pixels that are against background pixels
|
||||||
// when background alpha is zero, those need to be rendered with blending disabled
|
// when background alpha is zero, those need to be rendered with blending disabled
|
||||||
|
|
||||||
@ -1166,11 +1237,12 @@ void RenderFrame()
|
|||||||
|
|
||||||
iptr = PolygonList[firsttrans].Indices;
|
iptr = PolygonList[firsttrans].Indices;
|
||||||
curkey = 0xFFFFFFFF;
|
curkey = 0xFFFFFFFF;
|
||||||
lastwasshadow = false;
|
lastwasshadow = false; darp = false;
|
||||||
|
|
||||||
for (int i = firsttrans; i < npolys; i++)
|
for (int i = firsttrans; i < npolys; i++)
|
||||||
{
|
{
|
||||||
RendererPolygon* rp = &PolygonList[i];
|
RendererPolygon* rp = &PolygonList[i];
|
||||||
|
//printf("PASS 3 POLYGON %i: ATTR %08X (%d) | KEY %08X\n", i, rp->PolyData->Attr, (rp->PolyData->Attr>>4)&0x3, rp->RenderKey);
|
||||||
if (rp->RenderKey != curkey)
|
if (rp->RenderKey != curkey)
|
||||||
{
|
{
|
||||||
u16* endptr = rp->Indices;
|
u16* endptr = rp->Indices;
|
||||||
@ -1184,28 +1256,57 @@ void RenderFrame()
|
|||||||
|
|
||||||
if (rp->PolyData->IsShadowMask)
|
if (rp->PolyData->IsShadowMask)
|
||||||
{
|
{
|
||||||
if (!lastwasshadow)
|
//printf("beginning shadowmask batch: %d, %d\n", lastwasshadow, darp);
|
||||||
|
/*if (!lastwasshadow)
|
||||||
{
|
{
|
||||||
|
//glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
UseRenderShader(flags | RenderFlag_ShadowMask);
|
UseRenderShader(flags | RenderFlag_ShadowMask);
|
||||||
|
|
||||||
|
// shadow bits are set where the depth test fails
|
||||||
|
// sure enough, if GL_LESS fails, the opposite function would pass
|
||||||
|
glDepthFunc(GL_GEQUAL);
|
||||||
|
|
||||||
//glStencilFunc(GL_ALWAYS, 0x80, 0x80);
|
//glStencilFunc(GL_ALWAYS, 0x80, 0x80);
|
||||||
//glStencilOp(GL_REPLACE, GL_REPLACE, GL_KEEP);
|
//glStencilOp(GL_REPLACE, GL_REPLACE, GL_KEEP);
|
||||||
|
|
||||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
|
|
||||||
lastwasshadow = true;
|
lastwasshadow = true;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
UseRenderShader(flags | RenderFlag_ShadowMask);
|
||||||
|
|
||||||
|
glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
|
glDepthFunc(GL_GEQUAL);
|
||||||
|
glStencilFunc(GL_ALWAYS,0,0);
|
||||||
|
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
|
||||||
|
lastwasshadow=true;
|
||||||
|
|
||||||
|
darp = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (rp->PolyData->IsShadow) glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
|
||||||
|
//if (rp->PolyData->IsShadow) printf("beginning shadow batch: %d, %d\n", lastwasshadow, darp);
|
||||||
|
|
||||||
|
if (rp->PolyData->IsShadow)
|
||||||
|
UseRenderShader(flags | RenderFlag_Shadow);
|
||||||
|
else
|
||||||
|
UseRenderShader(flags | RenderFlag_Trans);
|
||||||
|
|
||||||
if (lastwasshadow)
|
if (lastwasshadow)
|
||||||
{
|
{
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
UseRenderShader(flags | RenderFlag_Trans);
|
|
||||||
|
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
|
||||||
lastwasshadow = false;
|
lastwasshadow = false;
|
||||||
}
|
}
|
||||||
@ -1221,6 +1322,8 @@ void RenderFrame()
|
|||||||
|
|
||||||
if (polyattr & (1<<11)) glDepthMask(GL_TRUE);
|
if (polyattr & (1<<11)) glDepthMask(GL_TRUE);
|
||||||
else glDepthMask(GL_FALSE);
|
else glDepthMask(GL_FALSE);
|
||||||
|
|
||||||
|
darp = rp->PolyData->IsShadow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user