Преглед на файлове

gpu: implement blend function and alpha test in the renderer.

legacy
Sam Hocevar sam преди 11 години
родител
ревизия
45c13689ec
променени са 6 файла, в които са добавени 222 реда и са изтрити 17 реда
  1. +34
    -0
      src/gpu/rendercontext.cpp
  2. +151
    -8
      src/gpu/renderer.cpp
  3. +0
    -8
      src/gpu/vertexbuffer.cpp
  4. +2
    -0
      src/lol/gpu/rendercontext.h
  5. +34
    -0
      src/lol/gpu/renderer.h
  6. +1
    -1
      src/scene.cpp

+ 34
- 0
src/gpu/rendercontext.cpp Целия файл

@@ -57,6 +57,9 @@ private:
TrackedState<vec4> m_clear_color;
TrackedState<float> m_clear_depth;
TrackedState<bool> m_alpha_blend;
TrackedState<BlendFactor> m_blend_src;
TrackedState<BlendFactor> m_blend_dst;
TrackedState<bool> m_alpha_test;
TrackedState<bool> m_depth_test;
TrackedState<bool> m_face_culling;
};
@@ -73,9 +76,22 @@ RenderContext::RenderContext()

RenderContext::~RenderContext()
{
if (m_data->m_clear_color.HasChanged())
g_renderer->SetClearColor(m_data->m_clear_color.GetValue());

if (m_data->m_clear_depth.HasChanged())
g_renderer->SetClearDepth(m_data->m_clear_depth.GetValue());

if (m_data->m_alpha_blend.HasChanged())
g_renderer->SetAlphaBlend(m_data->m_alpha_blend.GetValue());

if (m_data->m_blend_src.HasChanged())
g_renderer->SetBlendFunc(m_data->m_blend_src.GetValue(),
m_data->m_blend_dst.GetValue());

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());

@@ -109,6 +125,24 @@ void RenderContext::SetAlphaBlend(bool set)
g_renderer->SetAlphaBlend(set);
}

void RenderContext::SetBlendFunc(BlendFactor src, BlendFactor dst)
{
if (!m_data->m_blend_src.HasChanged())
m_data->m_blend_src.TrackValue(g_renderer->GetBlendFuncSrc());
if (!m_data->m_blend_dst.HasChanged())
m_data->m_blend_dst.TrackValue(g_renderer->GetBlendFuncDst());

g_renderer->SetBlendFunc(src, dst);
}

void RenderContext::SetAlphaTest(bool set)
{
if (!m_data->m_alpha_test.HasChanged())
m_data->m_alpha_test.TrackValue(g_renderer->GetAlphaTest());

g_renderer->SetAlphaTest(set);
}

void RenderContext::SetDepthTest(bool set)
{
if (!m_data->m_depth_test.HasChanged())


+ 151
- 8
src/gpu/renderer.cpp Целия файл

@@ -49,7 +49,8 @@ class RendererData
private:
vec4 m_clear_color;
float m_clear_depth;
bool m_blend, m_depth_test, m_face_culling;
BlendFactor m_blend_src, m_blend_dst;
bool m_alpha_blend, m_alpha_test, m_depth_test, m_face_culling;
};

/*
@@ -80,9 +81,16 @@ Renderer::Renderer()
m_data->m_clear_depth = -1.f;
SetClearDepth(1.f);

m_data->m_blend = false;
m_data->m_alpha_blend = false;
SetAlphaBlend(true);

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_depth_test = false;
SetDepthTest(true);

@@ -152,13 +160,11 @@ float Renderer::GetClearDepth() const

void Renderer::SetAlphaBlend(bool set)
{
if (m_data->m_blend == set)
if (m_data->m_alpha_blend == set)
return;

#if defined USE_D3D9 || defined _XBOX
# define STR0(x) #x
# define STR(x) STR0(x)
# pragma message(__FILE__ "(" STR(__LINE__) "): warning: Renderer::SetAlphaBlend() not implemented")
m_data->m_d3d_dev->SetRenderState(D3DRS_ALPHABLENDENABLE, set ? 1 : 0);
#else
if (set)
glEnable(GL_BLEND);
@@ -166,12 +172,149 @@ void Renderer::SetAlphaBlend(bool set)
glDisable(GL_BLEND);
#endif

m_data->m_blend = set;
m_data->m_alpha_blend = set;
}

bool Renderer::GetAlphaBlend() const
{
return m_data->m_blend;
return m_data->m_alpha_blend;
}

/*
* Blend function
*/

void Renderer::SetBlendFunc(BlendFactor src, BlendFactor 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 };

