From 0b9389055676a0fddf38903036a1c0873664ea6d Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 22 Jun 2013 14:10:11 +0000 Subject: [PATCH] gpu: implement face culling mode in render contexts. --- src/core.h | 5 +++ src/gpu/rendercontext.cpp | 6 ++-- src/gpu/renderer.cpp | 61 ++++++++++++++++++++++++++++--------- src/gpu/vertexbuffer.cpp | 8 ----- src/lol/gpu/rendercontext.h | 2 +- src/lol/gpu/renderer.h | 20 ++++++++++-- src/video.cpp | 2 +- 7 files changed, 75 insertions(+), 29 deletions(-) diff --git a/src/core.h b/src/core.h index a1f80a3a..59c5cf5c 100644 --- a/src/core.h +++ b/src/core.h @@ -85,6 +85,11 @@ static inline int isnan(float f) #endif +/* XXX: workaround for X11 headers that try to #define None */ +#undef None +#define None None + + /* External declaration for LolFx files. */ #define LOLFX_RESOURCE_DECLARE(name) \ extern "C" char const *LOLFX_RESOURCE_NAME(name) diff --git a/src/gpu/rendercontext.cpp b/src/gpu/rendercontext.cpp index d271c26b..863d1508 100644 --- a/src/gpu/rendercontext.cpp +++ b/src/gpu/rendercontext.cpp @@ -61,7 +61,7 @@ private: TrackedState m_blend_dst; TrackedState m_alpha_test; TrackedState m_depth_test; - TrackedState m_face_culling; + TrackedState m_face_culling; }; /* @@ -151,12 +151,12 @@ void RenderContext::SetDepthTest(bool set) g_renderer->SetDepthTest(set); } -void RenderContext::SetFaceCulling(bool set) +void RenderContext::SetFaceCulling(CullMode mode) { if (!m_data->m_face_culling.HasChanged()) m_data->m_face_culling.TrackValue(g_renderer->GetFaceCulling()); - g_renderer->SetFaceCulling(set); + g_renderer->SetFaceCulling(mode); } } /* namespace lol */ diff --git a/src/gpu/renderer.cpp b/src/gpu/renderer.cpp index 86250c18..139ceb1d 100644 --- a/src/gpu/renderer.cpp +++ b/src/gpu/renderer.cpp @@ -31,6 +31,12 @@ #include "core.h" #include "lolgl.h" +#if defined USE_D3D9 +extern IDirect3DDevice9 *g_d3ddevice; +#elif defined _XBOX +extern D3DDevice *g_d3ddevice; +#endif + namespace lol { @@ -50,7 +56,14 @@ private: vec4 m_clear_color; float m_clear_depth; BlendFactor m_blend_src, m_blend_dst; - bool m_alpha_blend, m_alpha_test, m_depth_test, m_face_culling; + CullMode m_face_culling; + bool m_alpha_blend, m_alpha_test, m_depth_test; + +#if defined USE_D3D9 + IDirect3DDevice9 *m_d3d_dev; +#elif defined _XBOX + D3DDevice *m_d3d_dev; +#endif }; /* @@ -61,7 +74,8 @@ Renderer::Renderer() : m_data(new RendererData()) { #if defined USE_D3D9 || defined _XBOX - /* TODO */ + /* FIXME: we should be in charge of creating this */ + m_data->m_d3d_dev = g_d3ddevice; #else # if defined USE_GLEW && !defined __APPLE__ /* Initialise GLEW if necessary */ @@ -94,8 +108,8 @@ Renderer::Renderer() m_data->m_depth_test = false; SetDepthTest(true); - m_data->m_face_culling = false; - SetFaceCulling(true); + m_data->m_face_culling = CullMode::None; + SetFaceCulling(CullMode::CCW); /* Add some rendering states that we don't export to the user */ #if defined USE_D3D9 || defined _XBOX @@ -349,26 +363,45 @@ bool Renderer::GetDepthTest() const * Face culling */ -void Renderer::SetFaceCulling(bool set) +void Renderer::SetFaceCulling(CullMode mode) { - if (m_data->m_face_culling == set) + if (m_data->m_face_culling == mode) return; #if defined USE_D3D9 || defined _XBOX -# define STR0(x) #x -# define STR(x) STR0(x) -# pragma message(__FILE__ "(" STR(__LINE__) "): warning: Renderer::SetFaceCulling() not implemented") + switch (mode) + { + case CullMode::None: + m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + break; + case CullMode::CW: + m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + break; + case CullMode::CCW: + m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); + break; + } #else - if (set) - glEnable(GL_CULL_FACE); - else + switch (mode) + { + case CullMode::None: glDisable(GL_CULL_FACE); + break; + case CullMode::CW: + glEnable(GL_CULL_FACE); + glFrontFace(GL_CW); + break; + case CullMode::CCW: + glEnable(GL_CULL_FACE); + glFrontFace(GL_CCW); + break; + } #endif - m_data->m_face_culling = set; + m_data->m_face_culling = mode; } -bool Renderer::GetFaceCulling() const +CullMode Renderer::GetFaceCulling() const { return m_data->m_face_culling; } diff --git a/src/gpu/vertexbuffer.cpp b/src/gpu/vertexbuffer.cpp index 7303bbc6..b325502d 100644 --- a/src/gpu/vertexbuffer.cpp +++ b/src/gpu/vertexbuffer.cpp @@ -127,8 +127,6 @@ void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count) return; #if defined _XBOX || defined USE_D3D9 - if (FAILED(g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW))) - Abort(); switch (type) { case MeshPrimitive::Triangles: @@ -159,8 +157,6 @@ void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count) } #else /* FIXME: this has nothing to do here! */ - glFrontFace(GL_CCW); - switch (type) { case MeshPrimitive::Triangles: @@ -190,8 +186,6 @@ void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase, return; #if defined _XBOX || defined USE_D3D9 - if (FAILED(g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW))) - Abort(); switch (type) { case MeshPrimitive::Triangles: @@ -225,8 +219,6 @@ void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase, } #else /* FIXME: this has nothing to do here! */ - glFrontFace(GL_CCW); - switch (type) { case MeshPrimitive::Triangles: diff --git a/src/lol/gpu/rendercontext.h b/src/lol/gpu/rendercontext.h index 19ae0041..6b0c0791 100644 --- a/src/lol/gpu/rendercontext.h +++ b/src/lol/gpu/rendercontext.h @@ -33,7 +33,7 @@ public: void SetBlendFunc(BlendFactor src, BlendFactor dst); void SetAlphaTest(bool set); void SetDepthTest(bool set); - void SetFaceCulling(bool set); + void SetFaceCulling(CullMode mode); private: RenderContextData *m_data; diff --git a/src/lol/gpu/renderer.h b/src/lol/gpu/renderer.h index 6086a4f3..85322282 100644 --- a/src/lol/gpu/renderer.h +++ b/src/lol/gpu/renderer.h @@ -48,6 +48,22 @@ struct BlendFactor inline operator Value() { return m_value; } }; +/* A safe enum to indicate the face culling mode. */ +struct CullMode +{ + enum Value + { + None, + CW, + CCW, + } + m_value; + + inline CullMode() : m_value(None) {} + inline CullMode(Value v) : m_value(v) {} + inline operator Value() { return m_value; } +}; + class Renderer { private: @@ -77,8 +93,8 @@ public: void SetDepthTest(bool set); bool GetDepthTest() const; - void SetFaceCulling(bool set); - bool GetFaceCulling() const; + void SetFaceCulling(CullMode mode); + CullMode GetFaceCulling() const; private: RendererData *m_data; diff --git a/src/video.cpp b/src/video.cpp index 964370c3..e0a7c5b2 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -180,7 +180,7 @@ void Video::SetDebugRenderMode(DebugRenderMode d) { #if defined USE_D3D9 || defined _XBOX #elif defined HAVE_GLES_2X - glEnable(GL_CULL_FACE); +// glEnable(GL_CULL_FACE); #else // if (VideoData::render_mode == d && glIsEnabled(GL_CULL_FACE) == GL_TRUE) // SetFaceCulling(false);