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(
pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,
geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,
inType, outType, verticesOut,
callback,getMaterialRenderer(baseMaterial), userData);
callback,baseMaterial, userData);
r->drop();
}
......
......@@ -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:
video::COpenGLDriver* Driver;
......@@ -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()
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
......@@ -153,6 +227,21 @@ public:
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.
/** Is not always transparent, but mostly. */
virtual bool isTransparent() const
......@@ -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()
{
glDisable(GL_BLEND);
}
virtual void OnUnsetBaseMaterial()
{
glDisable(GL_BLEND);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
......@@ -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()
{
// default values
......@@ -306,6 +427,17 @@ public:
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.
virtual bool isTransparent() const
{
......@@ -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()
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
......@@ -366,6 +522,17 @@ public:
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.
virtual bool isTransparent() const
{
......@@ -396,11 +563,22 @@ public:
}
}
virtual void OnSetBaseMaterial(const SMaterial& material)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
}
virtual void OnUnsetMaterial()
{
glDisable(GL_ALPHA_TEST);
}
virtual void OnUnsetBaseMaterial()
{
glDisable(GL_ALPHA_TEST);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
......
......@@ -20,6 +20,7 @@
#include "IVideoDriver.h"
#include "os.h"
#include "COpenGLDriver.h"
#include "COpenGLMaterialRenderer.h"
namespace irr
{
......@@ -41,10 +42,9 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType,
u32 verticesOut,
IShaderConstantSetCallBack* callback,
video::IMaterialRenderer* baseMaterial,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
: Driver(driver), CallBack(callback), BaseMaterial(baseMaterial),
Program(0), Program2(0), UserData(userData)
: Driver(driver), CallBack(callback), Program(0), Program2(0), BaseMaterial(0), UserData(userData)
{
#ifdef _DEBUG
setDebugName("COpenGLSLMaterialRenderer");
......@@ -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
//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)
BaseMaterial->grab();
......@@ -71,10 +77,15 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
//! create a fall back material for example.
COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver* driver,
IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial, s32 userData)
: Driver(driver), CallBack(callback), BaseMaterial(baseMaterial),
Program(0), Program2(0), UserData(userData)
E_MATERIAL_TYPE baseMaterial, s32 userData)
: Driver(driver), CallBack(callback), Program(0), Program2(0), BaseMaterial(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)
BaseMaterial->grab();
......@@ -209,15 +220,13 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
Driver->extGlUseProgramObject(Program);
if (BaseMaterial)
BaseMaterial->OnSetMaterial(material, lastMaterial, resetAllRenderstates, services);
BaseMaterial->OnSetBaseMaterial(material);
}
//let callback know used material
if (CallBack)
CallBack->OnSetMaterial(material);
for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
Driver->setActiveTexture(i, material.getTexture(i));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
}
......@@ -230,7 +239,7 @@ void COpenGLSLMaterialRenderer::OnUnsetMaterial()
Driver->extGlUseProgram(0);
if (BaseMaterial)
BaseMaterial->OnUnsetMaterial();
BaseMaterial->OnUnsetBaseMaterial();
}
......
......@@ -30,6 +30,7 @@
#endif
#include "EMaterialTypes.h"
#include "IMaterialRenderer.h"
#include "IMaterialRendererServices.h"
#include "IGPUProgrammingServices.h"
......@@ -42,6 +43,7 @@ namespace video
{
class COpenGLDriver;
class COpenGLMaterialRenderer;
class IShaderConstantSetCallBack;
//! Class for using GLSL shaders with OpenGL
......@@ -67,7 +69,7 @@ public:
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
IMaterialRenderer* baseMaterial = 0,
E_MATERIAL_TYPE baseMaterial = EMT_SOLID,
s32 userData = 0);
//! Destructor
......@@ -101,7 +103,7 @@ protected:
//! create a fall back material for example.
COpenGLSLMaterialRenderer(COpenGLDriver* driver,
IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial,
E_MATERIAL_TYPE baseMaterial,
s32 userData=0);
void init(s32& outMaterialTypeNr,
......@@ -118,7 +120,7 @@ protected:
COpenGLDriver* Driver;
IShaderConstantSetCallBack* CallBack;
IMaterialRenderer* BaseMaterial;
COpenGLMaterialRenderer* BaseMaterial;
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