mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 15:09:39 +00:00
use StateSet define for translucentFramebuffer (#3138)
With this PR we test out osg's shader define system for a somewhat harmless feature. As we can see, our code becomes more concise and efficient in this case. Most importantly, we no longer create unneeded vertex shader objects.
This commit is contained in:
parent
b2af81bc18
commit
4b1c009ffd
9 changed files with 20 additions and 40 deletions
|
@ -91,7 +91,7 @@ namespace MWRender
|
|||
class SetUpBlendVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
SetUpBlendVisitor(): osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), mNoAlphaUniform(new osg::Uniform("noAlpha", false))
|
||||
SetUpBlendVisitor(): osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ namespace MWRender
|
|||
}
|
||||
// Disable noBlendAlphaEnv
|
||||
newStateSet->setTextureMode(7, GL_TEXTURE_2D, osg::StateAttribute::OFF);
|
||||
newStateSet->addUniform(mNoAlphaUniform);
|
||||
newStateSet->setDefine("FORCE_OPAQUE", "0", osg::StateAttribute::ON);
|
||||
}
|
||||
if (SceneUtil::getReverseZ() && stateset->getAttribute(osg::StateAttribute::DEPTH))
|
||||
{
|
||||
|
@ -172,8 +172,6 @@ namespace MWRender
|
|||
}
|
||||
traverse(node);
|
||||
}
|
||||
private:
|
||||
osg::ref_ptr<osg::Uniform> mNoAlphaUniform;
|
||||
};
|
||||
|
||||
CharacterPreview::CharacterPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem,
|
||||
|
@ -216,6 +214,7 @@ namespace MWRender
|
|||
osg::ref_ptr<SceneUtil::LightManager> lightManager = new SceneUtil::LightManager(ffp);
|
||||
lightManager->setStartLight(1);
|
||||
osg::ref_ptr<osg::StateSet> stateset = lightManager->getOrCreateStateSet();
|
||||
stateset->setDefine("FORCE_OPAQUE", "1", osg::StateAttribute::ON);
|
||||
stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
|
||||
stateset->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
|
||||
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
|
||||
|
@ -253,7 +252,6 @@ namespace MWRender
|
|||
dummyTexture->setShadowCompareFunc(osg::Texture::ShadowCompareFunc::ALWAYS);
|
||||
stateset->setTextureAttributeAndModes(7, dummyTexture, osg::StateAttribute::ON);
|
||||
stateset->setTextureAttribute(7, noBlendAlphaEnv, osg::StateAttribute::ON);
|
||||
stateset->addUniform(new osg::Uniform("noAlpha", true));
|
||||
|
||||
osg::ref_ptr<osg::LightModel> lightmodel = new osg::LightModel;
|
||||
lightmodel->setAmbientIntensity(osg::Vec4(0.0, 0.0, 0.0, 1.0));
|
||||
|
@ -328,7 +326,6 @@ namespace MWRender
|
|||
|
||||
void CharacterPreview::setBlendMode()
|
||||
{
|
||||
mResourceSystem->getSceneManager()->recreateShaders(mNode, "objects", true);
|
||||
SetUpBlendVisitor visitor;
|
||||
mNode->accept(visitor);
|
||||
}
|
||||
|
|
|
@ -224,7 +224,7 @@ namespace MWRender
|
|||
group->setNodeMask(Mask_Groundcover);
|
||||
if (mSceneManager->getLightingMethod() != SceneUtil::LightingMethod::FFP)
|
||||
group->setCullCallback(new SceneUtil::LightListCallback);
|
||||
mSceneManager->recreateShaders(group, "groundcover", false, true, mProgramTemplate);
|
||||
mSceneManager->recreateShaders(group, "groundcover", true, mProgramTemplate);
|
||||
mSceneManager->shareState(group);
|
||||
group->getBound();
|
||||
return group;
|
||||
|
|
|
@ -331,9 +331,9 @@ namespace Resource
|
|||
return mForceShaders;
|
||||
}
|
||||
|
||||
void SceneManager::recreateShaders(osg::ref_ptr<osg::Node> node, const std::string& shaderPrefix, bool translucentFramebuffer, bool forceShadersForNode, const osg::Program* programTemplate)
|
||||
void SceneManager::recreateShaders(osg::ref_ptr<osg::Node> node, const std::string& shaderPrefix, bool forceShadersForNode, const osg::Program* programTemplate)
|
||||
{
|
||||
osg::ref_ptr<Shader::ShaderVisitor> shaderVisitor(createShaderVisitor(shaderPrefix, translucentFramebuffer));
|
||||
osg::ref_ptr<Shader::ShaderVisitor> shaderVisitor(createShaderVisitor(shaderPrefix));
|
||||
shaderVisitor->setAllowedToModifyStateSets(false);
|
||||
shaderVisitor->setProgramTemplate(programTemplate);
|
||||
if (forceShadersForNode)
|
||||
|
@ -871,7 +871,7 @@ namespace Resource
|
|||
stats->setAttribute(frameNumber, "Node", mCache->getCacheSize());
|
||||
}
|
||||
|
||||
Shader::ShaderVisitor *SceneManager::createShaderVisitor(const std::string& shaderPrefix, bool translucentFramebuffer)
|
||||
Shader::ShaderVisitor *SceneManager::createShaderVisitor(const std::string& shaderPrefix)
|
||||
{
|
||||
Shader::ShaderVisitor* shaderVisitor = new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, shaderPrefix);
|
||||
shaderVisitor->setForceShaders(mForceShaders);
|
||||
|
@ -882,7 +882,6 @@ namespace Resource
|
|||
shaderVisitor->setSpecularMapPattern(mSpecularMapPattern);
|
||||
shaderVisitor->setApplyLightingToEnvMaps(mApplyLightingToEnvMaps);
|
||||
shaderVisitor->setConvertAlphaTestToAlphaToCoverage(mConvertAlphaTestToAlphaToCoverage);
|
||||
shaderVisitor->setTranslucentFramebuffer(translucentFramebuffer);
|
||||
return shaderVisitor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace Resource
|
|||
Shader::ShaderManager& getShaderManager();
|
||||
|
||||
/// Re-create shaders for this node, need to call this if alpha testing, texture stages or vertex color mode have changed.
|
||||
void recreateShaders(osg::ref_ptr<osg::Node> node, const std::string& shaderPrefix = "objects", bool translucentFramebuffer = false, bool forceShadersForNode = false, const osg::Program* programTemplate = nullptr);
|
||||
void recreateShaders(osg::ref_ptr<osg::Node> node, const std::string& shaderPrefix = "objects", bool forceShadersForNode = false, const osg::Program* programTemplate = nullptr);
|
||||
|
||||
/// Applying shaders to a node may replace some fixed-function state.
|
||||
/// This restores it.
|
||||
|
@ -188,7 +188,7 @@ namespace Resource
|
|||
|
||||
private:
|
||||
|
||||
Shader::ShaderVisitor* createShaderVisitor(const std::string& shaderPrefix = "objects", bool translucentFramebuffer = false);
|
||||
Shader::ShaderVisitor* createShaderVisitor(const std::string& shaderPrefix = "objects");
|
||||
|
||||
std::unique_ptr<Shader::ShaderManager> mShaderManager;
|
||||
bool mForceShaders;
|
||||
|
|
|
@ -111,7 +111,6 @@ namespace Shader
|
|||
, mAutoUseSpecularMaps(false)
|
||||
, mApplyLightingToEnvMaps(false)
|
||||
, mConvertAlphaTestToAlphaToCoverage(false)
|
||||
, mTranslucentFramebuffer(false)
|
||||
, mShaderManager(shaderManager)
|
||||
, mImageManager(imageManager)
|
||||
, mDefaultShaderPrefix(defaultShaderPrefix)
|
||||
|
@ -266,7 +265,7 @@ namespace Shader
|
|||
mRequirements.back().mShaderRequired = true;
|
||||
}
|
||||
}
|
||||
else if (!mTranslucentFramebuffer)
|
||||
else
|
||||
Log(Debug::Error) << "ShaderVisitor encountered unknown texture " << texture;
|
||||
}
|
||||
}
|
||||
|
@ -547,8 +546,6 @@ namespace Shader
|
|||
updateAddedState(*writableUserData, addedState);
|
||||
}
|
||||
|
||||
defineMap["translucentFramebuffer"] = mTranslucentFramebuffer ? "1" : "0";
|
||||
|
||||
std::string shaderPrefix;
|
||||
if (!node.getUserValue("shaderPrefix", shaderPrefix))
|
||||
shaderPrefix = mDefaultShaderPrefix;
|
||||
|
@ -764,11 +761,6 @@ namespace Shader
|
|||
mConvertAlphaTestToAlphaToCoverage = convert;
|
||||
}
|
||||
|
||||
void ShaderVisitor::setTranslucentFramebuffer(bool translucent)
|
||||
{
|
||||
mTranslucentFramebuffer = translucent;
|
||||
}
|
||||
|
||||
ReinstateRemovedStateVisitor::ReinstateRemovedStateVisitor(bool allowedToModifyStateSets)
|
||||
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||
, mAllowedToModifyStateSets(allowedToModifyStateSets)
|
||||
|
|
|
@ -45,8 +45,6 @@ namespace Shader
|
|||
|
||||
void setConvertAlphaTestToAlphaToCoverage(bool convert);
|
||||
|
||||
void setTranslucentFramebuffer(bool translucent);
|
||||
|
||||
void apply(osg::Node& node) override;
|
||||
|
||||
void apply(osg::Drawable& drawable) override;
|
||||
|
@ -72,8 +70,6 @@ namespace Shader
|
|||
|
||||
bool mConvertAlphaTestToAlphaToCoverage;
|
||||
|
||||
bool mTranslucentFramebuffer;
|
||||
|
||||
ShaderManager& mShaderManager;
|
||||
Resource::ImageManager& mImageManager;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#version 120
|
||||
#pragma import_defines(FORCE_OPAQUE)
|
||||
|
||||
#if @useUBO
|
||||
#extension GL_ARB_uniform_buffer_object : require
|
||||
|
@ -24,8 +25,6 @@ varying vec2 normalMapUV;
|
|||
varying vec4 passTangent;
|
||||
#endif
|
||||
|
||||
uniform bool noAlpha;
|
||||
|
||||
varying float euclideanDepth;
|
||||
varying float linearDepth;
|
||||
|
||||
|
@ -95,8 +94,8 @@ void main()
|
|||
#endif
|
||||
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
|
||||
|
||||
#if @translucentFramebuffer
|
||||
if (noAlpha)
|
||||
#if FORCE_OPAQUE
|
||||
// having testing & blending isn't enough - we need to write an opaque pixel to be opaque
|
||||
gl_FragData[0].a = 1.0;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#version 120
|
||||
#pragma import_defines(FORCE_OPAQUE)
|
||||
|
||||
#if @useGPUShader4
|
||||
#extension GL_EXT_gpu_shader4: require
|
||||
|
@ -9,8 +10,6 @@ uniform sampler2D diffuseMap;
|
|||
varying vec2 diffuseMapUV;
|
||||
#endif
|
||||
|
||||
uniform bool noAlpha;
|
||||
|
||||
#if @radialFog
|
||||
varying float euclideanDepth;
|
||||
#else
|
||||
|
@ -46,8 +45,7 @@ void main()
|
|||
float fogValue = clamp((linearDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
#if @translucentFramebuffer
|
||||
if (noAlpha)
|
||||
#if FORCE_OPAQUE
|
||||
gl_FragData[0].a = 1.0;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#version 120
|
||||
#pragma import_defines(FORCE_OPAQUE)
|
||||
|
||||
#if @useUBO
|
||||
#extension GL_ARB_uniform_buffer_object : require
|
||||
|
@ -58,7 +59,6 @@ uniform mat2 bumpMapMatrix;
|
|||
#endif
|
||||
|
||||
uniform bool simpleWater;
|
||||
uniform bool noAlpha;
|
||||
|
||||
varying float euclideanDepth;
|
||||
varying float linearDepth;
|
||||
|
@ -220,9 +220,8 @@ void main()
|
|||
#endif
|
||||
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
|
||||
|
||||
#if @translucentFramebuffer
|
||||
#if FORCE_OPAQUE
|
||||
// having testing & blending isn't enough - we need to write an opaque pixel to be opaque
|
||||
if (noAlpha)
|
||||
gl_FragData[0].a = 1.0;
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue