- 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-e03cc46cb475master
parent
6058c27631
commit
9bad8de603
|
@ -1,6 +1,10 @@
|
|||
--------------------------
|
||||
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 override font to IGUITable
|
||||
- IGUITable can now disable the active column.
|
||||
|
|
|
@ -115,6 +115,9 @@ namespace video
|
|||
//! Support for different blend functions. Without, only ADD is available
|
||||
EVDF_BLEND_OPERATIONS,
|
||||
|
||||
//! Support for separate blending for RGB and Alpha.
|
||||
EVDF_BLEND_SEPARATE,
|
||||
|
||||
//! Support for texture coord transformation via texture matrix
|
||||
EVDF_TEXTURE_MATRIX,
|
||||
|
||||
|
|
|
@ -84,7 +84,10 @@ namespace video
|
|||
EMF_BLEND_OPERATION = 0x40000,
|
||||
|
||||
//! Flag for polygon offset
|
||||
EMF_POLYGON_OFFSET = 0x80000
|
||||
EMF_POLYGON_OFFSET = 0x80000,
|
||||
|
||||
//! Flag for blend factor
|
||||
EMF_BLEND_FACTOR = 0x160000
|
||||
};
|
||||
|
||||
} // end namespace video
|
||||
|
|
|
@ -197,6 +197,7 @@ namespace video
|
|||
case EMF_COLOR_MATERIAL: material.ColorMaterial = Material.ColorMaterial; break;
|
||||
case EMF_USE_MIP_MAPS: material.UseMipMaps = Material.UseMipMaps; break;
|
||||
case EMF_BLEND_OPERATION: material.BlendOperation = Material.BlendOperation; break;
|
||||
case EMF_BLEND_FACTOR: material.BlendFactor = Material.BlendFactor; break;
|
||||
case EMF_POLYGON_OFFSET:
|
||||
material.PolygonOffsetDirection = Material.PolygonOffsetDirection;
|
||||
material.PolygonOffsetFactor = Material.PolygonOffsetFactor; break;
|
||||
|
|
|
@ -113,27 +113,53 @@ namespace video
|
|||
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. */
|
||||
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);
|
||||
}
|
||||
|
||||
//! 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... */
|
||||
inline void unpack_textureBlendFunc ( E_BLEND_FACTOR &srcFact, E_BLEND_FACTOR &dstFact,
|
||||
E_MODULATE_FUNC &modulo, u32& alphaSource, const f32 param )
|
||||
inline void unpack_textureBlendFunc(E_BLEND_FACTOR &srcFact, E_BLEND_FACTOR &dstFact,
|
||||
E_MODULATE_FUNC &modulo, u32& alphaSource, const f32 param)
|
||||
{
|
||||
const u32 state = IR(param);
|
||||
alphaSource = (state & 0x0000F000) >> 12;
|
||||
modulo = E_MODULATE_FUNC( ( state & 0x00000F00 ) >> 8 );
|
||||
alphaSource = (state & 0x00F00000) >> 20;
|
||||
modulo = E_MODULATE_FUNC( ( state & 0x000F0000 ) >> 16 );
|
||||
srcFact = E_BLEND_FACTOR ( ( state & 0x000000F0 ) >> 4 );
|
||||
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 )
|
||||
{
|
||||
switch ( factor )
|
||||
|
@ -234,7 +260,7 @@ namespace video
|
|||
EmissiveColor(0,0,0,0), SpecularColor(255,255,255,255),
|
||||
Shininess(0.0f), MaterialTypeParam(0.0f), MaterialTypeParam2(0.0f), Thickness(1.0f),
|
||||
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),
|
||||
Wireframe(false), PointCloud(false), GouraudShading(true),
|
||||
Lighting(true), ZWriteEnable(true), BackfaceCulling(true), FrontfaceCulling(false),
|
||||
|
@ -288,6 +314,7 @@ namespace video
|
|||
ColorMask = other.ColorMask;
|
||||
ColorMaterial = other.ColorMaterial;
|
||||
BlendOperation = other.BlendOperation;
|
||||
BlendFactor = other.BlendFactor;
|
||||
PolygonOffsetFactor = other.PolygonOffsetFactor;
|
||||
PolygonOffsetDirection = other.PolygonOffsetDirection;
|
||||
UseMipMaps = other.UseMipMaps;
|
||||
|
@ -391,10 +418,15 @@ namespace video
|
|||
u8 ColorMaterial:3;
|
||||
|
||||
//! Store the blend operation of choice
|
||||
/** Values to be chosen from E_BLEND_OPERATION. The actual way to use this value
|
||||
is not yet determined, so ignore it for now. */
|
||||
/** Values to be chosen from E_BLEND_OPERATION. */
|
||||
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
|
||||
/** Specifying 0 disables the polygon offset. The direction is specified spearately.
|
||||
The factor can be from 0 to 7.*/
|
||||
|
@ -559,6 +591,8 @@ namespace video
|
|||
UseMipMaps = value; break;
|
||||
case EMF_BLEND_OPERATION:
|
||||
BlendOperation = value?EBO_ADD:EBO_NONE; break;
|
||||
case EMF_BLEND_FACTOR:
|
||||
break;
|
||||
case EMF_POLYGON_OFFSET:
|
||||
PolygonOffsetFactor = value?1:0;
|
||||
PolygonOffsetDirection = EPO_BACK;
|
||||
|
@ -620,6 +654,8 @@ namespace video
|
|||
return UseMipMaps;
|
||||
case EMF_BLEND_OPERATION:
|
||||
return BlendOperation != EBO_NONE;
|
||||
case EMF_BLEND_FACTOR:
|
||||
return BlendFactor != 0.f;
|
||||
case EMF_POLYGON_OFFSET:
|
||||
return PolygonOffsetFactor != 0;
|
||||
}
|
||||
|
@ -656,6 +692,7 @@ namespace video
|
|||
ColorMask != b.ColorMask ||
|
||||
ColorMaterial != b.ColorMaterial ||
|
||||
BlendOperation != b.BlendOperation ||
|
||||
BlendFactor != b.BlendFactor ||
|
||||
PolygonOffsetFactor != b.PolygonOffsetFactor ||
|
||||
PolygonOffsetDirection != b.PolygonOffsetDirection ||
|
||||
UseMipMaps != b.UseMipMaps;
|
||||
|
@ -671,6 +708,31 @@ namespace video
|
|||
\return True if the materials are equal, else false. */
|
||||
inline bool operator==(const SMaterial& b) const
|
||||
{ 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
|
||||
|
|
|
@ -164,7 +164,7 @@ void CAnimatedMeshSceneNode::OnRegisterSceneNode()
|
|||
video::IMaterialRenderer* rnd =
|
||||
driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
|
||||
if ((rnd && rnd->isTransparent()) || Materials[i].BlendOperation != video::EBO_NONE)
|
||||
if ((rnd && rnd->isTransparent()) || Materials[i].isTransparent())
|
||||
++transparentCount;
|
||||
else
|
||||
++solidCount;
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace video
|
|||
|
||||
//! constructor
|
||||
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),
|
||||
D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0),
|
||||
WindowId(0), SceneSourceRect(0),
|
||||
|
@ -66,6 +66,8 @@ CD3D8Driver::~CD3D8Driver()
|
|||
{
|
||||
deleteMaterialRenders();
|
||||
|
||||
delete BridgeCalls;
|
||||
|
||||
// drop d3d8
|
||||
|
||||
if (pID3DDevice)
|
||||
|
@ -369,6 +371,9 @@ bool CD3D8Driver::initDriver(HWND hwnd, bool pureSoftware)
|
|||
Params.Stencilbuffer = false;
|
||||
}
|
||||
|
||||
if (!BridgeCalls)
|
||||
BridgeCalls = new CD3D8CallBridge(pID3DDevice);
|
||||
|
||||
// set default vertex shader
|
||||
setVertexShader(EVT_STANDARD);
|
||||
|
||||
|
@ -608,6 +613,9 @@ bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
|
|||
case EVDF_COLOR_MASK:
|
||||
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0;
|
||||
case EVDF_BLEND_OPERATIONS:
|
||||
return true;
|
||||
case EVDF_BLEND_SEPARATE:
|
||||
return false;
|
||||
case EVDF_TEXTURE_MATRIX:
|
||||
return true;
|
||||
case EVDF_TEXTURE_COMPRESSED_DXT:
|
||||
|
@ -1533,7 +1541,7 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
|
|||
// zwrite
|
||||
// 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())))
|
||||
{
|
||||
pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE);
|
||||
|
@ -1591,40 +1599,50 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
|
|||
}
|
||||
|
||||
// Blend Operation
|
||||
if (resetAllRenderstates || lastmaterial.BlendOperation != material.BlendOperation)
|
||||
{
|
||||
if (material.BlendOperation==EBO_NONE)
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
else
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
if (material.BlendOperation == EBO_NONE)
|
||||
BridgeCalls->setBlend(false);
|
||||
else
|
||||
{
|
||||
BridgeCalls->setBlend(true);
|
||||
|
||||
if (queryFeature(EVDF_BLEND_OPERATIONS))
|
||||
{
|
||||
switch (material.BlendOperation)
|
||||
{
|
||||
case EBO_MAX:
|
||||
case EBO_MAX_FACTOR:
|
||||
case EBO_MAX_ALPHA:
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX);
|
||||
break;
|
||||
case EBO_MIN:
|
||||
case EBO_MIN_FACTOR:
|
||||
case EBO_MIN_ALPHA:
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN);
|
||||
break;
|
||||
case EBO_SUBTRACT:
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
|
||||
break;
|
||||
case EBO_REVSUBTRACT:
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT);
|
||||
break;
|
||||
default:
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
break;
|
||||
}
|
||||
if (queryFeature(EVDF_BLEND_OPERATIONS))
|
||||
{
|
||||
switch (material.BlendOperation)
|
||||
{
|
||||
case EBO_MAX:
|
||||
case EBO_MAX_FACTOR:
|
||||
case EBO_MAX_ALPHA:
|
||||
BridgeCalls->setBlendOperation(D3DBLENDOP_MAX);
|
||||
break;
|
||||
case EBO_MIN:
|
||||
case EBO_MIN_FACTOR:
|
||||
case EBO_MIN_ALPHA:
|
||||
BridgeCalls->setBlendOperation(D3DBLENDOP_MIN);
|
||||
break;
|
||||
case EBO_SUBTRACT:
|
||||
BridgeCalls->setBlendOperation(D3DBLENDOP_SUBTRACT);
|
||||
break;
|
||||
case EBO_REVSUBTRACT:
|
||||
BridgeCalls->setBlendOperation(D3DBLENDOP_REVSUBTRACT);
|
||||
break;
|
||||
default:
|
||||
BridgeCalls->setBlendOperation(D3DBLENDOP_ADD);
|
||||
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
|
||||
|
@ -1796,9 +1814,8 @@ void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha)
|
|||
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
|
||||
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
BridgeCalls->setBlend(true);
|
||||
BridgeCalls->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1806,7 +1823,7 @@ void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha)
|
|||
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
|
||||
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
|
||||
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
|
|||
|
||||
if (alpha || alphaChannel)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
BridgeCalls->setBlend(true);
|
||||
BridgeCalls->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
}
|
||||
else
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
BridgeCalls->setBlend(false);
|
||||
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
|
@ -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 irr
|
||||
|
||||
|
|
|
@ -25,8 +25,11 @@ namespace irr
|
|||
{
|
||||
namespace video
|
||||
{
|
||||
class CD3D8CallBridge;
|
||||
|
||||
class CD3D8Driver : public CNullDriver, IMaterialRendererServices
|
||||
{
|
||||
friend class CD3D8CallBridge;
|
||||
friend class CD3D8Texture;
|
||||
|
||||
public:
|
||||
|
@ -228,6 +231,16 @@ namespace video
|
|||
virtual core::dimension2du getMaxTextureSize() const _IRR_OVERRIDE_;
|
||||
|
||||
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:
|
||||
|
||||
// enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates.
|
||||
|
@ -295,6 +308,8 @@ namespace video
|
|||
return v;
|
||||
}
|
||||
|
||||
CD3D8CallBridge* BridgeCalls;
|
||||
|
||||
E_RENDER_MODE CurrentRenderMode;
|
||||
D3DPRESENT_PARAMETERS present;
|
||||
|
||||
|
@ -332,6 +347,31 @@ namespace video
|
|||
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 irr
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <d3d8.h>
|
||||
|
||||
#include "IMaterialRenderer.h"
|
||||
#include "CD3D8Driver.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -55,7 +56,7 @@ class CD3D8MaterialRenderer : public IMaterialRenderer
|
|||
public:
|
||||
|
||||
//! Constructor
|
||||
CD3D8MaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver)
|
||||
CD3D8MaterialRenderer(IDirect3DDevice8* d3ddev, CD3D8Driver* driver)
|
||||
: pID3DDevice(d3ddev), Driver(driver)
|
||||
{
|
||||
}
|
||||
|
@ -63,7 +64,7 @@ public:
|
|||
protected:
|
||||
|
||||
IDirect3DDevice8* pID3DDevice;
|
||||
video::IVideoDriver* Driver;
|
||||
CD3D8Driver* Driver;
|
||||
};
|
||||
|
||||
|
||||
|
@ -72,7 +73,7 @@ class CD3D8MaterialRenderer_SOLID : public CD3D8MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_SOLID(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_SOLID(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -95,7 +96,7 @@ class CD3D8MaterialRenderer_ONETEXTURE_BLEND : public CD3D8MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -113,19 +114,11 @@ public:
|
|||
u32 alphaSource;
|
||||
unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam );
|
||||
|
||||
if (srcFact == EBF_SRC_COLOR && dstFact == EBF_ZERO)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, getD3DBlend ( srcFact ) );
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, getD3DBlend ( dstFact ) );
|
||||
}
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(Driver->getD3DBlend(srcFact), Driver->getD3DBlend(dstFact));
|
||||
|
||||
setTextureColorStage(pID3DDevice, 0,
|
||||
D3DTA_TEXTURE, getD3DModulate(modulate), D3DTA_DIFFUSE);
|
||||
D3DTA_TEXTURE, CD3D8MaterialRenderer::getD3DModulate(modulate), D3DTA_DIFFUSE);
|
||||
|
||||
if ( alphaSource && (textureBlendFunc_hasAlpha ( srcFact ) || textureBlendFunc_hasAlpha ( dstFact ) ))
|
||||
{
|
||||
|
@ -151,7 +144,7 @@ public:
|
|||
|
||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent.
|
||||
|
@ -163,41 +156,6 @@ public:
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
u32 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 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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -206,7 +164,7 @@ class CD3D8MaterialRenderer_SOLID_2_LAYER : public CD3D8MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -230,7 +188,7 @@ class CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR : public CD3D8MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -238,9 +196,8 @@ public:
|
|||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_ONE, D3DBLEND_INVSRCCOLOR);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
|
@ -253,7 +210,7 @@ public:
|
|||
|
||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent. The scene management needs to know this
|
||||
|
@ -270,7 +227,7 @@ class CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public CD3D8MaterialRende
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -278,9 +235,8 @@ public:
|
|||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
|
@ -294,7 +250,7 @@ public:
|
|||
|
||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent. The scene managment needs to know this
|
||||
|
@ -311,7 +267,7 @@ class CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public CD3D8MaterialRend
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -319,9 +275,8 @@ public:
|
|||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates
|
||||
|| material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
|
||||
|
@ -341,7 +296,7 @@ public:
|
|||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent. The scene managment needs to know this
|
||||
|
@ -358,7 +313,7 @@ class CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public CD3D8Material
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -400,7 +355,7 @@ class CD3D8MaterialRenderer_LIGHTMAP : public CD3D8MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_LIGHTMAP(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_LIGHTMAP(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -443,7 +398,7 @@ class CD3D8MaterialRenderer_DETAIL_MAP : public CD3D8MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_DETAIL_MAP(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_DETAIL_MAP(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -468,7 +423,7 @@ class CD3D8MaterialRenderer_SPHERE_MAP : public CD3D8MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_SPHERE_MAP(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_SPHERE_MAP(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -503,7 +458,7 @@ class CD3D8MaterialRenderer_REFLECTION_2_LAYER : public CD3D8MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -539,7 +494,7 @@ class CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public CD3D8Materia
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d)
|
||||
CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice8* p, CD3D8Driver* d)
|
||||
: CD3D8MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -547,9 +502,8 @@ public:
|
|||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
|
@ -571,7 +525,7 @@ public:
|
|||
pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
|
||||
pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
|
||||
pID3DDevice->SetTransform(D3DTS_TEXTURE1, &UnitMatrixD3D8);
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent. The scene managment needs to know this
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace
|
|||
|
||||
//! constructor
|
||||
CD3D9Driver::CD3D9Driver(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),
|
||||
D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0),
|
||||
WindowId(0), SceneSourceRect(0),
|
||||
|
@ -88,6 +88,8 @@ CD3D9Driver::~CD3D9Driver()
|
|||
}
|
||||
DepthBuffers.clear();
|
||||
|
||||
delete BridgeCalls;
|
||||
|
||||
// drop d3d9
|
||||
|
||||
if (pID3DDevice)
|
||||
|
@ -420,6 +422,9 @@ bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
|
|||
Params.Stencilbuffer = false;
|
||||
}
|
||||
|
||||
if (!BridgeCalls)
|
||||
BridgeCalls = new CD3D9CallBridge(pID3DDevice, this);
|
||||
|
||||
// set default vertex shader
|
||||
setVertexShader(EVT_STANDARD);
|
||||
|
||||
|
@ -680,6 +685,9 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
|
|||
case EVDF_POLYGON_OFFSET:
|
||||
return (Caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS|D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) != 0;
|
||||
case EVDF_BLEND_OPERATIONS:
|
||||
return true;
|
||||
case EVDF_BLEND_SEPARATE:
|
||||
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) != 0;
|
||||
case EVDF_TEXTURE_MATRIX:
|
||||
return true;
|
||||
case EVDF_TEXTURE_COMPRESSED_DXT:
|
||||
|
@ -2244,7 +2252,7 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
|
|||
// zwrite
|
||||
// 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())))
|
||||
{
|
||||
pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE);
|
||||
|
@ -2302,40 +2310,53 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
|
|||
}
|
||||
|
||||
// Blend Operation
|
||||
if (resetAllRenderstates || lastmaterial.BlendOperation != material.BlendOperation)
|
||||
{
|
||||
if (material.BlendOperation==EBO_NONE)
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
else
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
if (material.BlendOperation == EBO_NONE)
|
||||
BridgeCalls->setBlend(false);
|
||||
else
|
||||
{
|
||||
BridgeCalls->setBlend(true);
|
||||
|
||||
if (queryFeature(EVDF_BLEND_OPERATIONS))
|
||||
{
|
||||
switch (material.BlendOperation)
|
||||
{
|
||||
case EBO_SUBTRACT:
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
|
||||
break;
|
||||
case EBO_REVSUBTRACT:
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT);
|
||||
break;
|
||||
case EBO_MIN:
|
||||
case EBO_MIN_FACTOR:
|
||||
case EBO_MIN_ALPHA:
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN);
|
||||
break;
|
||||
case EBO_MAX:
|
||||
case EBO_MAX_FACTOR:
|
||||
case EBO_MAX_ALPHA:
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX);
|
||||
break;
|
||||
default:
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
break;
|
||||
}
|
||||
if (queryFeature(EVDF_BLEND_OPERATIONS))
|
||||
{
|
||||
switch (material.BlendOperation)
|
||||
{
|
||||
case EBO_MAX:
|
||||
case EBO_MAX_FACTOR:
|
||||
case EBO_MAX_ALPHA:
|
||||
BridgeCalls->setBlendOperation(D3DBLENDOP_MAX);
|
||||
break;
|
||||
case EBO_MIN:
|
||||
case EBO_MIN_FACTOR:
|
||||
case EBO_MIN_ALPHA:
|
||||
BridgeCalls->setBlendOperation(D3DBLENDOP_MIN);
|
||||
break;
|
||||
case EBO_SUBTRACT:
|
||||
BridgeCalls->setBlendOperation(D3DBLENDOP_SUBTRACT);
|
||||
break;
|
||||
case EBO_REVSUBTRACT:
|
||||
BridgeCalls->setBlendOperation(D3DBLENDOP_REVSUBTRACT);
|
||||
break;
|
||||
default:
|
||||
BridgeCalls->setBlendOperation(D3DBLENDOP_ADD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
BridgeCalls->setBlendFuncSeparate(getD3DBlend(srcRGBFact), getD3DBlend(dstRGBFact),
|
||||
getD3DBlend(srcAlphaFact), getD3DBlend(dstAlphaFact));
|
||||
}
|
||||
|
||||
// Polygon offset
|
||||
|
@ -2565,13 +2586,12 @@ void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha)
|
|||
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
if (alpha)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
BridgeCalls->setBlend(true);
|
||||
BridgeCalls->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
BridgeCalls->setBlend(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2646,12 +2666,11 @@ void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChan
|
|||
|
||||
if (alpha || alphaChannel)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
BridgeCalls->setBlend(true);
|
||||
BridgeCalls->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
}
|
||||
else
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
BridgeCalls->setBlend(false);
|
||||
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
|
@ -3601,6 +3620,46 @@ core::dimension2du CD3D9Driver::getMaxTextureSize() const
|
|||
return core::dimension2du(Caps.MaxTextureWidth, Caps.MaxTextureHeight);
|
||||
}
|
||||
|
||||
|
||||
u32 CD3D9Driver::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 CD3D9Driver::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;
|
||||
}
|
||||
|
||||
|
||||
CD3D9CallBridge* CD3D9Driver::getBridgeCalls() const
|
||||
{
|
||||
return BridgeCalls;
|
||||
}
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_CG_
|
||||
const CGcontext& CD3D9Driver::getCgContext()
|
||||
{
|
||||
|
@ -3609,6 +3668,122 @@ const CGcontext& CD3D9Driver::getCgContext()
|
|||
#endif
|
||||
|
||||
|
||||
CD3D9CallBridge::CD3D9CallBridge(IDirect3DDevice9* p, CD3D9Driver* driver) : pID3DDevice(p),
|
||||
BlendOperation(D3DBLENDOP_ADD), BlendSourceRGB(D3DBLEND_ONE), BlendDestinationRGB(D3DBLEND_ZERO),
|
||||
BlendSourceAlpha(D3DBLEND_ONE), BlendDestinationAlpha(D3DBLEND_ZERO), Blend(false), BlendSeparate(false)
|
||||
{
|
||||
FeatureBlendSeparate = driver->queryFeature(EVDF_BLEND_SEPARATE);
|
||||
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
|
||||
if (FeatureBlendSeparate)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO);
|
||||
pID3DDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void CD3D9CallBridge::setBlendOperation(DWORD mode)
|
||||
{
|
||||
if (BlendOperation != mode)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_BLENDOP, mode);
|
||||
|
||||
BlendOperation = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void CD3D9CallBridge::setBlendFunc(DWORD source, DWORD destination)
|
||||
{
|
||||
if (BlendSourceRGB != source)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, source);
|
||||
|
||||
BlendSourceRGB = source;
|
||||
}
|
||||
|
||||
if (BlendDestinationRGB != destination)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, destination);
|
||||
|
||||
BlendDestinationRGB = destination;
|
||||
}
|
||||
|
||||
if (FeatureBlendSeparate && BlendSeparate)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
|
||||
|
||||
BlendSeparate = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CD3D9CallBridge::setBlendFuncSeparate(DWORD sourceRGB, DWORD destinationRGB, DWORD sourceAlpha, DWORD destinationAlpha)
|
||||
{
|
||||
if (BlendSourceRGB != sourceRGB)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, sourceRGB);
|
||||
|
||||
BlendSourceRGB = sourceRGB;
|
||||
}
|
||||
|
||||
if (BlendDestinationRGB != destinationRGB)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, destinationRGB);
|
||||
|
||||
BlendDestinationRGB = destinationRGB;
|
||||
}
|
||||
|
||||
if (FeatureBlendSeparate)
|
||||
{
|
||||
if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha)
|
||||
{
|
||||
if (BlendSourceAlpha != sourceAlpha)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLENDALPHA, sourceAlpha);
|
||||
|
||||
BlendSourceAlpha = sourceAlpha;
|
||||
}
|
||||
|
||||
if (BlendDestinationAlpha != destinationAlpha)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLENDALPHA, destinationAlpha);
|
||||
|
||||
BlendDestinationAlpha = destinationAlpha;
|
||||
}
|
||||
|
||||
if (!BlendSeparate)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
||||
|
||||
BlendSeparate = true;
|
||||
}
|
||||
}
|
||||
else if (BlendSeparate)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
|
||||
|
||||
BlendSeparate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CD3D9CallBridge::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 irr
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ namespace irr
|
|||
{
|
||||
namespace video
|
||||
{
|
||||
class CD3D9CallBridge;
|
||||
|
||||
struct SDepthSurface : public IReferenceCounted
|
||||
{
|
||||
SDepthSurface() : Surface(0)
|
||||
|
@ -53,6 +55,7 @@ namespace video
|
|||
{
|
||||
public:
|
||||
|
||||
friend class CD3D9CallBridge;
|
||||
friend class CD3D9Texture;
|
||||
|
||||
//! constructor
|
||||
|
@ -332,6 +335,15 @@ namespace video
|
|||
//! Get Irrlicht color format from D3D color format.
|
||||
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
|
||||
#ifdef _IRR_COMPILE_WITH_CG_
|
||||
const CGcontext& getCgContext();
|
||||
|
@ -427,6 +439,8 @@ namespace video
|
|||
return v;
|
||||
}
|
||||
|
||||
CD3D9CallBridge* BridgeCalls;
|
||||
|
||||
E_RENDER_MODE CurrentRenderMode;
|
||||
D3DPRESENT_PARAMETERS present;
|
||||
|
||||
|
@ -486,6 +500,37 @@ namespace video
|
|||
#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 irr
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <d3d9.h>
|
||||
|
||||
#include "IMaterialRenderer.h"
|
||||
#include "CD3D9Driver.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -58,7 +59,7 @@ class CD3D9MaterialRenderer : public IMaterialRenderer
|
|||
public:
|
||||
|
||||
//! Constructor
|
||||
CD3D9MaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver)
|
||||
CD3D9MaterialRenderer(IDirect3DDevice9* d3ddev, CD3D9Driver* driver)
|
||||
: pID3DDevice(d3ddev), Driver(driver)
|
||||
{
|
||||
}
|
||||
|
@ -91,7 +92,7 @@ public:
|
|||
protected:
|
||||
|
||||
IDirect3DDevice9* pID3DDevice;
|
||||
video::IVideoDriver* Driver;
|
||||
CD3D9Driver* Driver;
|
||||
};
|
||||
|
||||
|
||||
|
@ -100,7 +101,7 @@ class CD3D9MaterialRenderer_SOLID : public CD3D9MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_SOLID(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_SOLID(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -123,7 +124,7 @@ class CD3D9MaterialRenderer_ONETEXTURE_BLEND : public CD3D9MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -135,27 +136,20 @@ public:
|
|||
// material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
|
||||
// resetAllRenderstates)
|
||||
{
|
||||
|
||||
E_BLEND_FACTOR srcFact,dstFact;
|
||||
E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
|
||||
E_MODULATE_FUNC modulate;
|
||||
u32 alphaSource;
|
||||
unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam );
|
||||
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
|
||||
|
||||
if (srcFact == EBF_SRC_COLOR && dstFact == EBF_ZERO)
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, getD3DBlend ( srcFact ) );
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, getD3DBlend ( dstFact ) );
|
||||
}
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFuncSeparate(Driver->getD3DBlend(srcRGBFact), Driver->getD3DBlend(dstRGBFact),
|
||||
Driver->getD3DBlend(srcAlphaFact), Driver->getD3DBlend(dstAlphaFact));
|
||||
|
||||
setTextureColorStage(pID3DDevice, 0,
|
||||
D3DTA_TEXTURE, getD3DModulate(modulate), D3DTA_DIFFUSE);
|
||||
D3DTA_TEXTURE, Driver->getD3DModulate(modulate), D3DTA_DIFFUSE);
|
||||
|
||||
if ( textureBlendFunc_hasAlpha ( srcFact ) || textureBlendFunc_hasAlpha ( dstFact ) )
|
||||
if (textureBlendFunc_hasAlpha(srcRGBFact) || textureBlendFunc_hasAlpha(dstRGBFact) ||
|
||||
textureBlendFunc_hasAlpha(srcAlphaFact) || textureBlendFunc_hasAlpha(dstAlphaFact))
|
||||
{
|
||||
if (alphaSource==EAS_VERTEX_COLOR)
|
||||
{
|
||||
|
@ -179,7 +173,7 @@ public:
|
|||
|
||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent.
|
||||
|
@ -191,42 +185,6 @@ public:
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
u32 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 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;
|
||||
}
|
||||
|
||||
bool transparent;
|
||||
};
|
||||
|
||||
|
||||
|
@ -236,7 +194,7 @@ class CD3D9MaterialRenderer_SOLID_2_LAYER : public CD3D9MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -260,7 +218,7 @@ class CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR : public CD3D9MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -268,9 +226,8 @@ public:
|
|||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_ONE, D3DBLEND_INVSRCCOLOR);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
|
@ -283,7 +240,7 @@ public:
|
|||
|
||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent. The scene management needs to know this
|
||||
|
@ -300,7 +257,7 @@ class CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public CD3D9MaterialRende
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -308,9 +265,8 @@ public:
|
|||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
|
@ -324,7 +280,7 @@ public:
|
|||
|
||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent. The scene managment needs to know this
|
||||
|
@ -341,7 +297,7 @@ class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public CD3D9MaterialRend
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -349,9 +305,8 @@ public:
|
|||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates
|
||||
|| material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
|
||||
|
@ -371,7 +326,7 @@ public:
|
|||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent. The scene managment needs to know this
|
||||
|
@ -389,7 +344,7 @@ class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public CD3D9Material
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -431,7 +386,7 @@ class CD3D9MaterialRenderer_LIGHTMAP : public CD3D9MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_LIGHTMAP(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_LIGHTMAP(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -475,7 +430,7 @@ class CD3D9MaterialRenderer_DETAIL_MAP : public CD3D9MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_DETAIL_MAP(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_DETAIL_MAP(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -500,7 +455,7 @@ class CD3D9MaterialRenderer_SPHERE_MAP : public CD3D9MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_SPHERE_MAP(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_SPHERE_MAP(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -535,7 +490,7 @@ class CD3D9MaterialRenderer_REFLECTION_2_LAYER : public CD3D9MaterialRenderer
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -571,7 +526,7 @@ class CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public CD3D9Materia
|
|||
{
|
||||
public:
|
||||
|
||||
CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d)
|
||||
CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice9* p, CD3D9Driver* d)
|
||||
: CD3D9MaterialRenderer(p, d) {}
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
|
@ -579,9 +534,8 @@ public:
|
|||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
|
@ -603,7 +557,7 @@ public:
|
|||
pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
|
||||
pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
|
||||
pID3DDevice->SetTransform(D3DTS_TEXTURE1, &UnitMatrixD3D9);
|
||||
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent. The scene managment needs to know this
|
||||
|
|
|
@ -89,7 +89,7 @@ void CMeshSceneNode::OnRegisterSceneNode()
|
|||
video::IMaterialRenderer* rnd =
|
||||
driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
|
||||
if ((rnd && rnd->isTransparent()) || Materials[i].BlendOperation != video::EBO_NONE)
|
||||
if ((rnd && rnd->isTransparent()) || Materials[i].isTransparent())
|
||||
++transparentCount;
|
||||
else
|
||||
++solidCount;
|
||||
|
|
|
@ -76,7 +76,7 @@ void COctreeSceneNode::OnRegisterSceneNode()
|
|||
const video::IMaterialRenderer* const rnd =
|
||||
driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
|
||||
if ((rnd && rnd->isTransparent()) || Materials[i].BlendOperation != video::EBO_NONE)
|
||||
if ((rnd && rnd->isTransparent()) || Materials[i].isTransparent())
|
||||
++transparentCount;
|
||||
else
|
||||
++solidCount;
|
||||
|
|
|
@ -637,8 +637,6 @@ COpenGLDriver::~COpenGLDriver()
|
|||
cgDestroyContext(CgContext);
|
||||
#endif
|
||||
|
||||
delete BridgeCalls;
|
||||
|
||||
RequestedLights.clear();
|
||||
|
||||
deleteMaterialRenders();
|
||||
|
@ -650,6 +648,8 @@ COpenGLDriver::~COpenGLDriver()
|
|||
removeAllOcclusionQueries();
|
||||
removeAllHardwareBuffers();
|
||||
|
||||
delete BridgeCalls;
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
|
||||
if (DeviceType == EIDT_WIN32)
|
||||
{
|
||||
|
@ -3051,7 +3051,7 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
|
|||
// zwrite
|
||||
// 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())))
|
||||
{
|
||||
BridgeCalls->setDepthMask(true);
|
||||
|
@ -3095,104 +3095,124 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
|
|||
}
|
||||
|
||||
// Blend Equation
|
||||
if (resetAllRenderStates|| lastmaterial.BlendOperation != material.BlendOperation)
|
||||
{
|
||||
if (material.BlendOperation==EBO_NONE)
|
||||
BridgeCalls->setBlend(false);
|
||||
else
|
||||
{
|
||||
BridgeCalls->setBlend(true);
|
||||
if (material.BlendOperation == EBO_NONE)
|
||||
BridgeCalls->setBlend(false);
|
||||
else
|
||||
{
|
||||
BridgeCalls->setBlend(true);
|
||||
|
||||
#if defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op) || defined(GL_VERSION_1_4)
|
||||
if (queryFeature(EVDF_BLEND_OPERATIONS))
|
||||
{
|
||||
switch (material.BlendOperation)
|
||||
{
|
||||
case EBO_SUBTRACT:
|
||||
if (queryFeature(EVDF_BLEND_OPERATIONS))
|
||||
{
|
||||
switch (material.BlendOperation)
|
||||
{
|
||||
case EBO_SUBTRACT:
|
||||
#if defined(GL_VERSION_1_4)
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_SUBTRACT);
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_SUBTRACT);
|
||||
#elif defined(GL_EXT_blend_subtract)
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_SUBTRACT_EXT);
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_SUBTRACT_EXT);
|
||||
#endif
|
||||
break;
|
||||
case EBO_REVSUBTRACT:
|
||||
break;
|
||||
case EBO_REVSUBTRACT:
|
||||
#if defined(GL_VERSION_1_4)
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
#elif defined(GL_EXT_blend_subtract)
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_REVERSE_SUBTRACT_EXT);
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_REVERSE_SUBTRACT_EXT);
|
||||
#endif
|
||||
break;
|
||||
case EBO_MIN:
|
||||
break;
|
||||
case EBO_MIN:
|
||||
#if defined(GL_VERSION_1_4)
|
||||
BridgeCalls->setBlendEquation(GL_MIN);
|
||||
BridgeCalls->setBlendEquation(GL_MIN);
|
||||
#elif defined(GL_EXT_blend_minmax)
|
||||
BridgeCalls->setBlendEquation(GL_MIN_EXT);
|
||||
BridgeCalls->setBlendEquation(GL_MIN_EXT);
|
||||
#endif
|
||||
break;
|
||||
case EBO_MAX:
|
||||
break;
|
||||
case EBO_MAX:
|
||||
#if defined(GL_VERSION_1_4)
|
||||
BridgeCalls->setBlendEquation(GL_MAX);
|
||||
BridgeCalls->setBlendEquation(GL_MAX);
|
||||
#elif defined(GL_EXT_blend_minmax)
|
||||
BridgeCalls->setBlendEquation(GL_MAX_EXT);
|
||||
BridgeCalls->setBlendEquation(GL_MAX_EXT);
|
||||
#endif
|
||||
break;
|
||||
case EBO_MIN_FACTOR:
|
||||
break;
|
||||
case EBO_MIN_FACTOR:
|
||||
#if defined(GL_AMD_blend_minmax_factor)
|
||||
if (FeatureAvailable[IRR_AMD_blend_minmax_factor])
|
||||
BridgeCalls->setBlendEquation(GL_FACTOR_MIN_AMD);
|
||||
if (FeatureAvailable[IRR_AMD_blend_minmax_factor])
|
||||
BridgeCalls->setBlendEquation(GL_FACTOR_MIN_AMD);
|
||||
#endif
|
||||
// fallback in case of missing extension
|
||||
#if defined(GL_VERSION_1_4)
|
||||
#if defined(GL_AMD_blend_minmax_factor)
|
||||
else
|
||||
else
|
||||
#endif
|
||||
BridgeCalls->setBlendEquation(GL_MIN);
|
||||
BridgeCalls->setBlendEquation(GL_MIN);
|
||||
#endif
|
||||
break;
|
||||
case EBO_MAX_FACTOR:
|
||||
break;
|
||||
case EBO_MAX_FACTOR:
|
||||
#if defined(GL_AMD_blend_minmax_factor)
|
||||
if (FeatureAvailable[IRR_AMD_blend_minmax_factor])
|
||||
BridgeCalls->setBlendEquation(GL_FACTOR_MAX_AMD);
|
||||
if (FeatureAvailable[IRR_AMD_blend_minmax_factor])
|
||||
BridgeCalls->setBlendEquation(GL_FACTOR_MAX_AMD);
|
||||
#endif
|
||||
// fallback in case of missing extension
|
||||
#if defined(GL_VERSION_1_4)
|
||||
#if defined(GL_AMD_blend_minmax_factor)
|
||||
else
|
||||
else
|
||||
#endif
|
||||
BridgeCalls->setBlendEquation(GL_MAX);
|
||||
BridgeCalls->setBlendEquation(GL_MAX);
|
||||
#endif
|
||||
break;
|
||||
case EBO_MIN_ALPHA:
|
||||
break;
|
||||
case EBO_MIN_ALPHA:
|
||||
#if defined(GL_SGIX_blend_alpha_minmax)
|
||||
if (FeatureAvailable[IRR_SGIX_blend_alpha_minmax])
|
||||
BridgeCalls->setBlendEquation(GL_ALPHA_MIN_SGIX);
|
||||
// fallback in case of missing extension
|
||||
else
|
||||
if (FeatureAvailable[IRR_EXT_blend_minmax])
|
||||
BridgeCalls->setBlendEquation(GL_MIN_EXT);
|
||||
if (FeatureAvailable[IRR_SGIX_blend_alpha_minmax])
|
||||
BridgeCalls->setBlendEquation(GL_ALPHA_MIN_SGIX);
|
||||
// fallback in case of missing extension
|
||||
else
|
||||
if (FeatureAvailable[IRR_EXT_blend_minmax])
|
||||
BridgeCalls->setBlendEquation(GL_MIN_EXT);
|
||||
#endif
|
||||
break;
|
||||
case EBO_MAX_ALPHA:
|
||||
break;
|
||||
case EBO_MAX_ALPHA:
|
||||
#if defined(GL_SGIX_blend_alpha_minmax)
|
||||
if (FeatureAvailable[IRR_SGIX_blend_alpha_minmax])
|
||||
BridgeCalls->setBlendEquation(GL_ALPHA_MAX_SGIX);
|
||||
// fallback in case of missing extension
|
||||
else
|
||||
if (FeatureAvailable[IRR_EXT_blend_minmax])
|
||||
BridgeCalls->setBlendEquation(GL_MAX_EXT);
|
||||
if (FeatureAvailable[IRR_SGIX_blend_alpha_minmax])
|
||||
BridgeCalls->setBlendEquation(GL_ALPHA_MAX_SGIX);
|
||||
// fallback in case of missing extension
|
||||
else
|
||||
if (FeatureAvailable[IRR_EXT_blend_minmax])
|
||||
BridgeCalls->setBlendEquation(GL_MAX_EXT);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
#if defined(GL_VERSION_1_4)
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_ADD);
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_ADD);
|
||||
#elif defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op)
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_ADD_EXT);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
BridgeCalls->setBlendEquation(GL_FUNC_ADD_EXT);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#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
|
||||
|
@ -5045,8 +5065,10 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
|
|||
BlendIndexCount = core::max_(static_cast<GLuint>(1), static_cast<GLuint>(Driver->MaxMultipleRenderTargets));
|
||||
|
||||
BlendEquation = new GLenum[BlendIndexCount];
|
||||
BlendSource = new GLenum[BlendIndexCount];
|
||||
BlendDestination = new GLenum[BlendIndexCount];
|
||||
BlendSourceRGB = new GLenum[BlendIndexCount];
|
||||
BlendDestinationRGB = new GLenum[BlendIndexCount];
|
||||
BlendSourceAlpha = new GLenum[BlendIndexCount];
|
||||
BlendDestinationAlpha = new GLenum[BlendIndexCount];
|
||||
Blend = new bool[BlendIndexCount];
|
||||
|
||||
for (u32 i = 0; i < BlendIndexCount; ++i)
|
||||
|
@ -5057,8 +5079,10 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
|
|||
BlendEquation[i] = GL_FUNC_ADD_EXT;
|
||||
#endif
|
||||
|
||||
BlendSource[i] = GL_ONE;
|
||||
BlendDestination[i] = GL_ZERO;
|
||||
BlendSourceRGB[i] = GL_ONE;
|
||||
BlendDestinationRGB[i] = GL_ZERO;
|
||||
BlendSourceAlpha[i] = GL_ONE;
|
||||
BlendDestinationAlpha[i] = GL_ZERO;
|
||||
|
||||
Blend[i] = false;
|
||||
}
|
||||
|
@ -5111,8 +5135,10 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
|
|||
COpenGLCallBridge::~COpenGLCallBridge()
|
||||
{
|
||||
delete[] BlendEquation;
|
||||
delete[] BlendSource;
|
||||
delete[] BlendDestination;
|
||||
delete[] BlendSourceRGB;
|
||||
delete[] BlendDestinationRGB;
|
||||
delete[] BlendSourceAlpha;
|
||||
delete[] BlendDestinationAlpha;
|
||||
delete[] Blend;
|
||||
}
|
||||
|
||||
|
@ -5162,29 +5188,80 @@ void COpenGLCallBridge::setBlendEquationIndexed(GLuint index, GLenum mode)
|
|||
|
||||
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);
|
||||
|
||||
for (GLuint i = 0; i < BlendIndexCount; ++i)
|
||||
{
|
||||
BlendSource[i] = source;
|
||||
BlendDestination[i] = destination;
|
||||
BlendSourceRGB[i] = source;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
BlendSource[index] = source;
|
||||
BlendDestination[index] = destination;
|
||||
BlendSourceRGB[index] = source;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void COpenGLCallBridge::setBlend(bool enable)
|
||||
{
|
||||
if (Blend[0] != enable)
|
||||
|
|
|
@ -661,8 +661,12 @@ namespace video
|
|||
|
||||
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 setBlendFuncSeparateIndexed(GLuint index, GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha);
|
||||
|
||||
void setBlend(bool enable);
|
||||
|
||||
void setBlendIndexed(GLuint index, bool enable);
|
||||
|
@ -705,8 +709,10 @@ namespace video
|
|||
bool AlphaTest;
|
||||
|
||||
GLenum* BlendEquation;
|
||||
GLenum* BlendSource;
|
||||
GLenum* BlendDestination;
|
||||
GLenum* BlendSourceRGB;
|
||||
GLenum* BlendDestinationRGB;
|
||||
GLenum* BlendSourceAlpha;
|
||||
GLenum* BlendDestinationAlpha;
|
||||
bool* Blend;
|
||||
GLuint BlendIndexCount;
|
||||
|
||||
|
|
|
@ -100,10 +100,22 @@ public:
|
|||
// material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
|
||||
// resetAllRenderstates)
|
||||
{
|
||||
E_BLEND_FACTOR srcFact,dstFact;
|
||||
E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
|
||||
E_MODULATE_FUNC modulate;
|
||||
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
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
|
@ -119,12 +131,8 @@ public:
|
|||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
|
||||
#endif
|
||||
|
||||
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact));
|
||||
Driver->getBridgeCalls()->setAlphaTest(true);
|
||||
Driver->getBridgeCalls()->setAlphaFunc(GL_GREATER, 0.f);
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
|
||||
if ( textureBlendFunc_hasAlpha(srcFact) || textureBlendFunc_hasAlpha(dstFact) )
|
||||
if (textureBlendFunc_hasAlpha(srcRGBFact) || textureBlendFunc_hasAlpha(dstRGBFact) ||
|
||||
textureBlendFunc_hasAlpha(srcAlphaFact) || textureBlendFunc_hasAlpha(dstAlphaFact))
|
||||
{
|
||||
if (alphaSource==EAS_VERTEX_COLOR)
|
||||
{
|
||||
|
@ -164,16 +172,22 @@ public:
|
|||
|
||||
virtual void OnSetBaseMaterial(const SMaterial& material) _IRR_OVERRIDE_
|
||||
{
|
||||
E_BLEND_FACTOR srcFact,dstFact;
|
||||
E_MODULATE_FUNC modulate;
|
||||
u32 alphaSource;
|
||||
unpack_textureBlendFunc(srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam);
|
||||
E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
|
||||
E_MODULATE_FUNC modulate;
|
||||
u32 alphaSource;
|
||||
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
|
||||
|
||||
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact));
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
|
||||
Driver->getBridgeCalls()->setAlphaTest(true);
|
||||
Driver->getBridgeCalls()->setAlphaFunc(GL_GREATER, 0.f);
|
||||
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_
|
||||
|
@ -190,13 +204,11 @@ public:
|
|||
#endif
|
||||
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
Driver->getBridgeCalls()->setAlphaTest(false);
|
||||
}
|
||||
|
||||
virtual void OnUnsetBaseMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
Driver->getBridgeCalls()->setBlend(false);
|
||||
Driver->getBridgeCalls()->setAlphaTest(false);
|
||||
}
|
||||
|
||||
//! Returns if the material is transparent.
|
||||
|
|
|
@ -1317,7 +1317,7 @@ u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDE
|
|||
{
|
||||
video::IMaterialRenderer* rnd =
|
||||
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
|
||||
TransparentNodeEntry e(node, camWorldPos);
|
||||
|
|
|
@ -486,7 +486,7 @@ void CBurningVideoDriver::setCurrentShader()
|
|||
|
||||
bool zMaterialTest = Material.org.ZBuffer != ECFN_DISABLED &&
|
||||
Material.org.ZWriteEnable &&
|
||||
( AllowZWriteOnTransparent || (Material.org.BlendOperation == EBO_NONE &&
|
||||
( AllowZWriteOnTransparent || (!Material.org.isTransparent() &&
|
||||
!MaterialRenderers[Material.org.MaterialType].Renderer->isTransparent()) );
|
||||
|
||||
EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ;
|
||||
|
|
Loading…
Reference in New Issue