Added blend factor/color blend modes support.

This commit is contained in:
bkaradzic 2013-03-29 22:58:50 -07:00
parent 365f2655b3
commit 5b763a28bb
7 changed files with 89 additions and 44 deletions

View file

@ -37,6 +37,8 @@
#define BGFX_STATE_BLEND_DST_COLOR UINT64_C(0x0000000000009000) #define BGFX_STATE_BLEND_DST_COLOR UINT64_C(0x0000000000009000)
#define BGFX_STATE_BLEND_INV_DST_COLOR UINT64_C(0x000000000000a000) #define BGFX_STATE_BLEND_INV_DST_COLOR UINT64_C(0x000000000000a000)
#define BGFX_STATE_BLEND_SRC_ALPHA_SAT UINT64_C(0x000000000000b000) #define BGFX_STATE_BLEND_SRC_ALPHA_SAT UINT64_C(0x000000000000b000)
#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_SHIFT 12
#define BGFX_STATE_BLEND_MASK UINT64_C(0x000000000ffff000) #define BGFX_STATE_BLEND_MASK UINT64_C(0x000000000ffff000)
@ -724,10 +726,13 @@ namespace bgfx
/// BGFX_STATE_MSAA - Enable MSAA. /// BGFX_STATE_MSAA - Enable MSAA.
/// BGFX_STATE_PT_[LINES/POINTS] - Primitive type. /// BGFX_STATE_PT_[LINES/POINTS] - Primitive type.
/// ///
/// @param _rgba Sets blend factor used by BGFX_STATE_BLEND_FACTOR and
/// BGFX_STATE_BLEND_INV_FACTOR blend modes.
///
/// NOTE: /// NOTE:
/// Use BGFX_STATE_ALPHA_REF, BGFX_STATE_BLEND_FUNC and /// Use BGFX_STATE_ALPHA_REF, BGFX_STATE_BLEND_FUNC and
/// BGFX_STATE_BLEND_FUNC macros to setup more complex states. /// BGFX_STATE_BLEND_FUNC macros to setup more complex states.
void setState(uint64_t _state); void setState(uint64_t _state, uint32_t _rgba = UINT32_MAX);
/// Set stencil test state. /// Set stencil test state.
/// ///

View file

@ -1299,10 +1299,10 @@ namespace bgfx
s_ctx.setViewTransformMask(_viewMask, _view, _proj, _other); s_ctx.setViewTransformMask(_viewMask, _view, _proj, _other);
} }
void setState(uint64_t _state) void setState(uint64_t _state, uint32_t _rgba)
{ {
BGFX_CHECK_MAIN_THREAD(); BGFX_CHECK_MAIN_THREAD();
s_ctx.m_submit->setState(_state); s_ctx.m_submit->setState(_state, _rgba);
} }
void setStencil(uint32_t _fstencil, uint32_t _bstencil) void setStencil(uint32_t _fstencil, uint32_t _bstencil)

View file

