mirror of
https://github.com/minetest/irrlicht.git
synced 2024-12-25 15:42:25 +01:00
Add IMaterialRendererServices::startUseProgram/stopUseProgram
This makes it possible to set high-level shader constants (which are attached to shader programs) to be set outside of OnSetConstants. IShaderConstantSetCallBack::OnCreate has it set automatically now so it works the same as OnSetConstants. D3D9 and burnings both work different, so there hadn't been a problem with those. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6469 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
parent
16c960c5ed
commit
c4bbbe1aaf
@ -56,7 +56,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (UseHighLevelShaders)
|
if (UseHighLevelShaders)
|
||||||
{
|
{
|
||||||
// get shader constants id.
|
// Get shader constants id.
|
||||||
WorldViewProjID = services->getVertexShaderConstantID("mWorldViewProj");
|
WorldViewProjID = services->getVertexShaderConstantID("mWorldViewProj");
|
||||||
TransWorldID = services->getVertexShaderConstantID("mTransWorld");
|
TransWorldID = services->getVertexShaderConstantID("mTransWorld");
|
||||||
InvWorldID = services->getVertexShaderConstantID("mInvWorld");
|
InvWorldID = services->getVertexShaderConstantID("mInvWorld");
|
||||||
@ -68,6 +68,27 @@ public:
|
|||||||
if(driver->getDriverType() == video::EDT_OPENGL)
|
if(driver->getDriverType() == video::EDT_OPENGL)
|
||||||
TextureID = services->getVertexShaderConstantID("myTexture");
|
TextureID = services->getVertexShaderConstantID("myTexture");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set light color
|
||||||
|
// That could be set as well in OnSetConstants, but there's some cost to setting shader constants
|
||||||
|
// So when we have non-changing shader constants it's more performant to set them only once.
|
||||||
|
video::SColorf col(0.0f,1.0f,1.0f,0.0f);
|
||||||
|
if (UseHighLevelShaders)
|
||||||
|
{
|
||||||
|
services->setVertexShaderConstant(ColorID, reinterpret_cast<f32*>(&col), 4);
|
||||||
|
|
||||||
|
// Note: Since Irrlicht 1.9 it's possible to call setVertexShaderConstant
|
||||||
|
// from anywhere. To do that save the services pointer here in OnCreate, it
|
||||||
|
// won't change as long as you use one IShaderConstantSetCallBack per shader
|
||||||
|
// material. But when calling it ouside of IShaderConstantSetCallBack functions
|
||||||
|
// you have to call services->startUseProgram()stopUseProgram() before/after doing so.
|
||||||
|
// At least for high-level shader constants, low level constants are not attached
|
||||||
|
// to programs, so for those it doesn't matter.
|
||||||
|
// Doing that sometimes makes sense for performance reasons, like for constants which
|
||||||
|
// do only change once per frame or even less.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
services->setVertexShaderConstant(reinterpret_cast<f32*>(&col), 9, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnSetConstants(video::IMaterialRendererServices* services,
|
virtual void OnSetConstants(video::IMaterialRendererServices* services,
|
||||||
@ -109,16 +130,6 @@ public:
|
|||||||
else
|
else
|
||||||
services->setVertexShaderConstant(reinterpret_cast<f32*>(&pos), 8, 1);
|
services->setVertexShaderConstant(reinterpret_cast<f32*>(&pos), 8, 1);
|
||||||
|
|
||||||
// set light color
|
|
||||||
|
|
||||||
video::SColorf col(0.0f,1.0f,1.0f,0.0f);
|
|
||||||
|
|
||||||
if (UseHighLevelShaders)
|
|
||||||
services->setVertexShaderConstant(ColorID,
|
|
||||||
reinterpret_cast<f32*>(&col), 4);
|
|
||||||
else
|
|
||||||
services->setVertexShaderConstant(reinterpret_cast<f32*>(&col), 9, 1);
|
|
||||||
|
|
||||||
// set transposed world matrix
|
// set transposed world matrix
|
||||||
|
|
||||||
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
|
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
|
||||||
|
@ -41,6 +41,20 @@ public:
|
|||||||
//! Return an index constant for the vertex shader based on a name.
|
//! Return an index constant for the vertex shader based on a name.
|
||||||
virtual s32 getVertexShaderConstantID(const c8* name) = 0;
|
virtual s32 getVertexShaderConstantID(const c8* name) = 0;
|
||||||
|
|
||||||
|
//! Call when you set shader constants outside of IShaderConstantSetCallBack
|
||||||
|
/** Only for high-level shader functions, aka those using an index instead of
|
||||||
|
an register. Shader constants are attached to shader programs, so if you want
|
||||||
|
to set them you have to make sure the correct shader program is in use.
|
||||||
|
IShaderConstantSetCallBack functions like OnSetConstants do that for you,
|
||||||
|
but if you want to set shader constants outside of those (usually for performance
|
||||||
|
reasons) call startUseProgram() before doing so and stopUseProgram() afterwards.
|
||||||
|
Note: Currently only necessary in OpenGL, but no real calling costs on other drivers.
|
||||||
|
*/
|
||||||
|
virtual void startUseProgram() {}
|
||||||
|
|
||||||
|
//! Call this when you are done setting shader constants outside of OnCreate or OnSetConstants
|
||||||
|
virtual void stopUseProgram() {}
|
||||||
|
|
||||||
//! Sets a constant for the vertex shader based on a name.
|
//! Sets a constant for the vertex shader based on a name.
|
||||||
/** This can be used if you used a high level shader language like GLSL
|
/** This can be used if you used a high level shader language like GLSL
|
||||||
or HLSL to create a shader. Example: If you created a shader which has
|
or HLSL to create a shader. Example: If you created a shader which has
|
||||||
|
@ -3727,7 +3727,9 @@ s32 COpenGLDriver::addShaderMaterial(const c8* vertexShaderProgram,
|
|||||||
r->drop();
|
r->drop();
|
||||||
|
|
||||||
if (callback && nr >= 0)
|
if (callback && nr >= 0)
|
||||||
|
{
|
||||||
callback->OnCreate(this, userData);
|
callback->OnCreate(this, userData);
|
||||||
|
}
|
||||||
|
|
||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
@ -3764,7 +3766,11 @@ s32 COpenGLDriver::addHighLevelShaderMaterial(
|
|||||||
r->drop();
|
r->drop();
|
||||||
|
|
||||||
if (callback && nr >= 0)
|
if (callback && nr >= 0)
|
||||||
|
{
|
||||||
|
r->startUseProgram();
|
||||||
callback->OnCreate(r, userData);
|
callback->OnCreate(r, userData);
|
||||||
|
r->stopUseProgram();
|
||||||
|
}
|
||||||
|
|
||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
|
@ -415,6 +415,12 @@ namespace video
|
|||||||
//! Get current material.
|
//! Get current material.
|
||||||
const SMaterial& getCurrentMaterial() const;
|
const SMaterial& getCurrentMaterial() const;
|
||||||
|
|
||||||
|
//! Rest renderstates forcing stuff like OnSetMaterial to be called
|
||||||
|
void DoResetRenderStates()
|
||||||
|
{
|
||||||
|
ResetRenderStates = true;
|
||||||
|
}
|
||||||
|
|
||||||
COpenGLCacheHandler* getCacheHandler() const;
|
COpenGLCacheHandler* getCacheHandler() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -237,13 +237,10 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
|
|||||||
|
|
||||||
COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();
|
COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();
|
||||||
|
|
||||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
if (Program2)
|
||||||
{
|
Driver->irrGlUseProgram(Program2);
|
||||||
if (Program2)
|
else if (Program)
|
||||||
Driver->irrGlUseProgram(Program2);
|
Driver->extGlUseProgramObject(Program);
|
||||||
else if (Program)
|
|
||||||
Driver->extGlUseProgramObject(Program);
|
|
||||||
}
|
|
||||||
|
|
||||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||||
|
|
||||||
@ -572,6 +569,23 @@ void COpenGLSLMaterialRenderer::setBasicRenderStates(const SMaterial& material,
|
|||||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void COpenGLSLMaterialRenderer::startUseProgram()
|
||||||
|
{
|
||||||
|
if (Program2)
|
||||||
|
Driver->irrGlUseProgram(Program2);
|
||||||
|
else if (Program)
|
||||||
|
Driver->extGlUseProgramObject(Program);
|
||||||
|
}
|
||||||
|
|
||||||
|
void COpenGLSLMaterialRenderer::stopUseProgram()
|
||||||
|
{
|
||||||
|
// Not going to reset irrGlUseProgram/extGlUseProgramObject as it shouldn't really matter
|
||||||
|
|
||||||
|
// Force reset of material to ensure OnSetMaterial will be called or we can miss
|
||||||
|
// the next UseProgram call
|
||||||
|
Driver->DoResetRenderStates();
|
||||||
|
}
|
||||||
|
|
||||||
s32 COpenGLSLMaterialRenderer::getVertexShaderConstantID(const c8* name)
|
s32 COpenGLSLMaterialRenderer::getVertexShaderConstantID(const c8* name)
|
||||||
{
|
{
|
||||||
return getPixelShaderConstantID(name);
|
return getPixelShaderConstantID(name);
|
||||||
|
@ -73,6 +73,8 @@ public:
|
|||||||
|
|
||||||
// implementations for IMaterialRendererServices
|
// implementations for IMaterialRendererServices
|
||||||
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) IRR_OVERRIDE;
|
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) IRR_OVERRIDE;
|
||||||
|
virtual void startUseProgram() IRR_OVERRIDE;
|
||||||
|
virtual void stopUseProgram() IRR_OVERRIDE;
|
||||||
virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE;
|
virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE;
|
||||||
virtual s32 getPixelShaderConstantID(const c8* name) IRR_OVERRIDE;
|
virtual s32 getPixelShaderConstantID(const c8* name) IRR_OVERRIDE;
|
||||||
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) IRR_OVERRIDE;
|
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) IRR_OVERRIDE;
|
||||||
|
Loading…
Reference in New Issue
Block a user