Ver código fonte

Added blend factor/color blend modes support.

bkaradzic 12 anos atrás
pai
commit
5b763a28bb
7 arquivos alterados com 89 adições e 44 exclusões
  1. 6 1
      include/bgfx.h
  2. 2 2
      src/bgfx.cpp
  3. 5 2
      src/bgfx_p.h
  4. 1 0
      src/glimports.h
  5. 23 15
      src/renderer_d3d11.cpp
  6. 22 12
      src/renderer_d3d9.cpp
  7. 30 12
      src/renderer_gl.cpp

+ 6 - 1
include/bgfx.h

@@ -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.
 	///
 	///

+ 2 - 2
src/bgfx.cpp

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

+ 5 - 2
src/bgfx_p.h

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

+ 1 - 0
src/glimports.h

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

+ 23 - 15
src/renderer_d3d11.cpp

@@ -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_ZERO,           D3D11_BLEND_ZERO           },
-		{ D3D11_BLEND_ONE,            D3D11_BLEND_ONE            },
-		{ D3D11_BLEND_SRC_COLOR,      D3D11_BLEND_SRC_ALPHA      },
-		{ D3D11_BLEND_INV_SRC_COLOR,  D3D11_BLEND_INV_SRC_ALPHA  },
-		{ D3D11_BLEND_SRC_ALPHA,      D3D11_BLEND_SRC_ALPHA      },
-		{ D3D11_BLEND_INV_SRC_ALPHA,  D3D11_BLEND_INV_SRC_ALPHA  },
-		{ D3D11_BLEND_DEST_ALPHA,     D3D11_BLEND_DEST_ALPHA     },
-		{ D3D11_BLEND_INV_DEST_ALPHA, D3D11_BLEND_INV_DEST_ALPHA },
-		{ D3D11_BLEND_DEST_COLOR,     D3D11_BLEND_DEST_ALPHA     },
-		{ D3D11_BLEND_INV_DEST_COLOR, D3D11_BLEND_INV_DEST_ALPHA },
-		{ D3D11_BLEND_SRC_ALPHA_SAT,  D3D11_BLEND_ONE            },
+		{ (D3D11_BLEND)0,               (D3D11_BLEND)0               }, // ignored
+		{ D3D11_BLEND_ZERO,             D3D11_BLEND_ZERO             },
+		{ D3D11_BLEND_ONE,              D3D11_BLEND_ONE              },
+		{ D3D11_BLEND_SRC_COLOR,        D3D11_BLEND_SRC_ALPHA        },
+		{ D3D11_BLEND_INV_SRC_COLOR,    D3D11_BLEND_INV_SRC_ALPHA    },
+		{ D3D11_BLEND_SRC_ALPHA,        D3D11_BLEND_SRC_ALPHA        },
+		{ D3D11_BLEND_INV_SRC_ALPHA,    D3D11_BLEND_INV_SRC_ALPHA    },
+		{ D3D11_BLEND_DEST_ALPHA,       D3D11_BLEND_DEST_ALPHA       },
+		{ D3D11_BLEND_INV_DEST_ALPHA,   D3D11_BLEND_INV_DEST_ALPHA   },
+		{ D3D11_BLEND_DEST_COLOR,       D3D11_BLEND_DEST_ALPHA       },
+		{ D3D11_BLEND_INV_DEST_COLOR,   D3D11_BLEND_INV_DEST_ALPHA   },
+		{ 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)

+ 22 - 12
src/renderer_d3d9.cpp