for (int i = 0; i < 2; ++i)
{
switch (s2[i])
{
case BlendFactor::Zero:
s1[i] = D3DBLEND_ZERO; break;
case BlendFactor::One:
s1[i] = D3DBLEND_ONE; break;
case BlendFactor::SrcColor:
s1[i] = D3DBLEND_SRCCOLOR; break;
case BlendFactor::OneMinusSrcColor:
s1[i] = D3DBLEND_INVSRCCOLOR; break;
case BlendFactor::DstColor:
s1[i] = D3DBLEND_DESTCOLOR; break;
case BlendFactor::OneMinusDstColor:
s1[i] = D3DBLEND_INVDESTCOLOR; break;
case BlendFactor::SrcAlpha:
s1[i] = D3DBLEND_SRCALPHA; break;
case BlendFactor::OneMinusSrcAlpha:
s1[i] = D3DBLEND_INVSRCALPHA; break;
case BlendFactor::DstAlpha:
s1[i] = D3DBLEND_DESTALPHA; break;
case BlendFactor::OneMinusDstAlpha:
s1[i] = D3DBLEND_INVDESTALPHA; break;
/* FiXME: these can be supported using D3DPBLENDCAPS_BLENDFACTOR */
case BlendFactor::ConstantColor:
assert(0, "BlendFactor::ConstantColor not supported");
break;
case BlendFactor::OneMinusConstantColor:
assert(0, "BlendFactor::OneMinusConstantColor not supported");
break;
case BlendFactor::ConstantAlpha:
assert(0, "BlendFactor::ConstantAlpha not supported");
break;
case BlendFactor::OneMinusConstantAlpha:
assert(0, "BlendFactor::OneMinusConstantAlpha not supported");
break;
}
}

m_data->m_d3d_dev->SetRenderState(D3DRS_SRCBLEND, s1[0]);
m_data->m_d3d_dev->SetRenderState(D3DRS_DESTBLEND, s1[1]);
#else
GLenum s1[2] = { GL_ONE, GL_ZERO };
BlendFactor s2[2] = { src, dst };

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

glBlendFunc(s1[0], s1[1]);
#endif

m_data->m_blend_src = src;
m_data->m_blend_dst = dst;
}

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

BlendFactor Renderer::GetBlendFuncDst() const
{
return m_data->m_blend_dst;
}

/*
* Alpha testing
*/

void Renderer::SetAlphaTest(bool set)
{
if (m_data->m_alpha_test == set)
return;

#if defined USE_D3D9 || defined _XBOX
m_data->m_d3d_dev->SetRenderState(D3DRS_ALPHATESTENABLE, set ? 1 : 0);
#else
if (set)
glEnable(GL_ALPHA_TEST);
else
glDisable(GL_ALPHA_TEST);
#endif

m_data->m_alpha_test = set;
}

bool Renderer::GetAlphaTest() const
{
return m_data->m_alpha_test;
}

/*


+ 0
- 8
src/gpu/vertexbuffer.cpp Целия файл

@@ -127,9 +127,6 @@ void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count)
return;

#if defined _XBOX || defined USE_D3D9
g_d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
g_d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
if (FAILED(g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)))
Abort();
switch (type)
@@ -163,7 +160,6 @@ void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count)
#else
/* FIXME: this has nothing to do here! */
glFrontFace(GL_CCW);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

switch (type)
{
@@ -194,9 +190,6 @@ void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase,
return;

#if defined _XBOX || defined USE_D3D9
g_d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
g_d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
if (FAILED(g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)))
Abort();
switch (type)
@@ -233,7 +226,6 @@ void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase,
#else
/* FIXME: this has nothing to do here! */
glFrontFace(GL_CCW);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

switch (type)
{


+ 2
- 0
src/lol/gpu/rendercontext.h Целия файл

@@ -30,6 +30,8 @@ public:
void SetClearColor(vec4 color);
void SetClearDepth(float depth);
void SetAlphaBlend(bool set);
void SetBlendFunc(BlendFactor src, BlendFactor dst);
void SetAlphaTest(bool set);
void SetDepthTest(bool set);
void SetFaceCulling(bool set);



+ 34
- 0
src/lol/gpu/renderer.h Целия файл

@@ -21,6 +21,33 @@ namespace lol

class RendererData;

/* A safe enum to indicate the blending factors. */
struct BlendFactor
{
enum Value
{
Zero,
One,
SrcColor,
OneMinusSrcColor,
DstColor,
OneMinusDstColor,
SrcAlpha,
OneMinusSrcAlpha,
DstAlpha,
OneMinusDstAlpha,
ConstantColor,
OneMinusConstantColor,
ConstantAlpha,
OneMinusConstantAlpha,
}
m_value;

inline BlendFactor() : m_value(Zero) {}
inline BlendFactor(Value v) : m_value(v) {}
inline operator Value() { return m_value; }
};

class Renderer
{
private:
@@ -40,6 +67,13 @@ public:
void SetAlphaBlend(bool set);
bool GetAlphaBlend() const;

void SetBlendFunc(BlendFactor src, BlendFactor dst);
BlendFactor GetBlendFuncSrc() const;
BlendFactor GetBlendFuncDst() const;

void SetAlphaTest(bool set);
bool GetAlphaTest() const;

void SetDepthTest(bool set);
bool GetDepthTest() const;



+ 1
- 1
src/scene.cpp Целия файл

@@ -194,6 +194,7 @@ void Scene::Render() // XXX: rename to Blit()
RenderContext rc;
rc.SetDepthTest(true);
rc.SetAlphaBlend(true);
rc.SetBlendFunc(BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha);

#if defined USE_D3D9 || defined _XBOX
#else
@@ -202,7 +203,6 @@ void Scene::Render() // XXX: rename to Blit()
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GEQUAL, 0.01f);
#endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif

/* Early test if nothing needs to be rendered */


Зареждане…
Отказ
Запис