diff --git a/apps/openmw/mwrender/luminancecalculator.cpp b/apps/openmw/mwrender/luminancecalculator.cpp index 6655ae4d8f..a881b8818f 100644 --- a/apps/openmw/mwrender/luminancecalculator.cpp +++ b/apps/openmw/mwrender/luminancecalculator.cpp @@ -1,5 +1,6 @@ #include "luminancecalculator.hpp" +#include #include #include @@ -80,6 +81,7 @@ namespace MWRender buffer.sceneLumSS = new osg::StateSet; buffer.sceneLumSS->setAttributeAndModes(mLuminanceProgram); buffer.sceneLumSS->addUniform(new osg::Uniform("sceneTex", 0)); + buffer.sceneLumSS->addUniform(new osg::Uniform("scaling", mScale)); buffer.resolveSS = new osg::StateSet; buffer.resolveSS->setAttributeAndModes(mResolveProgram); @@ -108,6 +110,7 @@ namespace MWRender auto& buffer = mBuffers[frameId]; buffer.sceneLumFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); buffer.sceneLumSS->setTextureAttributeAndModes(0, canvas.getSceneTexture(frameId)); + buffer.sceneLumSS->getUniform("scaling")->set(mScale); state.apply(buffer.sceneLumSS); canvas.drawGeometry(renderInfo); @@ -140,4 +143,16 @@ namespace MWRender { return mBuffers[frameId].luminanceTex; } + + void LuminanceCalculator::dirty(int w, int h) + { + constexpr int minSize = 64; + + mWidth = std::max(minSize, Misc::nextPowerOfTwo(w) / 2); + mHeight = std::max(minSize, Misc::nextPowerOfTwo(h) / 2); + + mScale = osg::Vec2f(w / static_cast(mWidth), h / static_cast(mHeight)); + + mCompiled = false; + } } \ No newline at end of file diff --git a/apps/openmw/mwrender/luminancecalculator.hpp b/apps/openmw/mwrender/luminancecalculator.hpp index db823dd900..71ea2f7971 100644 --- a/apps/openmw/mwrender/luminancecalculator.hpp +++ b/apps/openmw/mwrender/luminancecalculator.hpp @@ -32,13 +32,7 @@ namespace MWRender void enable() { mEnabled = true; } void disable() { mEnabled = false; } - void dirty(int w, int h) - { - constexpr float scale = 0.5; - mWidth = w * scale; - mHeight = h * scale; - mCompiled = false; - } + void dirty(int w, int h); osg::ref_ptr getLuminanceTexture(size_t frameId) const; @@ -67,6 +61,7 @@ namespace MWRender int mWidth = 1; int mHeight = 1; + osg::Vec2f mScale = osg::Vec2f(1, 1); }; } diff --git a/apps/openmw/mwrender/pingpongcanvas.cpp b/apps/openmw/mwrender/pingpongcanvas.cpp index da1997b5fb..f05cefb8f3 100644 --- a/apps/openmw/mwrender/pingpongcanvas.cpp +++ b/apps/openmw/mwrender/pingpongcanvas.cpp @@ -38,6 +38,7 @@ namespace MWRender mFallbackStateSet->setAttributeAndModes(mFallbackProgram); mFallbackStateSet->addUniform(new osg::Uniform("omw_SamplerLastShader", 0)); + mFallbackStateSet->addUniform(new osg::Uniform("scaling", osg::Vec2f(1, 1))); auto multiviewResolveVertex = shaderManager.getShader("multiview_resolve_vertex.glsl", {}, osg::Shader::VERTEX); auto multiviewResolveFragment diff --git a/components/misc/mathutil.hpp b/components/misc/mathutil.hpp index cc333dec3c..7c29352f44 100644 --- a/components/misc/mathutil.hpp +++ b/components/misc/mathutil.hpp @@ -22,6 +22,23 @@ namespace Misc return osg::Vec2f(vec.x() * c + vec.y() * -s, vec.x() * s + vec.y() * c); } + inline bool isPowerOfTwo(int x) + { + return ((x > 0) && ((x & (x - 1)) == 0)); + } + + inline int nextPowerOfTwo(int v) + { + if (isPowerOfTwo(v)) + return v; + int depth = 0; + while (v) + { + v >>= 1; + depth++; + } + return 1 << depth; + } } #endif diff --git a/components/terrain/quadtreeworld.cpp b/components/terrain/quadtreeworld.cpp index e66d32a0c8..7b3a73f8bc 100644 --- a/components/terrain/quadtreeworld.cpp +++ b/components/terrain/quadtreeworld.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -22,25 +23,6 @@ namespace { - - bool isPowerOfTwo(int x) - { - return ((x > 0) && ((x & (x - 1)) == 0)); - } - - int nextPowerOfTwo(int v) - { - if (isPowerOfTwo(v)) - return v; - int depth = 0; - while (v) - { - v >>= 1; - depth++; - } - return 1 << depth; - } - unsigned int Log2(unsigned int n) { unsigned int targetlevel = 0; @@ -153,7 +135,7 @@ namespace Terrain int origSizeY = static_cast(mMaxY - mMinY); // Dividing a quad tree only works well for powers of two, so round up to the nearest one - int size = nextPowerOfTwo(std::max(origSizeX, origSizeY)); + int size = Misc::nextPowerOfTwo(std::max(origSizeX, origSizeY)); float centerX = (mMinX + mMaxX) / 2.f + (size - origSizeX) / 2.f; float centerY = (mMinY + mMaxY) / 2.f + (size - origSizeY) / 2.f; diff --git a/files/shaders/fullscreen_tri_vertex.glsl b/files/shaders/fullscreen_tri_vertex.glsl index 1166a44a54..ab394190a8 100644 --- a/files/shaders/fullscreen_tri_vertex.glsl +++ b/files/shaders/fullscreen_tri_vertex.glsl @@ -1,5 +1,7 @@ #version 120 +uniform vec2 scaling = vec2(1.0, 1.0); + varying vec2 uv; #include "openmw_vertex.h.glsl" @@ -7,5 +9,5 @@ varying vec2 uv; void main() { gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0); - uv = gl_Position.xy * 0.5 + 0.5; + uv = (gl_Position.xy * 0.5 + 0.5) * scaling; }