Commit 4dc79e88 authored by lukeph's avatar lukeph

added:

virtual void OnSetMaterial(const SMaterial& material) { }

to IShaderConstantSetCallBack, so the callback is able to set constants based on the properties of the used material.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1060 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 1e51dbcb
...@@ -9,11 +9,11 @@ ...@@ -9,11 +9,11 @@
namespace irr namespace irr
{ {
namespace video namespace video
{ {
class IMaterialRendererServices; class IMaterialRendererServices;
//! Interface making it possible to set constants for gpu programs every frame. //! Interface making it possible to set constants for gpu programs every frame.
/** Implement this interface in an own class and pass a pointer to it to one of the methods in /** Implement this interface in an own class and pass a pointer to it to one of the methods in
IGPUProgrammingServices when creating a shader. The OnSetConstants method will be called IGPUProgrammingServices when creating a shader. The OnSetConstants method will be called
every frame now. */ every frame now. */
...@@ -24,11 +24,33 @@ public: ...@@ -24,11 +24,33 @@ public:
//! Destructor. //! Destructor.
virtual ~IShaderConstantSetCallBack() {} virtual ~IShaderConstantSetCallBack() {}
//! Called to let the callBack know the used material (optional method)
/**
\code
class MyCallBack : public IShaderConstantSetCallBack
{
const video::SMaterial *UsedMaterial;
OnSetMaterial(const video::SMaterial& material)
{
UsedMaterial=&material;
}
OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
services->setVertexShaderConstant("myColor", reinterpret_cast<f32*>(&UsedMaterial->color), 4);
}
}
\endcode
*/
virtual void OnSetMaterial(const SMaterial& material) { }
//! Called by the engine when the vertex and/or pixel shader constants for an material renderer should be set. //! Called by the engine when the vertex and/or pixel shader constants for an material renderer should be set.
/** /**
Implement the IShaderConstantSetCallBack in an own class and implement your own Implement the IShaderConstantSetCallBack in an own class and implement your own
OnSetConstants method using the given IMaterialRendererServices interface. OnSetConstants method using the given IMaterialRendererServices interface.
Pass a pointer to this class to one of the methods in IGPUProgrammingServices Pass a pointer to this class to one of the methods in IGPUProgrammingServices
when creating a shader. The OnSetConstants method will now be called every time when creating a shader. The OnSetConstants method will now be called every time
before geometry is being drawn using your shader material. A sample implementation before geometry is being drawn using your shader material. A sample implementation
would look like this: would look like this:
...@@ -36,7 +58,7 @@ public: ...@@ -36,7 +58,7 @@ public:
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{ {
video::IVideoDriver* driver = services->getVideoDriver(); video::IVideoDriver* driver = services->getVideoDriver();
// set clip matrix at register 4 // set clip matrix at register 4
core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION));
worldViewProj *= driver->getTransform(video::ETS_VIEW); worldViewProj *= driver->getTransform(video::ETS_VIEW);
...@@ -44,7 +66,7 @@ public: ...@@ -44,7 +66,7 @@ public:
services->setVertexShaderConstant(&worldViewProj.M[0], 4, 4); services->setVertexShaderConstant(&worldViewProj.M[0], 4, 4);
// for high level shading languages, this would be another solution: // for high level shading languages, this would be another solution:
//services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16); //services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16);
// set some light color at register 9 // set some light color at register 9
video::SColorf col(0.0f,1.0f,1.0f,0.0f); video::SColorf col(0.0f,1.0f,1.0f,0.0f);
services->setVertexShaderConstant(reinterpret_cast<const f32*>(&col), 9, 1); services->setVertexShaderConstant(reinterpret_cast<const f32*>(&col), 9, 1);
......
...@@ -21,11 +21,11 @@ ...@@ -21,11 +21,11 @@
namespace irr namespace irr
{ {
namespace video namespace video
{ {
//! Public constructor //! Public constructor
CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver,
s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData)
: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), : pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial),
...@@ -43,7 +43,7 @@ CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3dde ...@@ -43,7 +43,7 @@ CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3dde
//! constructor only for use by derived classes who want to //! constructor only for use by derived classes who want to
//! create a fall back material for example. //! create a fall back material for example.
CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev,
video::IVideoDriver* driver, video::IVideoDriver* driver,
IShaderConstantSetCallBack* callback, IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial, IMaterialRenderer* baseMaterial,
s32 userData) s32 userData)
...@@ -105,17 +105,17 @@ bool CD3D8ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E ...@@ -105,17 +105,17 @@ bool CD3D8ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E
void CD3D8ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, void CD3D8ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial,
bool resetAllRenderstates, video::IMaterialRendererServices* services) bool resetAllRenderstates, video::IMaterialRendererServices* services)
{ {
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{ {
if (VertexShader) if (VertexShader)
{ {
// We do not need to save and reset the old vertex shader, because // We do not need to save and reset the old vertex shader, because
// in D3D8, this is mixed up with the fvf, and this is set by the driver // in D3D8, this is mixed up with the fvf, and this is set by the driver
// every time. // every time.
//pID3DDevice->GetVertexShader(&OldVertexShader); //pID3DDevice->GetVertexShader(&OldVertexShader);
// set new vertex shader // set new vertex shader
if (FAILED(pID3DDevice->SetVertexShader(VertexShader))) if (FAILED(pID3DDevice->SetVertexShader(VertexShader)))
os::Printer::log("Could not set vertex shader."); os::Printer::log("Could not set vertex shader.");
...@@ -132,12 +132,16 @@ void CD3D8ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material ...@@ -132,12 +132,16 @@ void CD3D8ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material
BaseMaterial->OnSetMaterial(material, material, true, services); BaseMaterial->OnSetMaterial(material, material, true, services);
} }
//let callback know used material
if (CallBack)
CallBack->OnSetMaterial(material);
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
} }
void CD3D8ShaderMaterialRenderer::OnUnsetMaterial() void CD3D8ShaderMaterialRenderer::OnUnsetMaterial()
{ {
// We do not need to save and reset the old vertex shader, because // We do not need to save and reset the old vertex shader, because
// in D3D8, this is mixed up with the fvf, and this is set by the driver // in D3D8, this is mixed up with the fvf, and this is set by the driver
// every time. // every time.
// if (VertexShader) // if (VertexShader)
...@@ -150,12 +154,12 @@ void CD3D8ShaderMaterialRenderer::OnUnsetMaterial() ...@@ -150,12 +154,12 @@ void CD3D8ShaderMaterialRenderer::OnUnsetMaterial()
BaseMaterial->OnUnsetMaterial(); BaseMaterial->OnUnsetMaterial();
} }
//! Returns if the material is transparent. The scene managment needs to know this //! Returns if the material is transparent. The scene managment needs to know this
//! for being able to sort the materials by opaque and transparent. //! for being able to sort the materials by opaque and transparent.
bool CD3D8ShaderMaterialRenderer::isTransparent() const bool CD3D8ShaderMaterialRenderer::isTransparent() const
{ {
return BaseMaterial ? BaseMaterial->isTransparent() : false; return BaseMaterial ? BaseMaterial->isTransparent() : false;
} }
bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh) bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh)
...@@ -178,7 +182,7 @@ bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh) ...@@ -178,7 +182,7 @@ bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh)
// compile shader and emitt some debug informations to // compile shader and emitt some debug informations to
// make it possible to debug the shader in visual studio // make it possible to debug the shader in visual studio
static int irr_dbg_file_nr = 0; static int irr_dbg_file_nr = 0;
++irr_dbg_file_nr; ++irr_dbg_file_nr;
char tmp[32]; char tmp[32];
sprintf(tmp, "irr_d3d8_dbg_shader_%d.psh", irr_dbg_file_nr); sprintf(tmp, "irr_d3d8_dbg_shader_%d.psh", irr_dbg_file_nr);
...@@ -189,7 +193,7 @@ bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh) ...@@ -189,7 +193,7 @@ bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh)
fclose(f); fclose(f);
D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors); D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors);
#endif #endif
if (errors) if (errors)
...@@ -237,7 +241,7 @@ bool CD3D8ShaderMaterialRenderer::createVertexShader(const char* vtxsh, E_VERTEX ...@@ -237,7 +241,7 @@ bool CD3D8ShaderMaterialRenderer::createVertexShader(const char* vtxsh, E_VERTEX
// compile shader and emitt some debug informations to // compile shader and emitt some debug informations to
// make it possible to debug the shader in visual studio // make it possible to debug the shader in visual studio
static int irr_dbg_file_nr = 0; static int irr_dbg_file_nr = 0;
++irr_dbg_file_nr; ++irr_dbg_file_nr;
char tmp[32]; char tmp[32];
sprintf(tmp, "irr_d3d8_dbg_shader_%d.vsh", irr_dbg_file_nr); sprintf(tmp, "irr_d3d8_dbg_shader_%d.vsh", irr_dbg_file_nr);
...@@ -293,7 +297,7 @@ bool CD3D8ShaderMaterialRenderer::createVertexShader(const char* vtxsh, E_VERTEX ...@@ -293,7 +297,7 @@ bool CD3D8ShaderMaterialRenderer::createVertexShader(const char* vtxsh, E_VERTEX
if (type == EVT_TANGENTS) if (type == EVT_TANGENTS)
decl = dwTngtDecl; decl = dwTngtDecl;
else else
decl = dwStdDecl; decl = dwStdDecl;
if (FAILED(pID3DDevice->CreateVertexShader(decl, if (FAILED(pID3DDevice->CreateVertexShader(decl,
(DWORD*)code->GetBufferPointer(), &VertexShader, 0))) (DWORD*)code->GetBufferPointer(), &VertexShader, 0)))
......
...@@ -141,6 +141,10 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material, ...@@ -141,6 +141,10 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
BaseMaterial->OnSetMaterial(material, material, true, this); BaseMaterial->OnSetMaterial(material, material, true, this);
} }
//let callback know used material
if (CallBack)
CallBack->OnSetMaterial(material);
for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
Driver->setTexture(i, material.getTexture(i)); Driver->setTexture(i, material.getTexture(i));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
......
...@@ -121,6 +121,10 @@ void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& materi ...@@ -121,6 +121,10 @@ void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& materi
BaseMaterial->OnSetMaterial(material, material, true, services); BaseMaterial->OnSetMaterial(material, material, true, services);
} }
//let callback know used material
if (CallBack)
CallBack->OnSetMaterial(material);
for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
Driver->setTexture(i, material.getTexture(i)); Driver->setTexture(i, material.getTexture(i));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
......
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