浏览代码

gpu: implement all depth test functions in the renderer.

legacy
Sam Hocevar sam 12 年前
父节点
当前提交
87a9c3730c
共有 7 个文件被更改,包括 169 次插入92 次删除
  1. +3
    -1
      src/core.h
  2. +10
    -10
      src/gpu/rendercontext.cpp
  3. +117
    -63
      src/gpu/renderer.cpp
  4. +2
    -2
      src/lol/gpu/rendercontext.h
  5. +34
    -12
      src/lol/gpu/renderer.h
  6. +2
    -3
      src/scene.cpp
  7. +1
    -1
      tutorial/08_fbo.cpp

+ 3
- 1
src/core.h 查看文件

@@ -85,7 +85,9 @@ static inline int isnan(float f)
#endif #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 #undef None
#define None None #define None None




+ 10
- 10
src/gpu/rendercontext.cpp 查看文件

@@ -57,10 +57,10 @@ private:
TrackedState<vec4> m_clear_color; TrackedState<vec4> m_clear_color;
TrackedState<float> m_clear_depth; TrackedState<float> m_clear_depth;
TrackedState<bool> m_alpha_blend; TrackedState<bool> m_alpha_blend;
TrackedState<BlendFactor> m_blend_src;
TrackedState<BlendFactor> m_blend_dst;
TrackedState<BlendFunc> m_blend_src;
TrackedState<BlendFunc> m_blend_dst;
TrackedState<bool> m_alpha_test; TrackedState<bool> m_alpha_test;
TrackedState<bool> m_depth_test;
TrackedState<DepthFunc> m_depth_func;
TrackedState<CullMode> m_face_culling; TrackedState<CullMode> m_face_culling;
}; };


@@ -92,8 +92,8 @@ RenderContext::~RenderContext()
if (m_data->m_alpha_test.HasChanged()) if (m_data->m_alpha_test.HasChanged())
g_renderer->SetAlphaTest(m_data->m_alpha_test.GetValue()); 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()) if (m_data->m_face_culling.HasChanged())
g_renderer->SetFaceCulling(m_data->m_face_culling.GetValue()); g_renderer->SetFaceCulling(m_data->m_face_culling.GetValue());
@@ -125,7 +125,7 @@ void RenderContext::SetAlphaBlend(bool set)
g_renderer->SetAlphaBlend(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()) if (!m_data->m_blend_src.HasChanged())
m_data->m_blend_src.TrackValue(g_renderer->GetBlendFuncSrc()); m_data->m_blend_src.TrackValue(g_renderer->GetBlendFuncSrc());
@@ -143,12 +143,12 @@ void RenderContext::SetAlphaTest(bool set)
g_renderer->SetAlphaTest(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) void RenderContext::SetFaceCulling(CullMode mode)


+ 117
- 63
src/gpu/renderer.cpp 查看文件

@@ -55,9 +55,10 @@ class RendererData
private: private:
vec4 m_clear_color; vec4 m_clear_color;
float m_clear_depth; 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; 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 #if defined USE_D3D9
IDirect3DDevice9 *m_d3d_dev; IDirect3DDevice9 *m_d3d_dev;
@@ -101,15 +102,15 @@ Renderer::Renderer()
m_data->m_alpha_test = true; m_data->m_alpha_test = true;
SetAlphaTest(false); 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 */ /* Add some rendering states that we don't export to the user */
#if defined USE_D3D9 || defined _XBOX #if defined USE_D3D9 || defined _XBOX
@@ -198,51 +199,51 @@ bool Renderer::GetAlphaBlend() const
* Blend function * 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) if (m_data->m_blend_src == src && m_data->m_blend_dst == dst)
return; return;


