mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-01 12:09:50 +00:00
Merge branch 'opaque-character-preview-preprocessor' into 'master'
Always write opaque fragments instead of relying on blending being off for translucent RTT II: Daggerfall Closes #5391 See merge request OpenMW/openmw!552
This commit is contained in:
commit
0ec953380f
7 changed files with 54 additions and 8 deletions
|
@ -44,6 +44,7 @@
|
||||||
Bug #5370: Opening an unlocked but trapped door uses the key
|
Bug #5370: Opening an unlocked but trapped door uses the key
|
||||||
Bug #5384: openmw-cs: deleting an instance requires reload of scene window to show in editor
|
Bug #5384: openmw-cs: deleting an instance requires reload of scene window to show in editor
|
||||||
Bug #5387: Move/MoveWorld don't update the object's cell properly
|
Bug #5387: Move/MoveWorld don't update the object's cell properly
|
||||||
|
Bug #5391: Races Redone 1.2 bodies don't show on the inventory
|
||||||
Bug #5397: NPC greeting does not reset if you leave + reenter area
|
Bug #5397: NPC greeting does not reset if you leave + reenter area
|
||||||
Bug #5400: Editor: Verifier checks race of non-skin bodyparts
|
Bug #5400: Editor: Verifier checks race of non-skin bodyparts
|
||||||
Bug #5403: Enchantment effect doesn't show on an enemy during death animation
|
Bug #5403: Enchantment effect doesn't show on an enemy during death animation
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <osg/Material>
|
#include <osg/Material>
|
||||||
#include <osg/Fog>
|
#include <osg/Fog>
|
||||||
#include <osg/BlendFunc>
|
#include <osg/BlendFunc>
|
||||||
|
#include <osg/TexEnvCombine>
|
||||||
#include <osg/Texture2D>
|
#include <osg/Texture2D>
|
||||||
#include <osg/Camera>
|
#include <osg/Camera>
|
||||||
#include <osg/PositionAttitudeTransform>
|
#include <osg/PositionAttitudeTransform>
|
||||||
|
@ -15,6 +16,8 @@
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/fallback/fallback.hpp>
|
#include <components/fallback/fallback.hpp>
|
||||||
|
#include <components/resource/scenemanager.hpp>
|
||||||
|
#include <components/resource/resourcesystem.hpp>
|
||||||
#include <components/sceneutil/lightmanager.hpp>
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
#include <components/sceneutil/shadow.hpp>
|
#include <components/sceneutil/shadow.hpp>
|
||||||
|
|
||||||
|
@ -85,7 +88,7 @@ namespace MWRender
|
||||||
class SetUpBlendVisitor : public osg::NodeVisitor
|
class SetUpBlendVisitor : public osg::NodeVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SetUpBlendVisitor(): osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
SetUpBlendVisitor(): osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), mNoAlphaUniform(new osg::Uniform("noAlpha", false))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,10 +105,17 @@ namespace MWRender
|
||||||
newStateSet->setAttribute(newBlendFunc, osg::StateAttribute::ON);
|
newStateSet->setAttribute(newBlendFunc, osg::StateAttribute::ON);
|
||||||
node.setStateSet(newStateSet);
|
node.setStateSet(newStateSet);
|
||||||
}
|
}
|
||||||
|
if (stateset->getMode(GL_BLEND) & osg::StateAttribute::ON)
|
||||||
|
{
|
||||||
|
// Disable noBlendAlphaEnv
|
||||||
|
stateset->setTextureMode(7, GL_TEXTURE_2D, osg::StateAttribute::OFF);
|
||||||
|
stateset->addUniform(mNoAlphaUniform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
traverse(node);
|
traverse(node);
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
osg::ref_ptr<osg::Uniform> mNoAlphaUniform;
|
||||||
};
|
};
|
||||||
|
|
||||||
CharacterPreview::CharacterPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem,
|
CharacterPreview::CharacterPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem,
|
||||||
|
@ -164,6 +174,20 @@ namespace MWRender
|
||||||
fog->setEnd(10000000);
|
fog->setEnd(10000000);
|
||||||
stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
|
stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
|
||||||
|
|
||||||
|
// Opaque stuff must have 1 as its fragment alpha as the FBO is translucent, so having blending off isn't enough
|
||||||
|
osg::ref_ptr<osg::TexEnvCombine> noBlendAlphaEnv = new osg::TexEnvCombine();
|
||||||
|
noBlendAlphaEnv->setCombine_Alpha(osg::TexEnvCombine::REPLACE);
|
||||||
|
noBlendAlphaEnv->setSource0_Alpha(osg::TexEnvCombine::CONSTANT);
|
||||||
|
noBlendAlphaEnv->setConstantColor(osg::Vec4(0.0, 0.0, 0.0, 1.0));
|
||||||
|
noBlendAlphaEnv->setCombine_RGB(osg::TexEnvCombine::REPLACE);
|
||||||
|
noBlendAlphaEnv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
|
||||||
|
osg::ref_ptr<osg::Texture2D> dummyTexture = new osg::Texture2D();
|
||||||
|
dummyTexture->setInternalFormat(GL_RED);
|
||||||
|
dummyTexture->setTextureSize(1, 1);
|
||||||
|
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;
|
osg::ref_ptr<osg::LightModel> lightmodel = new osg::LightModel;
|
||||||
lightmodel->setAmbientIntensity(osg::Vec4(0.0, 0.0, 0.0, 1.0));
|
lightmodel->setAmbientIntensity(osg::Vec4(0.0, 0.0, 0.0, 1.0));
|
||||||
stateset->setAttributeAndModes(lightmodel, osg::StateAttribute::ON);
|
stateset->setAttributeAndModes(lightmodel, osg::StateAttribute::ON);
|
||||||
|
@ -227,6 +251,7 @@ namespace MWRender
|
||||||
|
|
||||||
void CharacterPreview::setBlendMode()
|
void CharacterPreview::setBlendMode()
|
||||||
{
|
{
|
||||||
|
mResourceSystem->getSceneManager()->recreateShaders(mNode, "objects", true);
|
||||||
SetUpBlendVisitor visitor;
|
SetUpBlendVisitor visitor;
|
||||||
mNode->accept(visitor);
|
mNode->accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,9 +247,9 @@ namespace Resource
|
||||||
return mForceShaders;
|
return mForceShaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::recreateShaders(osg::ref_ptr<osg::Node> node, const std::string& shaderPrefix)
|
void SceneManager::recreateShaders(osg::ref_ptr<osg::Node> node, const std::string& shaderPrefix, bool translucentFramebuffer)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<Shader::ShaderVisitor> shaderVisitor(createShaderVisitor(shaderPrefix));
|
osg::ref_ptr<Shader::ShaderVisitor> shaderVisitor(createShaderVisitor(shaderPrefix, translucentFramebuffer));
|
||||||
shaderVisitor->setAllowedToModifyStateSets(false);
|
shaderVisitor->setAllowedToModifyStateSets(false);
|
||||||
node->accept(*shaderVisitor);
|
node->accept(*shaderVisitor);
|
||||||
}
|
}
|
||||||
|
@ -749,7 +749,7 @@ namespace Resource
|
||||||
stats->setAttribute(frameNumber, "Node Instance", mInstanceCache->getCacheSize());
|
stats->setAttribute(frameNumber, "Node Instance", mInstanceCache->getCacheSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader::ShaderVisitor *SceneManager::createShaderVisitor(const std::string& shaderPrefix)
|
Shader::ShaderVisitor *SceneManager::createShaderVisitor(const std::string& shaderPrefix, bool translucentFramebuffer)
|
||||||
{
|
{
|
||||||
Shader::ShaderVisitor* shaderVisitor = new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, shaderPrefix+"_vertex.glsl", shaderPrefix+"_fragment.glsl");
|
Shader::ShaderVisitor* shaderVisitor = new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, shaderPrefix+"_vertex.glsl", shaderPrefix+"_fragment.glsl");
|
||||||
shaderVisitor->setForceShaders(mForceShaders);
|
shaderVisitor->setForceShaders(mForceShaders);
|
||||||
|
@ -759,6 +759,7 @@ namespace Resource
|
||||||
shaderVisitor->setAutoUseSpecularMaps(mAutoUseSpecularMaps);
|
shaderVisitor->setAutoUseSpecularMaps(mAutoUseSpecularMaps);
|
||||||
shaderVisitor->setSpecularMapPattern(mSpecularMapPattern);
|
shaderVisitor->setSpecularMapPattern(mSpecularMapPattern);
|
||||||
shaderVisitor->setApplyLightingToEnvMaps(mApplyLightingToEnvMaps);
|
shaderVisitor->setApplyLightingToEnvMaps(mApplyLightingToEnvMaps);
|
||||||
|
shaderVisitor->setTranslucentFramebuffer(translucentFramebuffer);
|
||||||
return shaderVisitor;
|
return shaderVisitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace Resource
|
||||||
Shader::ShaderManager& getShaderManager();
|
Shader::ShaderManager& getShaderManager();
|
||||||
|
|
||||||
/// Re-create shaders for this node, need to call this if texture stages or vertex color mode have changed.
|
/// Re-create shaders for this node, need to call this if texture stages or vertex color mode have changed.
|
||||||
void recreateShaders(osg::ref_ptr<osg::Node> node, const std::string& shaderPrefix = "objects");
|
void recreateShaders(osg::ref_ptr<osg::Node> node, const std::string& shaderPrefix = "objects", bool translucentFramebuffer = false);
|
||||||
|
|
||||||
/// @see ShaderVisitor::setForceShaders
|
/// @see ShaderVisitor::setForceShaders
|
||||||
void setForceShaders(bool force);
|
void setForceShaders(bool force);
|
||||||
|
@ -173,7 +173,7 @@ namespace Resource
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Shader::ShaderVisitor* createShaderVisitor(const std::string& shaderPrefix = "objects");
|
Shader::ShaderVisitor* createShaderVisitor(const std::string& shaderPrefix = "objects", bool translucentFramebuffer = false);
|
||||||
|
|
||||||
std::unique_ptr<Shader::ShaderManager> mShaderManager;
|
std::unique_ptr<Shader::ShaderManager> mShaderManager;
|
||||||
bool mForceShaders;
|
bool mForceShaders;
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace Shader
|
||||||
, mAutoUseNormalMaps(false)
|
, mAutoUseNormalMaps(false)
|
||||||
, mAutoUseSpecularMaps(false)
|
, mAutoUseSpecularMaps(false)
|
||||||
, mApplyLightingToEnvMaps(false)
|
, mApplyLightingToEnvMaps(false)
|
||||||
|
, mTranslucentFramebuffer(false)
|
||||||
, mShaderManager(shaderManager)
|
, mShaderManager(shaderManager)
|
||||||
, mImageManager(imageManager)
|
, mImageManager(imageManager)
|
||||||
, mDefaultVsTemplate(defaultVsTemplate)
|
, mDefaultVsTemplate(defaultVsTemplate)
|
||||||
|
@ -146,7 +147,7 @@ namespace Shader
|
||||||
mRequirements.back().mShaderRequired = true;
|
mRequirements.back().mShaderRequired = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (!mTranslucentFramebuffer)
|
||||||
Log(Debug::Error) << "ShaderVisitor encountered unknown texture " << texture;
|
Log(Debug::Error) << "ShaderVisitor encountered unknown texture " << texture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,6 +323,8 @@ namespace Shader
|
||||||
|
|
||||||
writableStateSet->addUniform(new osg::Uniform("colorMode", reqs.mColorMode));
|
writableStateSet->addUniform(new osg::Uniform("colorMode", reqs.mColorMode));
|
||||||
|
|
||||||
|
defineMap["translucentFramebuffer"] = mTranslucentFramebuffer ? "1" : "0";
|
||||||
|
|
||||||
osg::ref_ptr<osg::Shader> vertexShader (mShaderManager.getShader(mDefaultVsTemplate, defineMap, osg::Shader::VERTEX));
|
osg::ref_ptr<osg::Shader> vertexShader (mShaderManager.getShader(mDefaultVsTemplate, defineMap, osg::Shader::VERTEX));
|
||||||
osg::ref_ptr<osg::Shader> fragmentShader (mShaderManager.getShader(mDefaultFsTemplate, defineMap, osg::Shader::FRAGMENT));
|
osg::ref_ptr<osg::Shader> fragmentShader (mShaderManager.getShader(mDefaultFsTemplate, defineMap, osg::Shader::FRAGMENT));
|
||||||
|
|
||||||
|
@ -474,4 +477,9 @@ namespace Shader
|
||||||
mApplyLightingToEnvMaps = apply;
|
mApplyLightingToEnvMaps = apply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderVisitor::setTranslucentFramebuffer(bool translucent)
|
||||||
|
{
|
||||||
|
mTranslucentFramebuffer = translucent;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ namespace Shader
|
||||||
|
|
||||||
void setApplyLightingToEnvMaps(bool apply);
|
void setApplyLightingToEnvMaps(bool apply);
|
||||||
|
|
||||||
|
void setTranslucentFramebuffer(bool translucent);
|
||||||
|
|
||||||
void apply(osg::Node& node) override;
|
void apply(osg::Node& node) override;
|
||||||
|
|
||||||
void apply(osg::Drawable& drawable) override;
|
void apply(osg::Drawable& drawable) override;
|
||||||
|
@ -63,6 +65,8 @@ namespace Shader
|
||||||
|
|
||||||
bool mApplyLightingToEnvMaps;
|
bool mApplyLightingToEnvMaps;
|
||||||
|
|
||||||
|
bool mTranslucentFramebuffer;
|
||||||
|
|
||||||
ShaderManager& mShaderManager;
|
ShaderManager& mShaderManager;
|
||||||
Resource::ImageManager& mImageManager;
|
Resource::ImageManager& mImageManager;
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ uniform mat2 bumpMapMatrix;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform bool simpleWater;
|
uniform bool simpleWater;
|
||||||
|
uniform bool noAlpha;
|
||||||
|
|
||||||
varying float euclideanDepth;
|
varying float euclideanDepth;
|
||||||
varying float linearDepth;
|
varying float linearDepth;
|
||||||
|
@ -208,5 +209,11 @@ void main()
|
||||||
#endif
|
#endif
|
||||||
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
|
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
|
||||||
|
|
||||||
|
#if @translucentFramebuffer
|
||||||
|
// 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
|
||||||
|
|
||||||
applyShadowDebugOverlay();
|
applyShadowDebugOverlay();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue