mirror of
https://github.com/minetest/irrlicht.git
synced 2024-12-24 15:12:24 +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)
|
||||
{
|
||||
// get shader constants id.
|
||||
// Get shader constants id.
|
||||
WorldViewProjID = services->getVertexShaderConstantID("mWorldViewProj");
|
||||
TransWorldID = services->getVertexShaderConstantID("mTransWorld");
|
||||
InvWorldID = services->getVertexShaderConstantID("mInvWorld");
|
||||
@ -68,6 +68,27 @@ public:
|
||||
if(driver->getDriverType() == video::EDT_OPENGL)
|
||||
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,
|
||||
@ -109,16 +130,6 @@ public:
|
||||
else
|
||||
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
|
||||
|
||||
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.
|
||||
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.
|
||||
/** 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
|
||||
|
@ -3727,7 +3727,9 @@ s32 COpenGLDriver::addShaderMaterial(const c8* vertexShaderProgram,
|
||||
r->drop();
|
||||
|
||||
if (callback && nr >= 0)
|
||||
{
|
||||
callback->OnCreate(this, userData);
|
||||
}
|
||||
|
||||
return nr;
|
||||
}
|
||||
@ -3764,7 +3766,11 @@ s32 COpenGLDriver::addHighLevelShaderMaterial(
|
||||
r->drop();
|
||||
|
||||
if (callback && nr >= 0)
|
||||
{
|
||||
r->startUseProgram();
|
||||
callback->OnCreate(r, userData);
|
||||
r->stopUseProgram();
|
||||
}
|
||||
|
||||
return nr;
|
||||
}
|
||||
|
@ -415,6 +415,12 @@ namespace video
|
||||
//! Get current material.
|
||||
const SMaterial& getCurrentMaterial() const;
|
||||
|
||||
//! Rest renderstates forcing stuff like OnSetMaterial to be called
|
||||
void DoResetRenderStates()
|
||||
{
|
||||
ResetRenderStates = true;
|
||||
}
|
||||
|
||||
COpenGLCacheHandler* getCacheHandler() const;
|
||||
|
||||
private:
|
||||
|
@ -237,13 +237,10 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
|
||||
|
||||
COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
if (Program2)
|
||||
Driver->irrGlUseProgram(Program2);
|
||||
else if (Program)
|
||||
Driver->extGlUseProgramObject(Program);
|
||||
}
|
||||
if (Program2)
|
||||
Driver->irrGlUseProgram(Program2);
|
||||
else if (Program)
|
||||
Driver->extGlUseProgramObject(Program);
|
||||
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
@ -572,6 +569,23 @@ void COpenGLSLMaterialRenderer::setBasicRenderStates(const SMaterial& material,
|
||||
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)
|
||||
{
|
||||
return getPixelShaderConstantID(name);
|
||||
|
@ -73,6 +73,8 @@ public:
|
||||
|
||||
// implementations for IMaterialRendererServices
|
||||
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 getPixelShaderConstantID(const c8* name) IRR_OVERRIDE;
|
||||
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) IRR_OVERRIDE;
|
||||
|
Loading…
Reference in New Issue
Block a user