#if defined USE_D3D9 || defined _XBOX #if defined USE_D3D9 || defined _XBOX
enum D3DBLEND s1[2] = { D3DBLEND_ONE, D3DBLEND_ZERO }; 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) for (int i = 0; i < 2; ++i)
{ {
switch (s2[i]) switch (s2[i])
{ {
case BlendFactor::Zero:
case BlendFunc::Zero:
s1[i] = D3DBLEND_ZERO; break; s1[i] = D3DBLEND_ZERO; break;
case BlendFactor::One:
case BlendFunc::One:
s1[i] = D3DBLEND_ONE; break; s1[i] = D3DBLEND_ONE; break;
case BlendFactor::SrcColor:
case BlendFunc::SrcColor:
s1[i] = D3DBLEND_SRCCOLOR; break; s1[i] = D3DBLEND_SRCCOLOR; break;
case BlendFactor::OneMinusSrcColor:
case BlendFunc::OneMinusSrcColor:
s1[i] = D3DBLEND_INVSRCCOLOR; break; s1[i] = D3DBLEND_INVSRCCOLOR; break;
case BlendFactor::DstColor:
case BlendFunc::DstColor:
s1[i] = D3DBLEND_DESTCOLOR; break; s1[i] = D3DBLEND_DESTCOLOR; break;
case BlendFactor::OneMinusDstColor:
case BlendFunc::OneMinusDstColor:
s1[i] = D3DBLEND_INVDESTCOLOR; break; s1[i] = D3DBLEND_INVDESTCOLOR; break;
case BlendFactor::SrcAlpha:
case BlendFunc::SrcAlpha:
s1[i] = D3DBLEND_SRCALPHA; break; s1[i] = D3DBLEND_SRCALPHA; break;
case BlendFactor::OneMinusSrcAlpha:
case BlendFunc::OneMinusSrcAlpha:
s1[i] = D3DBLEND_INVSRCALPHA; break; s1[i] = D3DBLEND_INVSRCALPHA; break;
case BlendFactor::DstAlpha:
case BlendFunc::DstAlpha:
s1[i] = D3DBLEND_DESTALPHA; break; s1[i] = D3DBLEND_DESTALPHA; break;
case BlendFactor::OneMinusDstAlpha:
case BlendFunc::OneMinusDstAlpha:
s1[i] = D3DBLEND_INVDESTALPHA; break; s1[i] = D3DBLEND_INVDESTALPHA; break;
/* FiXME: these can be supported using D3DPBLENDCAPS_BLENDFACTOR */ /* 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; break;
case BlendFactor::OneMinusConstantColor:
assert(0, "BlendFactor::OneMinusConstantColor not supported");
case BlendFunc::OneMinusConstantColor:
assert(0, "BlendFunc::OneMinusConstantColor not supported");
break; break;
case BlendFactor::ConstantAlpha:
assert(0, "BlendFactor::ConstantAlpha not supported");
case BlendFunc::ConstantAlpha:
assert(0, "BlendFunc::ConstantAlpha not supported");
break; break;
case BlendFactor::OneMinusConstantAlpha:
assert(0, "BlendFactor::OneMinusConstantAlpha not supported");
case BlendFunc::OneMinusConstantAlpha:
assert(0, "BlendFunc::OneMinusConstantAlpha not supported");
break; break;
} }
} }
@@ -251,39 +252,39 @@ void Renderer::SetBlendFunc(BlendFactor src, BlendFactor dst)
m_data->m_d3d_dev->SetRenderState(D3DRS_DESTBLEND, s1[1]); m_data->m_d3d_dev->SetRenderState(D3DRS_DESTBLEND, s1[1]);
#else #else
GLenum s1[2] = { GL_ONE, GL_ZERO }; GLenum s1[2] = { GL_ONE, GL_ZERO };
BlendFactor s2[2] = { src, dst };
BlendFunc s2[2] = { src, dst };


for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
{ {
switch (s2[i]) switch (s2[i])
{ {
case BlendFactor::Zero:
case BlendFunc::Zero:
s1[i] = GL_ZERO; break; s1[i] = GL_ZERO; break;
case BlendFactor::One:
case BlendFunc::One:
s1[i] = GL_ONE; break; s1[i] = GL_ONE; break;
case BlendFactor::SrcColor:
case BlendFunc::SrcColor:
s1[i] = GL_SRC_COLOR; break; s1[i] = GL_SRC_COLOR; break;
case BlendFactor::OneMinusSrcColor:
case BlendFunc::OneMinusSrcColor:
s1[i] = GL_ONE_MINUS_SRC_COLOR; break; s1[i] = GL_ONE_MINUS_SRC_COLOR; break;
case BlendFactor::DstColor:
case BlendFunc::DstColor:
s1[i] = GL_DST_COLOR; break; s1[i] = GL_DST_COLOR; break;
case BlendFactor::OneMinusDstColor:
case BlendFunc::OneMinusDstColor:
s1[i] = GL_ONE_MINUS_DST_COLOR; break; s1[i] = GL_ONE_MINUS_DST_COLOR; break;
case BlendFactor::SrcAlpha:
case BlendFunc::SrcAlpha:
s1[i] = GL_SRC_ALPHA; break; s1[i] = GL_SRC_ALPHA; break;
case BlendFactor::OneMinusSrcAlpha:
case BlendFunc::OneMinusSrcAlpha:
s1[i] = GL_ONE_MINUS_SRC_ALPHA; break; s1[i] = GL_ONE_MINUS_SRC_ALPHA; break;
case BlendFactor::DstAlpha:
case BlendFunc::DstAlpha:
s1[i] = GL_DST_ALPHA; break; s1[i] = GL_DST_ALPHA; break;
case BlendFactor::OneMinusDstAlpha:
case BlendFunc::OneMinusDstAlpha:
s1[i] = GL_ONE_MINUS_DST_ALPHA; break; s1[i] = GL_ONE_MINUS_DST_ALPHA; break;
case BlendFactor::ConstantColor:
case BlendFunc::ConstantColor:
s1[i] = GL_CONSTANT_COLOR; break; s1[i] = GL_CONSTANT_COLOR; break;
case BlendFactor::OneMinusConstantColor:
case BlendFunc::OneMinusConstantColor:
s1[i] = GL_ONE_MINUS_CONSTANT_COLOR; break; s1[i] = GL_ONE_MINUS_CONSTANT_COLOR; break;
case BlendFactor::ConstantAlpha:
case BlendFunc::ConstantAlpha:
s1[i] = GL_CONSTANT_ALPHA; break; s1[i] = GL_CONSTANT_ALPHA; break;
case BlendFactor::OneMinusConstantAlpha:
case BlendFunc::OneMinusConstantAlpha:
s1[i] = GL_ONE_MINUS_CONSTANT_ALPHA; break; 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; m_data->m_blend_dst = dst;
} }


BlendFactor Renderer::GetBlendFuncSrc() const
BlendFunc Renderer::GetBlendFuncSrc() const
{ {
return m_data->m_blend_src; return m_data->m_blend_src;
} }


BlendFactor Renderer::GetBlendFuncDst() const
BlendFunc Renderer::GetBlendFuncDst() const
{ {
return m_data->m_blend_dst; return m_data->m_blend_dst;
} }
@@ -335,28 +336,81 @@ bool Renderer::GetAlphaTest() const
* Depth test * 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; return;


#if defined USE_D3D9 || defined _XBOX #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 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); glDisable(GL_DEPTH_TEST);
else
glEnable(GL_DEPTH_TEST);
#endif #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 #if defined USE_D3D9 || defined _XBOX
switch (mode) switch (mode)
{ {
case CullMode::None:
case CullMode::Disabled:
m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
break; break;
case CullMode::CW:
case CullMode::Clockwise:
m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
break; break;
case CullMode::CCW:
case CullMode::CounterClockwise:
m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); m_data->m_d3d_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
break; break;
} }
#else #else
switch (mode) switch (mode)
{ {
case CullMode::None:
case CullMode::Disabled:
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
break; break;
case CullMode::CW:
case CullMode::Clockwise:
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glFrontFace(GL_CW); glFrontFace(GL_CW);
break; break;
case CullMode::CCW:
case CullMode::CounterClockwise:
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW); glFrontFace(GL_CCW);
break; break;


+ 2
- 2
src/lol/gpu/rendercontext.h 查看文件

@@ -30,9 +30,9 @@ public:
void SetClearColor(vec4 color); void SetClearColor(vec4 color);
void SetClearDepth(float depth); void SetClearDepth(float depth);
void SetAlphaBlend(bool set); void SetAlphaBlend(bool set);
void SetBlendFunc(BlendFactor src, BlendFactor dst);
void SetBlendFunc(BlendFunc src, BlendFunc dst);
void SetAlphaTest(bool set); void SetAlphaTest(bool set);
void SetDepthTest(bool set);
void SetDepthFunc(DepthFunc func);
void SetFaceCulling(CullMode mode); void SetFaceCulling(CullMode mode);


private: private:


+ 34
- 12
src/lol/gpu/renderer.h 查看文件

@@ -22,7 +22,7 @@ namespace lol
class RendererData; class RendererData;


/* A safe enum to indicate the blending factors. */ /* A safe enum to indicate the blending factors. */
struct BlendFactor
struct BlendFunc
{ {
enum Value enum Value
{ {
@@ -43,8 +43,8 @@ struct BlendFactor
} }
m_value; 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; } inline operator Value() { return m_value; }
}; };


@@ -53,17 +53,39 @@ struct CullMode
{ {
enum Value enum Value
{ {
None,
CW,
CCW,
Disabled,
Clockwise,
CounterClockwise,
} }
m_value; m_value;


inline CullMode() : m_value(None) {}
inline CullMode() : m_value(Disabled) {}
inline CullMode(Value v) : m_value(v) {} inline CullMode(Value v) : m_value(v) {}
inline operator Value() { return m_value; } 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 class Renderer
{ {
private: private:
@@ -83,15 +105,15 @@ public:
void SetAlphaBlend(bool set); void SetAlphaBlend(bool set);
bool GetAlphaBlend() const; 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); void SetAlphaTest(bool set);
bool GetAlphaTest() const; bool GetAlphaTest() const;


void SetDepthTest(bool set);
bool GetDepthTest() const;
void SetDepthFunc(DepthFunc func);
DepthFunc GetDepthFunc() const;


void SetFaceCulling(CullMode mode); void SetFaceCulling(CullMode mode);
CullMode GetFaceCulling() const; CullMode GetFaceCulling() const;


+ 2
- 3
src/scene.cpp 查看文件

@@ -192,13 +192,12 @@ Array<Light *> const &Scene::GetLights() const
void Scene::Render() // XXX: rename to Blit() void Scene::Render() // XXX: rename to Blit()
{ {
RenderContext rc; RenderContext rc;
rc.SetDepthTest(true);
rc.SetDepthFunc(DepthFunc::LessOrEqual);
rc.SetAlphaBlend(true); rc.SetAlphaBlend(true);
rc.SetBlendFunc(BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha);
rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha);


#if defined USE_D3D9 || defined _XBOX #if defined USE_D3D9 || defined _XBOX
#else #else
glDepthFunc(GL_LEQUAL);
#if defined HAVE_GL_2X && !defined __APPLE__ #if defined HAVE_GL_2X && !defined __APPLE__
glEnable(GL_ALPHA_TEST); glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GEQUAL, 0.01f); glAlphaFunc(GL_GEQUAL, 0.01f);


+ 1
- 1
tutorial/08_fbo.cpp 查看文件

@@ -90,7 +90,7 @@ public:


/* FIXME: we should just disable depth test in the shader */ /* FIXME: we should just disable depth test in the shader */
RenderContext rc; RenderContext rc;
rc.SetDepthTest(false);
rc.SetDepthFunc(DepthFunc::Disabled);


m_fbo->Bind(); m_fbo->Bind();
m_shader->Bind(); m_shader->Bind();


正在加载...
取消
保存