diff --git a/include/bgfx.h b/include/bgfx.h index 8016bc81..fbeaebd6 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -40,7 +40,14 @@ #define BGFX_STATE_BLEND_FACTOR UINT64_C(0x000000000000c000) #define BGFX_STATE_BLEND_INV_FACTOR UINT64_C(0x000000000000d000) #define BGFX_STATE_BLEND_SHIFT 12 -#define BGFX_STATE_BLEND_MASK UINT64_C(0x000000000ffff000) +#define BGFX_STATE_BLEND_MASK UINT64_C(0x00000000000ff000) + +#define BGFX_STATE_BLEND_EQUATION_SUB UINT64_C(0x0000000000100000) +#define BGFX_STATE_BLEND_EQUATION_REVSUB UINT64_C(0x0000000000200000) +#define BGFX_STATE_BLEND_EQUATION_MIN UINT64_C(0x0000000000300000) +#define BGFX_STATE_BLEND_EQUATION_MAX UINT64_C(0x0000000000400000) +#define BGFX_STATE_BLEND_EQUATION_SHIFT 20 +#define BGFX_STATE_BLEND_EQUATION_MASK UINT64_C(0x0000000000700000) #define BGFX_STATE_CULL_CW UINT64_C(0x0000000010000000) #define BGFX_STATE_CULL_CCW UINT64_C(0x0000000020000000) @@ -80,6 +87,14 @@ #define BGFX_STATE_POINT_SIZE(_size) ( (uint64_t(_size)<>BGFX_STATE_BLEND_SHIFT; + uint32_t equation = (_state&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT; uint32_t src = blend&0xf; uint32_t dst = (blend>>4)&0xf; uint32_t writeMask = (_state&BGFX_STATE_ALPHA_WRITE) ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0; @@ -813,11 +823,11 @@ namespace bgfx drt.SrcBlend = s_blendFactor[src][0]; drt.DestBlend = s_blendFactor[dst][0]; - drt.BlendOp = D3D11_BLEND_OP_ADD; + drt.BlendOp = s_blendEquation[equation]; drt.SrcBlendAlpha = s_blendFactor[src][1]; drt.DestBlendAlpha = s_blendFactor[dst][1]; - drt.BlendOpAlpha = D3D11_BLEND_OP_ADD; + drt.BlendOpAlpha = s_blendEquation[equation]; drt.RenderTargetWriteMask = writeMask; @@ -2385,11 +2395,20 @@ namespace bgfx s_renderCtx.setDepthStencilState(newFlags, newStencil); } - if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_ALPHA_MASK|BGFX_STATE_RGB_WRITE - |BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK - |BGFX_STATE_POINT_SIZE_MASK|BGFX_STATE_SRGBWRITE|BGFX_STATE_MSAA) & changedFlags) + if ( (0 + | BGFX_STATE_CULL_MASK + | BGFX_STATE_ALPHA_MASK + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_BLEND_MASK + | BGFX_STATE_BLEND_EQUATION_MASK + | BGFX_STATE_ALPHA_REF_MASK + | BGFX_STATE_PT_MASK + | BGFX_STATE_POINT_SIZE_MASK + | BGFX_STATE_SRGBWRITE + | BGFX_STATE_MSAA + ) & changedFlags) { - if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags) + if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags) { s_renderCtx.setBlendState(newFlags, state.m_rgba); } diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index d209f6ec..0d4629cb 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -62,6 +62,15 @@ namespace bgfx { D3DBLEND_INVBLENDFACTOR, D3DBLEND_INVBLENDFACTOR, true }, }; + static const D3DBLENDOP s_blendEquation[] = + { + D3DBLENDOP_ADD, + D3DBLENDOP_SUBTRACT, + D3DBLENDOP_REVSUBTRACT, + D3DBLENDOP_MIN, + D3DBLENDOP_MAX, + }; + static const D3DCMPFUNC s_depthFunc[] = { (D3DCMPFUNC)0, // ignored @@ -2361,10 +2370,20 @@ namespace bgfx } } - if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK - |BGFX_STATE_ALPHA_MASK|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_MASK - |BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK|BGFX_STATE_POINT_SIZE_MASK - |BGFX_STATE_SRGBWRITE|BGFX_STATE_MSAA) & changedFlags) + if ( (0 + | BGFX_STATE_CULL_MASK + | BGFX_STATE_DEPTH_WRITE + | BGFX_STATE_DEPTH_TEST_MASK + | BGFX_STATE_ALPHA_MASK + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_BLEND_MASK + | BGFX_STATE_BLEND_EQUATION_MASK + | BGFX_STATE_ALPHA_REF_MASK + | BGFX_STATE_PT_MASK + | BGFX_STATE_POINT_SIZE_MASK + | BGFX_STATE_SRGBWRITE + | BGFX_STATE_MSAA + ) & changedFlags) { if (BGFX_STATE_CULL_MASK & changedFlags) { @@ -2418,7 +2437,7 @@ namespace bgfx DX_CHECK(device->SetRenderState(D3DRS_COLORWRITEENABLE, writeEnable) ); } - if (BGFX_STATE_BLEND_MASK & changedFlags) + if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK) & changedFlags) { bool alphaBlendEnabled = !!(BGFX_STATE_BLEND_MASK & newFlags); DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, alphaBlendEnabled) ); @@ -2427,11 +2446,13 @@ namespace bgfx if (alphaBlendEnabled) { uint32_t blend = (newFlags&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT; + uint32_t equation = (newFlags&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT; uint32_t src = blend&0xf; uint32_t dst = (blend>>4)&0xf; DX_CHECK(device->SetRenderState(D3DRS_SRCBLEND, s_blendFactor[src].m_src) ); DX_CHECK(device->SetRenderState(D3DRS_DESTBLEND, s_blendFactor[dst].m_dst) ); + DX_CHECK(device->SetRenderState(D3DRS_BLENDOP, s_blendEquation[equation]) ); // DX_CHECK(device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_SRCALPHA) ); // DX_CHECK(device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA) ); diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index a61c3947..d67558b3 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -62,6 +62,8 @@ namespace bgfx OES_rgb8_rgba8, EXT_texture_storage, EXT_blend_color, + EXT_blend_subtract, + EXT_blend_minmax, ARB_debug_output, Count @@ -118,6 +120,8 @@ namespace bgfx { "GL_OES_rgb8_rgba8", false, true }, { "GL_EXT_texture_storage", false, true }, { "GL_EXT_blend_color", BGFX_CONFIG_RENDERER_OPENGL >= 31, true }, + { "GL_EXT_blend_subtract", BGFX_CONFIG_RENDERER_OPENGL >= 31, true }, + { "GL_EXT_blend_minmax", BGFX_CONFIG_RENDERER_OPENGL >= 31, true }, { "GL_ARB_debug_output", BGFX_CONFIG_RENDERER_OPENGL >= 43, true }, }; @@ -709,6 +713,15 @@ namespace bgfx { GL_ONE_MINUS_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, true }, }; + static const GLenum s_blendEquation[] = + { + GL_FUNC_ADD, + GL_FUNC_SUBTRACT, + GL_FUNC_REVERSE_SUBTRACT, + GL_MIN, + GL_MAX, + }; + static const GLenum s_depthFunc[] = { 0, // ignored @@ -2597,7 +2610,7 @@ namespace bgfx void Context::rendererSetMarker(const char* _marker, uint32_t /*_size*/) { - GREMEDY_SETMARKER(_marker); + GREMEDY_SETMARKER(_marker); } void Context::rendererSubmit() @@ -2762,10 +2775,19 @@ namespace bgfx } } - if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK - |BGFX_STATE_ALPHA_MASK|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_MASK - |BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK|BGFX_STATE_POINT_SIZE_MASK - |BGFX_STATE_MSAA) & changedFlags) + if ( (0 + | BGFX_STATE_CULL_MASK + | BGFX_STATE_DEPTH_WRITE + | BGFX_STATE_DEPTH_TEST_MASK + | BGFX_STATE_ALPHA_MASK + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_BLEND_MASK + | BGFX_STATE_BLEND_EQUATION_MASK + | BGFX_STATE_ALPHA_REF_MASK + | BGFX_STATE_PT_MASK + | BGFX_STATE_POINT_SIZE_MASK + | BGFX_STATE_MSAA + ) & changedFlags) { if (BGFX_STATE_CULL_MASK & changedFlags) { @@ -2838,15 +2860,17 @@ namespace bgfx GL_CHECK(glColorMask(rgb, rgb, rgb, alpha) ); } - if (BGFX_STATE_BLEND_MASK & changedFlags) + if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK) & changedFlags) { if (BGFX_STATE_BLEND_MASK & newFlags) { uint32_t blend = (newFlags&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT; + uint32_t equation = (newFlags&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT; uint32_t src = blend&0xf; uint32_t dst = (blend>>4)&0xf; GL_CHECK(glEnable(GL_BLEND) ); GL_CHECK(glBlendFunc(s_blendFactor[src].m_src, s_blendFactor[dst].m_dst) ); + GL_CHECK(glBlendEquation(s_blendEquation[equation]) ); if ( (s_blendFactor[src].m_factor || s_blendFactor[dst].m_factor) && blendFactor != state.m_rgba) diff --git a/src/renderer_gl.h b/src/renderer_gl.h index cce6739c..cf632551 100755 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -80,6 +80,8 @@ # define GL_R32F GL_R32F_EXT # define GL_UNSIGNED_INT_2_10_10_10_REV GL_UNSIGNED_INT_2_10_10_10_REV_EXT # define GL_SAMPLER_3D GL_SAMPLER_3D_OES +# define GL_MIN GL_MIN_EXT +# define GL_MAX GL_MAX_EXT # elif BGFX_CONFIG_RENDERER_OPENGLES3 # include # include @@ -256,7 +258,7 @@ namespace bgfx # define _GREMEDY_SETMARKER(_string) glStringMarkerGREMEDY(0, _string) # define _GREMEDY_FRAMETERMINATOR() glFrameTerminatorGREMEDY() #else -# define _GREMEDY_SETMARKER(_string) do {} while(0) +# define _GREMEDY_SETMARKER(_string) do { BX_UNUSED(_string); } while(0) # define _GREMEDY_FRAMETERMINATOR() do {} while(0) #endif // BGFX_CONFIG_DEBUG_GREMEDY