Commit 5b282f8f authored by nadro's avatar nadro

- Minor improved speed of shader based material rendering.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4403 dfc29bdd-3216-0410-991c-e03cc46cb475
parent d8611d82
...@@ -3986,7 +3986,7 @@ s32 COpenGLDriver::addHighLevelShaderMaterial( ...@@ -3986,7 +3986,7 @@ s32 COpenGLDriver::addHighLevelShaderMaterial(
pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget, pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,
geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget, geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,
inType, outType, verticesOut, inType, outType, verticesOut,
callback,getMaterialRenderer(baseMaterial), userData); callback,baseMaterial, userData);
r->drop(); r->drop();
} }
......
...@@ -26,6 +26,16 @@ public: ...@@ -26,6 +26,16 @@ public:
{ {
} }
//! On set material method for shader based materials
virtual void OnSetBaseMaterial(const SMaterial& material)
{
}
//! On unset material method for shader based materials
virtual void OnUnsetBaseMaterial()
{
}
protected: protected:
video::COpenGLDriver* Driver; video::COpenGLDriver* Driver;
...@@ -136,6 +146,70 @@ public: ...@@ -136,6 +146,70 @@ public:
} }
} }
virtual void OnSetBaseMaterial(const SMaterial& material)
{
E_BLEND_FACTOR srcFact,dstFact;
E_MODULATE_FUNC modulate;
u32 alphaSource;
unpack_textureBlendFunc(srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam);
glBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact));
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.f);
glEnable(GL_BLEND);
#ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (f32) modulate );
#else
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
#endif
if (textureBlendFunc_hasAlpha(srcFact) || textureBlendFunc_hasAlpha(dstFact) )
{
if (alphaSource==EAS_VERTEX_COLOR)
{
#ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
#else
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
#endif
}
else if (alphaSource==EAS_TEXTURE)
{
#ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
#else
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
#endif
}
else
{
#ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
#else
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE);
#endif
}
}
}
virtual void OnUnsetMaterial() virtual void OnUnsetMaterial()
{ {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
...@@ -153,6 +227,21 @@ public: ...@@ -153,6 +227,21 @@ public:
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
} }
virtual void OnUnsetBaseMaterial()
{
#ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
#else
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
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);
}
//! Returns if the material is transparent. //! Returns if the material is transparent.
/** Is not always transparent, but mostly. */ /** Is not always transparent, but mostly. */
virtual bool isTransparent() const virtual bool isTransparent() const
...@@ -243,11 +332,22 @@ public: ...@@ -243,11 +332,22 @@ public:
} }
} }
virtual void OnSetBaseMaterial(const SMaterial& material)
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glEnable(GL_BLEND);
}
virtual void OnUnsetMaterial() virtual void OnUnsetMaterial()
{ {
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
virtual void OnUnsetBaseMaterial()
{
glDisable(GL_BLEND);
}
//! Returns if the material is transparent. //! Returns if the material is transparent.
virtual bool isTransparent() const virtual bool isTransparent() const
{ {
...@@ -292,6 +392,27 @@ public: ...@@ -292,6 +392,27 @@ public:
} }
} }
virtual void OnSetBaseMaterial(const SMaterial& material)
{
#ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
#else
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT );
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
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);
}
virtual void OnUnsetMaterial() virtual void OnUnsetMaterial()
{ {
// default values // default values
...@@ -306,6 +427,17 @@ public: ...@@ -306,6 +427,17 @@ public:
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
virtual void OnUnsetBaseMaterial()
{
#ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE );
#else
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
#endif
}
//! Returns if the material is transparent. //! Returns if the material is transparent.
virtual bool isTransparent() const virtual bool isTransparent() const
{ {
...@@ -354,6 +486,30 @@ public: ...@@ -354,6 +486,30 @@ public:
} }
} }
virtual void OnSetBaseMaterial(const SMaterial& material)
{
#ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
#else
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
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);
glAlphaFunc(GL_GREATER, material.MaterialTypeParam);
}
virtual void OnUnsetMaterial() virtual void OnUnsetMaterial()
{ {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
...@@ -366,6 +522,17 @@ public: ...@@ -366,6 +522,17 @@ public:
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
virtual void OnUnsetBaseMaterial()
{
#ifdef GL_ARB_texture_env_combine
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
#else
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
#endif
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
}
//! Returns if the material is transparent. //! Returns if the material is transparent.
virtual bool isTransparent() const virtual bool isTransparent() const
{ {
...@@ -396,11 +563,22 @@ public: ...@@ -396,11 +563,22 @@ public:
} }
} }
virtual void OnSetBaseMaterial(const SMaterial& material)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
}
virtual void OnUnsetMaterial() virtual void OnUnsetMaterial()
{ {
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
} }
virtual void OnUnsetBaseMaterial()
{
glDisable(GL_ALPHA_TEST);
}
//! Returns if the material is transparent. //! Returns if the material is transparent.
virtual bool isTransparent() const virtual bool isTransparent() const
{ {
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "IVideoDriver.h" #include "IVideoDriver.h"
#include "os.h" #include "os.h"
#include "COpenGLDriver.h" #include "COpenGLDriver.h"
#include "COpenGLMaterialRenderer.h"
namespace irr namespace irr
{ {
...@@ -41,10 +42,9 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive ...@@ -41,10 +42,9 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType,
u32 verticesOut, u32 verticesOut,
IShaderConstantSetCallBack* callback, IShaderConstantSetCallBack* callback,
video::IMaterialRenderer* baseMaterial, E_MATERIAL_TYPE baseMaterial,
s32 userData) s32 userData)
: Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), : Driver(driver), CallBack(callback), Program(0), Program2(0), BaseMaterial(0), UserData(userData)
Program(0), Program2(0), UserData(userData)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("COpenGLSLMaterialRenderer"); setDebugName("COpenGLSLMaterialRenderer");
...@@ -54,6 +54,12 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive ...@@ -54,6 +54,12 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
//it is fine to ignore what has been asked for, as the compiler should spot anything wrong //it is fine to ignore what has been asked for, as the compiler should spot anything wrong
//just check that GLSL is available //just check that GLSL is available
if (baseMaterial == EMT_ONETEXTURE_BLEND || baseMaterial == EMT_TRANSPARENT_ADD_COLOR || baseMaterial == EMT_TRANSPARENT_VERTEX_ALPHA ||
baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL || baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
{
BaseMaterial = dynamic_cast<COpenGLMaterialRenderer*>(Driver->getMaterialRenderer(baseMaterial));
}
if (BaseMaterial) if (BaseMaterial)
BaseMaterial->grab(); BaseMaterial->grab();
...@@ -71,10 +77,15 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive ...@@ -71,10 +77,15 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
//! create a fall back material for example. //! create a fall back material for example.
COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver* driver, COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver* driver,
IShaderConstantSetCallBack* callback, IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial, s32 userData) E_MATERIAL_TYPE baseMaterial, s32 userData)
: Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), : Driver(driver), CallBack(callback), Program(0), Program2(0), BaseMaterial(0), UserData(userData)
Program(0), Program2(0), UserData(userData)
{ {
if (baseMaterial == EMT_ONETEXTURE_BLEND || baseMaterial == EMT_TRANSPARENT_ADD_COLOR || baseMaterial == EMT_TRANSPARENT_VERTEX_ALPHA ||
baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL || baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
{
BaseMaterial = dynamic_cast<COpenGLMaterialRenderer*>(Driver->getMaterialRenderer(baseMaterial));
}
if (BaseMaterial) if (BaseMaterial)
BaseMaterial->grab(); BaseMaterial->grab();
...@@ -209,15 +220,13 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material, ...@@ -209,15 +220,13 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
Driver->extGlUseProgramObject(Program); Driver->extGlUseProgramObject(Program);
if (BaseMaterial) if (BaseMaterial)
BaseMaterial->OnSetMaterial(material, lastMaterial, resetAllRenderstates, services); BaseMaterial->OnSetBaseMaterial(material);
} }
//let callback know used material //let callback know used material
if (CallBack) if (CallBack)
CallBack->OnSetMaterial(material); CallBack->OnSetMaterial(material);
for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
Driver->setActiveTexture(i, material.getTexture(i));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
} }
...@@ -230,7 +239,7 @@ void COpenGLSLMaterialRenderer::OnUnsetMaterial() ...@@ -230,7 +239,7 @@ void COpenGLSLMaterialRenderer::OnUnsetMaterial()
Driver->extGlUseProgram(0); Driver->extGlUseProgram(0);
if (BaseMaterial) if (BaseMaterial)
BaseMaterial->OnUnsetMaterial(); BaseMaterial->OnUnsetBaseMaterial();
} }
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#endif #endif
#include "EMaterialTypes.h"
#include "IMaterialRenderer.h" #include "IMaterialRenderer.h"
#include "IMaterialRendererServices.h" #include "IMaterialRendererServices.h"
#include "IGPUProgrammingServices.h" #include "IGPUProgrammingServices.h"
...@@ -42,6 +43,7 @@ namespace video ...@@ -42,6 +43,7 @@ namespace video
{ {
class COpenGLDriver; class COpenGLDriver;
class COpenGLMaterialRenderer;
class IShaderConstantSetCallBack; class IShaderConstantSetCallBack;
//! Class for using GLSL shaders with OpenGL //! Class for using GLSL shaders with OpenGL
...@@ -67,7 +69,7 @@ public: ...@@ -67,7 +69,7 @@ public:
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0, u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0, IShaderConstantSetCallBack* callback = 0,
IMaterialRenderer* baseMaterial = 0, E_MATERIAL_TYPE baseMaterial = EMT_SOLID,
s32 userData = 0); s32 userData = 0);
//! Destructor //! Destructor
...@@ -101,7 +103,7 @@ protected: ...@@ -101,7 +103,7 @@ protected:
//! create a fall back material for example. //! create a fall back material for example.
COpenGLSLMaterialRenderer(COpenGLDriver* driver, COpenGLSLMaterialRenderer(COpenGLDriver* driver,
IShaderConstantSetCallBack* callback, IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial, E_MATERIAL_TYPE baseMaterial,
s32 userData=0); s32 userData=0);
void init(s32& outMaterialTypeNr, void init(s32& outMaterialTypeNr,
...@@ -118,7 +120,7 @@ protected: ...@@ -118,7 +120,7 @@ protected:
COpenGLDriver* Driver; COpenGLDriver* Driver;
IShaderConstantSetCallBack* CallBack; IShaderConstantSetCallBack* CallBack;
IMaterialRenderer* BaseMaterial; COpenGLMaterialRenderer* BaseMaterial;
struct SUniformInfo struct SUniformInfo
{ {
......
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