@@ -57,6 +57,7 @@ private: | |||
TrackedState<float> m_clear_depth; | |||
TrackedState<AlphaFunc> m_alpha_func; | |||
TrackedState<float> m_alpha_value; | |||
TrackedState<BlendEquation> m_blend_rgb, m_blend_alpha; | |||
TrackedState<BlendFunc> m_blend_src, m_blend_dst; | |||
TrackedState<DepthFunc> m_depth_func; | |||
TrackedState<DepthMask> m_depth_mask; | |||
@@ -166,6 +167,26 @@ float RenderContext::GetAlphaValue() | |||
return g_renderer->GetAlphaValue(); | |||
} | |||
void RenderContext::SetBlendEquation(BlendEquation rgb, BlendEquation alpha) | |||
{ | |||
if (!m_data->m_blend_rgb.HasChanged()) | |||
m_data->m_blend_rgb.TrackValue(g_renderer->GetBlendEquationRgb()); | |||
if (!m_data->m_blend_alpha.HasChanged()) | |||
m_data->m_blend_alpha.TrackValue(g_renderer->GetBlendEquationAlpha()); | |||
g_renderer->SetBlendEquation(rgb, alpha); | |||
} | |||
BlendEquation RenderContext::GetBlendEquationRgb() | |||
{ | |||
return g_renderer->GetBlendEquationRgb(); | |||
} | |||
BlendEquation RenderContext::GetBlendEquationAlpha() | |||
{ | |||
return g_renderer->GetBlendEquationAlpha(); | |||
} | |||
void RenderContext::SetBlendFunc(BlendFunc src, BlendFunc dst) | |||
{ | |||
if (!m_data->m_blend_src.HasChanged()) | |||
@@ -61,6 +61,7 @@ private: | |||
float m_clear_depth; | |||
AlphaFunc m_alpha_func; | |||
float m_alpha_value; | |||
BlendEquation m_blend_rgb, m_blend_alpha; | |||
BlendFunc m_blend_src, m_blend_dst; | |||
DepthFunc m_depth_func; | |||
DepthMask m_depth_mask; | |||
@@ -150,6 +151,10 @@ Renderer::Renderer(ivec2 size) | |||
m_data->m_alpha_value = -1.0f; | |||
SetAlphaFunc(AlphaFunc::Disabled, 0.0f); | |||
m_data->m_blend_rgb = BlendEquation::Subtract; | |||
m_data->m_blend_alpha = BlendEquation::Subtract; | |||
SetBlendEquation(BlendEquation::Add, BlendEquation::Add); | |||
m_data->m_blend_src = BlendFunc::Disabled; | |||
m_data->m_blend_dst = BlendFunc::Disabled; | |||
SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha); | |||
@@ -408,6 +413,84 @@ float Renderer::GetAlphaValue() const | |||
return m_data->m_alpha_value; | |||
} | |||
/* | |||
* Blend equation | |||
*/ | |||
void Renderer::SetBlendEquation(BlendEquation rgb, BlendEquation alpha) | |||
{ | |||
if (m_data->m_blend_rgb == rgb && m_data->m_blend_alpha == alpha) | |||
return; | |||
#if defined USE_D3D9 || defined _XBOX | |||
D3DBLEND s1[2] = { D3DBLENDOP_ADD, D3DBLENDOP_ADD }; | |||
BlendEquation s2[2] = { rgb, alpha }; | |||
for (int i = 0; i < 2; ++i) | |||
{ | |||
switch (s2[i]) | |||
{ | |||
case BlendEquation::Add: | |||
s1[i] = D3DBLENDOP_ADD; break; | |||
case BlendEquation::Subtract: | |||
s1[i] = D3DBLENDOP_SUBTRACT; break; | |||
case BlendEquation::ReverseSubtract: | |||
s1[i] = D3DBLENDOP_REVSUBTRACT; break; | |||
case BlendEquation::Max: | |||
s1[i] = D3DBLENDOP_MAX; break; | |||
case BlendEquation::Min: | |||
s1[i] = D3DBLENDOP_MIN; break; | |||
} | |||
} | |||
m_data->m_d3d_dev->SetRenderState(D3DRS_BLENDOP, s1[0]); | |||
m_data->m_d3d_dev->SetRenderState(D3DRS_BLENDOPALPHA, s1[1]); | |||
#else | |||
GLenum s1[2] = { GL_FUNC_ADD, GL_FUNC_ADD }; | |||
BlendEquation s2[2] = { rgb, alpha }; | |||
for (int i = 0; i < 2; ++i) | |||
{ | |||
switch (s2[i]) | |||
{ | |||
case BlendEquation::Add: | |||
s1[i] = GL_FUNC_ADD; break; | |||
case BlendEquation::Subtract: | |||
s1[i] = GL_FUNC_SUBTRACT; break; | |||
case BlendEquation::ReverseSubtract: | |||
s1[i] = GL_FUNC_REVERSE_SUBTRACT; break; | |||
case BlendEquation::Max: | |||
#if defined GL_MAX | |||
s1[i] = GL_MAX; break; | |||
#else | |||
s1[i] = GL_MAX_EXT; break; | |||
#endif | |||
case BlendEquation::Min: | |||
#if defined GL_MIN | |||
s1[i] = GL_MIN; break; | |||
#else | |||
s1[i] = GL_MIN_EXT; break; | |||
#endif | |||
} | |||
} | |||
glBlendEquationSeparate(s1[0], s1[1]); | |||
#endif | |||
m_data->m_blend_rgb = rgb; | |||
m_data->m_blend_alpha = alpha; | |||
} | |||
BlendEquation Renderer::GetBlendEquationRgb() const | |||
{ | |||
return m_data->m_blend_rgb; | |||
} | |||
BlendEquation Renderer::GetBlendEquationAlpha() const | |||
{ | |||
return m_data->m_blend_alpha; | |||
} | |||
/* | |||
* Blend function | |||
*/ | |||
@@ -31,6 +31,7 @@ public: | |||
void SetClearColor(vec4 color); | |||
void SetClearDepth(float depth); | |||
void SetAlphaFunc(AlphaFunc func, float alpha); | |||
void SetBlendEquation(BlendEquation rgb, BlendEquation alpha); | |||
void SetBlendFunc(BlendFunc src, BlendFunc dst); | |||
void SetDepthFunc(DepthFunc func); | |||
void SetDepthMask(DepthMask mask); | |||
@@ -42,6 +43,8 @@ public: | |||
float GetClearDepth(); | |||
AlphaFunc GetAlphaFunc(); | |||
float GetAlphaValue(); | |||
BlendEquation GetBlendEquationRgb(); | |||
BlendEquation GetBlendEquationAlpha(); | |||
BlendFunc GetBlendFuncSrc(); | |||
BlendFunc GetBlendFuncDst(); | |||
DepthFunc GetDepthFunc(); | |||
@@ -41,6 +41,24 @@ struct ClearMask | |||
inline operator Value() { return m_value; } | |||
}; | |||
/* A safe enum to indicate the blend equation. */ | |||
struct BlendEquation | |||
{ | |||
enum Value | |||
{ | |||
Add, | |||
Subtract, | |||
ReverseSubtract, | |||
Min, | |||
Max, | |||
} | |||
m_value; | |||
inline BlendEquation() : m_value(Add) {} | |||
inline BlendEquation(Value v) : m_value(v) {} | |||
inline operator Value() { return m_value; } | |||
}; | |||
/* A safe enum to indicate the blending factors. */ | |||
struct BlendFunc | |||
{ | |||
@@ -190,6 +208,10 @@ public: | |||
AlphaFunc GetAlphaFunc() const; | |||
float GetAlphaValue() const; | |||
void SetBlendEquation(BlendEquation rgb, BlendEquation alpha); | |||
BlendEquation GetBlendEquationRgb() const; | |||
BlendEquation GetBlendEquationAlpha() const; | |||
void SetBlendFunc(BlendFunc src, BlendFunc dst); | |||
BlendFunc GetBlendFuncSrc() const; | |||
BlendFunc GetBlendFuncDst() const; | |||
@@ -282,6 +282,7 @@ void Scene::RenderTiles() // XXX: rename to Blit() | |||
rc.SetDepthFunc(DepthFunc::LessOrEqual); | |||
rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha); | |||
rc.SetBlendEquation(BlendEquation::Add, BlendEquation::Max); | |||
rc.SetAlphaFunc(AlphaFunc::GreaterOrEqual, 0.01f); | |||
#if defined USE_D3D9 || defined _XBOX | |||
@@ -397,6 +398,7 @@ void Scene::RenderLines(float seconds) // XXX: rename to Blit() | |||
rc.SetDepthFunc(DepthFunc::LessOrEqual); | |||
rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha); | |||
rc.SetBlendEquation(BlendEquation::Add, BlendEquation::Max); | |||
rc.SetAlphaFunc(AlphaFunc::GreaterOrEqual, 0.01f); | |||
int linecount = data->m_lines.Count(); | |||