Commit 9bad8de6 authored by nadro's avatar nadro

- Added separate blending support for both OpenGL and D3D9.

- Added blend factor to SMaterial.
- Improved transparent nodes handling.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4794 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 6058c276
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- Added support for separate blending in OpenGL and D3D9 drivers.
- Added pack_textureBlendFuncSeparate and unpack_textureBlendFuncSeparate functions, which allow to use separate blending functions in OpenGL.
- Added BlendFactor field to SMaterial which allow user to set blending factor per SMaterial set call without use EMT_ONETEXTURE_BLEND type.
- Fixed issue with blending operation set to EBO_NONE and some transparent material types.
- Add a code profiler (stop-watch style) - Add a code profiler (stop-watch style)
- Add override font to IGUITable - Add override font to IGUITable
- IGUITable can now disable the active column. - IGUITable can now disable the active column.
......
...@@ -115,6 +115,9 @@ namespace video ...@@ -115,6 +115,9 @@ namespace video
//! Support for different blend functions. Without, only ADD is available //! Support for different blend functions. Without, only ADD is available
EVDF_BLEND_OPERATIONS, EVDF_BLEND_OPERATIONS,
//! Support for separate blending for RGB and Alpha.
EVDF_BLEND_SEPARATE,
//! Support for texture coord transformation via texture matrix //! Support for texture coord transformation via texture matrix
EVDF_TEXTURE_MATRIX, EVDF_TEXTURE_MATRIX,
......
...@@ -84,7 +84,10 @@ namespace video ...@@ -84,7 +84,10 @@ namespace video
EMF_BLEND_OPERATION = 0x40000, EMF_BLEND_OPERATION = 0x40000,
//! Flag for polygon offset //! Flag for polygon offset
EMF_POLYGON_OFFSET = 0x80000 EMF_POLYGON_OFFSET = 0x80000,
//! Flag for blend factor
EMF_BLEND_FACTOR = 0x160000
}; };
} // end namespace video } // end namespace video
......
...@@ -197,6 +197,7 @@ namespace video ...@@ -197,6 +197,7 @@ namespace video
case EMF_COLOR_MATERIAL: material.ColorMaterial = Material.ColorMaterial; break; case EMF_COLOR_MATERIAL: material.ColorMaterial = Material.ColorMaterial; break;
case EMF_USE_MIP_MAPS: material.UseMipMaps = Material.UseMipMaps; break; case EMF_USE_MIP_MAPS: material.UseMipMaps = Material.UseMipMaps; break;
case EMF_BLEND_OPERATION: material.BlendOperation = Material.BlendOperation; break; case EMF_BLEND_OPERATION: material.BlendOperation = Material.BlendOperation; break;
case EMF_BLEND_FACTOR: material.BlendFactor = Material.BlendFactor; break;
case EMF_POLYGON_OFFSET: case EMF_POLYGON_OFFSET:
material.PolygonOffsetDirection = Material.PolygonOffsetDirection; material.PolygonOffsetDirection = Material.PolygonOffsetDirection;
material.PolygonOffsetFactor = Material.PolygonOffsetFactor; break; material.PolygonOffsetFactor = Material.PolygonOffsetFactor; break;
......
...@@ -113,27 +113,53 @@ namespace video ...@@ -113,27 +113,53 @@ namespace video
EAS_TEXTURE EAS_TEXTURE
}; };
//! EMT_ONETEXTURE_BLEND: pack srcFact, dstFact, Modulate and alpha source to MaterialTypeParam //! Pack srcFact, dstFact, Modulate and alpha source to MaterialTypeParam or BlendFactor
/** alpha source can be an OR'ed combination of E_ALPHA_SOURCE values. */ /** alpha source can be an OR'ed combination of E_ALPHA_SOURCE values. */
inline f32 pack_textureBlendFunc ( const E_BLEND_FACTOR srcFact, const E_BLEND_FACTOR dstFact, const E_MODULATE_FUNC modulate=EMFN_MODULATE_1X, const u32 alphaSource=EAS_TEXTURE ) inline f32 pack_textureBlendFunc(const E_BLEND_FACTOR srcFact, const E_BLEND_FACTOR dstFact,
const E_MODULATE_FUNC modulate=EMFN_MODULATE_1X, const u32 alphaSource=EAS_TEXTURE)
{ {
const u32 tmp = (alphaSource << 12) | (modulate << 8) | (srcFact << 4) | dstFact; const u32 tmp = (alphaSource << 20) | (modulate << 16) | (srcFact << 12) | (dstFact << 8) | (srcFact << 4) | dstFact;
return FR(tmp); return FR(tmp);
} }
//! EMT_ONETEXTURE_BLEND: unpack srcFact & dstFact and Modulo to MaterialTypeParam //! Pack srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, Modulate and alpha source to MaterialTypeParam or BlendFactor
/** alpha source can be an OR'ed combination of E_ALPHA_SOURCE values. */
inline f32 pack_textureBlendFuncSeparate(const E_BLEND_FACTOR srcRGBFact, const E_BLEND_FACTOR dstRGBFact,
const E_BLEND_FACTOR srcAlphaFact, const E_BLEND_FACTOR dstAlphaFact,
const E_MODULATE_FUNC modulate=EMFN_MODULATE_1X, const u32 alphaSource=EAS_TEXTURE)
{
const u32 tmp = (alphaSource << 20) | (modulate << 16) | (srcAlphaFact << 12) | (dstAlphaFact << 8) | (srcRGBFact << 4) | dstRGBFact;
return FR(tmp);
}
//! Unpack srcFact, dstFact, modulo and alphaSource factors
/** The fields don't use the full byte range, so we could pack even more... */ /** The fields don't use the full byte range, so we could pack even more... */
inline void unpack_textureBlendFunc ( E_BLEND_FACTOR &srcFact, E_BLEND_FACTOR &dstFact, inline void unpack_textureBlendFunc(E_BLEND_FACTOR &srcFact, E_BLEND_FACTOR &dstFact,
E_MODULATE_FUNC &modulo, u32& alphaSource, const f32 param ) E_MODULATE_FUNC &modulo, u32& alphaSource, const f32 param)
{ {
const u32 state = IR(param); const u32 state = IR(param);
alphaSource = (state & 0x0000F000) >> 12; alphaSource = (state & 0x00F00000) >> 20;
modulo = E_MODULATE_FUNC( ( state & 0x00000F00 ) >> 8 ); modulo = E_MODULATE_FUNC( ( state & 0x000F0000 ) >> 16 );
srcFact = E_BLEND_FACTOR ( ( state & 0x000000F0 ) >> 4 ); srcFact = E_BLEND_FACTOR ( ( state & 0x000000F0 ) >> 4 );
dstFact = E_BLEND_FACTOR ( ( state & 0x0000000F ) ); dstFact = E_BLEND_FACTOR ( ( state & 0x0000000F ) );
} }
//! EMT_ONETEXTURE_BLEND: has BlendFactor Alphablending //! Unpack srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulo and alphaSource factors
/** The fields don't use the full byte range, so we could pack even more... */
inline void unpack_textureBlendFuncSeparate(E_BLEND_FACTOR &srcRGBFact, E_BLEND_FACTOR &dstRGBFact,
E_BLEND_FACTOR &srcAlphaFact, E_BLEND_FACTOR &dstAlphaFact,
E_MODULATE_FUNC &modulo, u32& alphaSource, const f32 param)
{
const u32 state = IR(param);
alphaSource = (state & 0x00F00000) >> 20;
modulo = E_MODULATE_FUNC( ( state & 0x000F0000 ) >> 16 );
srcAlphaFact = E_BLEND_FACTOR ( ( state & 0x0000F000 ) >> 12 );
dstAlphaFact = E_BLEND_FACTOR ( ( state & 0x00000F00 ) >> 8 );
srcRGBFact = E_BLEND_FACTOR ( ( state & 0x000000F0 ) >> 4 );
dstRGBFact = E_BLEND_FACTOR ( ( state & 0x0000000F ) );
}
//! has blend factor alphablending
inline bool textureBlendFunc_hasAlpha ( const E_BLEND_FACTOR factor ) inline bool textureBlendFunc_hasAlpha ( const E_BLEND_FACTOR factor )
{ {
switch ( factor ) switch ( factor )
...@@ -234,7 +260,7 @@ namespace video ...@@ -234,7 +260,7 @@ namespace video
EmissiveColor(0,0,0,0), SpecularColor(255,255,255,255), EmissiveColor(0,0,0,0), SpecularColor(255,255,255,255),
Shininess(0.0f), MaterialTypeParam(0.0f), MaterialTypeParam2(0.0f), Thickness(1.0f), Shininess(0.0f), MaterialTypeParam(0.0f), MaterialTypeParam2(0.0f), Thickness(1.0f),
ZBuffer(ECFN_LESSEQUAL), AntiAliasing(EAAM_SIMPLE), ColorMask(ECP_ALL), ZBuffer(ECFN_LESSEQUAL), AntiAliasing(EAAM_SIMPLE), ColorMask(ECP_ALL),
ColorMaterial(ECM_DIFFUSE), BlendOperation(EBO_NONE), ColorMaterial(ECM_DIFFUSE), BlendOperation(EBO_NONE), BlendFactor(0.0f),
PolygonOffsetFactor(0), PolygonOffsetDirection(EPO_FRONT), PolygonOffsetFactor(0), PolygonOffsetDirection(EPO_FRONT),
Wireframe(false), PointCloud(false), GouraudShading(true), Wireframe(false), PointCloud(false), GouraudShading(true),
Lighting(true), ZWriteEnable(true), BackfaceCulling(true), FrontfaceCulling(false), Lighting(true), ZWriteEnable(true), BackfaceCulling(true), FrontfaceCulling(false),
...@@ -288,6 +314,7 @@ namespace video ...@@ -288,6 +314,7 @@ namespace video
ColorMask = other.ColorMask; ColorMask = other.ColorMask;
ColorMaterial = other.ColorMaterial; ColorMaterial = other.ColorMaterial;
BlendOperation = other.BlendOperation; BlendOperation = other.BlendOperation;
BlendFactor = other.BlendFactor;
PolygonOffsetFactor = other.PolygonOffsetFactor; PolygonOffsetFactor = other.PolygonOffsetFactor;
PolygonOffsetDirection = other.PolygonOffsetDirection; PolygonOffsetDirection = other.PolygonOffsetDirection;
UseMipMaps = other.UseMipMaps; UseMipMaps = other.UseMipMaps;
...@@ -391,10 +418,15 @@ namespace video ...@@ -391,10 +418,15 @@ namespace video
u8 ColorMaterial:3; u8 ColorMaterial:3;
//! Store the blend operation of choice //! Store the blend operation of choice
/** Values to be chosen from E_BLEND_OPERATION. The actual way to use this value /** Values to be chosen from E_BLEND_OPERATION. */
is not yet determined, so ignore it for now. */
E_BLEND_OPERATION BlendOperation:4; E_BLEND_OPERATION BlendOperation:4;
//! Store the blend factors
/** textureBlendFunc/textureBlendFuncSeparate functions should be used to write
properly blending factors to this parameter. If you use EMT_ONETEXTURE_BLEND
type for this material, this field should be equal to MaterialTypeParam. */
f32 BlendFactor;
//! Factor specifying how far the polygon offset should be made //! Factor specifying how far the polygon offset should be made
/** Specifying 0 disables the polygon offset. The direction is specified spearately. /** Specifying 0 disables the polygon offset. The direction is specified spearately.
The factor can be from 0 to 7.*/ The factor can be from 0 to 7.*/
...@@ -559,6 +591,8 @@ namespace video ...@@ -559,6 +591,8 @@ namespace video
UseMipMaps = value; break; UseMipMaps = value; break;
case EMF_BLEND_OPERATION: case EMF_BLEND_OPERATION:
BlendOperation = value?EBO_ADD:EBO_NONE; break; BlendOperation = value?EBO_ADD:EBO_NONE; break;
case EMF_BLEND_FACTOR:
break;
case EMF_POLYGON_OFFSET: case EMF_POLYGON_OFFSET:
PolygonOffsetFactor = value?1:0; PolygonOffsetFactor = value?1:0;
PolygonOffsetDirection = EPO_BACK; PolygonOffsetDirection = EPO_BACK;
...@@ -620,6 +654,8 @@ namespace video ...@@ -620,6 +654,8 @@ namespace video
return UseMipMaps; return UseMipMaps;
case EMF_BLEND_OPERATION: case EMF_BLEND_OPERATION:
return BlendOperation != EBO_NONE; return BlendOperation != EBO_NONE;
case EMF_BLEND_FACTOR:
return BlendFactor != 0.f;
case EMF_POLYGON_OFFSET: case EMF_POLYGON_OFFSET:
return PolygonOffsetFactor != 0; return PolygonOffsetFactor != 0;
} }
...@@ -656,6 +692,7 @@ namespace video ...@@ -656,6 +692,7 @@ namespace video
ColorMask != b.ColorMask || ColorMask != b.ColorMask ||
ColorMaterial != b.ColorMaterial || ColorMaterial != b.ColorMaterial ||
BlendOperation != b.BlendOperation || BlendOperation != b.BlendOperation ||
BlendFactor != b.BlendFactor ||
PolygonOffsetFactor != b.PolygonOffsetFactor || PolygonOffsetFactor != b.PolygonOffsetFactor ||
PolygonOffsetDirection != b.PolygonOffsetDirection || PolygonOffsetDirection != b.PolygonOffsetDirection ||
UseMipMaps != b.UseMipMaps; UseMipMaps != b.UseMipMaps;
...@@ -671,6 +708,31 @@ namespace video ...@@ -671,6 +708,31 @@ namespace video
\return True if the materials are equal, else false. */ \return True if the materials are equal, else false. */
inline bool operator==(const SMaterial& b) const inline bool operator==(const SMaterial& b) const
{ return !(b!=*this); } { return !(b!=*this); }
bool isTransparent() const
{
bool status = false;
if (BlendOperation != EBO_NONE)
{
E_BLEND_FACTOR srcRGBFact = EBF_ZERO;
E_BLEND_FACTOR dstRGBFact = EBF_ZERO;
E_BLEND_FACTOR srcAlphaFact = EBF_ZERO;
E_BLEND_FACTOR dstAlphaFact = EBF_ZERO;
E_MODULATE_FUNC modulo = EMFN_MODULATE_1X;
u32 alphaSource = 0;
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulo, alphaSource, BlendFactor);
if (textureBlendFunc_hasAlpha(srcRGBFact) || textureBlendFunc_hasAlpha(dstRGBFact) ||
textureBlendFunc_hasAlpha(srcAlphaFact) || textureBlendFunc_hasAlpha(dstAlphaFact))
{
status = true;
}
}
return status;
}
}; };
//! global const identity Material //! global const identity Material
......
...@@ -164,7 +164,7 @@ void CAnimatedMeshSceneNode::OnRegisterSceneNode() ...@@ -164,7 +164,7 @@ void CAnimatedMeshSceneNode::OnRegisterSceneNode()
video::IMaterialRenderer* rnd = video::IMaterialRenderer* rnd =
driver->getMaterialRenderer(Materials[i].MaterialType); driver->getMaterialRenderer(Materials[i].MaterialType);
if ((rnd && rnd->isTransparent()) || Materials[i].BlendOperation != video::EBO_NONE) if ((rnd && rnd->isTransparent()) || Materials[i].isTransparent())
++transparentCount; ++transparentCount;
else else
++solidCount; ++solidCount;
......
...@@ -26,7 +26,7 @@ namespace video ...@@ -26,7 +26,7 @@ namespace video
//! constructor //! constructor
CD3D8Driver::CD3D8Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io) CD3D8Driver::CD3D8Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io)
: CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE), : CNullDriver(io, params.WindowSize), BridgeCalls(0), CurrentRenderMode(ERM_NONE),
ResetRenderStates(true), Transformation3DChanged(false), ResetRenderStates(true), Transformation3DChanged(false),
D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0),
WindowId(0), SceneSourceRect(0), WindowId(0), SceneSourceRect(0),
...@@ -66,6 +66,8 @@ CD3D8Driver::~CD3D8Driver() ...@@ -66,6 +66,8 @@ CD3D8Driver::~CD3D8Driver()
{ {
deleteMaterialRenders(); deleteMaterialRenders();
delete BridgeCalls;
// drop d3d8 // drop d3d8
if (pID3DDevice) if (pID3DDevice)
...@@ -369,6 +371,9 @@ bool CD3D8Driver::initDriver(HWND hwnd, bool pureSoftware) ...@@ -369,6 +371,9 @@ bool CD3D8Driver::initDriver(HWND hwnd, bool pureSoftware)
Params.Stencilbuffer = false; Params.Stencilbuffer = false;
} }
if (!BridgeCalls)
BridgeCalls = new CD3D8CallBridge(pID3DDevice);
// set default vertex shader // set default vertex shader
setVertexShader(EVT_STANDARD); setVertexShader(EVT_STANDARD);
...@@ -608,6 +613,9 @@ bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const ...@@ -608,6 +613,9 @@ bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
case EVDF_COLOR_MASK: case EVDF_COLOR_MASK:
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0; return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0;
case EVDF_BLEND_OPERATIONS: case EVDF_BLEND_OPERATIONS:
return true;
case EVDF_BLEND_SEPARATE:
return false;
case EVDF_TEXTURE_MATRIX: case EVDF_TEXTURE_MATRIX:
return true; return true;
case EVDF_TEXTURE_COMPRESSED_DXT: case EVDF_TEXTURE_COMPRESSED_DXT:
...@@ -1533,7 +1541,7 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria ...@@ -1533,7 +1541,7 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
// zwrite // zwrite
// if (resetAllRenderstates || lastmaterial.ZWriteEnable != material.ZWriteEnable) // if (resetAllRenderstates || lastmaterial.ZWriteEnable != material.ZWriteEnable)
{ {
if (material.ZWriteEnable && (AllowZWriteOnTransparent || (material.BlendOperation == EBO_NONE && if (material.ZWriteEnable && (AllowZWriteOnTransparent || (!material.isTransparent() &&
!MaterialRenderers[material.MaterialType].Renderer->isTransparent()))) !MaterialRenderers[material.MaterialType].Renderer->isTransparent())))
{ {
pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE);
...@@ -1591,13 +1599,11 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria ...@@ -1591,13 +1599,11 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
} }
// Blend Operation // Blend Operation
if (resetAllRenderstates || lastmaterial.BlendOperation != material.BlendOperation) if (material.BlendOperation == EBO_NONE)
{ BridgeCalls->setBlend(false);
if (material.BlendOperation==EBO_NONE)
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
else else
{ {
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); BridgeCalls->setBlend(true);
if (queryFeature(EVDF_BLEND_OPERATIONS)) if (queryFeature(EVDF_BLEND_OPERATIONS))
{ {
...@@ -1606,25 +1612,37 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria ...@@ -1606,25 +1612,37 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
case EBO_MAX: case EBO_MAX:
case EBO_MAX_FACTOR: case EBO_MAX_FACTOR:
case EBO_MAX_ALPHA: case EBO_MAX_ALPHA:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); BridgeCalls->setBlendOperation(D3DBLENDOP_MAX);
break; break;
case EBO_MIN: case EBO_MIN:
case EBO_MIN_FACTOR: case EBO_MIN_FACTOR:
case EBO_MIN_ALPHA: case EBO_MIN_ALPHA:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN); BridgeCalls->setBlendOperation(D3DBLENDOP_MIN);
break; break;
case EBO_SUBTRACT: case EBO_SUBTRACT:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); BridgeCalls->setBlendOperation(D3DBLENDOP_SUBTRACT);
break; break;
case EBO_REVSUBTRACT: case EBO_REVSUBTRACT:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT); BridgeCalls->setBlendOperation(D3DBLENDOP_REVSUBTRACT);
break; break;
default: default:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); BridgeCalls->setBlendOperation(D3DBLENDOP_ADD);
break; break;
} }
} }
} }
// Blend Factor
if (material.BlendFactor != 0.f)
{
E_BLEND_FACTOR srcFact = EBF_ZERO;
E_BLEND_FACTOR dstFact = EBF_ZERO;
E_MODULATE_FUNC modulo = EMFN_MODULATE_1X;
u32 alphaSource = 0;
unpack_textureBlendFunc(srcFact, dstFact, modulo, alphaSource, material.BlendFactor);
BridgeCalls->setBlendFunc(getD3DBlend(srcFact), getD3DBlend(dstFact));
} }
// Polygon offset // Polygon offset
...@@ -1796,9 +1814,8 @@ void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha) ...@@ -1796,9 +1814,8 @@ void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha)
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); BridgeCalls->setBlend(true);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); BridgeCalls->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
} }
else else
{ {
...@@ -1806,7 +1823,7 @@ void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha) ...@@ -1806,7 +1823,7 @@ void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha)
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); BridgeCalls->setBlend(false);
} }
} }
...@@ -1868,12 +1885,11 @@ void CD3D8Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChan ...@@ -1868,12 +1885,11 @@ void CD3D8Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChan
if (alpha || alphaChannel) if (alpha || alphaChannel)
{ {
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); BridgeCalls->setBlend(true);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); BridgeCalls->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
} }
else else
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); BridgeCalls->setBlend(false);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
...@@ -2433,6 +2449,96 @@ core::dimension2du CD3D8Driver::getMaxTextureSize() const ...@@ -2433,6 +2449,96 @@ core::dimension2du CD3D8Driver::getMaxTextureSize() const
} }
u32 CD3D8Driver::getD3DBlend(E_BLEND_FACTOR factor) const
{
u32 r = 0;
switch ( factor )
{
case EBF_ZERO: r = D3DBLEND_ZERO; break;
case EBF_ONE: r = D3DBLEND_ONE; break;
case EBF_DST_COLOR: r = D3DBLEND_DESTCOLOR; break;
case EBF_ONE_MINUS_DST_COLOR: r = D3DBLEND_INVDESTCOLOR; break;
case EBF_SRC_COLOR: r = D3DBLEND_SRCCOLOR; break;
case EBF_ONE_MINUS_SRC_COLOR: r = D3DBLEND_INVSRCCOLOR; break;
case EBF_SRC_ALPHA: r = D3DBLEND_SRCALPHA; break;
case EBF_ONE_MINUS_SRC_ALPHA: r = D3DBLEND_INVSRCALPHA; break;
case EBF_DST_ALPHA: r = D3DBLEND_DESTALPHA; break;
case EBF_ONE_MINUS_DST_ALPHA: r = D3DBLEND_INVDESTALPHA; break;
case EBF_SRC_ALPHA_SATURATE: r = D3DBLEND_SRCALPHASAT; break;
}
return r;
}
u32 CD3D8Driver::getD3DModulate(E_MODULATE_FUNC func) const
{
u32 r = D3DTOP_MODULATE;
switch ( func )
{
case EMFN_MODULATE_1X: r = D3DTOP_MODULATE; break;
case EMFN_MODULATE_2X: r = D3DTOP_MODULATE2X; break;
case EMFN_MODULATE_4X: r = D3DTOP_MODULATE4X; break;
}
return r;
}
CD3D8CallBridge* CD3D8Driver::getBridgeCalls() const
{
return BridgeCalls;
}
CD3D8CallBridge::CD3D8CallBridge(IDirect3DDevice8* p) : pID3DDevice(p),
BlendOperation(D3DBLENDOP_ADD), BlendSource(D3DBLEND_ONE), BlendDestination(D3DBLEND_ZERO), Blend(false)
{
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
void CD3D8CallBridge::setBlendOperation(DWORD mode)
{
if (BlendOperation != mode)
{
pID3DDevice->SetRenderState(D3DRS_BLENDOP, mode);
BlendOperation = mode;
}
}
void CD3D8CallBridge::setBlendFunc(DWORD source, DWORD destination)
{
if (BlendSource != source)
{
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, source);
BlendSource = source;
}
if (BlendDestination != destination)
{
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, destination);
BlendDestination = destination;
}
}
void CD3D8CallBridge::setBlend(bool enable)
{
if (Blend != enable)
{
if (enable)
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
else
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
Blend = enable;
}
}
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr
......
...@@ -25,8 +25,11 @@ namespace irr ...@@ -25,8 +25,11 @@ namespace irr
{ {
namespace video namespace video
{ {
class CD3D8CallBridge;
class CD3D8Driver : public CNullDriver, IMaterialRendererServices class CD3D8Driver : public CNullDriver, IMaterialRendererServices
{ {
friend class CD3D8CallBridge;
friend class CD3D8Texture; friend class CD3D8Texture;
public: public:
...@@ -228,6 +231,16 @@ namespace video ...@@ -228,6 +231,16 @@ namespace video
virtual core::dimension2du getMaxTextureSize() const _IRR_OVERRIDE_; virtual core::dimension2du getMaxTextureSize() const _IRR_OVERRIDE_;
virtual bool checkDriverReset() _IRR_OVERRIDE_ {return DriverWasReset;} virtual bool checkDriverReset() _IRR_OVERRIDE_ {return DriverWasReset;}
//! Get D3D blending factor.
u32 getD3DBlend(E_BLEND_FACTOR factor) const;
//! Get D3D modulate.
u32 getD3DModulate(E_MODULATE_FUNC func) const;
//! Get bridge calls.
CD3D8CallBridge* getBridgeCalls() const;
private: private:
// enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates. // enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates.
...@@ -295,6 +308,8 @@ namespace video ...@@ -295,6 +308,8 @@ namespace video
return v; return v;
} }
CD3D8CallBridge* BridgeCalls;
E_RENDER_MODE CurrentRenderMode; E_RENDER_MODE CurrentRenderMode;
D3DPRESENT_PARAMETERS present; D3DPRESENT_PARAMETERS present;
...@@ -332,6 +347,31 @@ namespace video ...@@ -332,6 +347,31 @@ namespace video
SIrrlichtCreationParameters Params; SIrrlichtCreationParameters Params;
}; };
//! This bridge between Irlicht pseudo D3D8 calls
//! and true D3D8 calls.
class CD3D8CallBridge
{
public:
CD3D8CallBridge(IDirect3DDevice8* p);
// Blending calls.
void setBlendOperation(DWORD mode);
void setBlendFunc(DWORD source, DWORD destination);
void setBlend(bool enable);
private:
IDirect3DDevice8* pID3DDevice;
DWORD BlendOperation;
DWORD BlendSource;
DWORD BlendDestination;
bool Blend;
};
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr
......
This diff is collapsed.
This diff is collapsed.
...@@ -31,6 +31,8 @@ namespace irr ...@@ -31,6 +31,8 @@ namespace irr
{ {
namespace video namespace video
{ {
class CD3D9CallBridge;
struct SDepthSurface : public IReferenceCounted struct SDepthSurface : public IReferenceCounted
{ {
SDepthSurface() : Surface(0) SDepthSurface() : Surface(0)
...@@ -53,6 +55,7 @@ namespace video ...@@ -53,6 +55,7 @@ namespace video
{ {
public: public:
friend class CD3D9CallBridge;
friend class CD3D9Texture; friend class CD3D9Texture;
//! constructor //! constructor
...@@ -332,6 +335,15 @@ namespace video ...@@ -332,6 +335,15 @@ namespace video
//! Get Irrlicht color format from D3D color format. //! Get Irrlicht color format from D3D color format.
ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format) const; ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format) const;
//! Get D3D blending factor.
u32 getD3DBlend(E_BLEND_FACTOR factor) const;
//! Get D3D modulate.
u32 getD3DModulate(E_MODULATE_FUNC func) const;
//! Get bridge calls.
CD3D9CallBridge* getBridgeCalls() const;
//! Get Cg context //! Get Cg context
#ifdef _IRR_COMPILE_WITH_CG_ #ifdef _IRR_COMPILE_WITH_CG_
const CGcontext& getCgContext(); const CGcontext& getCgContext();
...@@ -427,6 +439,8 @@ namespace video ...@@ -427,6 +439,8 @@ namespace video
return v; return v;
} }
CD3D9CallBridge* BridgeCalls;
E_RENDER_MODE CurrentRenderMode; E_RENDER_MODE CurrentRenderMode;
D3DPRESENT_PARAMETERS present; D3DPRESENT_PARAMETERS present;
...@@ -486,6 +500,37 @@ namespace video ...@@ -486,6 +500,37 @@ namespace video
#endif #endif
}; };
//! This bridge between Irlicht pseudo D3D8 calls
//! and true D3D8 calls.
class CD3D9CallBridge
{
public:
CD3D9CallBridge(IDirect3DDevice9* p, CD3D9Driver* driver);
// Blending calls.
void setBlendOperation(DWORD mode);
void setBlendFunc(DWORD source, DWORD destination);
void setBlendFuncSeparate(DWORD sourceRGB, DWORD destinationRGB, DWORD sourceAlpha, DWORD destinationAlpha);
void setBlend(bool enable);
private:
IDirect3DDevice9* pID3DDevice;
DWORD BlendOperation;
DWORD BlendSourceRGB;
DWORD BlendDestinationRGB;
DWORD BlendSourceAlpha;
DWORD BlendDestinationAlpha;
bool Blend;
bool BlendSeparate;
bool FeatureBlendSeparate;
};
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr
......
This diff is collapsed.
...@@ -89,7 +89,7 @@ void CMeshSceneNode::OnRegisterSceneNode() ...@@ -89,7 +89,7 @@ void CMeshSceneNode::OnRegisterSceneNode()
video::IMaterialRenderer* rnd = video::IMaterialRenderer* rnd =
driver->getMaterialRenderer(Materials[i].MaterialType); driver->getMaterialRenderer(Materials[i].MaterialType);
if ((rnd && rnd->isTransparent()) || Materials[i].BlendOperation != video::EBO_NONE) if ((rnd && rnd->isTransparent()) || Materials[i].isTransparent())
++transparentCount; ++transparentCount;
else else
++solidCount; ++solidCount;
......
...@@ -76,7 +76,7 @@ void COctreeSceneNode::OnRegisterSceneNode() ...@@ -76,7 +76,7 @@ void COctreeSceneNode::OnRegisterSceneNode()
const video::IMaterialRenderer* const rnd = const video::IMaterialRenderer* const rnd =
driver->getMaterialRenderer(Materials[i].MaterialType); driver->getMaterialRenderer(Materials[i].MaterialType);
if ((rnd && rnd->isTransparent()) || Materials[i].BlendOperation != video::EBO_NONE) if ((rnd && rnd->isTransparent()) || Materials[i].isTransparent())
++transparentCount; ++transparentCount;
else else
++solidCount; ++solidCount;
......
...@@ -637,8 +637,6 @@ COpenGLDriver::~COpenGLDriver() ...@@ -637,8 +637,6 @@ COpenGLDriver::~COpenGLDriver()
cgDestroyContext(CgContext); cgDestroyContext(CgContext);
#endif #endif
delete BridgeCalls;
RequestedLights.clear(); RequestedLights.clear();
deleteMaterialRenders(); deleteMaterialRenders();
...@@ -650,6 +648,8 @@ COpenGLDriver::~COpenGLDriver() ...@@ -650,6 +648,8 @@ COpenGLDriver::~COpenGLDriver()
removeAllOcclusionQueries(); removeAllOcclusionQueries();
removeAllHardwareBuffers(); removeAllHardwareBuffers();
delete BridgeCalls;
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
if (DeviceType == EIDT_WIN32) if (DeviceType == EIDT_WIN32)
{ {
...@@ -3051,7 +3051,7 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater ...@@ -3051,7 +3051,7 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
// zwrite // zwrite
// if (resetAllRenderStates || lastmaterial.ZWriteEnable != material.ZWriteEnable) // if (resetAllRenderStates || lastmaterial.ZWriteEnable != material.ZWriteEnable)
{ {
if (material.ZWriteEnable && (AllowZWriteOnTransparent || (material.BlendOperation == EBO_NONE && if (material.ZWriteEnable && (AllowZWriteOnTransparent || (!material.isTransparent() &&
!MaterialRenderers[material.MaterialType].Renderer->isTransparent()))) !MaterialRenderers[material.MaterialType].Renderer->isTransparent())))
{ {
BridgeCalls->setDepthMask(true); BridgeCalls->setDepthMask(true);
...@@ -3095,9 +3095,7 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater ...@@ -3095,9 +3095,7 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
} }
// Blend Equation // Blend Equation
if (resetAllRenderStates|| lastmaterial.BlendOperation != material.BlendOperation) if (material.BlendOperation == EBO_NONE)
{
if (material.BlendOperation==EBO_NONE)
BridgeCalls->setBlend(false); BridgeCalls->setBlend(false);
else else
{ {
...@@ -3193,6 +3191,28 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater ...@@ -3193,6 +3191,28 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
} }
#endif #endif
} }
// Blend Factor
if (material.BlendFactor != 0.f)
{
E_BLEND_FACTOR srcRGBFact = EBF_ZERO;
E_BLEND_FACTOR dstRGBFact = EBF_ZERO;
E_BLEND_FACTOR srcAlphaFact = EBF_ZERO;
E_BLEND_FACTOR dstAlphaFact = EBF_ZERO;
E_MODULATE_FUNC modulo = EMFN_MODULATE_1X;
u32 alphaSource = 0;
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulo, alphaSource, material.BlendFactor);
if (queryFeature(EVDF_BLEND_SEPARATE))
{
BridgeCalls->setBlendFuncSeparate(getGLBlend(srcRGBFact), getGLBlend(dstRGBFact),
getGLBlend(srcAlphaFact), getGLBlend(dstAlphaFact));
}
else
{
BridgeCalls->setBlendFunc(getGLBlend(srcRGBFact), getGLBlend(dstRGBFact));
}
} }
// Polygon Offset // Polygon Offset
...@@ -5045,8 +5065,10 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver), ...@@ -5045,8 +5065,10 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
BlendIndexCount = core::max_(static_cast<GLuint>(1), static_cast<GLuint>(Driver->MaxMultipleRenderTargets)); BlendIndexCount = core::max_(static_cast<GLuint>(1), static_cast<GLuint>(Driver->MaxMultipleRenderTargets));
BlendEquation = new GLenum[BlendIndexCount]; BlendEquation = new GLenum[BlendIndexCount];
BlendSource = new GLenum[BlendIndexCount]; BlendSourceRGB = new GLenum[BlendIndexCount];
BlendDestination = new GLenum[BlendIndexCount]; BlendDestinationRGB = new GLenum[BlendIndexCount];
BlendSourceAlpha = new GLenum[BlendIndexCount];
BlendDestinationAlpha = new GLenum[BlendIndexCount];
Blend = new bool[BlendIndexCount]; Blend = new bool[BlendIndexCount];
for (u32 i = 0; i < BlendIndexCount; ++i) for (u32 i = 0; i < BlendIndexCount; ++i)
...@@ -5057,8 +5079,10 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver), ...@@ -5057,8 +5079,10 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
BlendEquation[i] = GL_FUNC_ADD_EXT; BlendEquation[i] = GL_FUNC_ADD_EXT;
#endif #endif
BlendSource[i] = GL_ONE; BlendSourceRGB[i] = GL_ONE;
BlendDestination[i] = GL_ZERO; BlendDestinationRGB[i] = GL_ZERO;
BlendSourceAlpha[i] = GL_ONE;
BlendDestinationAlpha[i] = GL_ZERO;
Blend[i] = false; Blend[i] = false;
} }
...@@ -5111,8 +5135,10 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver), ...@@ -5111,8 +5135,10 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
COpenGLCallBridge::~COpenGLCallBridge() COpenGLCallBridge::~COpenGLCallBridge()
{ {
delete[] BlendEquation; delete[] BlendEquation;
delete[] BlendSource; delete[] BlendSourceRGB;
delete[] BlendDestination; delete[] BlendDestinationRGB;
delete[] BlendSourceAlpha;
delete[] BlendDestinationAlpha;
delete[] Blend; delete[] Blend;
} }
...@@ -5162,26 +5188,77 @@ void COpenGLCallBridge::setBlendEquationIndexed(GLuint index, GLenum mode) ...@@ -5162,26 +5188,77 @@ void COpenGLCallBridge::setBlendEquationIndexed(GLuint index, GLenum mode)
void COpenGLCallBridge::setBlendFunc(GLenum source, GLenum destination) void COpenGLCallBridge::setBlendFunc(GLenum source, GLenum destination)
{ {
if (BlendSource[0] != source || BlendDestination[0] != destination) if (BlendSourceRGB[0] != source || BlendDestinationRGB[0] != destination ||
BlendSourceAlpha[0] != source || BlendDestinationAlpha[0] != destination)
{ {
glBlendFunc(source, destination); glBlendFunc(source, destination);
for (GLuint i = 0; i < BlendIndexCount; ++i) for (GLuint i = 0; i < BlendIndexCount; ++i)
{ {
BlendSource[i] = source; BlendSourceRGB[i] = source;
BlendDestination[i] = destination; BlendDestinationRGB[i] = destination;
BlendSourceAlpha[i] = source;
BlendDestinationAlpha[i] = destination;
} }
} }
} }
void COpenGLCallBridge::setBlendFuncSeparate(GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha)
{
if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha)
{
if (BlendSourceRGB[0] != sourceRGB || BlendDestinationRGB[0] != destinationRGB ||
BlendSourceAlpha[0] != sourceAlpha || BlendDestinationAlpha[0] != destinationAlpha)
{
Driver->extGlBlendFuncSeparate(sourceRGB, destinationRGB, sourceAlpha, destinationAlpha);
for (GLuint i = 0; i < BlendIndexCount; ++i)
{
BlendSourceRGB[i] = sourceRGB;
BlendDestinationRGB[i] = destinationRGB;
BlendSourceAlpha[i] = sourceAlpha;
BlendDestinationAlpha[i] = destinationAlpha;
}
}
}
else
{
setBlendFunc(sourceRGB, destinationRGB);
}
}
void COpenGLCallBridge::setBlendFuncIndexed(GLuint index, GLenum source, GLenum destination) void COpenGLCallBridge::setBlendFuncIndexed(GLuint index, GLenum source, GLenum destination)
{ {
if (index < BlendIndexCount && (BlendSource[index] != source || BlendDestination[index] != destination)) if (index < BlendIndexCount && (BlendSourceRGB[index] != source || BlendDestinationRGB[index] != destination ||
BlendSourceAlpha[index] != source || BlendDestinationAlpha[index] != destination))
{ {
Driver->extGlBlendFuncIndexed(index, source, destination); Driver->extGlBlendFuncIndexed(index, source, destination);
BlendSource[index] = source; BlendSourceRGB[index] = source;
BlendDestination[index] = destination; BlendDestinationRGB[index] = destination;
BlendSourceAlpha[index] = source;
BlendDestinationAlpha[index] = destination;
}
}
void COpenGLCallBridge::setBlendFuncSeparateIndexed(GLuint index, GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha)
{
if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha)
{
if (index < BlendIndexCount && (BlendSourceRGB[index] != sourceRGB || BlendDestinationRGB[index] != destinationRGB ||
BlendSourceAlpha[index] != sourceAlpha || BlendDestinationAlpha[index] != destinationAlpha))
{
Driver->extGlBlendFuncSeparateIndexed(index, sourceRGB, destinationRGB, sourceAlpha, destinationAlpha);
BlendSourceRGB[index] = sourceRGB;
BlendDestinationRGB[index] = destinationRGB;
BlendSourceAlpha[index] = sourceAlpha;
BlendDestinationAlpha[index] = destinationAlpha;
}
}
else
{
setBlendFuncIndexed(index, sourceRGB, destinationRGB);
} }
} }
......
...@@ -661,8 +661,12 @@ namespace video ...@@ -661,8 +661,12 @@ namespace video
void setBlendFunc(GLenum source, GLenum destination); void setBlendFunc(GLenum source, GLenum destination);
void setBlendFuncSeparate(GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha);
void setBlendFuncIndexed(GLuint index, GLenum source, GLenum destination); void setBlendFuncIndexed(GLuint index, GLenum source, GLenum destination);
void setBlendFuncSeparateIndexed(GLuint index, GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha);
void setBlend(bool enable); void setBlend(bool enable);
void setBlendIndexed(GLuint index, bool enable); void setBlendIndexed(GLuint index, bool enable);
...@@ -705,8 +709,10 @@ namespace video ...@@ -705,8 +709,10 @@ namespace video
bool AlphaTest; bool AlphaTest;
GLenum* BlendEquation; GLenum* BlendEquation;
GLenum* BlendSource; GLenum* BlendSourceRGB;
GLenum* BlendDestination; GLenum* BlendDestinationRGB;
GLenum* BlendSourceAlpha;
GLenum* BlendDestinationAlpha;
bool* Blend; bool* Blend;
GLuint BlendIndexCount; GLuint BlendIndexCount;
......
...@@ -100,10 +100,22 @@ public: ...@@ -100,10 +100,22 @@ public:
// material.MaterialTypeParam != lastMaterial.MaterialTypeParam || // material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
// resetAllRenderstates) // resetAllRenderstates)
{ {
E_BLEND_FACTOR srcFact,dstFact; E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
E_MODULATE_FUNC modulate; E_MODULATE_FUNC modulate;
u32 alphaSource; u32 alphaSource;
unpack_textureBlendFunc(srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam); unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
Driver->getBridgeCalls()->setBlend(true);
if (Driver->queryFeature(EVDF_BLEND_SEPARATE))
{
Driver->getBridgeCalls()->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
}
else
{
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
}
#ifdef GL_ARB_texture_env_combine #ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
...@@ -119,12 +131,8 @@ public: ...@@ -119,12 +131,8 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate ); glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
#endif #endif
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact)); if (textureBlendFunc_hasAlpha(srcRGBFact) || textureBlendFunc_hasAlpha(dstRGBFact) ||
Driver->getBridgeCalls()->setAlphaTest(true); textureBlendFunc_hasAlpha(srcAlphaFact) || textureBlendFunc_hasAlpha(dstAlphaFact))
Driver->getBridgeCalls()->setAlphaFunc(GL_GREATER, 0.f);
Driver->getBridgeCalls()->setBlend(true);
if ( textureBlendFunc_hasAlpha(srcFact) || textureBlendFunc_hasAlpha(dstFact) )
{ {
if (alphaSource==EAS_VERTEX_COLOR) if (alphaSource==EAS_VERTEX_COLOR)
{ {
...@@ -164,16 +172,22 @@ public: ...@@ -164,16 +172,22 @@ public:
virtual void OnSetBaseMaterial(const SMaterial& material) _IRR_OVERRIDE_ virtual void OnSetBaseMaterial(const SMaterial& material) _IRR_OVERRIDE_
{ {
E_BLEND_FACTOR srcFact,dstFact; E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
E_MODULATE_FUNC modulate; E_MODULATE_FUNC modulate;
u32 alphaSource; u32 alphaSource;
unpack_textureBlendFunc(srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam); unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact));
Driver->getBridgeCalls()->setAlphaTest(true);
Driver->getBridgeCalls()->setAlphaFunc(GL_GREATER, 0.f);
Driver->getBridgeCalls()->setBlend(true); Driver->getBridgeCalls()->setBlend(true);
if (Driver->queryFeature(EVDF_BLEND_SEPARATE))
{
Driver->getBridgeCalls()->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
}
else
{
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
}
} }
virtual void OnUnsetMaterial() _IRR_OVERRIDE_ virtual void OnUnsetMaterial() _IRR_OVERRIDE_
...@@ -190,13 +204,11 @@ public: ...@@ -190,13 +204,11 @@ public:
#endif #endif
Driver->getBridgeCalls()->setBlend(false); Driver->getBridgeCalls()->setBlend(false);
Driver->getBridgeCalls()->setAlphaTest(false);
} }
virtual void OnUnsetBaseMaterial() _IRR_OVERRIDE_ virtual void OnUnsetBaseMaterial() _IRR_OVERRIDE_
{ {
Driver->getBridgeCalls()->setBlend(false); Driver->getBridgeCalls()->setBlend(false);
Driver->getBridgeCalls()->setAlphaTest(false);
} }
//! Returns if the material is transparent. //! Returns if the material is transparent.
......
...@@ -1317,7 +1317,7 @@ u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDE ...@@ -1317,7 +1317,7 @@ u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDE
{ {
video::IMaterialRenderer* rnd = video::IMaterialRenderer* rnd =
Driver->getMaterialRenderer(node->getMaterial(i).MaterialType); Driver->getMaterialRenderer(node->getMaterial(i).MaterialType);
if ((rnd && rnd->isTransparent()) || node->getMaterial(i).BlendOperation != video::EBO_NONE) if ((rnd && rnd->isTransparent()) || node->getMaterial(i).isTransparent())
{ {
// register as transparent node // register as transparent node
TransparentNodeEntry e(node, camWorldPos); TransparentNodeEntry e(node, camWorldPos);
......
...@@ -486,7 +486,7 @@ void CBurningVideoDriver::setCurrentShader() ...@@ -486,7 +486,7 @@ void CBurningVideoDriver::setCurrentShader()
bool zMaterialTest = Material.org.ZBuffer != ECFN_DISABLED && bool zMaterialTest = Material.org.ZBuffer != ECFN_DISABLED &&
Material.org.ZWriteEnable && Material.org.ZWriteEnable &&
( AllowZWriteOnTransparent || (Material.org.BlendOperation == EBO_NONE && ( AllowZWriteOnTransparent || (!Material.org.isTransparent() &&
!MaterialRenderers[Material.org.MaterialType].Renderer->isTransparent()) ); !MaterialRenderers[Material.org.MaterialType].Renderer->isTransparent()) );
EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ; EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment