- Added next optimizations to OpenGL driver related to blending, alpha testing and cull facing.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4426 dfc29bdd-3216-0410-991c-e03cc46cb475
master
nadro 2013-01-03 19:28:50 +00:00
parent 433445cdc2
commit ba95913a1a
4 changed files with 178 additions and 66 deletions

View File

@ -1,6 +1,9 @@
--------------------------
Changes in 1.9 (not yet released)
- Added ECFN_DISABLED value (it works like ECFN_NEVER worked before) and changed ECFN_NEVER behaviour
(it works like its equivalent value in OpenGL/Direct3D).
- Removed boolean interface from IShaderConstantSetCallBack, please use integer interface instead of them.
- Add a LeakHunter class which can be enabled with compile-flag _IRR_COMPILE_WITH_LEAK_HUNTER_ to find leaking IReferenceCounted objects.
- Add _IRR_COMPILE_WITH_XML_ define to allow compiling Irrlicht without xml (patch written by curaga)
- Add functions to set/get cursor character and blinktime to IGUIEditBox

View File

@ -748,7 +748,6 @@ bool COpenGLDriver::genericDriverInit()
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
glDepthFunc(GL_LEQUAL);
glFrontFace(GL_CW);
// adjust flat coloring scheme to DirectX version
#if defined(GL_ARB_provoking_vertex) || defined(GL_EXT_provoking_vertex)
@ -778,8 +777,6 @@ bool COpenGLDriver::genericDriverInit()
// set the renderstates
setRenderStates3DMode();
glAlphaFunc(GL_GREATER, 0.f);
// set fog mode
setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog);
@ -2694,9 +2691,9 @@ void COpenGLDriver::setRenderStates3DMode()
if (CurrentRenderMode != ERM_3D)
{
// Reset Texture Stages
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
BridgeCalls->setBlend(false);
BridgeCalls->setAlphaTest(false);
BridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// switch back the matrices
BridgeCalls->setMatrixMode(GL_MODELVIEW);
@ -3042,23 +3039,23 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
{
if ((material.FrontfaceCulling) && (material.BackfaceCulling))
{
glCullFace(GL_FRONT_AND_BACK);
glEnable(GL_CULL_FACE);
BridgeCalls->setCullFaceFunc(GL_FRONT_AND_BACK);
BridgeCalls->setCullFace(true);
}
else
if (material.BackfaceCulling)
{
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
BridgeCalls->setCullFaceFunc(GL_BACK);
BridgeCalls->setCullFace(true);
}
else
if (material.FrontfaceCulling)
{
glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);
BridgeCalls->setCullFaceFunc(GL_FRONT);
BridgeCalls->setCullFace(true);
}
else
glDisable(GL_CULL_FACE);
BridgeCalls->setCullFace(false);
}
// Color Mask
@ -3075,10 +3072,10 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
(resetAllRenderStates|| lastmaterial.BlendOperation != material.BlendOperation))
{
if (material.BlendOperation==EBO_NONE)
glDisable(GL_BLEND);
BridgeCalls->setBlend(false);
else
{
glEnable(GL_BLEND);
BridgeCalls->setBlend(true);
#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)
{
@ -3449,7 +3446,7 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
setBasicRenderStates(InitMaterial2D, LastMaterial, true, true);
LastMaterial = InitMaterial2D;
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
BridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#ifdef GL_EXT_clip_volume_hint
if (FeatureAvailable[IRR_EXT_clip_volume_hint])
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
@ -3468,14 +3465,14 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
if (alphaChannel || alpha)
{
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.f);
BridgeCalls->setBlend(true);
BridgeCalls->setAlphaTest(true);
BridgeCalls->setAlphaFunc(GL_GREATER, 0.f);
}
else
{
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
BridgeCalls->setBlend(false);
BridgeCalls->setAlphaTest(false);
}
if (texture)
@ -4998,7 +4995,10 @@ const CGcontext& COpenGLDriver::getCgContext()
#endif
COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
AlphaMode(GL_ALWAYS), AlphaRef(0.0f), AlphaTest(false),
BlendSource(GL_ONE), BlendDestination(GL_ZERO), Blend(false),
ClientStateVertex(false), ClientStateNormal(false), ClientStateColor(false), ClientStateTexCoord0(false),
CullFaceMode(GL_BACK), CullFace(false),
DepthFunc(GL_LESS), DepthMask(true), DepthTest(false), MatrixMode(GL_MODELVIEW),
ActiveTexture(GL_TEXTURE0_ARB), ClientActiveTexture(GL_TEXTURE0_ARB)
{
@ -5009,6 +5009,15 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
Texture[i] = 0;
TextureFixedPipeline[i] = true;
}
glAlphaFunc(GL_ALWAYS, 0.0f);
glDisable(GL_ALPHA_TEST);
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND);
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
@ -5030,6 +5039,54 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void COpenGLCallBridge::setAlphaFunc(GLenum mode, GLclampf ref)
{
if(AlphaMode != mode || AlphaRef != ref)
{
glAlphaFunc(mode, ref);
AlphaMode = mode;
AlphaRef = ref;
}
}
void COpenGLCallBridge::setAlphaTest(bool enable)
{
if(AlphaTest != enable)
{
if (enable)
glEnable(GL_ALPHA_TEST);
else
glDisable(GL_ALPHA_TEST);
AlphaTest = enable;
}
}
void COpenGLCallBridge::setBlendFunc(GLenum source, GLenum destination)
{
if(BlendSource != source || BlendDestination != destination)
{
glBlendFunc(source, destination);
BlendSource = source;
BlendDestination = destination;
}
}
void COpenGLCallBridge::setBlend(bool enable)
{
if(Blend != enable)
{
if (enable)
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
Blend = enable;
}
}
void COpenGLCallBridge::setClientState(bool vertex, bool normal, bool color, bool texCoord0)
{
if(ClientStateVertex != vertex)
@ -5075,6 +5132,29 @@ void COpenGLCallBridge::setClientState(bool vertex, bool normal, bool color, boo
}
}
void COpenGLCallBridge::setCullFaceFunc(GLenum mode)
{
if(CullFaceMode != mode)
{
glCullFace(mode);
CullFaceMode = mode;
}
}
void COpenGLCallBridge::setCullFace(bool enable)
{
if(CullFace != enable)
{
if (enable)
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
CullFace = enable;
}
}
void COpenGLCallBridge::setDepthFunc(GLenum mode)
{
if(DepthFunc != mode)

View File

@ -637,9 +637,27 @@ namespace video
public:
COpenGLCallBridge(COpenGLDriver* driver);
// Client State calls.
// Alpha calls.
void setAlphaFunc(GLenum mode, GLclampf ref);
void setAlphaTest(bool enable);
// Blending calls.
void setBlendFunc(GLenum source, GLenum destination);
void setBlend(bool enable);
// Client state calls.
void setClientState(bool vertex, bool normal, bool color, bool texCoord0);
// Cull face calls.
void setCullFaceFunc(GLenum mode);
void setCullFace(bool enable);
// Depth calls.
@ -664,10 +682,21 @@ namespace video
private:
COpenGLDriver* Driver;
GLenum AlphaMode;
GLclampf AlphaRef;
bool AlphaTest;
GLenum BlendSource;
GLenum BlendDestination;
bool Blend;
bool ClientStateVertex;
bool ClientStateNormal;
bool ClientStateColor;
bool ClientStateTexCoord0;
GLenum CullFaceMode;
bool CullFace;
GLenum DepthFunc;
bool DepthMask;

View File

@ -110,10 +110,10 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
#endif
glBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact));
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.f);
glEnable(GL_BLEND);
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) )
{
@ -160,11 +160,11 @@ public:
u32 alphaSource;
unpack_textureBlendFunc(srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam);
glBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact));
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact));
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.f);
glEnable(GL_BLEND);
Driver->getBridgeCalls()->setAlphaTest(true);
Driver->getBridgeCalls()->setAlphaFunc(GL_GREATER, 0.f);
Driver->getBridgeCalls()->setBlend(true);
#ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
@ -230,8 +230,8 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
#endif
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
Driver->getBridgeCalls()->setBlend(false);
Driver->getBridgeCalls()->setAlphaTest(false);
}
virtual void OnUnsetBaseMaterial()
@ -245,8 +245,8 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
#endif
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
Driver->getBridgeCalls()->setBlend(false);
Driver->getBridgeCalls()->setAlphaTest(false);
}
//! Returns if the material is transparent.
@ -333,26 +333,26 @@ public:
if ((material.MaterialType != lastMaterial.MaterialType) || resetAllRenderstates)
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
Driver->getBridgeCalls()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(true);
}
}
virtual void OnSetBaseMaterial(const SMaterial& material)
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glEnable(GL_BLEND);
Driver->getBridgeCalls()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
Driver->getBridgeCalls()->setBlend(true);
}
virtual void OnUnsetMaterial()
{
glDisable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(false);
}
virtual void OnUnsetBaseMaterial()
{
glDisable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(false);
}
//! Returns if the material is transparent.
@ -394,8 +394,8 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
#endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
Driver->getBridgeCalls()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Driver->getBridgeCalls()->setBlend(true);
}
}
@ -416,8 +416,8 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
#endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
Driver->getBridgeCalls()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Driver->getBridgeCalls()->setBlend(true);
}
virtual void OnUnsetMaterial()
@ -431,7 +431,7 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
#endif
glDisable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(false);
}
virtual void OnUnsetBaseMaterial()
@ -485,11 +485,11 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
#endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
Driver->getBridgeCalls()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Driver->getBridgeCalls()->setBlend(true);
Driver->getBridgeCalls()->setAlphaTest(true);
glAlphaFunc(GL_GREATER, material.MaterialTypeParam);
Driver->getBridgeCalls()->setAlphaFunc(GL_GREATER, material.MaterialTypeParam);
}
}
@ -511,10 +511,10 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
#endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, material.MaterialTypeParam);
Driver->getBridgeCalls()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Driver->getBridgeCalls()->setBlend(true);
Driver->getBridgeCalls()->setAlphaTest(true);
Driver->getBridgeCalls()->setAlphaFunc(GL_GREATER, material.MaterialTypeParam);
}
virtual void OnUnsetMaterial()
@ -525,8 +525,8 @@ public:
#else
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
#endif
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
Driver->getBridgeCalls()->setAlphaTest(false);
Driver->getBridgeCalls()->setBlend(false);
}
virtual void OnUnsetBaseMaterial()
@ -536,8 +536,8 @@ public:
#else
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
#endif
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
Driver->getBridgeCalls()->setBlend(false);
Driver->getBridgeCalls()->setAlphaTest(false);
}
//! Returns if the material is transparent.
@ -564,26 +564,26 @@ public:
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
Driver->getBridgeCalls()->setAlphaTest(true);
Driver->getBridgeCalls()->setAlphaFunc(GL_GREATER, 0.5f);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
}
virtual void OnSetBaseMaterial(const SMaterial& material)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
Driver->getBridgeCalls()->setAlphaTest(true);
Driver->getBridgeCalls()->setAlphaFunc(GL_GREATER, 0.5f);
}
virtual void OnUnsetMaterial()
{
glDisable(GL_ALPHA_TEST);
Driver->getBridgeCalls()->setAlphaTest(false);
}
virtual void OnUnsetBaseMaterial()
{
glDisable(GL_ALPHA_TEST);
Driver->getBridgeCalls()->setAlphaTest(false);
}
//! Returns if the material is transparent.
@ -905,8 +905,8 @@ public:
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
Driver->getBridgeCalls()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Driver->getBridgeCalls()->setBlend(true);
}
}
@ -923,7 +923,7 @@ public:
{
Driver->getBridgeCalls()->setActiveTexture(GL_TEXTURE0_ARB);
}
glDisable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(false);
}
//! Returns if the material is transparent.