@ -855,11 +855,12 @@ namespace bgfx
m_constBegin = m_constEnd; m_constBegin = m_constEnd;
m_flags = BGFX_STATE_DEFAULT; m_flags = BGFX_STATE_DEFAULT;
m_stencil = packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT); m_stencil = packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT);
m_rgba = UINT32_MAX;
m_matrix = 0; m_matrix = 0;
m_startIndex = 0; m_startIndex = 0;
m_numIndices = UINT32_MAX; m_numIndices = UINT32_MAX;
m_startVertex = 0; m_startVertex = 0;
m_numVertices = UINT32_C(0xffffffff); m_numVertices = UINT32_MAX;
m_instanceDataOffset = 0; m_instanceDataOffset = 0;
m_instanceDataStride = 0; m_instanceDataStride = 0;
m_numInstances = 1; m_numInstances = 1;
@ -878,6 +879,7 @@ namespace bgfx
uint64_t m_flags; uint64_t m_flags;
uint64_t m_stencil; uint64_t m_stencil;
uint32_t m_rgba;
uint32_t m_constBegin; uint32_t m_constBegin;
uint32_t m_constEnd; uint32_t m_constEnd;
uint32_t m_matrix; uint32_t m_matrix;
@ -984,11 +986,12 @@ namespace bgfx
} }
} }
void setState(uint64_t _state) void setState(uint64_t _state, uint32_t _rgba)
{ {
uint8_t blend = ( (_state&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT)&0xff; uint8_t blend = ( (_state&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT)&0xff;
m_key.m_trans = "\x0\x1\x1\x2\x2\x1\x2\x1\x2\x1\x1\x1\x1\x1\x1\x1\x1"[( (blend)&0xf) + (!!blend)]; m_key.m_trans = "\x0\x1\x1\x2\x2\x1\x2\x1\x2\x1\x1\x1\x1\x1\x1\x1\x1"[( (blend)&0xf) + (!!blend)];
m_state.m_flags = _state; m_state.m_flags = _state;
m_state.m_rgba = _rgba;
} }
void setStencil(uint32_t _fstencil, uint32_t _bstencil) void setStencil(uint32_t _fstencil, uint32_t _bstencil)

View file

@ -135,6 +135,7 @@ GL_IMPORT(true, PFNGLSTENCILOPSEPARATEPROC, glStencilOpSeparate);
GL_IMPORT(true, PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate); GL_IMPORT(true, PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate);
GL_IMPORT(true, PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate); GL_IMPORT(true, PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate);
GL_IMPORT(true, PFNGLBLENDCOLORPROC, glBlendColor);
#if BGFX_CONFIG_DEBUG_GREMEDY #if BGFX_CONFIG_DEBUG_GREMEDY
GL_IMPORT(true, PFNGLSTRINGMARKERGREMEDYPROC, glStringMarkerGREMEDY); GL_IMPORT(true, PFNGLSTRINGMARKERGREMEDYPROC, glStringMarkerGREMEDY);

View file

@ -19,18 +19,20 @@ namespace bgfx
static const D3D11_BLEND s_blendFactor[][2] = static const D3D11_BLEND s_blendFactor[][2] =
{ {
{ (D3D11_BLEND)0, (D3D11_BLEND)0 }, // ignored { (D3D11_BLEND)0, (D3D11_BLEND)0 }, // ignored
{ D3D11_BLEND_ZERO, D3D11_BLEND_ZERO }, { D3D11_BLEND_ZERO, D3D11_BLEND_ZERO },
{ D3D11_BLEND_ONE, D3D11_BLEND_ONE }, { D3D11_BLEND_ONE, D3D11_BLEND_ONE },
{ D3D11_BLEND_SRC_COLOR, D3D11_BLEND_SRC_ALPHA }, { D3D11_BLEND_SRC_COLOR, D3D11_BLEND_SRC_ALPHA },
{ D3D11_BLEND_INV_SRC_COLOR, D3D11_BLEND_INV_SRC_ALPHA }, { D3D11_BLEND_INV_SRC_COLOR, D3D11_BLEND_INV_SRC_ALPHA },
{ D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_SRC_ALPHA }, { D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_SRC_ALPHA },
{ D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA }, { D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA },
{ D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_DEST_ALPHA }, { D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_DEST_ALPHA },
{ D3D11_BLEND_INV_DEST_ALPHA, D3D11_BLEND_INV_DEST_ALPHA }, { D3D11_BLEND_INV_DEST_ALPHA, D3D11_BLEND_INV_DEST_ALPHA },
{ D3D11_BLEND_DEST_COLOR, D3D11_BLEND_DEST_ALPHA }, { D3D11_BLEND_DEST_COLOR, D3D11_BLEND_DEST_ALPHA },
{ D3D11_BLEND_INV_DEST_COLOR, D3D11_BLEND_INV_DEST_ALPHA }, { D3D11_BLEND_INV_DEST_COLOR, D3D11_BLEND_INV_DEST_ALPHA },
{ D3D11_BLEND_SRC_ALPHA_SAT, D3D11_BLEND_ONE }, { D3D11_BLEND_SRC_ALPHA_SAT, D3D11_BLEND_ONE },
{ D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_BLEND_FACTOR },
{ D3D11_BLEND_INV_BLEND_FACTOR, D3D11_BLEND_INV_BLEND_FACTOR },
}; };
static const D3D11_COMPARISON_FUNC s_depthFunc[] = static const D3D11_COMPARISON_FUNC s_depthFunc[] =
@ -642,7 +644,7 @@ namespace bgfx
m_deviceCtx->IASetInputLayout(layout); m_deviceCtx->IASetInputLayout(layout);
} }
void setBlendState(uint64_t _state) void setBlendState(uint64_t _state, uint32_t _rgba = UINT32_MAX)
{ {
_state &= BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE; _state &= BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE;
@ -675,7 +677,13 @@ namespace bgfx
m_blendStateCache.add(_state, bs); m_blendStateCache.add(_state, bs);
} }
m_deviceCtx->OMSetBlendState(bs, NULL, 0xffffffff); float blendFactor[4];
blendFactor[0] = (_rgba>>24)/255.0f;
blendFactor[1] = ( (_rgba>>16)&0xff)/255.0f;
blendFactor[2] = ( (_rgba>>8)&0xff)/255.0f;
blendFactor[3] = (_rgba&0xff)/255.0f;
m_deviceCtx->OMSetBlendState(bs, blendFactor, 0xffffffff);
} }
void setDepthStencilState(uint64_t _state, uint64_t _stencil = 0) void setDepthStencilState(uint64_t _state, uint64_t _stencil = 0)
@ -2192,7 +2200,7 @@ namespace bgfx
{ {
if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags) if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags)
{ {
s_renderCtx.setBlendState(newFlags); s_renderCtx.setBlendState(newFlags, state.m_rgba);
} }
if ( (BGFX_STATE_CULL_MASK) & changedFlags) if ( (BGFX_STATE_CULL_MASK) & changedFlags)

