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 @@
namespace irr
{
namespace video
namespace video
{
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
IGPUProgrammingServices when creating a shader. The OnSetConstants method will be called
every frame now. */
......@@ -24,11 +24,33 @@ public:
//! Destructor.
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.
/**
/**
Implement the IShaderConstantSetCallBack in an own class and implement your own
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
before geometry is being drawn using your shader material. A sample implementation
would look like this:
......@@ -36,7 +58,7 @@ public:
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
// set clip matrix at register 4
core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION));
worldViewProj *= driver->getTransform(video::ETS_VIEW);
......@@ -44,7 +66,7 @@ public:
services->setVertexShaderConstant(&worldViewProj.M[0], 4, 4);
// for high level shading languages, this would be another solution:
//services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16);
// set some light color at register 9
video::SColorf col(0.0f,1.0f,1.0f,0.0f);
services->setVertexShaderConstant(reinterpret_cast<const f32*>(&col), 9, 1);
......
......@@ -21,11 +21,11 @@
namespace irr
{
namespace video
namespace video
{
//! Public constructor
CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver,
CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver,
s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData)
: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial),
......@@ -43,7 +43,7 @@ CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3dde
//! constructor only for use by derived classes who want to
//! create a fall back material for example.
CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev,
video::IVideoDriver* driver,
video::IVideoDriver* driver,
IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial,
s32 userData)
......@@ -105,17 +105,17 @@ bool CD3D8ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E
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 (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
// every time.
//pID3DDevice->GetVertexShader(&OldVertexShader);
// set new vertex shader
if (FAILED(pID3DDevice->SetVertexShader(VertexShader)))
os::Printer::log("Could not set vertex shader.");
......@@ -132,12 +132,16 @@ void CD3D8ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material
BaseMaterial->OnSetMaterial(material, material, true, services);
}
//let callback know used material
if (CallBack)
CallBack->OnSetMaterial(material);
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
// every time.
// if (VertexShader)
......@@ -150,12 +154,12 @@ void CD3D8ShaderMaterialRenderer::OnUnsetMaterial()
BaseMaterial->OnUnsetMaterial();
}
//! Returns if the material is transparent. The scene managment needs to know this
//! for being able to sort the materials by opaque and transparent.
bool CD3D8ShaderMaterialRenderer::isTransparent() const
{
return BaseMaterial ? BaseMaterial->isTransparent() : false;
return BaseMaterial ? BaseMaterial->isTransparent() : false;
}
bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh)
......@@ -178,7 +182,7 @@ bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh)
// compile shader and emitt some debug informations to
// 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;
char tmp[32];
sprintf(tmp, "irr_d3d8_dbg_shader_%d.psh", irr_dbg_file_nr);
......@@ -189,7 +193,7 @@ bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh)
fclose(f);
D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors);
#endif
if (errors)
......@@ -237,7 +241,7 @@ bool CD3D8ShaderMaterialRenderer::createVertexShader(const char* vtxsh, E_VERTEX
// compile shader and emitt some debug informations to
// 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;
char tmp[32];
sprintf(tmp, "irr_d3d8_dbg_shader_%d.vsh", irr_dbg_file_nr);
......@@ -293,7 +297,7 @@ bool CD3D8ShaderMaterialRenderer::createVertexShader(const char* vtxsh, E_VERTEX
if (type == EVT_TANGENTS)
decl = dwTngtDecl;
else
decl = dwStdDecl;
decl = dwStdDecl;
if (FAILED(pID3DDevice->CreateVertexShader(decl,
(DWORD*)code->GetBufferPointer(), &VertexShader, 0)))
......
......@@ -23,7 +23,7 @@ namespace video
{
//! Public constructor
CD3D9ShaderMaterialRenderer::CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver,
CD3D9ShaderMaterialRenderer::CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver,
s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData)
: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial),
......@@ -43,7 +43,7 @@ CD3D9ShaderMaterialRenderer::CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3dde
//! constructor only for use by derived classes who want to
//! create a fall back material for example.
CD3D9ShaderMaterialRenderer::CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev,
video::IVideoDriver* driver,
video::IVideoDriver* driver,
IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial,
s32 userData)
......@@ -103,15 +103,15 @@ bool CD3D9ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E
}
void CD3D9ShaderMaterialRenderer::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 (VertexShader)
{
// save old vertex shader
pID3DDevice->GetVertexShader(&OldVertexShader);
// set new vertex shader
if (FAILED(pID3DDevice->SetVertexShader(VertexShader)))
os::Printer::log("Could not set vertex shader.");
......@@ -128,10 +128,14 @@ void CD3D9ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material
BaseMaterial->OnSetMaterial(material, material, true, services);
}
//let callback know used material
if (CallBack)
CallBack->OnSetMaterial(material);
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
}
void CD3D9ShaderMaterialRenderer::OnUnsetMaterial()
void CD3D9ShaderMaterialRenderer::OnUnsetMaterial()
{
if (VertexShader)
pID3DDevice->SetVertexShader(OldVertexShader);
......@@ -143,12 +147,12 @@ void CD3D9ShaderMaterialRenderer::OnUnsetMaterial()
BaseMaterial->OnUnsetMaterial();
}
//! Returns if the material is transparent. The scene managment needs to know this
//! for being able to sort the materials by opaque and transparent.
bool CD3D9ShaderMaterialRenderer::isTransparent() const
{
return BaseMaterial ? BaseMaterial->isTransparent() : false;
return BaseMaterial ? BaseMaterial->isTransparent() : false;
}
bool CD3D9ShaderMaterialRenderer::createPixelShader(const c8* pxsh)
......@@ -170,7 +174,7 @@ bool CD3D9ShaderMaterialRenderer::createPixelShader(const c8* pxsh)
// compile shader and emitt some debug informations to
// 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;
char tmp[32];
sprintf(tmp, "irr_d3d9_dbg_shader_%d.psh", irr_dbg_file_nr);
......@@ -231,7 +235,7 @@ bool CD3D9ShaderMaterialRenderer::createVertexShader(const char* vtxsh)
// compile shader and emitt some debug informations to
// 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;
char tmp[32];
sprintf(tmp, "irr_d3d9_dbg_shader_%d.vsh", irr_dbg_file_nr);
......@@ -244,7 +248,7 @@ bool CD3D9ShaderMaterialRenderer::createVertexShader(const char* vtxsh)
stubD3DXAssembleShaderFromFile(tmp, 0, 0, D3DXSHADER_DEBUG, &code, &errors);
#endif
if (errors)
{
......@@ -273,7 +277,7 @@ bool CD3D9ShaderMaterialRenderer::createVertexShader(const char* vtxsh)
HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen,
CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude,
DWORD Flags, LPD3DXBUFFER* ppShader,
DWORD Flags, LPD3DXBUFFER* ppShader,
LPD3DXBUFFER* ppErrorMsgs)
{
// Because Irrlicht needs to be able to start up even without installed d3d dlls, it
......@@ -283,11 +287,11 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader(LPCSTR pSrcData, UI
// February 2005: d3dx9_24.dll 24
// April 2005: d3dx9_25.dll 25
// June 2005: d3dx9_26.dll 26
// August 2005: d3dx9_27.dll 27
// October 2005,
// August 2005: d3dx9_27.dll 27
// October 2005,
// December 2005: d3dx9_28.dll 28
#if ( D3DX_SDK_VERSION < 24 )
#if ( D3DX_SDK_VERSION < 24 )
// directly link functions, old d3d sdks didn't try to load external dlls
// when linking to the d3dx9.lib
#ifdef _MSC_VER
......@@ -295,16 +299,16 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader(LPCSTR pSrcData, UI
#endif
// invoke static linked function
return D3DXAssembleShader(pSrcData, SrcDataLen, pDefines, pInclude,
return D3DXAssembleShader(pSrcData, SrcDataLen, pDefines, pInclude,
Flags, ppShader, ppErrorMsgs);
#else
{
// try to load shader functions from the dll and print error if failed.
// D3DXAssembleShader signature
typedef HRESULT (WINAPI *AssembleShaderFunction)(LPCSTR pSrcData, UINT SrcDataLen,
CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude,
DWORD Flags, LPD3DXBUFFER* ppShader,
DWORD Flags, LPD3DXBUFFER* ppShader,
LPD3DXBUFFER* ppErrorMsgs);
static bool LoadFailed = false;
......@@ -324,8 +328,8 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader(LPCSTR pSrcData, UI
if (!pFn)
{
LoadFailed = true;
os::Printer::log("Could not load shader function D3DXAssembleShader from dll, shaders disabled",
strDllName.c_str(), ELL_ERROR);
os::Printer::log("Could not load shader function D3DXAssembleShader from dll, shaders disabled",
strDllName.c_str(), ELL_ERROR);
}
}
......@@ -347,7 +351,7 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShaderFromFile(LPCSTR pSrcF
// wondering what I'm doing here?
// see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader()
#if ( D3DX_SDK_VERSION < 24 )
#if ( D3DX_SDK_VERSION < 24 )
// directly link functions, old d3d sdks didn't try to load external dlls
// when linking to the d3dx9.lib
#ifdef _MSC_VER
......@@ -355,14 +359,14 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShaderFromFile(LPCSTR pSrcF
#endif
// invoke static linked function
return D3DXAssembleShaderFromFile(pSrcFile, pDefines, pInclude, Flags,
return D3DXAssembleShaderFromFile(pSrcFile, pDefines, pInclude, Flags,
ppShader, ppErrorMsgs);
#else
{
// try to load shader functions from the dll and print error if failed.
// D3DXAssembleShaderFromFileA signature
typedef HRESULT (WINAPI *AssembleShaderFromFileFunction)(LPCSTR pSrcFile,
typedef HRESULT (WINAPI *AssembleShaderFromFileFunction)(LPCSTR pSrcFile,
CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags,
LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs);
......@@ -383,8 +387,8 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShaderFromFile(LPCSTR pSrcF
if (!pFn)
{
LoadFailed = true;
os::Printer::log("Could not load shader function D3DXAssembleShaderFromFileA from dll, shaders disabled",
strDllName.c_str(), ELL_ERROR);
os::Printer::log("Could not load shader function D3DXAssembleShaderFromFileA from dll, shaders disabled",
strDllName.c_str(), ELL_ERROR);
}
}
......@@ -408,7 +412,7 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShader(LPCSTR pSrcData, UINT
// wondering what I'm doing here?
// see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader()
#if ( D3DX_SDK_VERSION < 24 )
#if ( D3DX_SDK_VERSION < 24 )
// directly link functions, old d3d sdks didn't try to load external dlls
// when linking to the d3dx9.lib
#ifdef _MSC_VER
......@@ -420,7 +424,7 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShader(LPCSTR pSrcData, UINT
#else
{
// try to load shader functions from the dll and print error if failed.
// D3DXCompileShader
typedef HRESULT (WINAPI *D3DXCompileShaderFunction)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines,
LPD3DXINCLUDE pInclude, LPCSTR pFunctionName,
......@@ -444,8 +448,8 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShader(LPCSTR pSrcData, UINT
if (!pFn)
{
LoadFailed = true;
os::Printer::log("Could not load shader function D3DXCompileShader from dll, shaders disabled",
strDllName.c_str(), ELL_ERROR);
os::Printer::log("Could not load shader function D3DXCompileShader from dll, shaders disabled",
strDllName.c_str(), ELL_ERROR);
}
}
......@@ -460,7 +464,7 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShader(LPCSTR pSrcData, UINT
return 0;
}
HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShaderFromFile(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines,
HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShaderFromFile(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines,
LPD3DXINCLUDE pInclude, LPCSTR pFunctionName,
LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs,
LPD3DXCONSTANTTABLE* ppConstantTable)
......@@ -468,7 +472,7 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShaderFromFile(LPCSTR pSrcFi
// wondering what I'm doing here?
// see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader()
#if ( D3DX_SDK_VERSION < 24 )
#if ( D3DX_SDK_VERSION < 24 )
// directly link functions, old d3d sdks didn't try to load external dlls
// when linking to the d3dx9.lib
#ifdef _MSC_VER
......@@ -480,7 +484,7 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShaderFromFile(LPCSTR pSrcFi
#else
{
// try to load shader functions from the dll and print error if failed.
// D3DXCompileShaderFromFileA
typedef HRESULT (WINAPI *D3DXCompileShaderFromFileFunction)(LPCSTR pSrcFile,
CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName,
......@@ -504,8 +508,8 @@ HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShaderFromFile(LPCSTR pSrcFi
if (!pFn)
{
LoadFailed = true;
os::Printer::log("Could not load shader function D3DXCompileShaderFromFileA from dll, shaders disabled",
strDllName.c_str(), ELL_ERROR);
os::Printer::log("Could not load shader function D3DXCompileShaderFromFileA from dll, shaders disabled",
strDllName.c_str(), ELL_ERROR);
}
}
......
......@@ -141,6 +141,10 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
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)
Driver->setTexture(i, material.getTexture(i));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
......
......@@ -121,6 +121,10 @@ void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& materi
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)
Driver->setTexture(i, material.getTexture(i));
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