From f105237a2efe64f89b030699837108a53c7fd46e Mon Sep 17 00:00:00 2001 From: LRFLEW Date: Sat, 23 Sep 2017 21:51:40 -0500 Subject: [PATCH] OpenGL: Delay Palette Mapping Until Final Framebuffer Copy to Screen --- data/shaders/copyframebuffer.frag | 5 +- data/shaders/drawimage.frag | 36 +++++++++------ data/shaders/drawimage.vert | 5 +- data/shaders/drawline.frag | 5 +- data/shaders/fillrect.frag | 26 +++-------- .../engines/opengl/CopyFramebufferShader.cpp | 5 ++ .../engines/opengl/CopyFramebufferShader.h | 2 + .../drawing/engines/opengl/DrawCommands.h | 6 +-- .../engines/opengl/DrawImageShader.cpp | 8 +--- .../drawing/engines/opengl/DrawImageShader.h | 2 - .../drawing/engines/opengl/DrawLineShader.cpp | 4 +- .../drawing/engines/opengl/DrawLineShader.h | 2 +- .../drawing/engines/opengl/FillRectShader.cpp | 13 ++---- .../drawing/engines/opengl/FillRectShader.h | 4 +- .../drawing/engines/opengl/OpenGLAPIProc.h | 3 ++ .../engines/opengl/OpenGLDrawingEngine.cpp | 32 +++++-------- .../engines/opengl/OpenGLFramebuffer.cpp | 40 +++++++++------- .../engines/opengl/OpenGLFramebuffer.h | 7 ++- .../engines/opengl/SwapFramebuffer.cpp | 46 ++++++------------- .../drawing/engines/opengl/SwapFramebuffer.h | 15 ++---- .../drawing/engines/opengl/TextureCache.cpp | 6 ++- src/openrct2/drawing/NewDrawing.cpp | 7 +-- 22 files changed, 124 insertions(+), 155 deletions(-) diff --git a/data/shaders/copyframebuffer.frag b/data/shaders/copyframebuffer.frag index 25e4b83e08..10349cfe13 100644 --- a/data/shaders/copyframebuffer.frag +++ b/data/shaders/copyframebuffer.frag @@ -1,6 +1,7 @@ #version 150 -uniform sampler2D uTexture; +uniform vec4 uPalette[256]; +uniform usampler2D uTexture; in vec2 fPosition; in vec2 fTextureCoordinate; @@ -9,5 +10,5 @@ out vec4 oColour; void main() { - oColour = texture(uTexture, fTextureCoordinate); + oColour = uPalette[texture(uTexture, fTextureCoordinate).r]; } diff --git a/data/shaders/drawimage.frag b/data/shaders/drawimage.frag index 1a9c1c9f8c..6f60b23505 100644 --- a/data/shaders/drawimage.frag +++ b/data/shaders/drawimage.frag @@ -5,12 +5,11 @@ const int FLAG_REMAP = (1 << 1); const int FLAG_TRANSPARENT = (1 << 2); const int FLAG_TRANSPARENT_SPECIAL = (1 << 3); -uniform vec4 uPalette[256]; uniform usampler2DArray uTexture; flat in ivec4 fClip; flat in int fFlags; -in vec4 fColour; +flat in uint fColour; flat in int fTexColourAtlas; in vec2 fTexColourCoords; flat in int fTexMaskAtlas; @@ -20,9 +19,8 @@ flat in vec4 fTexPaletteBounds; flat in int fMask; in vec2 fPosition; -in vec2 fTextureCoordinate; -out vec4 oColour; +out uint oColour; void main() { @@ -32,43 +30,46 @@ void main() discard; } - vec4 texel; + uint texel; // If remap palette used if ((fFlags & FLAG_REMAP) != 0) { // z is the size of each x pixel in the atlas float x = fTexPaletteBounds.x + texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r * fTexPaletteBounds.z; - texel = uPalette[texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r]; + texel = texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r; } // If transparent or special transparent else if ((fFlags & (FLAG_TRANSPARENT | FLAG_TRANSPARENT_SPECIAL)) != 0) { - float line = texture(uTexture,vec3(fTexColourCoords, float(fTexColourAtlas))).r; - if (line == 0.0) + uint line = texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r; + if (line == 0u) { discard; } + /* float alpha = 0.5; if ((fFlags & FLAG_TRANSPARENT_SPECIAL) != 0) { alpha = 0.5 + (line - 1.0) / 10.0; } - + */ + // z is the size of each x pixel in the atlas float x = fTexPaletteBounds.x + fTexPaletteBounds.z * 50.0; - oColour = vec4(uPalette[texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r].rgb, alpha); - + //oColour = vec4(uPalette[texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r].rgb, alpha); + oColour = texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r; + return; } else { - texel = uPalette[texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r]; + texel = texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r; } if (fMask != 0) { - float mask = texture(uTexture, vec3(fTexMaskCoords, float(fTexMaskAtlas))).r; - if ( mask == 0.0 ) + uint mask = texture(uTexture, vec3(fTexMaskCoords, float(fTexMaskAtlas))).r; + if ( mask == 0u ) { discard; } @@ -77,9 +78,14 @@ void main() } else { + if (texel == 0u) + { + discard; + } if ((fFlags & FLAG_COLOUR) != 0) { - oColour = vec4(fColour.rgb, fColour.a * texel.a); + //oColour = vec4(fColour.rgb, fColour.a * texel.a); + oColour = fColour; } else { diff --git a/data/shaders/drawimage.vert b/data/shaders/drawimage.vert index 4a2b56b59f..ca95726301 100644 --- a/data/shaders/drawimage.vert +++ b/data/shaders/drawimage.vert @@ -10,17 +10,16 @@ in vec4 ivTexMaskBounds; in int ivTexPaletteAtlas; in vec4 ivTexPaletteBounds; in int ivFlags; -in vec4 ivColour; +in uint ivColour; in ivec4 ivBounds; in int ivMask; in uint vIndex; -out vec2 fTextureCoordinate; out vec2 fPosition; flat out ivec4 fClip; flat out int fFlags; -out vec4 fColour; +flat out uint fColour; flat out int fTexColourAtlas; out vec2 fTexColourCoords; flat out int fTexMaskAtlas; diff --git a/data/shaders/drawline.frag b/data/shaders/drawline.frag index 0ca4a0b9c6..6674d9c11e 100644 --- a/data/shaders/drawline.frag +++ b/data/shaders/drawline.frag @@ -1,12 +1,11 @@ #version 150 -uniform ivec2 uScreenSize; uniform ivec4 uClip; -uniform vec4 uColour; +uniform uint uColour; in vec2 fPosition; -out vec4 oColour; +out uint oColour; void main() { diff --git a/data/shaders/fillrect.frag b/data/shaders/fillrect.frag index fb824c05ee..0692628b46 100644 --- a/data/shaders/fillrect.frag +++ b/data/shaders/fillrect.frag @@ -3,14 +3,12 @@ uniform ivec2 uScreenSize; uniform ivec4 uClip; uniform int uFlags; -uniform sampler2D uSourceFramebuffer; -uniform ivec4 uBounds; -uniform vec4 uPalette[256]; -uniform int uPaletteRemap[256]; +uniform usampler2D uSourceFramebuffer; +uniform uint uPaletteRemap[256]; in vec2 fPosition; -out vec4 oColour; +out uint oColour; void main() { @@ -29,19 +27,7 @@ void main() } } - vec2 textureCoordinates = (fPosition / vec2(uScreenSize)) * vec2(1, -1); - vec4 sourceColour = texture(uSourceFramebuffer, textureCoordinates); - - // find "best match" palette index of the current 32 bit color - float nearestDistance = length(uPalette[0] - sourceColour); - uint bestPaletteIndexMatch = 0u; - for (uint i = 1u; i < 256u; i++) - { - float distance = length(uPalette[i] - sourceColour); - uint isBetter = -uint(distance < nearestDistance); // unpredictable - bestPaletteIndexMatch = (bestPaletteIndexMatch & ~isBetter) | (i & isBetter); - nearestDistance = min(nearestDistance, distance); - } - - oColour = uPalette[uPaletteRemap[bestPaletteIndexMatch]]; + vec2 textureCoordinates = (fPosition / vec2(uScreenSize)) * vec2(1.0, -1.0) + vec2(0.0, 1.0); + uint sourceColour = texture(uSourceFramebuffer, textureCoordinates).r; + oColour = uPaletteRemap[sourceColour]; } diff --git a/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.cpp b/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.cpp index 8148283d02..333302ea90 100644 --- a/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.cpp @@ -50,6 +50,7 @@ void CopyFramebufferShader::GetLocations() uBounds = GetUniformLocation("uBounds"); uTextureCoordinates = GetUniformLocation("uTextureCoordinates"); uTexture = GetUniformLocation("uTexture"); + uPalette = GetUniformLocation("uPalette"); vIndex = GetAttributeLocation("vIndex"); } @@ -74,6 +75,10 @@ void CopyFramebufferShader::SetTexture(GLuint texture) OpenGLAPI::SetTexture(0, GL_TEXTURE_2D, texture); } +void CopyFramebufferShader::SetPalette(const vec4f * glPalette) { + glUniform4fv(uPalette, 256, (const GLfloat *)glPalette); +} + void CopyFramebufferShader::Draw() { glBindVertexArray(_vao); diff --git a/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.h b/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.h index 54bc51f1ac..ab7f58d020 100644 --- a/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.h @@ -26,6 +26,7 @@ private: GLuint uBounds; GLuint uTextureCoordinates; GLuint uTexture; + GLuint uPalette; GLuint vIndex; @@ -40,6 +41,7 @@ public: void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetTexture(GLuint texture); + void SetPalette(const vec4f * glPalette); void Draw(); diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h b/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h index 4108ff4f6e..6fc3b5260f 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h +++ b/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h @@ -69,11 +69,11 @@ struct DrawRectCommand { GLuint sourceFramebuffer; sint32 clip[4]; sint32 bounds[4]; - GLint paletteRemap[256]; + GLuint paletteRemap[256]; }; struct DrawLineCommand { - vec4f colour; + uint8 colour; sint32 clip[4]; sint32 pos[4]; }; @@ -88,7 +88,7 @@ struct DrawImageCommand { sint32 texPaletteAtlas; vec4f texPaletteBounds; sint32 flags; - vec4f colour; + uint8 colour; vec4i bounds; sint32 mask; diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.cpp b/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.cpp index 5b7277c9c4..534fc675f3 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.cpp @@ -43,7 +43,7 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage") glVertexAttribIPointer(vTexPaletteAtlas, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texPaletteAtlas)); glVertexAttribPointer(vTexPaletteBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texPaletteBounds)); glVertexAttribIPointer(vFlags, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, flags)); - glVertexAttribPointer(vColour, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, colour)); + glVertexAttribIPointer(vColour, 1, GL_UNSIGNED_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, colour)); glVertexAttribIPointer(vBounds, 4, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, bounds)); glVertexAttribIPointer(vMask, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, mask)); @@ -87,7 +87,6 @@ void DrawImageShader::GetLocations() { uScreenSize = GetUniformLocation("uScreenSize"); uTexture = GetUniformLocation("uTexture"); - uPalette = GetUniformLocation("uPalette"); vIndex = GetAttributeLocation("vIndex"); vClip = GetAttributeLocation("ivClip"); @@ -108,11 +107,6 @@ void DrawImageShader::SetScreenSize(sint32 width, sint32 height) glUniform2i(uScreenSize, width, height); } -void DrawImageShader::SetPalette(const vec4f *glPalette) -{ - glUniform4fv(uPalette, 256, (const GLfloat *) glPalette); -} - void DrawImageShader::DrawInstances(const ImageCommandBatch& instances) { glBindVertexArray(_vao); diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.h b/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.h index 23c26bbc45..578c13eac6 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.h @@ -27,7 +27,6 @@ class DrawImageShader final : public OpenGLShaderProgram private: GLuint uScreenSize; GLuint uTexture; - GLuint uPalette; GLuint vIndex; GLuint vClip; @@ -51,7 +50,6 @@ public: ~DrawImageShader() override; void SetScreenSize(sint32 width, sint32 height); - void SetPalette(const vec4f *glPalette); void DrawInstances(const ImageCommandBatch& instances); private: diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp index 8e3747b3d2..5ef399b498 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp @@ -68,9 +68,9 @@ void DrawLineShader::SetBounds(sint32 x0, sint32 y0, sint32 x1, sint32 y1) glUniform4i(uBounds, x0, y0, x1, y1); } -void DrawLineShader::SetColour(vec4f colour) +void DrawLineShader::SetColour(uint8 colour) { - glUniform4f(uColour, colour.r, colour.g, colour.b, colour.a); + glUniform1ui(uColour, colour); } void DrawLineShader::Draw(sint32 x0, sint32 y0, sint32 x1, sint32 y1) diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h index d2b69d761c..d559da4ef5 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h @@ -39,7 +39,7 @@ public: void SetScreenSize(sint32 width, sint32 height); void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetBounds(sint32 x0, sint32 y0, sint32 x1, sint32 y1); - void SetColour(vec4f colour); + void SetColour(uint8 colour); void Draw(sint32 x0, sint32 y0, sint32 x1, sint32 y1); diff --git a/src/openrct2-ui/drawing/engines/opengl/FillRectShader.cpp b/src/openrct2-ui/drawing/engines/opengl/FillRectShader.cpp index 65daf06f42..7b8931bc64 100644 --- a/src/openrct2-ui/drawing/engines/opengl/FillRectShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/FillRectShader.cpp @@ -52,7 +52,6 @@ void FillRectShader::GetLocations() uBounds = GetUniformLocation("uBounds"); uFlags = GetUniformLocation("uFlags"); uSourceFramebuffer = GetUniformLocation("uSourceFramebuffer"); - uPalette = GetUniformLocation("uPalette"); uPaletteRemap = GetUniformLocation("uPaletteRemap"); vIndex = GetAttributeLocation("vIndex"); @@ -84,14 +83,9 @@ void FillRectShader::SetSourceFramebuffer(GLuint texture) OpenGLAPI::SetTexture(0, GL_TEXTURE_2D, texture); } -void FillRectShader::SetPalette(const vec4f * glPalette) +void FillRectShader::SetPaletteRemap(const GLuint * paletteRemap) { - glUniform4fv(uPalette, 256, (const GLfloat *)glPalette); -} - -void FillRectShader::SetPaletteRemap(const GLint * paletteRemap) -{ - glUniform1iv(uPaletteRemap, 256, paletteRemap); + glUniform1uiv(uPaletteRemap, 256, paletteRemap); } void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) @@ -102,7 +96,8 @@ void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) glDrawArrays(GL_TRIANGLES, 0, 6); } -GLuint FillRectShader::GetSourceFramebuffer() const { +GLuint FillRectShader::GetSourceFramebuffer() const +{ return _sourceFramebuffer; } diff --git a/src/openrct2-ui/drawing/engines/opengl/FillRectShader.h b/src/openrct2-ui/drawing/engines/opengl/FillRectShader.h index 4ab9f6841e..eda0794c53 100644 --- a/src/openrct2-ui/drawing/engines/opengl/FillRectShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/FillRectShader.h @@ -29,7 +29,6 @@ private: GLuint uBounds; GLuint uFlags; GLuint uSourceFramebuffer; - GLuint uPalette; GLuint uPaletteRemap; GLuint vIndex; @@ -48,8 +47,7 @@ public: void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetFlags(uint32 flags); void SetSourceFramebuffer(GLuint texture); - void SetPalette(const vec4f * glPalette); - void SetPaletteRemap(const GLint * filterMap); + void SetPaletteRemap(const GLuint * filterMap); void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom); diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h index 6eb9b85508..dde02bc9a9 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h @@ -49,6 +49,7 @@ OPENGL_PROC(PFNGLBINDBUFFERPROC, glBindBuffer) OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation) OPENGL_PROC(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer) OPENGL_PROC(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray) +OPENGL_PROC(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer); OPENGL_PROC(PFNGLBUFFERDATAPROC, glBufferData) OPENGL_PROC(PFNGLCOMPILESHADERPROC, glCompileShader) OPENGL_PROC(PFNGLCREATEPROGRAMPROC, glCreateProgram) @@ -74,6 +75,8 @@ OPENGL_PROC(PFNGLLINKPROGRAMPROC, glLinkProgram) OPENGL_PROC(PFNGLSHADERSOURCEPROC, glShaderSource) OPENGL_PROC(PFNGLUNIFORM1IPROC, glUniform1i) OPENGL_PROC(PFNGLUNIFORM1IVPROC, glUniform1iv) +OPENGL_PROC(PFNGLUNIFORM1UIPROC, glUniform1ui); +OPENGL_PROC(PFNGLUNIFORM1UIVPROC, glUniform1uiv); OPENGL_PROC(PFNGLUNIFORM2IPROC, glUniform2i) OPENGL_PROC(PFNGLUNIFORM2FPROC, glUniform2f) OPENGL_PROC(PFNGLUNIFORM4FPROC, glUniform4f) diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 464212e7f1..5e32764ef4 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -186,9 +186,6 @@ public: _drawingContext->Initialise(); - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - _copyFramebufferShader = new CopyFramebufferShader(); } @@ -215,6 +212,9 @@ public: colour.b / 255.0f, colour.a / 255.0f }; } + + _copyFramebufferShader->Use(); + _copyFramebufferShader->SetPalette(GLPalette); _drawingContext->ResetPalette(); } @@ -267,10 +267,8 @@ public: { const OpenGLFramebuffer * framebuffer = _swapFramebuffer->GetTargetFramebuffer(); framebuffer->Bind(); - void * pixels = framebuffer->GetPixels(); - - sint32 result = screenshot_dump_png_32bpp(_width, _height, pixels); - Memory::Free(pixels); + framebuffer->GetPixels(_bitsDPI); + sint32 result = screenshot_dump_png(&_bitsDPI); return result; } @@ -442,13 +440,9 @@ void OpenGLDrawingContext::Resize(sint32 width, sint32 height) void OpenGLDrawingContext::ResetPalette() { - FlushCommandBuffers(); + //FlushCommandBuffers(); _textureCache->SetPalette(_engine->Palette); - _drawImageShader->Use(); - _drawImageShader->SetPalette(_engine->GLPalette); - _fillRectShader->Use(); - _fillRectShader->SetPalette(_engine->GLPalette); } void OpenGLDrawingContext::Clear(uint8 paletteIndex) @@ -548,11 +542,9 @@ void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2 += _offsetX; y2 += _offsetY; - vec4f paletteColour = _engine->GLPalette[colour & 0xFF]; - DrawLineCommand& command = _commandBuffers.lines.allocate(); - command.colour = paletteColour; + command.colour = colour & 0xFF; command.clip[0] = _clipLeft; command.clip[1] = _clipTop; @@ -672,7 +664,7 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t command.texMaskBounds = { 0.0f, 0.0f, 0.0f }; command.texPaletteAtlas = texture2->index; command.texPaletteBounds = texture2->computedBounds; - command.colour = { 0.0f, 0.0f, 0.0f }; + command.colour = 0; command.bounds = { left, top, right, bottom }; command.mask = 0; command.flags = 0; @@ -746,15 +738,13 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm command.texPaletteAtlas = 0; command.texPaletteBounds = {0.0f, 0.0f, 0.0f}; command.flags = 0; - command.colour = {0.0f, 0.0f, 0.0f}; + command.colour = 0; command.bounds = { left, top, right, bottom }; command.mask = 1; } void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) { - vec4f paletteColour = _engine->GLPalette[colour & 0xFF]; - sint32 g1Id = image & 0x7FFFF; rct_g1_element * g1Element = gfx_get_g1_element(g1Id); @@ -794,7 +784,7 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin command.texPaletteAtlas = texture->index; command.texPaletteBounds = texture->computedBounds; command.flags = DrawImageCommand::FLAG_COLOUR; - command.colour = paletteColour; + command.colour = colour & 0xFF; command.bounds = { left, top, right, bottom }; command.mask = 0; } @@ -840,7 +830,7 @@ void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * p command.texPaletteAtlas = 0; command.texPaletteBounds = { 0.0f, 0.0f, 0.0f}; command.flags = 0; - command.colour = { 0.0f, 0.0f, 0.0f }; + command.colour = 0; command.bounds = { left, top, right, bottom }; command.mask = 0; } diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp index 9aa2631a8f..4f2f20a172 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp @@ -37,9 +37,9 @@ OpenGLFramebuffer::OpenGLFramebuffer(sint32 width, sint32 height) glGenTextures(1, &_texture); glBindTexture(GL_TEXTURE_2D, _texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glGenFramebuffers(1, &_id); glBindFramebuffer(GL_FRAMEBUFFER, _id); @@ -61,25 +61,33 @@ void OpenGLFramebuffer::Bind() const glViewport(0, 0, (GLsizei)_width, (GLsizei)_height); } -void * OpenGLFramebuffer::GetPixels() const +void OpenGLFramebuffer::BindDraw() const { - void * pixels = Memory::Allocate(_width * _height * 4); - glReadPixels(0, 0, _width, _height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _id); +} - // Flip pixels vertically - void * flippedPixels = Memory::Allocate(_width * _height * 4); - size_t stride = _width * 4; - uint8 * src = (uint8 *)pixels + ((_height - 1) * stride); - uint8 * dst = (uint8 *)flippedPixels; +void OpenGLFramebuffer::BindRead() const +{ + glBindFramebuffer(GL_READ_FRAMEBUFFER, _id); +} + +void OpenGLFramebuffer::GetPixels(rct_drawpixelinfo &dpi) const +{ + assert(dpi.width == _width && dpi.height == _height); + + uint8 * pixels = Memory::Allocate(_width * _height); + glReadPixels(0, 0, _width, _height, GL_RED_INTEGER, GL_UNSIGNED_BYTE, pixels); + + // Flip pixels vertically on copy + uint8 * src = pixels + ((_height - 1) * _width); + uint8 * dst = dpi.bits; for (sint32 y = 0; y < _height; y++) { - Memory::Copy(dst, src, stride); - src -= stride; - dst += stride; + Memory::Copy(dst, src, _width); + src -= _width; + dst += dpi.width + dpi.pitch; } Memory::Free(pixels); - - return flippedPixels; } #endif /* DISABLE_OPENGL */ diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h index fb474605be..9b1d3e2747 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h @@ -17,8 +17,11 @@ #pragma once #include +#include #include "OpenGLAPI.h" +#include + struct SDL_Window; class OpenGLFramebuffer @@ -39,5 +42,7 @@ public: GLuint GetTexture() const { return _texture; } void Bind() const; - void * GetPixels() const; + void BindDraw() const; + void BindRead() const; + void GetPixels(rct_drawpixelinfo &dpi) const; }; diff --git a/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp b/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp index 6c3fee2881..db105c01ff 100644 --- a/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp @@ -20,49 +20,31 @@ #include "OpenGLFramebuffer.h" #include "SwapFramebuffer.h" -SwapFramebuffer::SwapFramebuffer(sint32 width, sint32 height) -{ - _width = width; - _height = height; - _targetFramebufferIndex = 0; - _framebuffer[0] = new OpenGLFramebuffer(width, height); - _framebuffer[1] = new OpenGLFramebuffer(width, height); - _targetFramebuffer = _framebuffer[0]; - - _copyFramebufferShader = new CopyFramebufferShader(); - _copyFramebufferShader->Use(); - _copyFramebufferShader->SetScreenSize(_width, _height); - _copyFramebufferShader->SetBounds(0, 0, _width, _height); - _copyFramebufferShader->SetTextureCoordinates(0, 1, 1, 0); -} - -SwapFramebuffer::~SwapFramebuffer() -{ - delete _framebuffer[0]; - delete _framebuffer[1]; - delete _copyFramebufferShader; -} +SwapFramebuffer::SwapFramebuffer(sint32 width, sint32 height) : +_width(width), _height(height), +_targetFramebuffer(width, height), _sourceFramebuffer(width, height) +{ } GLuint SwapFramebuffer::GetSourceTexture() const { - return _sourceFramebuffer->GetTexture(); + return _sourceFramebuffer.GetTexture(); } void SwapFramebuffer::SwapCopy() { - _sourceFramebuffer = _targetFramebuffer; - _targetFramebufferIndex = (_targetFramebufferIndex + 1) & 1; - _targetFramebuffer = _framebuffer[_targetFramebufferIndex]; - _targetFramebuffer->Bind(); - - _copyFramebufferShader->Use(); - _copyFramebufferShader->SetTexture(GetSourceTexture()); - _copyFramebufferShader->Draw(); + // no longer performs swap, TODO rename function + // blit target's texture to source's texture + _sourceFramebuffer.BindDraw(); + _targetFramebuffer.BindRead(); + glBlitFramebuffer(0, 0, _width, _height, + 0, 0, _width, _height, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + _targetFramebuffer.Bind(); } void SwapFramebuffer::Bind() { - _targetFramebuffer->Bind(); + _targetFramebuffer.Bind(); } #endif /* DISABLE_OPENGL */ diff --git a/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.h b/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.h index 44fc3776b3..7721106b23 100644 --- a/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.h +++ b/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.h @@ -33,23 +33,18 @@ class OpenGLFramebuffer; class SwapFramebuffer final { private: - sint32 _width = 0; - sint32 _height = 0; - uint8 _targetFramebufferIndex = 0; - OpenGLFramebuffer * _targetFramebuffer = nullptr; - OpenGLFramebuffer * _sourceFramebuffer = nullptr; - OpenGLFramebuffer * _framebuffer[2] = { 0 }; - - CopyFramebufferShader * _copyFramebufferShader = nullptr; + const sint32 _width; + const sint32 _height; + OpenGLFramebuffer _targetFramebuffer; + OpenGLFramebuffer _sourceFramebuffer; public: SwapFramebuffer(sint32 width, sint32 height); - ~SwapFramebuffer(); /** * Gets the current target framebuffer. */ - const OpenGLFramebuffer * GetTargetFramebuffer() const { return _targetFramebuffer; } + const OpenGLFramebuffer * GetTargetFramebuffer() const { return &_targetFramebuffer; } /** * Gets the texture ID for the source framebuffer. diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 9c6ca3eb0e..fe61ba663d 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -41,7 +41,6 @@ void TextureCache::InvalidateImage(uint32 image) _atlases[kvp->second.index].Free(kvp->second); _imageTextureMap.erase(kvp); } - } const CachedTextureInfo* TextureCache::GetOrLoadImageTexture(uint32 image) @@ -153,7 +152,10 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries) // Retrieve current array data auto oldPixels = std::vector(_atlasesTextureDimensions * _atlasesTextureDimensions * _atlasesTextureIndices); - glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, oldPixels.data()); + if (oldPixels.size() > 0) + { + glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, oldPixels.data()); + } // Delete old texture, allocate a new one, then define the new format on the newly created texture glDeleteTextures(1, &_atlasesTexture); diff --git a/src/openrct2/drawing/NewDrawing.cpp b/src/openrct2/drawing/NewDrawing.cpp index 2dc29b8059..fe63938268 100644 --- a/src/openrct2/drawing/NewDrawing.cpp +++ b/src/openrct2/drawing/NewDrawing.cpp @@ -81,8 +81,6 @@ extern "C" auto uiContext = context->GetUiContext(); auto drawingEngine = uiContext->CreateDrawingEngine((DRAWING_ENGINE_TYPE)_drawingEngineType); - _painter = new Painter(uiContext); - if (drawingEngine == nullptr) { if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE) @@ -103,6 +101,7 @@ extern "C" } else { + _painter = new Painter(uiContext); try { drawingEngine->Initialise(); @@ -111,6 +110,8 @@ extern "C" } catch (const Exception &ex) { + delete _painter; + _painter = nullptr; delete drawingEngine; drawingEngine = nullptr; if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE) @@ -156,7 +157,7 @@ extern "C" if (_drawingEngine != nullptr && _painter != nullptr) { _drawingEngine->BeginDraw(); - _painter->Paint(_drawingEngine); + _painter->Paint(_drawingEngine); _drawingEngine->EndDraw(); } }