From 7db8d0f00ab3f5bcd9c89733438f4f20ffbf3fe7 Mon Sep 17 00:00:00 2001 From: LRFLEW Date: Tue, 24 Oct 2017 20:17:40 -0500 Subject: [PATCH] OpenGL: Fix linear DPI scaling --- src/openrct2-ui/UiContext.cpp | 12 ++++++-- .../engines/opengl/OpenGLDrawingEngine.cpp | 30 ++++++++++++++++--- .../engines/opengl/OpenGLFramebuffer.cpp | 22 ++++++++++++-- .../engines/opengl/OpenGLFramebuffer.h | 3 +- src/openrct2/ui/DummyUiContext.cpp | 1 + src/openrct2/ui/UiContext.h | 1 + 6 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp index 8780602343..595045870b 100644 --- a/src/openrct2-ui/UiContext.cpp +++ b/src/openrct2-ui/UiContext.cpp @@ -69,6 +69,7 @@ private: SDL_Window * _window = nullptr; sint32 _width = 0; sint32 _height = 0; + sint32 _scaleQuality = 0; bool _resolutionsAllowAnyAspectRatio = false; std::vector _fsResolutions; @@ -124,6 +125,11 @@ public: return _height; } + sint32 GetScaleQuality() override + { + return _scaleQuality; + } + void SetFullscreenMode(FULLSCREEN_MODE mode) override { static const sint32 SDLFSFlags[] = { 0, SDL_WINDOW_FULLSCREEN, SDL_WINDOW_FULLSCREEN_DESKTOP }; @@ -485,13 +491,13 @@ public: void TriggerResize() override { char scaleQualityBuffer[4]; - uint8 scaleQuality = gConfigGeneral.scale_quality; + _scaleQuality = gConfigGeneral.scale_quality; if (gConfigGeneral.use_nn_at_integer_scales && gConfigGeneral.window_scale == std::floor(gConfigGeneral.window_scale)) { - scaleQuality = 0; + _scaleQuality = 0; } - snprintf(scaleQualityBuffer, sizeof(scaleQualityBuffer), "%u", scaleQuality); + snprintf(scaleQualityBuffer, sizeof(scaleQualityBuffer), "%u", _scaleQuality); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, scaleQualityBuffer); sint32 width, height; diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 7ba4b15f3c..de60d2bbfc 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -144,6 +144,7 @@ private: CopyFramebufferShader * _copyFramebufferShader = nullptr; OpenGLFramebuffer * _screenFramebuffer = nullptr; + OpenGLFramebuffer * _scaleFramebuffer = nullptr; public: SDL_Color Palette[256]; @@ -245,13 +246,26 @@ public: { _drawingContext->FlushCommandBuffers(); - // Scale up to window glDisable(GL_DEPTH_TEST); - _screenFramebuffer->Bind(); + if (_scaleFramebuffer != nullptr) + { + // Render to intermediary RGB buffer for GL_LINEAR + _scaleFramebuffer->Bind(); + } + else + { + _screenFramebuffer->Bind(); + } + _copyFramebufferShader->Use(); _copyFramebufferShader->SetTexture(_drawingContext->GetFinalFramebuffer().GetTexture()); _copyFramebufferShader->Draw(); + if (_scaleFramebuffer != nullptr) + { + _screenFramebuffer->Copy(*_scaleFramebuffer, GL_LINEAR); + } + CheckGLError(); Display(); } @@ -379,6 +393,15 @@ private: delete _screenFramebuffer; _screenFramebuffer = new OpenGLFramebuffer(_window); + if (_scaleFramebuffer != nullptr) + { + delete _scaleFramebuffer; + _scaleFramebuffer = nullptr; + } + if (GetContext()->GetUiContext()->GetScaleQuality() > 0) + { + _scaleFramebuffer = new OpenGLFramebuffer(_width, _height, false, false); + } } void Display() @@ -998,8 +1021,7 @@ sint32 OpenGLDrawingContext::MaxTransparencyDepth() if (top_it->second.count == 1) { auto top_next = std::next(top_it); - assert(top_next == y_intersect.end() ? - top_it->second.depth == 0 : + assert(top_next != y_intersect.end() && top_it->second.depth == top_next->second.depth - 1); } diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp index d8ea63c452..f75731a462 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp @@ -31,14 +31,21 @@ OpenGLFramebuffer::OpenGLFramebuffer(SDL_Window * window) SDL_GetWindowSize(window, &_width, &_height); } -OpenGLFramebuffer::OpenGLFramebuffer(sint32 width, sint32 height, bool depth) +OpenGLFramebuffer::OpenGLFramebuffer(sint32 width, sint32 height, bool depth, bool integer) { _width = width; _height = height; glGenTextures(1, &_texture); glBindTexture(GL_TEXTURE_2D, _texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr); + if (integer) + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr); + } + else + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -125,6 +132,17 @@ GLuint OpenGLFramebuffer::SwapDepthTexture(GLuint depth) return depth; } +void OpenGLFramebuffer::Copy(OpenGLFramebuffer &src, GLenum filter) +{ + BindDraw(); + src.BindRead(); + glBlitFramebuffer( + 0, 0, src.GetWidth(), src.GetHeight(), + 0, 0, _width, _height, GL_COLOR_BUFFER_BIT, filter + ); + Bind(); +} + GLuint OpenGLFramebuffer::CreateDepthTexture(sint32 width, sint32 height) { GLuint depth; diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h index 6bf4d18bb2..c81e59c71f 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h @@ -35,7 +35,7 @@ private: public: explicit OpenGLFramebuffer(SDL_Window * window); - OpenGLFramebuffer(sint32 width, sint32 height, bool depth = true); + OpenGLFramebuffer(sint32 width, sint32 height, bool depth = true, bool integer = true); ~OpenGLFramebuffer(); OpenGLFramebuffer(const OpenGLFramebuffer &) = delete; @@ -53,6 +53,7 @@ public: void SwapColourBuffer(OpenGLFramebuffer &other); GLuint SwapDepthTexture(GLuint depth); + void Copy(OpenGLFramebuffer &src, GLenum filter); static GLuint CreateDepthTexture(sint32 width, sint32 height); }; diff --git a/src/openrct2/ui/DummyUiContext.cpp b/src/openrct2/ui/DummyUiContext.cpp index 952b91b268..53ded40df2 100644 --- a/src/openrct2/ui/DummyUiContext.cpp +++ b/src/openrct2/ui/DummyUiContext.cpp @@ -37,6 +37,7 @@ namespace OpenRCT2 { namespace Ui void * GetWindow() override { return nullptr; } sint32 GetWidth() override { return 0; } sint32 GetHeight() override { return 0; } + sint32 GetScaleQuality() override { return 0; } void SetFullscreenMode(FULLSCREEN_MODE mode) override { } std::vector GetFullscreenResolutions() override { return std::vector(); } bool HasFocus() override { return false; } diff --git a/src/openrct2/ui/UiContext.h b/src/openrct2/ui/UiContext.h index ffcd6648fe..6169a66812 100644 --- a/src/openrct2/ui/UiContext.h +++ b/src/openrct2/ui/UiContext.h @@ -100,6 +100,7 @@ namespace OpenRCT2 virtual void * GetWindow() abstract; virtual sint32 GetWidth() abstract; virtual sint32 GetHeight() abstract; + virtual sint32 GetScaleQuality() abstract; virtual void SetFullscreenMode(FULLSCREEN_MODE mode) abstract; virtual std::vector GetFullscreenResolutions() abstract; virtual bool HasFocus() abstract;