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
......@@ -16,45 +16,12 @@ namespace irr
namespace video
{
//! Base class for all internal OpenGL material renderers
class COpenGLMaterialRenderer : public IMaterialRenderer
{
public:
//! Constructor
COpenGLMaterialRenderer(video::COpenGLDriver* driver) : Driver(driver)
{
}
//! 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()
{
}
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) _IRR_OVERRIDE_
{
Driver->setTextureRenderStates(Driver->getCurrentMaterial(), false);
return true;
}
protected:
video::COpenGLDriver* Driver;
};
//! Solid material renderer
class COpenGLMaterialRenderer_SOLID : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_SOLID : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_SOLID(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_SOLID(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -74,16 +41,19 @@ public:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
}
protected:
video::COpenGLDriver* Driver;
};
//! Generic Texture Blend
class COpenGLMaterialRenderer_ONETEXTURE_BLEND : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_ONETEXTURE_BLEND : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_ONETEXTURE_BLEND(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_ONETEXTURE_BLEND(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -170,26 +140,6 @@ public:
}
}
virtual void OnSetBaseMaterial(const SMaterial& material) _IRR_OVERRIDE_
{
E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
E_MODULATE_FUNC modulate;
u32 alphaSource;
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
Driver->getBridgeCalls()->setBlend(true);
if (Driver->queryFeature(EVDF_BLEND_SEPARATE))
{
Driver->getBridgeCalls()->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
}
else
{
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
}
}
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
......@@ -206,27 +156,25 @@ public:
Driver->getBridgeCalls()->setBlend(false);
}
virtual void OnUnsetBaseMaterial() _IRR_OVERRIDE_
{
Driver->getBridgeCalls()->setBlend(false);
}
//! Returns if the material is transparent.
/** Is not always transparent, but mostly. */
virtual bool isTransparent() const _IRR_OVERRIDE_
{
return true;
}
protected:
video::COpenGLDriver* Driver;
};
//! Solid 2 layer material renderer
class COpenGLMaterialRenderer_SOLID_2_LAYER : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_SOLID_2_LAYER : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_SOLID_2_LAYER(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_SOLID_2_LAYER(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -281,16 +229,19 @@ public:
Driver->getBridgeCalls()->setActiveTexture(GL_TEXTURE0_ARB);
}
}
protected:
video::COpenGLDriver* Driver;
};
//! Transparent add color material renderer
class COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -310,37 +261,29 @@ public:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
virtual void OnSetBaseMaterial(const SMaterial& material) _IRR_OVERRIDE_
{
Driver->getBridgeCalls()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
Driver->getBridgeCalls()->setBlend(true);
}
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
{
Driver->getBridgeCalls()->setBlend(false);
}
virtual void OnUnsetBaseMaterial() _IRR_OVERRIDE_
{
Driver->getBridgeCalls()->setBlend(false);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const _IRR_OVERRIDE_
{
return true;
}
protected:
video::COpenGLDriver* Driver;
};
//! Transparent vertex alpha material renderer
class COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -376,12 +319,6 @@ public:
}
}
virtual void OnSetBaseMaterial(const SMaterial& material) _IRR_OVERRIDE_
{
Driver->getBridgeCalls()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Driver->getBridgeCalls()->setBlend(true);
}
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
{
// default values
......@@ -396,26 +333,24 @@ public:
Driver->getBridgeCalls()->setBlend(false);
}
virtual void OnUnsetBaseMaterial() _IRR_OVERRIDE_
{
Driver->getBridgeCalls()->setBlend(false);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const _IRR_OVERRIDE_
{
return true;
}
protected:
video::COpenGLDriver* Driver;
};
//! Transparent alpha channel material renderer
class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -454,14 +389,6 @@ public:
}
}
virtual void OnSetBaseMaterial(const SMaterial& material) _IRR_OVERRIDE_
{
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() _IRR_OVERRIDE_
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
......@@ -474,27 +401,24 @@ public:
Driver->getBridgeCalls()->setBlend(false);
}
virtual void OnUnsetBaseMaterial() _IRR_OVERRIDE_
{
Driver->getBridgeCalls()->setBlend(false);
Driver->getBridgeCalls()->setAlphaTest(false);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const _IRR_OVERRIDE_
{
return true;
}
protected:
video::COpenGLDriver* Driver;
};
//! Transparent alpha channel material renderer
class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -515,37 +439,29 @@ public:
}
}
virtual void OnSetBaseMaterial(const SMaterial& material) _IRR_OVERRIDE_
{
Driver->getBridgeCalls()->setAlphaTest(true);
Driver->getBridgeCalls()->setAlphaFunc(GL_GREATER, 0.5f);
}
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
{
Driver->getBridgeCalls()->setAlphaTest(false);
}
virtual void OnUnsetBaseMaterial() _IRR_OVERRIDE_
{
Driver->getBridgeCalls()->setAlphaTest(false);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const _IRR_OVERRIDE_
{
return false; // this material is not really transparent because it does no blending.
}
protected:
video::COpenGLDriver* Driver;
};
//! material renderer for all kinds of lightmaps
class COpenGLMaterialRenderer_LIGHTMAP : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_LIGHTMAP : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_LIGHTMAP(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_LIGHTMAP(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -656,17 +572,20 @@ public:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
}
protected:
video::COpenGLDriver* Driver;
};
//! detail map material renderer
class COpenGLMaterialRenderer_DETAIL_MAP : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_DETAIL_MAP : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_DETAIL_MAP(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_DETAIL_MAP(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -711,16 +630,19 @@ public:
Driver->getBridgeCalls()->setActiveTexture(GL_TEXTURE0_ARB);
}
}
protected:
video::COpenGLDriver* Driver;
};
//! sphere map material renderer
class COpenGLMaterialRenderer_SPHERE_MAP : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_SPHERE_MAP : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_SPHERE_MAP(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_SPHERE_MAP(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -752,16 +674,19 @@ public:
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
}
protected:
video::COpenGLDriver* Driver;
};
//! reflection 2 layer material renderer
class COpenGLMaterialRenderer_REFLECTION_2_LAYER : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_REFLECTION_2_LAYER : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_REFLECTION_2_LAYER(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_REFLECTION_2_LAYER(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -812,16 +737,19 @@ public:
Driver->getBridgeCalls()->setActiveTexture(GL_TEXTURE0_ARB);
}
}
protected:
video::COpenGLDriver* Driver;
};
//! reflection 2 layer material renderer
class COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public COpenGLMaterialRenderer
class COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public IMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(video::COpenGLDriver* d) : Driver(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
......@@ -901,6 +829,10 @@ public:
{
return true;
}
protected:
video::COpenGLDriver* Driver;
};
} // end namespace video
......
......@@ -44,25 +44,35 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
IShaderConstantSetCallBack* callback,
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)
{
#ifdef _DEBUG
setDebugName("COpenGLSLMaterialRenderer");
#endif
//entry points must always be main, and the compile target isn't selectable
//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)
switch (baseMaterial)
{
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)
CallBack->grab();
......@@ -78,17 +88,31 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver* driver,
IShaderConstantSetCallBack* callback,
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 ||
baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL || baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
switch (baseMaterial)
{
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)
CallBack->grab();
}
......@@ -129,9 +153,6 @@ COpenGLSLMaterialRenderer::~COpenGLSLMaterialRenderer()
}
UniformInfo.clear();
if (BaseMaterial)
BaseMaterial->drop();
}
......@@ -192,8 +213,6 @@ void COpenGLSLMaterialRenderer::init(s32& outMaterialTypeNr,
bool COpenGLSLMaterialRenderer::OnRender(IMaterialRendererServices* service,
E_VERTEX_TYPE vtxtype)
{
Driver->setTextureRenderStates(Driver->getCurrentMaterial(), false);
// call callback to set shader constants
if (CallBack && (Program||Program2))
CallBack->OnSetConstants(this, UserData);
......@@ -212,6 +231,8 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
else
Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE);
COpenGLCallBridge* bridgeCalls = Driver->getBridgeCalls();
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
if (Program2)
......@@ -222,8 +243,40 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (BaseMaterial)
BaseMaterial->OnSetBaseMaterial(material);
if (Alpha)
{
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)
CallBack->OnSetMaterial(material);
......@@ -236,16 +289,13 @@ void COpenGLSLMaterialRenderer::OnUnsetMaterial()
Driver->extGlUseProgramObject(0);
if (Program2)
Driver->extGlUseProgram(0);
if (BaseMaterial)
BaseMaterial->OnUnsetBaseMaterial();
}
//! Returns if the material is transparent.
bool COpenGLSLMaterialRenderer::isTransparent() const
{
return BaseMaterial ? BaseMaterial->isTransparent() : false;
return (Alpha || Blending || FixedBlending);
}
......
......@@ -43,7 +43,6 @@ namespace video
{
class COpenGLDriver;
class COpenGLMaterialRenderer;
class IShaderConstantSetCallBack;
//! Class for using GLSL shaders with OpenGL
......@@ -120,7 +119,11 @@ protected:
COpenGLDriver* Driver;
IShaderConstantSetCallBack* CallBack;
COpenGLMaterialRenderer* BaseMaterial;
bool Alpha;
bool Blending;
bool FixedBlending;
bool AlphaTest;
struct SUniformInfo
{
......
......@@ -23,8 +23,8 @@ namespace video
COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver,
s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial, s32 userData)
: Driver(driver), CallBack(callback), BaseMaterial(0),
VertexShader(0), UserData(userData)
: Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false),
AlphaTest(false), VertexShader(0), UserData(userData)
{
#ifdef _DEBUG
setDebugName("COpenGLShaderMaterialRenderer");
......@@ -36,15 +36,29 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDrive
PixelShader[i]=0;
}
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)
switch (baseMaterial)
{
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)
CallBack->grab();
......@@ -57,8 +71,8 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDrive
COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(COpenGLDriver* driver,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial, s32 userData)
: Driver(driver), CallBack(callback), BaseMaterial(0),
VertexShader(0), UserData(userData)
: Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false),
AlphaTest(false), VertexShader(0), UserData(userData)
{
PixelShader.set_used(4);
for (u32 i=0; i<4; ++i)
......@@ -66,15 +80,29 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(COpenGLDriver* driv
PixelShader[i]=0;
}
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)
switch (baseMaterial)
{
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)
CallBack->grab();
}
......@@ -92,9 +120,6 @@ COpenGLShaderMaterialRenderer::~COpenGLShaderMaterialRenderer()
for (u32 i=0; i<PixelShader.size(); ++i)
if (PixelShader[i])
Driver->extGlDeletePrograms(1, &PixelShader[i]);
if (BaseMaterial)
BaseMaterial->drop();
}
......@@ -120,8 +145,6 @@ void COpenGLShaderMaterialRenderer::init(s32& outMaterialTypeNr,
bool COpenGLShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{
Driver->setTextureRenderStates(Driver->getCurrentMaterial(), false);
// call callback to set shader constants
if (CallBack && (VertexShader || PixelShader[0]))
CallBack->OnSetConstants(service, UserData);
......@@ -138,6 +161,8 @@ void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& materi
else
Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE);
COpenGLCallBridge* bridgeCalls = Driver->getBridgeCalls();
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
if (VertexShader)
......@@ -181,8 +206,40 @@ void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& materi
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (BaseMaterial)
BaseMaterial->OnSetBaseMaterial(material);
if (Alpha)
{
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)
CallBack->OnSetMaterial(material);
......@@ -207,16 +264,13 @@ void COpenGLShaderMaterialRenderer::OnUnsetMaterial()
if (PixelShader[0])
glDisable(GL_FRAGMENT_PROGRAM_NV);
#endif
if (BaseMaterial)
BaseMaterial->OnUnsetBaseMaterial();
}
//! Returns if the material is transparent.
bool COpenGLShaderMaterialRenderer::isTransparent() const
{
return BaseMaterial ? BaseMaterial->isTransparent() : false;
return (Alpha || Blending || FixedBlending);
}
......
......@@ -35,7 +35,6 @@ namespace video
{
class COpenGLDriver;
class COpenGLMaterialRenderer;
class IShaderConstantSetCallBack;
//! Class for using vertex and pixel shaders with OpenGL
......@@ -79,7 +78,11 @@ protected:
COpenGLDriver* Driver;
IShaderConstantSetCallBack* CallBack;
COpenGLMaterialRenderer* BaseMaterial;
bool Alpha;
bool Blending;
bool FixedBlending;
bool AlphaTest;
GLuint VertexShader;
// 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