View file

@ -37,18 +37,20 @@ namespace bgfx
static const D3DBLEND s_blendFactor[][2] = static const D3DBLEND s_blendFactor[][2] =
{ {
{ (D3DBLEND)0, (D3DBLEND)0 }, // ignored { (D3DBLEND)0, (D3DBLEND)0 }, // ignored
{ D3DBLEND_ZERO, D3DBLEND_ZERO }, { D3DBLEND_ZERO, D3DBLEND_ZERO },
{ D3DBLEND_ONE, D3DBLEND_ONE }, { D3DBLEND_ONE, D3DBLEND_ONE },
{ D3DBLEND_SRCCOLOR, D3DBLEND_SRCCOLOR }, { D3DBLEND_SRCCOLOR, D3DBLEND_SRCCOLOR },
{ D3DBLEND_INVSRCCOLOR, D3DBLEND_INVSRCCOLOR }, { D3DBLEND_INVSRCCOLOR, D3DBLEND_INVSRCCOLOR },
{ D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA }, { D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA },
{ D3DBLEND_INVSRCALPHA, D3DBLEND_INVSRCALPHA }, { D3DBLEND_INVSRCALPHA, D3DBLEND_INVSRCALPHA },
{ D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA }, { D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA },
{ D3DBLEND_INVDESTALPHA, D3DBLEND_INVDESTALPHA }, { D3DBLEND_INVDESTALPHA, D3DBLEND_INVDESTALPHA },
{ D3DBLEND_DESTCOLOR, D3DBLEND_DESTCOLOR }, { D3DBLEND_DESTCOLOR, D3DBLEND_DESTCOLOR },
{ D3DBLEND_INVDESTCOLOR, D3DBLEND_INVDESTCOLOR }, { D3DBLEND_INVDESTCOLOR, D3DBLEND_INVDESTCOLOR },
{ D3DBLEND_SRCALPHASAT, D3DBLEND_ONE }, { D3DBLEND_SRCALPHASAT, D3DBLEND_ONE },
{ D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR },
{ D3DBLEND_INVBLENDFACTOR, D3DBLEND_INVBLENDFACTOR },
}; };
static const D3DCMPFUNC s_depthFunc[] = static const D3DCMPFUNC s_depthFunc[] =
@ -2165,6 +2167,7 @@ namespace bgfx
uint8_t view = 0xff; uint8_t view = 0xff;
RenderTargetHandle rt = BGFX_INVALID_HANDLE; RenderTargetHandle rt = BGFX_INVALID_HANDLE;
float alphaRef = 0.0f; float alphaRef = 0.0f;
uint32_t blendFactor = 0;
D3DPRIMITIVETYPE primType = D3DPT_TRIANGLELIST; D3DPRIMITIVETYPE primType = D3DPT_TRIANGLELIST;
uint32_t primNumVerts = 3; uint32_t primNumVerts = 3;
@ -2395,6 +2398,13 @@ namespace bgfx
DX_CHECK(device->SetRenderState(D3DRS_DESTBLEND, s_blendFactor[dst][1]) ); DX_CHECK(device->SetRenderState(D3DRS_DESTBLEND, s_blendFactor[dst][1]) );
// DX_CHECK(device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_SRCALPHA) ); // DX_CHECK(device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_SRCALPHA) );
// DX_CHECK(device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA) ); // DX_CHECK(device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA) );
if (0 != (blend&(BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_FACTOR, BGFX_STATE_BLEND_FACTOR) ) )
&& blendFactor != state.m_rgba)
{
blendFactor = state.m_rgba;
DX_CHECK(device->SetRenderState(D3DRS_BLENDFACTOR, blendFactor) );
}
} }
} }

