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 ...@@ -112,6 +112,9 @@ namespace video
//! Supports polygon offset/depth bias for avoiding z-fighting //! Supports polygon offset/depth bias for avoiding z-fighting
EVDF_POLYGON_OFFSET, 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 //! Only used for counting the elements of this enum
EVDF_COUNT EVDF_COUNT
}; };
......
...@@ -605,6 +605,8 @@ bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const ...@@ -605,6 +605,8 @@ bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0;
case EVDF_COLOR_MASK: case EVDF_COLOR_MASK:
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0; return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0;
case EVDF_BLEND_OPERATIONS:
return true;
default: default:
return false; return false;
}; };
...@@ -1562,6 +1564,35 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria ...@@ -1562,6 +1564,35 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); 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 // Polygon offset
if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates || if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates ||
lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection ||
......
...@@ -666,6 +666,8 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const ...@@ -666,6 +666,8 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
return OcclusionQuerySupport; return OcclusionQuerySupport;
case EVDF_POLYGON_OFFSET: case EVDF_POLYGON_OFFSET:
return (Caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS|D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) != 0; return (Caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS|D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) != 0;
case EVDF_BLEND_OPERATIONS:
return true;
default: default:
return false; return false;
}; };
...@@ -2253,6 +2255,35 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria ...@@ -2253,6 +2255,35 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); 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 // Polygon offset
if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates || if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates ||
lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection ||
......
...@@ -2913,6 +2913,57 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater ...@@ -2913,6 +2913,57 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
(material.ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE); (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 // Polygon Offset
if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderStates || if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderStates ||
lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection ||
......
...@@ -824,6 +824,9 @@ bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const ...@@ -824,6 +824,9 @@ bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
case EVDF_POLYGON_OFFSET: case EVDF_POLYGON_OFFSET:
// both features supported with OpenGL 1.1 // both features supported with OpenGL 1.1
return Version>=110; 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: default:
return false; return false;
}; };
......
...@@ -1049,6 +1049,9 @@ class COpenGLExtensionHandler ...@@ -1049,6 +1049,9 @@ class COpenGLExtensionHandler
// generic vsync setting method for several extensions // generic vsync setting method for several extensions
void extGlSwapInterval(int interval); void extGlSwapInterval(int interval);
// blend operations
void extGlBlendEquation(GLenum mode);
// the global feature array // the global feature array
bool FeatureAvailable[IRR_OpenGL_Feature_Count]; bool FeatureAvailable[IRR_OpenGL_Feature_Count];
...@@ -1157,6 +1160,8 @@ class COpenGLExtensionHandler ...@@ -1157,6 +1160,8 @@ class COpenGLExtensionHandler
PFNGLENDOCCLUSIONQUERYNVPROC pGlEndOcclusionQueryNV; PFNGLENDOCCLUSIONQUERYNVPROC pGlEndOcclusionQueryNV;
PFNGLGETOCCLUSIONQUERYIVNVPROC pGlGetOcclusionQueryivNV; PFNGLGETOCCLUSIONQUERYIVNVPROC pGlGetOcclusionQueryivNV;
PFNGLGETOCCLUSIONQUERYUIVNVPROC pGlGetOcclusionQueryuivNV; PFNGLGETOCCLUSIONQUERYUIVNVPROC pGlGetOcclusionQueryuivNV;
PFNGLBLENDEQUATIONEXTPROC pGlBlendEquationEXT;
PFNGLBLENDEQUATIONPROC pGlBlendEquation;
#if defined(WGL_EXT_swap_control) #if defined(WGL_EXT_swap_control)
PFNWGLSWAPINTERVALEXTPROC pWglSwapIntervalEXT; PFNWGLSWAPINTERVALEXTPROC pWglSwapIntervalEXT;
#endif #endif
...@@ -2355,6 +2360,22 @@ inline void COpenGLExtensionHandler::extGlSwapInterval(int interval) ...@@ -2355,6 +2360,22 @@ inline void COpenGLExtensionHandler::extGlSwapInterval(int interval)
#endif #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