Commit 9499db56 authored by hybrid's avatar hybrid

Add support for blend operation field.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3652 dfc29bdd-3216-0410-991c-e03cc46cb475
parent c895c0e1
......@@ -112,6 +112,9 @@ namespace video
//! Supports polygon offset/depth bias for avoiding z-fighting
EVDF_POLYGON_OFFSET,
//! Support for different blend functions. Without, only ADD is available
EVDF_BLEND_OPERATIONS,
//! Only used for counting the elements of this enum
EVDF_COUNT
};
......
......@@ -605,6 +605,8 @@ bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0;
case EVDF_COLOR_MASK:
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0;
case EVDF_BLEND_OPERATIONS:
return true;
default:
return false;
};
......@@ -1562,6 +1564,35 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag);
}
if (queryFeature(EVDF_BLEND_OPERATIONS) &&
(resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation))
{
if (EBO_NONE)
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
else
{
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
switch (material.BlendOperation)
{
case EBO_MAX:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX);
break;
case EBO_MIN:
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;
}
}
}
// Polygon offset
if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates ||
lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection ||
......
......@@ -666,6 +666,8 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
return OcclusionQuerySupport;
case EVDF_POLYGON_OFFSET:
return (Caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS|D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) != 0;
case EVDF_BLEND_OPERATIONS:
return true;
default:
return false;
};
......@@ -2253,6 +2255,35 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag);
}
if (queryFeature(EVDF_BLEND_OPERATIONS) &&
(resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation))
{
if (EBO_NONE)
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
else
{
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
switch (material.BlendOperation)
{
case EBO_MAX:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX);
break;
case EBO_MIN:
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;
}
}
}
// Polygon offset
if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates ||
lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection ||
......
......@@ -2913,6 +2913,57 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
(material.ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
}
if (queryFeature(EVDF_BLEND_OPERATIONS) &&
(resetAllRenderStates|| lastmaterial.BlendOperation != material.BlendOperation))
{
if (EBO_NONE)
glDisable(GL_BLEND);
else
{
glEnable(GL_BLEND);
#if defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op) || defined(GL_VERSION_1_2)
switch (material.BlendOperation)
{
case EBO_MAX:
#if defined(GL_EXT_blend_minmax)
extGlBlendEquation(GL_MAX_EXT);
#elif defined(GL_VERSION_1_2)
extGlBlendEquation(GL_MAX);
#endif
break;
case EBO_MIN:
#if defined(GL_EXT_blend_minmax)
extGlBlendEquation(GL_MIN_EXT);
#elif defined(GL_VERSION_1_2)
extGlBlendEquation(GL_MIN);
#endif
break;
case EBO_SUBTRACT:
#if defined(GL_EXT_blend_subtract)
extGlBlendEquation(GL_FUNC_SUBTRACT_EXT);
#elif defined(GL_VERSION_1_2)
extGlBlendEquation(GL_FUNC_SUBTRACT);
#endif
break;
case EBO_REVSUBTRACT:
#if defined(GL_EXT_blend_subtract)
extGlBlendEquation(GL_FUNC_REVERSE_SUBTRACT_EXT);
#elif defined(GL_VERSION_1_2)
extGlBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
#endif
break;
default:
#if defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op)
extGlBlendEquation(GL_FUNC_ADD_EXT);
#elif defined(GL_VERSION_1_2)
extGlBlendEquation(GL_FUNC_ADD);
#endif
break;
}
#endif
}
}
// Polygon Offset
if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderStates ||
lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection ||
......
......@@ -824,6 +824,9 @@ bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
case EVDF_POLYGON_OFFSET:
// both features supported with OpenGL 1.1
return Version>=110;
case EVDF_BLEND_OPERATIONS:
return (Version>=120) || FeatureAvailable[IRR_EXT_blend_minmax] ||
FeatureAvailable[IRR_EXT_blend_subtract] || FeatureAvailable[IRR_EXT_blend_logic_op];
default:
return false;
};
......
......@@ -1049,6 +1049,9 @@ class COpenGLExtensionHandler
// generic vsync setting method for several extensions
void extGlSwapInterval(int interval);
// blend operations
void extGlBlendEquation(GLenum mode);
// the global feature array
bool FeatureAvailable[IRR_OpenGL_Feature_Count];
......@@ -1157,6 +1160,8 @@ class COpenGLExtensionHandler
PFNGLENDOCCLUSIONQUERYNVPROC pGlEndOcclusionQueryNV;
PFNGLGETOCCLUSIONQUERYIVNVPROC pGlGetOcclusionQueryivNV;
PFNGLGETOCCLUSIONQUERYUIVNVPROC pGlGetOcclusionQueryuivNV;
PFNGLBLENDEQUATIONEXTPROC pGlBlendEquationEXT;
PFNGLBLENDEQUATIONPROC pGlBlendEquation;
#if defined(WGL_EXT_swap_control)
PFNWGLSWAPINTERVALEXTPROC pWglSwapIntervalEXT;
#endif
......@@ -2355,6 +2360,22 @@ inline void COpenGLExtensionHandler::extGlSwapInterval(int interval)
#endif
}
inline void COpenGLExtensionHandler::extGlBlendEquation(GLenum mode)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
if (pGlBlendEquation)
pGlBlendEquation(mode);
else if (pGlBlendEquationEXT)
pGlBlendEquationEXT(mode);
#elif defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_logic_op)
glBlendEquationEXT(mode);
#elif defined(GL_VERSION_1_2)
glBlendEquation(mode);
#else
os::Printer::log("glBlendEquation not supported", ELL_ERROR);
#endif
}
}
}
......
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