Merge branch 'rippleshaders' into 'master'
Some checks failed
Build and test / Ubuntu (push) Has been cancelled
Build and test / MacOS (push) Has been cancelled
Build and test / Read .env file and expose it as output (push) Has been cancelled
Build and test / Windows (2019) (push) Has been cancelled
Build and test / Windows (2022) (push) Has been cancelled

Fix crash if ripple pipeline shaders are unavailable

See merge request OpenMW/openmw!4622
This commit is contained in:
psi29a 2025-04-17 09:26:12 +00:00
commit 87d77a6882

View file

@ -49,18 +49,6 @@ namespace MWRender
&& exts.glslLanguageVersion >= minimumGLVersionRequiredForCompute; && exts.glslLanguageVersion >= minimumGLVersionRequiredForCompute;
#endif #endif
static bool pipelineLogged = false;
if (!pipelineLogged)
{
if (mUseCompute)
Log(Debug::Info) << "Initialized compute shader pipeline for water ripples";
else
Log(Debug::Info) << "Initialized fallback fragment shader pipeline for water ripples";
pipelineLogged = true;
}
for (size_t i = 0; i < mState.size(); ++i) for (size_t i = 0; i < mState.size(); ++i)
{ {
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet; osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
@ -98,6 +86,18 @@ namespace MWRender
else else
setupFragmentPipeline(); setupFragmentPipeline();
if (mProgramBlobber != nullptr)
{
static bool pipelineLogged = [&] {
if (mUseCompute)
Log(Debug::Info) << "Initialized compute shader pipeline for water ripples";
else
Log(Debug::Info) << "Initialized fallback fragment shader pipeline for water ripples";
return true;
}();
(void)pipelineLogged;
}
setCullCallback(new osg::NodeCallback); setCullCallback(new osg::NodeCallback);
setUpdateCallback(new osg::NodeCallback); setUpdateCallback(new osg::NodeCallback);
} }
@ -109,21 +109,36 @@ namespace MWRender
Shader::ShaderManager::DefineMap defineMap = { { "rippleMapSize", std::to_string(sRTTSize) + ".0" } }; Shader::ShaderManager::DefineMap defineMap = { { "rippleMapSize", std::to_string(sRTTSize) + ".0" } };
osg::ref_ptr<osg::Shader> vertex = shaderManager.getShader("fullscreen_tri.vert", {}, osg::Shader::VERTEX); osg::ref_ptr<osg::Shader> vertex = shaderManager.getShader("fullscreen_tri.vert", {}, osg::Shader::VERTEX);
osg::ref_ptr<osg::Shader> blobber
= shaderManager.getShader("ripples_blobber.frag", defineMap, osg::Shader::FRAGMENT);
osg::ref_ptr<osg::Shader> simulate
= shaderManager.getShader("ripples_simulate.frag", defineMap, osg::Shader::FRAGMENT);
if (vertex == nullptr || blobber == nullptr || simulate == nullptr)
{
Log(Debug::Error) << "Failed to load shaders required for fragment shader ripple pipeline";
return;
}
mProgramBlobber = shaderManager.getProgram( mProgramBlobber = shaderManager.getProgram(vertex, std::move(blobber));
vertex, shaderManager.getShader("ripples_blobber.frag", defineMap, osg::Shader::FRAGMENT)); mProgramSimulation = shaderManager.getProgram(std::move(vertex), std::move(simulate));
mProgramSimulation = shaderManager.getProgram(
std::move(vertex), shaderManager.getShader("ripples_simulate.frag", defineMap, osg::Shader::FRAGMENT));
} }
void RipplesSurface::setupComputePipeline() void RipplesSurface::setupComputePipeline()
{ {
auto& shaderManager = mResourceSystem->getSceneManager()->getShaderManager(); auto& shaderManager = mResourceSystem->getSceneManager()->getShaderManager();
mProgramBlobber = shaderManager.getProgram( osg::ref_ptr<osg::Shader> blobber
nullptr, shaderManager.getShader("core/ripples_blobber.comp", {}, osg::Shader::COMPUTE)); = shaderManager.getShader("core/ripples_blobber.comp", {}, osg::Shader::COMPUTE);
mProgramSimulation = shaderManager.getProgram( osg::ref_ptr<osg::Shader> simulate
nullptr, shaderManager.getShader("core/ripples_simulate.comp", {}, osg::Shader::COMPUTE)); = shaderManager.getShader("core/ripples_simulate.comp", {}, osg::Shader::COMPUTE);
if (blobber == nullptr || simulate == nullptr)
{
Log(Debug::Error) << "Failed to load shaders required for compute shader ripple pipeline";
return;
}
mProgramBlobber = shaderManager.getProgram(nullptr, std::move(blobber));
mProgramSimulation = shaderManager.getProgram(nullptr, std::move(simulate));
} }
void RipplesSurface::updateState(const osg::FrameStamp& frameStamp, State& state) void RipplesSurface::updateState(const osg::FrameStamp& frameStamp, State& state)
@ -191,6 +206,9 @@ namespace MWRender
void RipplesSurface::drawImplementation(osg::RenderInfo& renderInfo) const void RipplesSurface::drawImplementation(osg::RenderInfo& renderInfo) const
{ {
if (mProgramBlobber == nullptr || mProgramSimulation == nullptr)
return;
osg::State& state = *renderInfo.getState(); osg::State& state = *renderInfo.getState();
const std::size_t currentFrame = state.getFrameStamp()->getFrameNumber() % 2; const std::size_t currentFrame = state.getFrameStamp()->getFrameNumber() % 2;
const State& frameState = mState[currentFrame]; const State& frameState = mState[currentFrame];