Commit d8ed51f1 authored by nadro's avatar nadro

- Improved base material handling in OpenGL driver.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4979 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 1cb3b8ee
This diff is collapsed.
...@@ -44,25 +44,35 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive ...@@ -44,25 +44,35 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
IShaderConstantSetCallBack* callback, IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial, E_MATERIAL_TYPE baseMaterial,
s32 userData) s32 userData)
: Driver(driver), CallBack(callback), BaseMaterial(0), Program(0), Program2(0), UserData(userData) : Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false), AlphaTest(false), Program(0), Program2(0), UserData(userData)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("COpenGLSLMaterialRenderer"); setDebugName("COpenGLSLMaterialRenderer");
#endif #endif
//entry points must always be main, and the compile target isn't selectable switch (baseMaterial)
//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 = static_cast<COpenGLMaterialRenderer*>(Driver->getMaterialRenderer(baseMaterial)); case EMT_TRANSPARENT_VERTEX_ALPHA:
case EMT_TRANSPARENT_ALPHA_CHANNEL:
case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
Alpha = true;
break;
case EMT_TRANSPARENT_ADD_COLOR:
case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
FixedBlending = true;
break;
case EMT_ONETEXTURE_BLEND:
Blending = true;
break;
case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
AlphaTest = true;
break;
default:
break;
} }
if (BaseMaterial)
BaseMaterial->grab();
if (CallBack) if (CallBack)
CallBack->grab(); CallBack->grab();
...@@ -78,17 +88,31 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive ...@@ -78,17 +88,31 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver* driver, COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver* driver,
IShaderConstantSetCallBack* callback, IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial, s32 userData) E_MATERIAL_TYPE baseMaterial, s32 userData)
: Driver(driver), CallBack(callback), BaseMaterial(0), Program(0), Program2(0), UserData(userData) : Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false), AlphaTest(false), Program(0), Program2(0), UserData(userData)
{ {
if (baseMaterial == EMT_ONETEXTURE_BLEND || baseMaterial == EMT_TRANSPARENT_ADD_COLOR || baseMaterial == EMT_TRANSPARENT_VERTEX_ALPHA || switch (baseMaterial)
baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL || baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
{ {
BaseMaterial = static_cast<COpenGLMaterialRenderer*>(Driver->getMaterialRenderer(baseMaterial)); case EMT_TRANSPARENT_VERTEX_ALPHA:
case EMT_TRANSPARENT_ALPHA_CHANNEL:
case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
Alpha = true;
break;
case EMT_TRANSPARENT_ADD_COLOR:
case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
FixedBlending = true;
break;
case EMT_ONETEXTURE_BLEND:
Blending = true;
break;
case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
AlphaTest = true;
break;
default:
break;
} }
if (BaseMaterial)
BaseMaterial->grab();
if (CallBack) if (CallBack)
CallBack->grab(); CallBack->grab();
} }
...@@ -129,9 +153,6 @@ COpenGLSLMaterialRenderer::~COpenGLSLMaterialRenderer() ...@@ -129,9 +153,6 @@ COpenGLSLMaterialRenderer::~COpenGLSLMaterialRenderer()
} }
UniformInfo.clear(); UniformInfo.clear();
if (BaseMaterial)
BaseMaterial->drop();
} }
...@@ -192,8 +213,6 @@ void COpenGLSLMaterialRenderer::init(s32& outMaterialTypeNr, ...@@ -192,8 +213,6 @@ void COpenGLSLMaterialRenderer::init(s32& outMaterialTypeNr,
bool COpenGLSLMaterialRenderer::OnRender(IMaterialRendererServices* service, bool COpenGLSLMaterialRenderer::OnRender(IMaterialRendererServices* service,
E_VERTEX_TYPE vtxtype) E_VERTEX_TYPE vtxtype)
{ {
Driver->setTextureRenderStates(Driver->getCurrentMaterial(), false);
// call callback to set shader constants // call callback to set shader constants
if (CallBack && (Program||Program2)) if (CallBack && (Program||Program2))
CallBack->OnSetConstants(this, UserData); CallBack->OnSetConstants(this, UserData);
...@@ -212,6 +231,8 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material, ...@@ -212,6 +231,8 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
else else
Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE); Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE);
COpenGLCallBridge* bridgeCalls = Driver->getBridgeCalls();
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{ {
if (Program2) if (Program2)
...@@ -222,8 +243,40 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material, ...@@ -222,8 +243,40 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (BaseMaterial) if (Alpha)
BaseMaterial->OnSetBaseMaterial(material); {
bridgeCalls->setBlend(true);
bridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (FixedBlending)
{
bridgeCalls->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
bridgeCalls->setBlend(true);
}
else if (Blending)
{
E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
E_MODULATE_FUNC modulate;
u32 alphaSource;
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
if (Driver->queryFeature(EVDF_BLEND_SEPARATE))
{
bridgeCalls->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
}
else
{
bridgeCalls->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
}
bridgeCalls->setBlend(true);
}
else if (AlphaTest)
{
bridgeCalls->setAlphaTest(true);
bridgeCalls->setAlphaFunc(GL_GREATER, 0.5f);
}
if (CallBack) if (CallBack)
CallBack->OnSetMaterial(material); CallBack->OnSetMaterial(material);
...@@ -236,16 +289,13 @@ void COpenGLSLMaterialRenderer::OnUnsetMaterial() ...@@ -236,16 +289,13 @@ void COpenGLSLMaterialRenderer::OnUnsetMaterial()
Driver->extGlUseProgramObject(0); Driver->extGlUseProgramObject(0);
if (Program2) if (Program2)
Driver->extGlUseProgram(0); Driver->extGlUseProgram(0);
if (BaseMaterial)
BaseMaterial->OnUnsetBaseMaterial();
} }
//! Returns if the material is transparent. //! Returns if the material is transparent.
bool COpenGLSLMaterialRenderer::isTransparent() const bool COpenGLSLMaterialRenderer::isTransparent() const
{ {
return BaseMaterial ? BaseMaterial->isTransparent() : false; return (Alpha || Blending || FixedBlending);
} }
......
...@@ -43,7 +43,6 @@ namespace video ...@@ -43,7 +43,6 @@ 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
...@@ -120,7 +119,11 @@ protected: ...@@ -120,7 +119,11 @@ protected:
COpenGLDriver* Driver; COpenGLDriver* Driver;
IShaderConstantSetCallBack* CallBack; IShaderConstantSetCallBack* CallBack;
COpenGLMaterialRenderer* BaseMaterial;
bool Alpha;
bool Blending;
bool FixedBlending;
bool AlphaTest;
struct SUniformInfo struct SUniformInfo
{ {
......
...@@ -23,8 +23,8 @@ namespace video ...@@ -23,8 +23,8 @@ namespace video
COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver, COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver,
s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial, s32 userData) IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial, s32 userData)
: Driver(driver), CallBack(callback), BaseMaterial(0), : Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false),
VertexShader(0), UserData(userData) AlphaTest(false), VertexShader(0), UserData(userData)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("COpenGLShaderMaterialRenderer"); setDebugName("COpenGLShaderMaterialRenderer");
...@@ -36,15 +36,29 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDrive ...@@ -36,15 +36,29 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDrive
PixelShader[i]=0; PixelShader[i]=0;
} }
if (baseMaterial == EMT_ONETEXTURE_BLEND || baseMaterial == EMT_TRANSPARENT_ADD_COLOR || baseMaterial == EMT_TRANSPARENT_VERTEX_ALPHA || switch (baseMaterial)
baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL || baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
{ {
BaseMaterial = static_cast<COpenGLMaterialRenderer*>(Driver->getMaterialRenderer(baseMaterial)); case EMT_TRANSPARENT_VERTEX_ALPHA:
case EMT_TRANSPARENT_ALPHA_CHANNEL:
case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
Alpha = true;
break;
case EMT_TRANSPARENT_ADD_COLOR:
case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
FixedBlending = true;
break;
case EMT_ONETEXTURE_BLEND:
Blending = true;
break;
case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
AlphaTest = true;
break;
default:
break;
} }
if (BaseMaterial)
BaseMaterial->grab();
if (CallBack) if (CallBack)
CallBack->grab(); CallBack->grab();
...@@ -57,8 +71,8 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDrive ...@@ -57,8 +71,8 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDrive
COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(COpenGLDriver* driver, COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(COpenGLDriver* driver,
IShaderConstantSetCallBack* callback, IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial, s32 userData) E_MATERIAL_TYPE baseMaterial, s32 userData)
: Driver(driver), CallBack(callback), BaseMaterial(0), : Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false),
VertexShader(0), UserData(userData) AlphaTest(false), VertexShader(0), UserData(userData)
{ {
PixelShader.set_used(4); PixelShader.set_used(4);
for (u32 i=0; i<4; ++i) for (u32 i=0; i<4; ++i)
...@@ -66,15 +80,29 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(COpenGLDriver* driv ...@@ -66,15 +80,29 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(COpenGLDriver* driv
PixelShader[i]=0; PixelShader[i]=0;
} }
if (baseMaterial == EMT_ONETEXTURE_BLEND || baseMaterial == EMT_TRANSPARENT_ADD_COLOR || baseMaterial == EMT_TRANSPARENT_VERTEX_ALPHA || switch (baseMaterial)
baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL || baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
{ {
BaseMaterial = static_cast<COpenGLMaterialRenderer*>(Driver->getMaterialRenderer(baseMaterial)); case EMT_TRANSPARENT_VERTEX_ALPHA:
case EMT_TRANSPARENT_ALPHA_CHANNEL:
case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
Alpha = true;
break;
case EMT_TRANSPARENT_ADD_COLOR:
case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
FixedBlending = true;
break;
case EMT_ONETEXTURE_BLEND:
Blending = true;
break;
case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
AlphaTest = true;
break;
default:
break;
} }
if (BaseMaterial)
BaseMaterial->grab();
if (CallBack) if (CallBack)
CallBack->grab(); CallBack->grab();
} }
...@@ -92,9 +120,6 @@ COpenGLShaderMaterialRenderer::~COpenGLShaderMaterialRenderer() ...@@ -92,9 +120,6 @@ COpenGLShaderMaterialRenderer::~COpenGLShaderMaterialRenderer()
for (u32 i=0; i<PixelShader.size(); ++i) for (u32 i=0; i<PixelShader.size(); ++i)
if (PixelShader[i]) if (PixelShader[i])
Driver->extGlDeletePrograms(1, &PixelShader[i]); Driver->extGlDeletePrograms(1, &PixelShader[i]);
if (BaseMaterial)
BaseMaterial->drop();
} }
...@@ -120,8 +145,6 @@ void COpenGLShaderMaterialRenderer::init(s32& outMaterialTypeNr, ...@@ -120,8 +145,6 @@ void COpenGLShaderMaterialRenderer::init(s32& outMaterialTypeNr,
bool COpenGLShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) bool COpenGLShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{ {
Driver->setTextureRenderStates(Driver->getCurrentMaterial(), false);
// call callback to set shader constants // call callback to set shader constants
if (CallBack && (VertexShader || PixelShader[0])) if (CallBack && (VertexShader || PixelShader[0]))
CallBack->OnSetConstants(service, UserData); CallBack->OnSetConstants(service, UserData);
...@@ -138,6 +161,8 @@ void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& materi ...@@ -138,6 +161,8 @@ void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& materi
else else
Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE); Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE);
COpenGLCallBridge* bridgeCalls = Driver->getBridgeCalls();
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{ {
if (VertexShader) if (VertexShader)
...@@ -181,8 +206,40 @@ void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& materi ...@@ -181,8 +206,40 @@ void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& materi
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (BaseMaterial) if (Alpha)
BaseMaterial->OnSetBaseMaterial(material); {
bridgeCalls->setBlend(true);
bridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (FixedBlending)
{
bridgeCalls->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
bridgeCalls->setBlend(true);
}
else if (Blending)
{
E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
E_MODULATE_FUNC modulate;
u32 alphaSource;
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
if (Driver->queryFeature(EVDF_BLEND_SEPARATE))
{
bridgeCalls->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
}
else
{
bridgeCalls->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
}
bridgeCalls->setBlend(true);
}
else if (AlphaTest)
{
bridgeCalls->setAlphaTest(true);
bridgeCalls->setAlphaFunc(GL_GREATER, 0.5f);
}
if (CallBack) if (CallBack)
CallBack->OnSetMaterial(material); CallBack->OnSetMaterial(material);
...@@ -207,16 +264,13 @@ void COpenGLShaderMaterialRenderer::OnUnsetMaterial() ...@@ -207,16 +264,13 @@ void COpenGLShaderMaterialRenderer::OnUnsetMaterial()
if (PixelShader[0]) if (PixelShader[0])
glDisable(GL_FRAGMENT_PROGRAM_NV); glDisable(GL_FRAGMENT_PROGRAM_NV);
#endif #endif
if (BaseMaterial)
BaseMaterial->OnUnsetBaseMaterial();
} }
//! Returns if the material is transparent. //! Returns if the material is transparent.
bool COpenGLShaderMaterialRenderer::isTransparent() const bool COpenGLShaderMaterialRenderer::isTransparent() const
{ {
return BaseMaterial ? BaseMaterial->isTransparent() : false; return (Alpha || Blending || FixedBlending);
} }
......
...@@ -35,7 +35,6 @@ namespace video ...@@ -35,7 +35,6 @@ namespace video
{ {
class COpenGLDriver; class COpenGLDriver;
class COpenGLMaterialRenderer;
class IShaderConstantSetCallBack; class IShaderConstantSetCallBack;
//! Class for using vertex and pixel shaders with OpenGL //! Class for using vertex and pixel shaders with OpenGL
...@@ -79,7 +78,11 @@ protected: ...@@ -79,7 +78,11 @@ protected:
COpenGLDriver* Driver; COpenGLDriver* Driver;
IShaderConstantSetCallBack* CallBack; IShaderConstantSetCallBack* CallBack;
COpenGLMaterialRenderer* BaseMaterial;
bool Alpha;
bool Blending;
bool FixedBlending;
bool AlphaTest;
GLuint VertexShader; GLuint VertexShader;
// We have 4 values here, [0] is the non-fog version, the other three are // We have 4 values here, [0] is the non-fog version, the other three are
......
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