@@ -37,18 +37,20 @@ namespace bgfx
 
 
 	static const D3DBLEND s_blendFactor[][2] =
 	static const D3DBLEND s_blendFactor[][2] =
 	{
 	{
-		{ (D3DBLEND)0,           (D3DBLEND)0           }, // ignored
-		{ D3DBLEND_ZERO,         D3DBLEND_ZERO         },
-		{ D3DBLEND_ONE,          D3DBLEND_ONE          },
-		{ D3DBLEND_SRCCOLOR,     D3DBLEND_SRCCOLOR     },
-		{ D3DBLEND_INVSRCCOLOR,  D3DBLEND_INVSRCCOLOR  },
-		{ D3DBLEND_SRCALPHA,     D3DBLEND_SRCALPHA     },
-		{ D3DBLEND_INVSRCALPHA,  D3DBLEND_INVSRCALPHA  },
-		{ D3DBLEND_DESTALPHA,    D3DBLEND_DESTALPHA    },
-		{ D3DBLEND_INVDESTALPHA, D3DBLEND_INVDESTALPHA },
-		{ D3DBLEND_DESTCOLOR,    D3DBLEND_DESTCOLOR    },
-		{ D3DBLEND_INVDESTCOLOR, D3DBLEND_INVDESTCOLOR },
-		{ D3DBLEND_SRCALPHASAT,  D3DBLEND_ONE          },
+		{ (D3DBLEND)0,             (D3DBLEND)0             }, // ignored
+		{ D3DBLEND_ZERO,           D3DBLEND_ZERO           },
+		{ D3DBLEND_ONE,            D3DBLEND_ONE            },
+		{ D3DBLEND_SRCCOLOR,       D3DBLEND_SRCCOLOR       },
+		{ D3DBLEND_INVSRCCOLOR,    D3DBLEND_INVSRCCOLOR    },
+		{ D3DBLEND_SRCALPHA,       D3DBLEND_SRCALPHA       },
+		{ D3DBLEND_INVSRCALPHA,    D3DBLEND_INVSRCALPHA    },
+		{ D3DBLEND_DESTALPHA,      D3DBLEND_DESTALPHA      },
+		{ D3DBLEND_INVDESTALPHA,   D3DBLEND_INVDESTALPHA   },
+		{ D3DBLEND_DESTCOLOR,      D3DBLEND_DESTCOLOR      },
+		{ D3DBLEND_INVDESTCOLOR,   D3DBLEND_INVDESTCOLOR   },
+		{ 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) );
+							}
 						}
 						}
 					}
 					}
 
 

+ 30 - 12
src/renderer_gl.cpp

@@ -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
-		{ GL_ZERO,                GL_ZERO                },
-		{ GL_ONE,                 GL_ONE                 },
-		{ GL_SRC_COLOR,           GL_SRC_COLOR           },
-		{ GL_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR },
-		{ GL_SRC_ALPHA,           GL_SRC_ALPHA           },
-		{ GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA },
-		{ GL_DST_ALPHA,           GL_DST_ALPHA           },
-		{ GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA },
-		{ GL_DST_COLOR,           GL_DST_COLOR           },
-		{ GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_DST_COLOR },
-		{ GL_SRC_ALPHA_SATURATE,  GL_ONE                 },
+		{ 0,                           0                           }, // ignored
+		{ GL_ZERO,                     GL_ZERO                     },
+		{ GL_ONE,                      GL_ONE                      },
+		{ GL_SRC_COLOR,                GL_SRC_COLOR                },
+		{ GL_ONE_MINUS_SRC_COLOR,      GL_ONE_MINUS_SRC_COLOR      },
+		{ GL_SRC_ALPHA,                GL_SRC_ALPHA                },
+		{ GL_ONE_MINUS_SRC_ALPHA,      GL_ONE_MINUS_SRC_ALPHA      },
+		{ GL_DST_ALPHA,                GL_DST_ALPHA                },
+		{ GL_ONE_MINUS_DST_ALPHA,      GL_ONE_MINUS_DST_ALPHA      },
+		{ GL_DST_COLOR,                GL_DST_COLOR                },
+		{ GL_ONE_MINUS_DST_COLOR,      GL_ONE_MINUS_DST_COLOR      },
+		{ 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
 						{
 						{