View file

@ -59,6 +59,7 @@ namespace bgfx
NVX_gpu_memory_info, NVX_gpu_memory_info,
OES_rgb8_rgba8, OES_rgb8_rgba8,
EXT_texture_storage, EXT_texture_storage,
EXT_blend_color,
Count Count
}; };
@ -113,6 +114,7 @@ namespace bgfx
{ "GL_NVX_gpu_memory_info", false, true }, { "GL_NVX_gpu_memory_info", false, true },
{ "GL_OES_rgb8_rgba8", false, true }, { "GL_OES_rgb8_rgba8", false, true },
{ "GL_EXT_texture_storage", false, true }, { "GL_EXT_texture_storage", false, true },
{ "GL_EXT_blend_color", BGFX_CONFIG_RENDERER_OPENGL >= 31, true },
}; };
#if BGFX_CONFIG_RENDERER_OPENGLES3 #if BGFX_CONFIG_RENDERER_OPENGLES3
@ -556,18 +558,20 @@ namespace bgfx
static const GLenum s_blendFactor[][2] = static const GLenum s_blendFactor[][2] =
{ {
{ 0, 0 }, // ignored { 0, 0 }, // ignored
{ GL_ZERO, GL_ZERO }, { GL_ZERO, GL_ZERO },
{ GL_ONE, GL_ONE }, { GL_ONE, GL_ONE },
{ GL_SRC_COLOR, GL_SRC_COLOR }, { GL_SRC_COLOR, GL_SRC_COLOR },
{ GL_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR }, { GL_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR },
{ GL_SRC_ALPHA, GL_SRC_ALPHA }, { GL_SRC_ALPHA, GL_SRC_ALPHA },
{ GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, { GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA },
{ GL_DST_ALPHA, GL_DST_ALPHA }, { GL_DST_ALPHA, GL_DST_ALPHA },
{ GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA }, { GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA },
{ GL_DST_COLOR, GL_DST_COLOR }, { GL_DST_COLOR, GL_DST_COLOR },
{ GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_DST_COLOR }, { GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_DST_COLOR },
{ GL_SRC_ALPHA_SATURATE, GL_ONE }, { GL_SRC_ALPHA_SATURATE, GL_ONE },
{ GL_CONSTANT_COLOR, GL_CONSTANT_COLOR },
{ GL_ONE_MINUS_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR },
}; };
static const GLenum s_depthFunc[] = static const GLenum s_depthFunc[] =
@ -2454,6 +2458,7 @@ namespace bgfx
RenderTargetHandle rt = BGFX_INVALID_HANDLE; RenderTargetHandle rt = BGFX_INVALID_HANDLE;
int32_t height = m_render->m_resolution.m_height; int32_t height = m_render->m_resolution.m_height;
float alphaRef = 0.0f; float alphaRef = 0.0f;
uint32_t blendFactor = 0;
GLenum primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : GL_TRIANGLES; GLenum primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : GL_TRIANGLES;
uint32_t primNumVerts = 3; uint32_t primNumVerts = 3;
uint32_t baseVertex = 0; uint32_t baseVertex = 0;
@ -2647,6 +2652,19 @@ namespace bgfx
uint32_t dst = (blend>>4)&0xf; uint32_t dst = (blend>>4)&0xf;
GL_CHECK(glEnable(GL_BLEND) ); GL_CHECK(glEnable(GL_BLEND) );
GL_CHECK(glBlendFunc(s_blendFactor[src][0], s_blendFactor[dst][1]) ); GL_CHECK(glBlendFunc(s_blendFactor[src][0], s_blendFactor[dst][1]) );
if (0 != (blend&(BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_FACTOR, BGFX_STATE_BLEND_FACTOR) ) )
&& blendFactor != state.m_rgba)
{
blendFactor = state.m_rgba;
GLclampf rr = (blendFactor>>24)/255.0f;
GLclampf gg = ( (blendFactor>>16)&0xff)/255.0f;
GLclampf bb = ( (blendFactor>>8)&0xff)/255.0f;
GLclampf aa = (blendFactor&0xff)/255.0f;
GL_CHECK(glBlendColor(rr, gg, bb, aa) );
}
} }
else else
{ {