Skip to content

Commit

Permalink
OpenGL Renderer: Don't force backface culling when drawing shadow pol…
Browse files Browse the repository at this point in the history
…ygons.

Do note that we need to do this for SoftRasterizer as well, but
SoftRasterizer will need some additional rework on shadow polygon
handling to get all the test cases to work.

Fixes issue #21.
  • Loading branch information
rogerman committed Dec 30, 2016
1 parent c9d5d69 commit cf8f021
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 32 deletions.
22 changes: 7 additions & 15 deletions desmume/src/OGLRender.cpp
Expand Up @@ -3012,25 +3012,17 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly)
glDepthFunc(oglDepthFunc[attr.enableDepthEqualTest]);

// Set up culling mode
if ( (attr.polygonMode == POLYGON_MODE_SHADOW) && (attr.polygonID != 0) )
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];

if (cullingMode == 0)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE);
}
else
{
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];

if (cullingMode == 0)
{
glDisable(GL_CULL_FACE);
}
else
{
glEnable(GL_CULL_FACE);
glCullFace(cullingMode);
}
glEnable(GL_CULL_FACE);
glCullFace(cullingMode);
}

// Handle drawing states for the polygon
Expand Down
22 changes: 7 additions & 15 deletions desmume/src/OGLRender_3_2.cpp
Expand Up @@ -1660,25 +1660,17 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly)
glDepthFunc(oglDepthFunc[attr.enableDepthEqualTest]);

// Set up culling mode
if ( (attr.polygonMode == POLYGON_MODE_SHADOW) && (attr.polygonID != 0) )
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];

if (cullingMode == 0)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE);
}
else
{
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];

if (cullingMode == 0)
{
glDisable(GL_CULL_FACE);
}
else
{
glEnable(GL_CULL_FACE);
glCullFace(cullingMode);
}
glEnable(GL_CULL_FACE);
glCullFace(cullingMode);
}

// Handle drawing states for the polygon
Expand Down
26 changes: 24 additions & 2 deletions desmume/src/rasterize.cpp
Expand Up @@ -1565,15 +1565,37 @@ void SoftRasterizerRenderer::GetAndLoadAllTextures()

bool PolygonIsVisible(const PolygonAttributes &polyAttr, const bool backfacing)
{
//this was added after adding multi-bit stencil buffer
//it seems that we also need to prevent drawing back faces of shadow polys for rendering
// Force backface culling when drawing shadow polygons.
if (polyAttr.polygonMode == POLYGON_MODE_SHADOW && polyAttr.polygonID != 0) return !backfacing;

// 2009/08/02 initial comments:
//this was added after adding multi-bit stencil buffer
//it seems that we also need to prevent drawing back faces of shadow polys for rendering
//
//another reasonable possibility is that we should be forcing back faces to draw (mariokart doesnt use them)
//and then only using a single bit buffer (but a cursory test of this doesnt actually work)
//
//this code needs to be here for shadows in wizard of oz to work.

// 2016/12/30 update:
// According to GBATEK, there really shouldn't be any special case for forcing backface culling on shadow
// polygons. All polygons, regardless of what they are, should always respect the culling mode. This is
// necessary for Mario Kart DS, where shadow polygons will fail to render under the Karts during Kart select
// if backface culling is forced (only fails for 150cc MIRROR, but works on the normal 150cc). Apparently,
// Mario Kart does use the backfaces of shadow polygons, but only for 150cc MIRROR and not the normal 150cc!
//
// However, there are a number of test cases where forcing backface culling is beneficial for the proper
// rendering of shadows, including:
// 1. The Wizard of Oz: Beyond the Yellow Brick Road -- shadows under Dorothy and Toto
// 2. Kingdom Hearts Re:coded -- shadow under Sora
// 3. Golden Sun: Dark Dawn -- shadow under the main character
//
// Based on these tests, we will need to rework shadow polygon handling at some point to pass all of these
// conditions. To note, the OpenGL renderer does render shadow polygons properly, without forced backface
// culling, for every one of these test cases.
//
// TODO: Rework shadow polygon handling in SoftRasterizer.

switch (polyAttr.surfaceCullingMode)
{
case 0: return false;
Expand Down

0 comments on commit cf8f021

Please sign in to comment.