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