From 87a9c3730cbc36c278e2218b8d8d81b9dfa354dd Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 22 Jun 2013 15:31:19 +0000 Subject: [PATCH] gpu: implement all depth test functions in the renderer. --- src/core.h | 4 +- src/gpu/rendercontext.cpp | 20 ++-- src/gpu/renderer.cpp | 180 +++++++++++++++++++++++------------- src/lol/gpu/rendercontext.h | 4 +- src/lol/gpu/renderer.h | 46 ++++++--- src/scene.cpp | 5 +- tutorial/08_fbo.cpp | 2 +- 7 files changed, 169 insertions(+), 92 deletions(-) diff --git a/src/core.h b/src/core.h index 59c5cf5c..8c514d6a 100644 --- a/src/core.h +++ b/src/core.h @@ -85,7 +85,9 @@ static inline int isnan(float f) #endif -/* XXX: workaround for X11 headers that try to #define None */ +/* XXX: workaround for X11 headers that try to #define these */ +#undef Always +#define Always Always #undef None #define None None diff --git a/src/gpu/rendercontext.cpp b/src/gpu/rendercontext.cpp index 863d1508..288ed2d7 100644 --- a/src/gpu/rendercontext.cpp +++ b/src/gpu/rendercontext.cpp @@ -57,10 +57,10 @@ private: TrackedState m_clear_color; TrackedState m_clear_depth; TrackedState m_alpha_blend; - TrackedState m_blend_src; - TrackedState m_blend_dst; + TrackedState m_blend_src; + TrackedState m_blend_dst; TrackedState m_alpha_test; - TrackedState m_depth_test; + TrackedState m_depth_func; TrackedState m_face_culling; }; @@ -92,8 +92,8 @@ RenderContext::~RenderContext() if (m_data->m_alpha_test.HasChanged()) g_renderer->SetAlphaTest(m_data->m_alpha_test.GetValue()); - if (m_data->m_depth_test.HasChanged()) - g_renderer->SetDepthTest(m_data->m_depth_test.GetValue()); + if (m_data->m_depth_func.HasChanged()) + g_renderer->SetDepthFunc(m_data->m_depth_func.GetValue()); if (m_data->m_face_culling.HasChanged()) g_renderer->SetFaceCulling(m_data->m_face_culling.GetValue()); @@ -125,7 +125,7 @@ void RenderContext::SetAlphaBlend(bool set) g_renderer->SetAlphaBlend(set); } -void RenderContext::SetBlendFunc(BlendFactor src, BlendFactor dst) +void RenderContext::SetBlendFunc(BlendFunc src, BlendFunc dst) { if (!m_data->m_blend_src.HasChanged()) m_data->m_blend_src.TrackValue(g_renderer->GetBlendFuncSrc()); @@ -143,12 +143,12 @@ void RenderContext::SetAlphaTest(bool set) g_renderer->SetAlphaTest(set); } -void RenderContext::SetDepthTest(bool set) +void RenderContext::SetDepthFunc(DepthFunc func) { - if (!m_data->m_depth_test.HasChanged()) - m_data->m_depth_test.TrackValue(g_renderer->GetDepthTest()); + if (!m_data->m_depth_func.HasChanged()) + m_data->m_depth_func.TrackValue(g_renderer->GetDepthFunc()); - g_renderer->SetDepthTest(set); + g_renderer->SetDepthFunc(func); } void RenderContext::SetFaceCulling(CullMode mode) diff --git a/src/gpu/renderer.cpp b/src/gpu/renderer.cpp index 139ceb1d..bcc7898a 100644 --- a/src/gpu/renderer.cpp +++ b/src/gpu/renderer.cpp @@ -55,9 +55,10 @@ class RendererData private: vec4 m_clear_color; float m_clear_depth; - BlendFactor m_blend_src, m_blend_dst; + BlendFunc m_blend_src, m_blend_dst; + DepthFunc m_depth_func; CullMode m_face_culling; - bool m_alpha_blend, m_alpha_test, m_depth_test; + bool m_alpha_blend, m_alpha_test; #if defined USE_D3D9 IDirect3DDevice9 *m_d3d_dev; @@ -101,15 +102,15 @@ Renderer::Renderer() m_data->m_alpha_test = true; SetAlphaTest(false); - m_data->m_blend_src = BlendFactor::Zero; - m_data->m_blend_dst = BlendFactor::Zero; - SetBlendFunc(BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha); + m_data->m_blend_src = BlendFunc::Zero; + m_data->m_blend_dst = BlendFunc::Zero; + SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha); - m_data->m_depth_test = false; - SetDepthTest(true); + m_data->m_depth_func = DepthFunc::Disabled; + SetDepthFunc(DepthFunc::LessOrEqual); - m_data->m_face_culling = CullMode::None; - SetFaceCulling(CullMode::CCW); + m_data->m_face_culling = CullMode::Disabled; + SetFaceCulling(CullMode::CounterClockwise); /* Add some rendering states that we don't export to the user */ #if defined USE_D3D9 || defined _XBOX @@ -198,51 +199,51 @@ bool Renderer::GetAlphaBlend() const * Blend function */ -void Renderer::SetBlendFunc(BlendFactor src, BlendFactor dst) +void Renderer::SetBlendFunc(BlendFunc src, BlendFunc dst) { if (m_data->m_blend_src == src && m_data->m_blend_dst == dst) return; #if defined USE_D3D9 || defined _XBOX enum D3DBLEND s1[2] = { D3DBLEND_ONE, D3DBLEND_ZERO }; - BlendFactor s2[2] = { src, dst }; + BlendFunc s2[2] = { src, dst }; for (int i = 0; i < 2; ++i) { switch (s2[i]) { - case BlendFactor::Zero: + case BlendFunc::Zero: s1[i] = D3DBLEND_ZERO; break; - case BlendFactor::One: + case BlendFunc::One: s1[i] = D3DBLEND_ONE; break; - case BlendFactor::SrcColor: + case BlendFunc::SrcColor: s1[i] = D3DBLEND_SRCCOLOR; break; - case BlendFactor::OneMinusSrcColor: + case BlendFunc::OneMinusSrcColor: s1[i] = D3DBLEND_INVSRCCOLOR; break; - case BlendFactor::DstColor: + case BlendFunc::DstColor: s1[i] = D3DBLEND_DESTCOLOR; break; - case BlendFactor::OneMinusDstColor: + case BlendFunc::OneMinusDstColor: s1[i] = D3DBLEND_INVDESTCOLOR; break; - case BlendFactor::SrcAlpha: + case BlendFunc::SrcAlpha: s1[i] = D3DBLEND_SRCALPHA; break; - case BlendFactor::OneMinusSrcAlpha: + case BlendFunc::OneMinusSrcAlpha: s1[i] = D3DBLEND_INVSRCALPHA; break; - case BlendFactor::DstAlpha: + case BlendFunc::DstAlpha: s1[i] = D3DBLEND_DESTALPHA; break; - case BlendFactor::OneMinusDstAlpha: + case BlendFunc::OneMinusDstAlpha: s1[i] = D3DBLEND_INVDESTALPHA; break; /* FiXME: these can be supported using D3DPBLENDCAPS_BLENDFACTOR */ - case BlendFactor::ConstantColor: - assert(0, "BlendFactor::ConstantColor not supported"); + case BlendFunc::ConstantColor: + assert(0, "BlendFunc::ConstantColor not supported"); break; - case BlendFactor::OneMinusConstantColor: - assert(0, "BlendFactor::OneMinusConstantColor not supported"); + case BlendFunc::OneMinusConstantColor: + assert(0, "BlendFunc::OneMinusConstantColor not supported"); break; - case BlendFactor::ConstantAlpha: - assert(0, "BlendFactor::ConstantAlpha not supported"); + case BlendFunc::ConstantAlpha: + assert(0, "BlendFunc::ConstantAlpha not supported"); break; - case BlendFactor::OneMinusConstantAlpha: - assert(0, "BlendFactor::OneMinusConstantAlpha not supported"); + case BlendFunc::OneMinusConstantAlpha: + assert(0, "BlendFunc::OneMinusConstantAlpha not supported"); break; } } @@ -251,39 +252,39 @@ void Renderer::SetBlendFunc(BlendFactor src, BlendFactor dst) m_data->m_d3d_dev->SetRenderState(D3DRS_DESTBLEND, s1[1]); #else GLenum s1[2] = { GL_ONE, GL_ZERO }; - BlendFactor s2[2] = { src, dst }; + BlendFunc s2[2] = { src, dst }; for (int i = 0; i < 2; ++i) { switch (s2[i]) { - case BlendFactor::Zero: + case BlendFunc::Zero: s1[i] = GL_ZERO; break; - case BlendFactor::One: + case BlendFunc::One: s1[i] = GL_ONE; break; - case BlendFactor::SrcColor: + case BlendFunc::SrcColor: s1[i] = GL_SRC_COLOR; break; - case BlendFactor::OneMinusSrcColor: + case BlendFunc::OneMinusSrcColor: s1[i] = GL_ONE_MINUS_SRC_COLOR; break; - case BlendFactor::DstColor: + case BlendFunc::DstColor: s1[i] = GL_DST_COLOR; break; - case BlendFactor::OneMinusDstColor: + case BlendFunc::OneMinusDstColor: s1[i] = GL_ONE_MINUS_DST_COLOR; break; - case BlendFactor::SrcAlpha: + case BlendFunc::SrcAlpha: s1[i] = GL_SRC_ALPHA; break; - case BlendFactor::OneMinusSrcAlpha: + case BlendFunc::OneMinusSrcAlpha: s1[i] = GL_ONE_MINUS_SRC_ALPHA; break; - case BlendFactor::DstAlpha: + case BlendFunc::DstAlpha: s1[i] = GL_DST_ALPHA; break; - case BlendFactor::OneMinusDstAlpha: + case BlendFunc::OneMinusDstAlpha: s1[i] = GL_ONE_MINUS_DST_ALPHA; break; - case BlendFactor::ConstantColor: + case BlendFunc::ConstantColor: s1[i] = GL_CONSTANT_COLOR; break; - case BlendFactor::OneMinusConstantColor: + case BlendFunc::OneMinusConstantColor: s1[i] = GL_ONE_MINUS_CONSTANT_COLOR; break; - case BlendFactor::ConstantAlpha: + case BlendFunc::ConstantAlpha: s1[i] = GL_CONSTANT_ALPHA; break; - case BlendFactor::OneMinusConstantAlpha: + case BlendFunc::OneMinusConstantAlpha: s1[i] = GL_ONE_MINUS_CONSTANT_ALPHA; break; } } @@ -295,12 +296,12 @@ void Renderer::SetBlendFunc(BlendFactor src, BlendFactor dst) m_data->m_blend_dst = dst; } -BlendFactor Renderer::GetBlendFuncSrc() const +BlendFunc Renderer::GetBlendFuncSrc() const { return m_data->m_blend_src; } -BlendFactor Renderer::GetBlendFuncDst() const +BlendFunc Renderer::GetBlendFuncDst() const { return m_data->m_blend_dst; } @@ -335,28 +336,81 @@ bool Renderer::GetAlphaTest() const * Depth test */ -void Renderer::SetDepthTest(bool set) +void Renderer::SetDepthFunc(DepthFunc func) { - if (m_data->m_depth_test == set) + if (m_data->m_depth_func == func) return; #if defined USE_D3D9 || defined _XBOX -# define STR0(x) #x -# define STR(x) STR0(x) -# pragma message(__FILE__ "(" STR(__LINE__) "): warning: Renderer::SetDepthTest() not implemented") -#else - if (set) - glEnable(GL_DEPTH_TEST); + switch (func) + { + case DepthFunc::Disabled: + break; /* Nothing to do */ + case DepthFunc::Never: + m_data->m_d3d_dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_NEVER); + break; + case DepthFunc::Less: + m_data->m_d3d_dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); + break; + case DepthFunc::Equal: + m_data->m_d3d_dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + break; + case DepthFunc::LessOrEqual: + m_data->m_d3d_dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + break; + case DepthFunc::Greater: + m_data->m_d3d_dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER); + break; + case DepthFunc::NotEqual: + m_data->m_d3d_dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_NOTEQUAL); + break; + case DepthFunc::GreaterOrEqual: + m_data->m_d3d_dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATEREQUAL); + break; + case DepthFunc::Always: + m_data->m_d3d_dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + break; + } + + if (func == DepthFunc::Disabled) + m_data->m_d3d_dev->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); else + m_data->m_d3d_dev->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); +#else + switch (func) + { + case DepthFunc::Disabled: + break; /* Nothing to do */ + case DepthFunc::Never: + glDepthFunc(GL_NEVER); break; + case DepthFunc::Less: + glDepthFunc(GL_LESS); break; + case DepthFunc::Equal: + glDepthFunc(GL_EQUAL); break; + case DepthFunc::LessOrEqual: + glDepthFunc(GL_LEQUAL); break; + case DepthFunc::Greater: + glDepthFunc(GL_GREATER); break; + case DepthFunc::NotEqual: + glDepthFunc(GL_NOTEQUAL); break; + case DepthFunc::GreaterOrEqual: + glDepthFunc(GL_GEQUAL); break; + case DepthFunc::Always: + glDepthFunc(GL_ALWAYS); break; + } + + if (func == DepthFunc::Disabled) glDisable(GL_DEPTH_TEST); + else + glEnable(GL_DEPTH_TEST); #endif - m_data->m_depth_test = set; + m_data->m_depth_func = func; } -bool Renderer::GetDepthTest() const +DepthFunc Renderer::GetDepthFunc() const { - return m_data->m_depth_test; + return m_data->m_depth_func; } /* @@ -371,27 +425,27 @@ void Renderer::SetFaceCulling(CullMode mode) #if defined USE_D3D9 || defined _XBOX switch (mode) { - case CullMode::None: + case CullMode::Disabled: m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); break; - case CullMode::CW: + case CullMode::Clockwise: m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); break; - case CullMode::CCW: + case CullMode::CounterClockwise: m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); break; } #else switch (mode) { - case CullMode::None: + case CullMode::Disabled: glDisable(GL_CULL_FACE); break; - case CullMode::CW: + case CullMode::Clockwise: glEnable(GL_CULL_FACE); glFrontFace(GL_CW); break; - case CullMode::CCW: + case CullMode::CounterClockwise: glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); break; diff --git a/src/lol/gpu/rendercontext.h b/src/lol/gpu/rendercontext.h index 6b0c0791..aac83065 100644 --- a/src/lol/gpu/rendercontext.h +++ b/src/lol/gpu/rendercontext.h @@ -30,9 +30,9 @@ public: void SetClearColor(vec4 color); void SetClearDepth(float depth); void SetAlphaBlend(bool set); - void SetBlendFunc(BlendFactor src, BlendFactor dst); + void SetBlendFunc(BlendFunc src, BlendFunc dst); void SetAlphaTest(bool set); - void SetDepthTest(bool set); + void SetDepthFunc(DepthFunc func); void SetFaceCulling(CullMode mode); private: diff --git a/src/lol/gpu/renderer.h b/src/lol/gpu/renderer.h index 85322282..d6920429 100644 --- a/src/lol/gpu/renderer.h +++ b/src/lol/gpu/renderer.h @@ -22,7 +22,7 @@ namespace lol class RendererData; /* A safe enum to indicate the blending factors. */ -struct BlendFactor +struct BlendFunc { enum Value { @@ -43,8 +43,8 @@ struct BlendFactor } m_value; - inline BlendFactor() : m_value(Zero) {} - inline BlendFactor(Value v) : m_value(v) {} + inline BlendFunc() : m_value(Zero) {} + inline BlendFunc(Value v) : m_value(v) {} inline operator Value() { return m_value; } }; @@ -53,17 +53,39 @@ struct CullMode { enum Value { - None, - CW, - CCW, + Disabled, + Clockwise, + CounterClockwise, } m_value; - inline CullMode() : m_value(None) {} + inline CullMode() : m_value(Disabled) {} inline CullMode(Value v) : m_value(v) {} inline operator Value() { return m_value; } }; +/* A safe enum to indicate the depth test mode. */ +struct DepthFunc +{ + enum Value + { + Disabled, + Never, + Less, + Equal, + LessOrEqual, + Greater, + NotEqual, + GreaterOrEqual, + Always, + } + m_value; + + inline DepthFunc() : m_value(Disabled) {} + inline DepthFunc(Value v) : m_value(v) {} + inline operator Value() { return m_value; } +}; + class Renderer { private: @@ -83,15 +105,15 @@ public: void SetAlphaBlend(bool set); bool GetAlphaBlend() const; - void SetBlendFunc(BlendFactor src, BlendFactor dst); - BlendFactor GetBlendFuncSrc() const; - BlendFactor GetBlendFuncDst() const; + void SetBlendFunc(BlendFunc src, BlendFunc dst); + BlendFunc GetBlendFuncSrc() const; + BlendFunc GetBlendFuncDst() const; void SetAlphaTest(bool set); bool GetAlphaTest() const; - void SetDepthTest(bool set); - bool GetDepthTest() const; + void SetDepthFunc(DepthFunc func); + DepthFunc GetDepthFunc() const; void SetFaceCulling(CullMode mode); CullMode GetFaceCulling() const; diff --git a/src/scene.cpp b/src/scene.cpp index 1ad30a51..e819807e 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -192,13 +192,12 @@ Array const &Scene::GetLights() const void Scene::Render() // XXX: rename to Blit() { RenderContext rc; - rc.SetDepthTest(true); + rc.SetDepthFunc(DepthFunc::LessOrEqual); rc.SetAlphaBlend(true); - rc.SetBlendFunc(BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha); + rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha); #if defined USE_D3D9 || defined _XBOX #else - glDepthFunc(GL_LEQUAL); #if defined HAVE_GL_2X && !defined __APPLE__ glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GEQUAL, 0.01f); diff --git a/tutorial/08_fbo.cpp b/tutorial/08_fbo.cpp index 40b4cbe9..43201bc2 100644 --- a/tutorial/08_fbo.cpp +++ b/tutorial/08_fbo.cpp @@ -90,7 +90,7 @@ public: /* FIXME: we should just disable depth test in the shader */ RenderContext rc; - rc.SetDepthTest(false); + rc.SetDepthFunc(DepthFunc::Disabled); m_fbo->Bind(); m_shader->Bind();