dont bind rendertargets unless we use them, otherwise texture limit will be reached quickly

openmw-fix_osx_build_maybe
glassmancody.info 3 years ago
parent 668be586cd
commit 3d03052717

@ -79,7 +79,7 @@ namespace MWLua
shader.mQueuedAction = true;
context.mLuaManager->addAction(
[&] { MWBase::Environment::get().getWorld()->getPostProcessor()->enableTechnique(shader.mShader, pos); },
[=] { MWBase::Environment::get().getWorld()->getPostProcessor()->enableTechnique(shader.mShader, pos); },
"Enable shader " + (shader.mShader ? shader.mShader->getName() : "nil")
);
};

@ -574,10 +574,11 @@ namespace MWRender
uniform->setUniform(node.mRootStateSet->getOrCreateUniform(uniform->mName, type.value()));
}
int subTexUnit = texUnit;
std::unordered_map<osg::Texture2D*, osg::Texture2D*> renderTargetCache;
for (const auto& pass : technique->getPasses())
{
int subTexUnit = texUnit;
fx::DispatchNode::SubPass subPass;
pass->prepareStateSet(subPass.mStateSet, technique->getName());
@ -591,6 +592,7 @@ namespace MWRender
const auto [w, h] = rt.mSize.get(mWidth, mHeight);
subPass.mRenderTexture = new osg::Texture2D(*rt.mTarget);
renderTargetCache[rt.mTarget] = subPass.mRenderTexture;
subPass.mRenderTexture->setTextureSize(w, h);
subPass.mRenderTexture->setName(std::string(pass->getTarget()));
@ -600,10 +602,18 @@ namespace MWRender
subPass.mRenderTarget = new osg::FrameBufferObject;
subPass.mRenderTarget->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, osg::FrameBufferAttachment(subPass.mRenderTexture));
subPass.mStateSet->setAttributeAndModes(new osg::Viewport(0, 0, w, h));
}
node.mRootStateSet->setTextureAttributeAndModes(subTexUnit, subPass.mRenderTexture);
node.mRootStateSet->addUniform(new osg::Uniform(subPass.mRenderTexture->getName().c_str(), subTexUnit++));
for (const auto& whitelist : pass->getRenderTargets())
{
auto it = technique->getRenderTargetsMap().find(whitelist);
if (it != technique->getRenderTargetsMap().end() && renderTargetCache[it->second.mTarget])
{
subPass.mStateSet->setTextureAttributeAndModes(subTexUnit, renderTargetCache[it->second.mTarget]);
subPass.mStateSet->addUniform(new osg::Uniform(std::string(it->first).c_str(), subTexUnit++));
}
}
node.mPasses.emplace_back(std::move(subPass));
}

@ -200,6 +200,9 @@ float omw_GetPointLightRadius(int index)
for (size_t pos = header.find(define); pos != std::string::npos; pos = header.find(define))
header.replace(pos, define.size(), value);
for (const auto& target : mRenderTargets)
header.append("uniform sampler2D " + std::string(target) + ";");
for (auto& uniform : technique.getUniformMap())
if (auto glsl = uniform->getGLSL())
header.append(glsl.value());

@ -43,7 +43,9 @@ namespace fx
void compile(Technique& technique, std::string_view preamble);
std::string_view getTarget() const { return mTarget; }
std::string getTarget() const { return mTarget; }
const std::array<std::string, 3>& getRenderTargets() const { return mRenderTargets; }
void prepareStateSet(osg::StateSet* stateSet, const std::string& name) const;
@ -67,7 +69,9 @@ namespace fx
bool mUBO;
bool mSupportsNormals;
std::string_view mTarget;
std::array<std::string, 3> mRenderTargets;
std::string mTarget;
std::optional<osg::Vec4f> mClearColor;
std::optional<osg::BlendFunc::BlendFuncMode> mBlendSource;

@ -822,6 +822,21 @@ namespace fx
expect<Lexer::Literal>();
pass->mTarget = std::get<Lexer::Literal>(mToken).value;
}
else if (key == "rt1")
{
expect<Lexer::Literal>();
pass->mRenderTargets[0] = std::get<Lexer::Literal>(mToken).value;
}
else if (key == "rt2")
{
expect<Lexer::Literal>();
pass->mRenderTargets[1] = std::get<Lexer::Literal>(mToken).value;
}
else if (key == "rt3")
{
expect<Lexer::Literal>();
pass->mRenderTargets[2] =std::get<Lexer::Literal>(mToken).value;
}
else if (key == "blend")
{
expect<Lexer::Open_Parenthesis>();

@ -500,7 +500,8 @@ is not wanted and you want a custom render target.
To use the render target you must assign passes to it, along with any optional clear modes or custom blend modes.
In the code snippet below a rendertarget is used to draw the red cannel of a scene at half resolution.
In the code snippet below a rendertarget is used to draw the red cannel of a scene at half resolution, then a quarter. As a restriction,
only three render targets can be bound per pass with ``rt1``, ``rt2``, ``rt3``, respectively.
.. code-block:: none
@ -512,6 +513,11 @@ In the code snippet below a rendertarget is used to draw the red cannel of a sce
source_format = red;
}
render_target RT_Downsample4 {
width_ratio = 0.25;
height_ratio = 0.25;
}
fragment downsample2x(target=RT_Downsample) {
omw_In vec2 omw_TexCoord;
@ -522,6 +528,16 @@ In the code snippet below a rendertarget is used to draw the red cannel of a sce
}
}
fragment downsample4x(target=RT_Downsample4, rt1=RT_Downsample) {
omw_In vec2 omw_TexCoord;
void main()
{
omw_FragColor = omw_Texture2D(RT_Downsample, omw_TexCoord);
}
}
Now, if we ever run the `downsample2x` pass it will write to the target buffer instead of the default
one assigned by the engine.

Loading…
Cancel
Save