diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index ac5b67cd2e..daf8cd7c31 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -470,9 +470,8 @@ F76C887D1EC5324E00FA49E2 /* CursorData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C858A1EC4E82600FA49E2 /* CursorData.cpp */; }; F76C887E1EC5324E00FA49E2 /* CursorRepository.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C858B1EC4E82600FA49E2 /* CursorRepository.cpp */; }; F76C887F1EC5324E00FA49E2 /* CopyFramebufferShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C85911EC4E82600FA49E2 /* CopyFramebufferShader.cpp */; }; - F76C88801EC5324E00FA49E2 /* DrawImageShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C85941EC4E82600FA49E2 /* DrawImageShader.cpp */; }; + F76C88801EC5324E00FA49E2 /* DrawRectShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C85941EC4E82600FA49E2 /* DrawRectShader.cpp */; }; F76C88811EC5324E00FA49E2 /* DrawLineShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C85961EC4E82600FA49E2 /* DrawLineShader.cpp */; }; - F76C88821EC5324E00FA49E2 /* FillRectShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C85981EC4E82600FA49E2 /* FillRectShader.cpp */; }; F76C88831EC5324E00FA49E2 /* OpenGLAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C859B1EC4E82600FA49E2 /* OpenGLAPI.cpp */; }; F76C88841EC5324E00FA49E2 /* OpenGLDrawingEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C859D1EC4E82600FA49E2 /* OpenGLDrawingEngine.cpp */; }; F76C88851EC5324E00FA49E2 /* OpenGLFramebuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C859E1EC4E82600FA49E2 /* OpenGLFramebuffer.cpp */; }; @@ -1392,12 +1391,10 @@ F76C85911EC4E82600FA49E2 /* CopyFramebufferShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CopyFramebufferShader.cpp; sourceTree = ""; }; F76C85921EC4E82600FA49E2 /* CopyFramebufferShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CopyFramebufferShader.h; sourceTree = ""; }; F76C85931EC4E82600FA49E2 /* DrawCommands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawCommands.h; sourceTree = ""; }; - F76C85941EC4E82600FA49E2 /* DrawImageShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DrawImageShader.cpp; sourceTree = ""; }; - F76C85951EC4E82600FA49E2 /* DrawImageShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawImageShader.h; sourceTree = ""; }; + F76C85941EC4E82600FA49E2 /* DrawRectShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DrawRectShader.cpp; sourceTree = ""; }; + F76C85951EC4E82600FA49E2 /* DrawRectShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawRectShader.h; sourceTree = ""; }; F76C85961EC4E82600FA49E2 /* DrawLineShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DrawLineShader.cpp; sourceTree = ""; }; F76C85971EC4E82600FA49E2 /* DrawLineShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawLineShader.h; sourceTree = ""; }; - F76C85981EC4E82600FA49E2 /* FillRectShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FillRectShader.cpp; sourceTree = ""; }; - F76C85991EC4E82600FA49E2 /* FillRectShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FillRectShader.h; sourceTree = ""; }; F76C859A1EC4E82600FA49E2 /* GLSLTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GLSLTypes.h; sourceTree = ""; }; F76C859B1EC4E82600FA49E2 /* OpenGLAPI.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGLAPI.cpp; sourceTree = ""; }; F76C859C1EC4E82600FA49E2 /* OpenGLAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OpenGLAPI.h; sourceTree = ""; }; @@ -2669,12 +2666,10 @@ F76C85911EC4E82600FA49E2 /* CopyFramebufferShader.cpp */, F76C85921EC4E82600FA49E2 /* CopyFramebufferShader.h */, F76C85931EC4E82600FA49E2 /* DrawCommands.h */, - F76C85941EC4E82600FA49E2 /* DrawImageShader.cpp */, - F76C85951EC4E82600FA49E2 /* DrawImageShader.h */, F76C85961EC4E82600FA49E2 /* DrawLineShader.cpp */, F76C85971EC4E82600FA49E2 /* DrawLineShader.h */, - F76C85981EC4E82600FA49E2 /* FillRectShader.cpp */, - F76C85991EC4E82600FA49E2 /* FillRectShader.h */, + F76C85941EC4E82600FA49E2 /* DrawRectShader.cpp */, + F76C85951EC4E82600FA49E2 /* DrawRectShader.h */, F76C859A1EC4E82600FA49E2 /* GLSLTypes.h */, F76C859B1EC4E82600FA49E2 /* OpenGLAPI.cpp */, F76C859C1EC4E82600FA49E2 /* OpenGLAPI.h */, @@ -3232,7 +3227,7 @@ 4C93F18F1F8B747A00A9330D /* PirateShip.cpp in Sources */, C654DF381F69C0430040F43D /* StaffFirePrompt.cpp in Sources */, C651A8D91F30204300443BCA /* Text.cpp in Sources */, - F76C88801EC5324E00FA49E2 /* DrawImageShader.cpp in Sources */, + F76C88801EC5324E00FA49E2 /* DrawRectShader.cpp in Sources */, C685E51D1F8907850090598F /* Research.cpp in Sources */, C64644FB1F3FA4120026AC2D /* EditorScenarioOptions.cpp in Sources */, F775F5371EE3724F001F00E7 /* DummyAudioContext.cpp in Sources */, @@ -3263,7 +3258,6 @@ 4CFE4E801F90A3F1005243C2 /* Peep.cpp in Sources */, C654DF3A1F69C0430040F43D /* TitleEditor.cpp in Sources */, C666EE6F1F37ACB10061AA04 /* DebugPaint.cpp in Sources */, - F76C88821EC5324E00FA49E2 /* FillRectShader.cpp in Sources */, F76C88831EC5324E00FA49E2 /* OpenGLAPI.cpp in Sources */, 4C93F1521F8B744400A9330D /* Steeplechase.cpp in Sources */, 4C93F1BD1F8E185600A9330D /* NewsItem.cpp in Sources */, diff --git a/data/shaders/copyframebuffer.frag b/data/shaders/copyframebuffer.frag index 10349cfe13..1f5f4f8e3b 100644 --- a/data/shaders/copyframebuffer.frag +++ b/data/shaders/copyframebuffer.frag @@ -3,7 +3,6 @@ uniform vec4 uPalette[256]; uniform usampler2D uTexture; -in vec2 fPosition; in vec2 fTextureCoordinate; out vec4 oColour; diff --git a/data/shaders/copyframebuffer.vert b/data/shaders/copyframebuffer.vert index 84b893c0dc..a8fca19e79 100644 --- a/data/shaders/copyframebuffer.vert +++ b/data/shaders/copyframebuffer.vert @@ -1,42 +1,12 @@ #version 150 -uniform ivec2 uScreenSize; -uniform ivec4 uBounds; -uniform ivec4 uTextureCoordinates; +in vec4 vPosition; +in vec2 vTextureCoordinate; -in uint vIndex; - -out vec2 fPosition; out vec2 fTextureCoordinate; void main() { - vec2 pos; - switch (vIndex) { - case 0u: - pos = uBounds.xy; - fTextureCoordinate = uTextureCoordinates.xy; - break; - case 1u: - pos = uBounds.zy; - fTextureCoordinate = uTextureCoordinates.zy; - break; - case 2u: - pos = uBounds.xw; - fTextureCoordinate = uTextureCoordinates.xw; - break; - case 3u: - pos = uBounds.zw; - fTextureCoordinate = uTextureCoordinates.zw; - break; - } - - fPosition = pos; - - // Transform screen coordinates to viewport - pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0; - pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0; - pos.y *= -1; - - gl_Position = vec4(pos, 0.0, 1.0); + fTextureCoordinate = vTextureCoordinate; + gl_Position = vPosition; } diff --git a/data/shaders/drawimage.frag b/data/shaders/drawimage.frag deleted file mode 100644 index 6f60b23505..0000000000 --- a/data/shaders/drawimage.frag +++ /dev/null @@ -1,95 +0,0 @@ -#version 150 - -const int FLAG_COLOUR = (1 << 0); -const int FLAG_REMAP = (1 << 1); -const int FLAG_TRANSPARENT = (1 << 2); -const int FLAG_TRANSPARENT_SPECIAL = (1 << 3); - -uniform usampler2DArray uTexture; - -flat in ivec4 fClip; -flat in int fFlags; -flat in uint fColour; -flat in int fTexColourAtlas; -in vec2 fTexColourCoords; -flat in int fTexMaskAtlas; -in vec2 fTexMaskCoords; -flat in int fTexPaletteAtlas; -flat in vec4 fTexPaletteBounds; -flat in int fMask; - -in vec2 fPosition; - -out uint oColour; - -void main() -{ - if (fPosition.x < fClip.x || fPosition.x > fClip.z || - fPosition.y < fClip.y || fPosition.y > fClip.w) - { - discard; - } - - 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 = texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r; - } // If transparent or special transparent - else if ((fFlags & (FLAG_TRANSPARENT | FLAG_TRANSPARENT_SPECIAL)) != 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 = texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r; - - return; - } - else - { - texel = texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r; - } - - if (fMask != 0) - { - uint mask = texture(uTexture, vec3(fTexMaskCoords, float(fTexMaskAtlas))).r; - if ( mask == 0u ) - { - discard; - } - - oColour = texel; - } - else - { - if (texel == 0u) - { - discard; - } - if ((fFlags & FLAG_COLOUR) != 0) - { - //oColour = vec4(fColour.rgb, fColour.a * texel.a); - oColour = fColour; - } - else - { - oColour = texel; - } - } -} diff --git a/data/shaders/drawimage.vert b/data/shaders/drawimage.vert deleted file mode 100644 index ca95726301..0000000000 --- a/data/shaders/drawimage.vert +++ /dev/null @@ -1,74 +0,0 @@ -#version 150 - -uniform ivec2 uScreenSize; - -in ivec4 ivClip; -in int ivTexColourAtlas; -in vec4 ivTexColourBounds; -in int ivTexMaskAtlas; -in vec4 ivTexMaskBounds; -in int ivTexPaletteAtlas; -in vec4 ivTexPaletteBounds; -in int ivFlags; -in uint ivColour; -in ivec4 ivBounds; -in int ivMask; - -in uint vIndex; - -out vec2 fPosition; -flat out ivec4 fClip; -flat out int fFlags; -flat out uint fColour; -flat out int fTexColourAtlas; -out vec2 fTexColourCoords; -flat out int fTexMaskAtlas; -out vec2 fTexMaskCoords; -flat out int fTexPaletteAtlas; -flat out vec4 fTexPaletteBounds; -flat out int fMask; - -void main() -{ - vec2 pos; - switch (vIndex) { - case 0u: - pos = ivBounds.xy; - fTexColourCoords = ivTexColourBounds.xy; - fTexMaskCoords = ivTexMaskBounds.xy; - break; - case 1u: - pos = ivBounds.zy; - fTexColourCoords = ivTexColourBounds.zy; - fTexMaskCoords = ivTexMaskBounds.zy; - break; - case 2u: - pos = ivBounds.xw; - fTexColourCoords = ivTexColourBounds.xw; - fTexMaskCoords = ivTexMaskBounds.xw; - break; - case 3u: - pos = ivBounds.zw; - fTexColourCoords = ivTexColourBounds.zw; - fTexMaskCoords = ivTexMaskBounds.zw; - break; - } - - fPosition = pos; - - // Transform screen coordinates to viewport - pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0; - pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0; - pos.y *= -1; - - fClip = ivClip; - fFlags = ivFlags; - fColour = ivColour; - fMask = ivMask; - fTexColourAtlas = ivTexColourAtlas; - fTexMaskAtlas = ivTexMaskAtlas; - fTexPaletteAtlas = ivTexPaletteAtlas; - fTexPaletteBounds = ivTexPaletteBounds; - - gl_Position = vec4(pos, 0.0, 1.0); -} diff --git a/data/shaders/drawline.frag b/data/shaders/drawline.frag index 6674d9c11e..e385164708 100644 --- a/data/shaders/drawline.frag +++ b/data/shaders/drawline.frag @@ -1,6 +1,5 @@ #version 150 -uniform ivec4 uClip; uniform uint uColour; in vec2 fPosition; @@ -9,11 +8,5 @@ out uint oColour; void main() { - if (fPosition.x < uClip.x || fPosition.x > uClip.z || - fPosition.y < uClip.y || fPosition.y > uClip.w) - { - discard; - } - oColour = uColour; } diff --git a/data/shaders/drawline.vert b/data/shaders/drawline.vert index d705ba0023..ebbfe202ec 100644 --- a/data/shaders/drawline.vert +++ b/data/shaders/drawline.vert @@ -2,23 +2,15 @@ uniform ivec2 uScreenSize; uniform ivec4 uBounds; +uniform ivec4 uClip; -in uint vIndex; +in mat4x2 vVertMat; out vec2 fPosition; void main() { - vec2 pos; - if (vIndex == 0u) - { - pos = uBounds.xy; - } - else - { - pos = uBounds.zw; - } - + vec2 pos = clamp(vVertMat * uBounds, uClip.xy, uClip.zw); fPosition = pos; // Transform screen coordinates to viewport diff --git a/data/shaders/drawrect.frag b/data/shaders/drawrect.frag new file mode 100644 index 0000000000..cf4a8265a8 --- /dev/null +++ b/data/shaders/drawrect.frag @@ -0,0 +1,76 @@ +#version 150 + +const int MASK_REMAP_COUNT = 3; +const int FLAG_NO_TEXTURE = (1 << 2); +const int FLAG_MASK = (1 << 3); +const int FLAG_CROSS_HATCH = (1 << 4); + +uniform usampler2DArray uTexture; +uniform usampler2DRect uPaletteTex; + +flat in int fFlags; +flat in uint fColour; +in vec3 fTexColour; +in vec3 fTexMask; +flat in vec3 fPalettes; + +in vec2 fPosition; + +out uint oColour; + +void main() +{ + uint texel; + if ((fFlags & FLAG_NO_TEXTURE) == 0) + { + texel = texture(uTexture, fTexColour).r; + if (texel == 0u) + { + discard; + } + texel += fColour; + } + else + { + texel = fColour; + } + + int paletteCount = fFlags & MASK_REMAP_COUNT; + if (paletteCount >= 3 && texel >= 0x2Eu && texel < 0x3Au) + { + texel = texture(uPaletteTex, vec2(texel + 0xC5u, fPalettes.z)).r; + } + else if (paletteCount >= 2 && texel >= 0xCAu && texel < 0xD6u) + { + texel = texture(uPaletteTex, vec2(texel + 0x29u, fPalettes.y)).r; + } + else if (paletteCount >= 1) + { + texel = texture(uPaletteTex, vec2(texel, fPalettes.x)).r; + } + + if (texel == 0u) + { + discard; + } + + if ((fFlags & FLAG_CROSS_HATCH) != 0) + { + int posSum = int(fPosition.x) + int(fPosition.y); + if ((posSum % 2) == 0) + { + discard; + } + } + + if ((fFlags & FLAG_MASK) != 0) + { + uint mask = texture(uTexture, fTexMask).r; + if ( mask == 0u ) + { + discard; + } + } + + oColour = texel; +} diff --git a/data/shaders/drawrect.vert b/data/shaders/drawrect.vert new file mode 100644 index 0000000000..6a89106728 --- /dev/null +++ b/data/shaders/drawrect.vert @@ -0,0 +1,45 @@ +#version 150 + +uniform ivec2 uScreenSize; + +in ivec4 vClip; +in int vTexColourAtlas; +in vec4 vTexColourBounds; +in int vTexMaskAtlas; +in vec4 vTexMaskBounds; +in ivec3 vPalettes; +in int vFlags; +in uint vColour; +in ivec4 vBounds; + +in mat4x2 vVertMat; +in vec2 vVertVec; + +out vec2 fPosition; +flat out int fFlags; +flat out uint fColour; +out vec3 fTexColour; +out vec3 fTexMask; +flat out vec3 fPalettes; + +void main() +{ + // Clamp position by vClip, correcting interpolated values for the clipping + vec2 m = clamp(((vVertMat * vClip) - (vVertMat * vBounds))/(vBounds.zw - vBounds.xy) + vVertVec, 0.0, 1.0); + vec2 pos = mix(vBounds.xy, vBounds.zw, m); + fTexColour = vec3(mix(vTexColourBounds.xy, vTexColourBounds.zw, m), vTexColourAtlas); + fTexMask = vec3(mix(vTexMaskBounds.xy, vTexMaskBounds.zw, m), vTexMaskAtlas); + + fPosition = pos; + + // Transform screen coordinates to viewport + pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0; + pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0; + pos.y *= -1; + + fFlags = vFlags; + fColour = vColour; + fPalettes = vec3(vPalettes); + + gl_Position = vec4(pos, 0.0, 1.0); +} diff --git a/data/shaders/fillrect.frag b/data/shaders/fillrect.frag deleted file mode 100644 index 0692628b46..0000000000 --- a/data/shaders/fillrect.frag +++ /dev/null @@ -1,33 +0,0 @@ -#version 150 - -uniform ivec2 uScreenSize; -uniform ivec4 uClip; -uniform int uFlags; -uniform usampler2D uSourceFramebuffer; -uniform uint uPaletteRemap[256]; - -in vec2 fPosition; - -out uint oColour; - -void main() -{ - if (fPosition.x < uClip.x || fPosition.x > uClip.z || - fPosition.y < uClip.y || fPosition.y > uClip.w) - { - discard; - } - - if ((uFlags & 1) != 0) // cross-hatch pattern - { - int posSum = int(fPosition.x) + int(fPosition.y); - if ((posSum % 2) == 0) - { - discard; - } - } - - 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/data/shaders/fillrect.vert b/data/shaders/fillrect.vert deleted file mode 100644 index 9f888f4c66..0000000000 --- a/data/shaders/fillrect.vert +++ /dev/null @@ -1,36 +0,0 @@ -#version 150 - -uniform ivec2 uScreenSize; -uniform ivec4 uBounds; - -in uint vIndex; - -out vec2 fPosition; - -void main() -{ - vec2 pos; - switch (vIndex) { - case 0u: - pos = uBounds.xy; - break; - case 1u: - pos = uBounds.zy; - break; - case 2u: - pos = uBounds.xw; - break; - case 3u: - pos = uBounds.zw; - break; - } - - fPosition = pos; - - // Transform screen coordinates to viewport - pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0; - pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0; - pos.y *= -1; - - gl_Position = vec4(pos, 0.0, 1.0); -} diff --git a/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.cpp b/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.cpp index 333302ea90..db043b6d9e 100644 --- a/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.cpp @@ -18,6 +18,20 @@ #include "CopyFramebufferShader.h" +struct VDStruct +{ + GLfloat position[2]; + GLfloat texturecoordinate[2]; +}; + +constexpr VDStruct VertexData[4] = +{ + { -1.0f, -1.0f, 0.0f, 0.0f }, + { 1.0f, -1.0f, 1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, +}; + CopyFramebufferShader::CopyFramebufferShader() : OpenGLShaderProgram("copyframebuffer") { GetLocations(); @@ -25,16 +39,17 @@ CopyFramebufferShader::CopyFramebufferShader() : OpenGLShaderProgram("copyframeb glGenBuffers(1, &_vbo); glGenVertexArrays(1, &_vao); - GLuint vertices[] = { 0, 1, 2, 2, 1, 3 }; glBindBuffer(GL_ARRAY_BUFFER, _vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW); glBindVertexArray(_vao); - glEnableVertexAttribArray(vIndex); - glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr); + glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, position)); + glVertexAttribPointer(vTextureCoordinate, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, texturecoordinate)); + + glEnableVertexAttribArray(vPosition); + glEnableVertexAttribArray(vTextureCoordinate); Use(); - SetTextureCoordinates(0, 0, 1, 1); glUniform1i(uTexture, 0); } @@ -46,28 +61,11 @@ CopyFramebufferShader::~CopyFramebufferShader() void CopyFramebufferShader::GetLocations() { - uScreenSize = GetUniformLocation("uScreenSize"); - uBounds = GetUniformLocation("uBounds"); - uTextureCoordinates = GetUniformLocation("uTextureCoordinates"); uTexture = GetUniformLocation("uTexture"); uPalette = GetUniformLocation("uPalette"); - vIndex = GetAttributeLocation("vIndex"); -} - -void CopyFramebufferShader::SetScreenSize(sint32 width, sint32 height) -{ - glUniform2i(uScreenSize, width, height); -} - -void CopyFramebufferShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom) -{ - glUniform4i(uBounds, left, top, right, bottom); -} - -void CopyFramebufferShader::SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom) -{ - glUniform4i(uTextureCoordinates, left, top, right, bottom); + vPosition = GetAttributeLocation("vPosition"); + vTextureCoordinate = GetAttributeLocation("vTextureCoordinate"); } void CopyFramebufferShader::SetTexture(GLuint texture) @@ -82,7 +80,7 @@ void CopyFramebufferShader::SetPalette(const vec4f * glPalette) { void CopyFramebufferShader::Draw() { glBindVertexArray(_vao); - glDrawArrays(GL_TRIANGLES, 0, 6); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } #endif /* DISABLE_OPENGL */ diff --git a/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.h b/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.h index ab7f58d020..8f24fdf851 100644 --- a/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/CopyFramebufferShader.h @@ -22,13 +22,11 @@ class CopyFramebufferShader final : public OpenGLShaderProgram { private: - GLuint uScreenSize; - GLuint uBounds; - GLuint uTextureCoordinates; GLuint uTexture; GLuint uPalette; - GLuint vIndex; + GLuint vPosition; + GLuint vTextureCoordinate; GLuint _vbo; GLuint _vao; @@ -37,9 +35,6 @@ public: CopyFramebufferShader(); ~CopyFramebufferShader() override; - void SetScreenSize(sint32 width, sint32 height); - 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); diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h b/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h index 6fc3b5260f..89fda218fa 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h +++ b/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h @@ -64,43 +64,33 @@ public: } }; -struct DrawRectCommand { - uint32 flags; - GLuint sourceFramebuffer; - sint32 clip[4]; - sint32 bounds[4]; - GLuint paletteRemap[256]; -}; - -struct DrawLineCommand { +struct DrawLineCommand +{ uint8 colour; - sint32 clip[4]; + vec4i clip; sint32 pos[4]; }; // Per-instance data for images -struct DrawImageCommand { +struct DrawRectCommand +{ vec4i clip; sint32 texColourAtlas; vec4f texColourBounds; sint32 texMaskAtlas; vec4f texMaskBounds; - sint32 texPaletteAtlas; - vec4f texPaletteBounds; + vec3i palettes; sint32 flags; - uint8 colour; + uint32 colour; vec4i bounds; - sint32 mask; enum { - FLAG_COLOUR = (1 << 0), - FLAG_REMAP = (1 << 1), - FLAG_TRANSPARENT = (1 << 2), - FLAG_TRANSPARENT_SPECIAL = (1 << 3), + FLAG_NO_TEXTURE = (1 << 2), + FLAG_MASK = (1 << 3), + FLAG_CROSS_HATCH = (1 << 4), }; }; -typedef CommandBatch ImageCommandBatch; typedef CommandBatch LineCommandBatch; typedef CommandBatch RectCommandBatch; diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.cpp b/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.cpp deleted file mode 100644 index 534fc675f3..0000000000 --- a/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers -/***************************************************************************** - * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. - * - * OpenRCT2 is the work of many authors, a full list can be found in contributors.md - * For more information, visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * A full copy of the GNU General Public License can be found in licence.txt - *****************************************************************************/ -#pragma endregion - -#ifndef DISABLE_OPENGL - -#include "DrawImageShader.h" - -DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage") -{ - GetLocations(); - - glGenBuffers(1, &_vbo); - glGenBuffers(1, &_vboInstances); - glGenVertexArrays(1, &_vao); - - GLuint vertices[] = { 0, 1, 2, 2, 1, 3 }; - glBindBuffer(GL_ARRAY_BUFFER, _vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glBindVertexArray(_vao); - - glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr); - - glBindBuffer(GL_ARRAY_BUFFER, _vboInstances); - glVertexAttribIPointer(vClip, 4, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, clip)); - glVertexAttribIPointer(vTexColourAtlas, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texColourAtlas)); - glVertexAttribPointer(vTexColourBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texColourBounds)); - glVertexAttribIPointer(vTexMaskAtlas, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texMaskAtlas)); - glVertexAttribPointer(vTexMaskBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texMaskBounds)); - 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)); - 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)); - - glEnableVertexAttribArray(vIndex); - glEnableVertexAttribArray(vClip); - glEnableVertexAttribArray(vTexColourAtlas); - glEnableVertexAttribArray(vTexColourBounds); - glEnableVertexAttribArray(vTexMaskAtlas); - glEnableVertexAttribArray(vTexMaskBounds); - glEnableVertexAttribArray(vTexPaletteAtlas); - glEnableVertexAttribArray(vTexPaletteBounds); - glEnableVertexAttribArray(vFlags); - glEnableVertexAttribArray(vColour); - glEnableVertexAttribArray(vBounds); - glEnableVertexAttribArray(vMask); - - glVertexAttribDivisor(vClip, 1); - glVertexAttribDivisor(vTexColourAtlas, 1); - glVertexAttribDivisor(vTexColourBounds, 1); - glVertexAttribDivisor(vTexMaskAtlas, 1); - glVertexAttribDivisor(vTexMaskBounds, 1); - glVertexAttribDivisor(vTexPaletteAtlas, 1); - glVertexAttribDivisor(vTexPaletteBounds, 1); - glVertexAttribDivisor(vFlags, 1); - glVertexAttribDivisor(vColour, 1); - glVertexAttribDivisor(vBounds, 1); - glVertexAttribDivisor(vMask, 1); - - Use(); - glUniform1i(uTexture, 0); -} - -DrawImageShader::~DrawImageShader() -{ - glDeleteBuffers(1, &_vbo); - glDeleteBuffers(1, &_vboInstances); - glDeleteVertexArrays(1, &_vao); -} - -void DrawImageShader::GetLocations() -{ - uScreenSize = GetUniformLocation("uScreenSize"); - uTexture = GetUniformLocation("uTexture"); - - vIndex = GetAttributeLocation("vIndex"); - vClip = GetAttributeLocation("ivClip"); - vTexColourAtlas = GetAttributeLocation("ivTexColourAtlas"); - vTexColourBounds = GetAttributeLocation("ivTexColourBounds"); - vTexMaskAtlas = GetAttributeLocation("ivTexMaskAtlas"); - vTexMaskBounds = GetAttributeLocation("ivTexMaskBounds"); - vTexPaletteAtlas = GetAttributeLocation("ivTexPaletteAtlas"); - vTexPaletteBounds = GetAttributeLocation("ivTexPaletteBounds"); - vFlags = GetAttributeLocation("ivFlags"); - vColour = GetAttributeLocation("ivColour"); - vBounds = GetAttributeLocation("ivBounds"); - vMask = GetAttributeLocation("ivMask"); -} - -void DrawImageShader::SetScreenSize(sint32 width, sint32 height) -{ - glUniform2i(uScreenSize, width, height); -} - -void DrawImageShader::DrawInstances(const ImageCommandBatch& instances) -{ - glBindVertexArray(_vao); - - glBindBuffer(GL_ARRAY_BUFFER, _vboInstances); - glBufferData(GL_ARRAY_BUFFER, sizeof(DrawImageCommand) * instances.size(), instances.data(), GL_STREAM_DRAW); - - glDrawArraysInstanced(GL_TRIANGLES, 0, 6, (GLsizei)instances.size()); -} - -#endif /* DISABLE_OPENGL */ diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp index 5ef399b498..530ba25575 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp @@ -19,6 +19,17 @@ #include "DrawLineShader.h" #include "OpenGLFramebuffer.h" +struct VDStruct +{ + GLfloat mat[4][2]; +}; + +constexpr VDStruct VertexData[2] = +{ + { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, +}; + DrawLineShader::DrawLineShader() : OpenGLShaderProgram("drawline") { GetLocations(); @@ -26,13 +37,19 @@ DrawLineShader::DrawLineShader() : OpenGLShaderProgram("drawline") glGenBuffers(1, &_vbo); glGenVertexArrays(1, &_vao); - GLuint vertices[] = { 0, 1 }; glBindBuffer(GL_ARRAY_BUFFER, _vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW); glBindVertexArray(_vao); - glEnableVertexAttribArray(vIndex); - glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr); + glVertexAttribPointer(vVertMat+0, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[0])); + glVertexAttribPointer(vVertMat+1, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[1])); + glVertexAttribPointer(vVertMat+2, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[2])); + glVertexAttribPointer(vVertMat+3, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[3])); + + glEnableVertexAttribArray(vVertMat+0); + glEnableVertexAttribArray(vVertMat+1); + glEnableVertexAttribArray(vVertMat+2); + glEnableVertexAttribArray(vVertMat+3); Use(); } @@ -50,7 +67,7 @@ void DrawLineShader::GetLocations() uBounds = GetUniformLocation("uBounds"); uColour = GetUniformLocation("uColour"); - vIndex = GetAttributeLocation("vIndex"); + vVertMat = GetAttributeLocation("vVertMat"); } void DrawLineShader::SetScreenSize(sint32 width, sint32 height) diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h index d559da4ef5..176da2edd7 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h @@ -27,7 +27,7 @@ private: GLuint uBounds; GLuint uColour; - GLuint vIndex; + GLuint vVertMat; GLuint _vbo; GLuint _vao; diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp b/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp new file mode 100644 index 0000000000..31985ca626 --- /dev/null +++ b/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp @@ -0,0 +1,138 @@ +#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +/***************************************************************************** + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * OpenRCT2 is the work of many authors, a full list can be found in contributors.md + * For more information, visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * A full copy of the GNU General Public License can be found in licence.txt + *****************************************************************************/ +#pragma endregion + +#ifndef DISABLE_OPENGL + +#include "DrawRectShader.h" + +struct VDStruct +{ + GLfloat mat[4][2]; + GLfloat vec[2]; +}; + +constexpr VDStruct VertexData[4] = +{ + { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f }, + { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }, +}; + +DrawRectShader::DrawRectShader() : OpenGLShaderProgram("drawrect") +{ + GetLocations(); + + glGenBuffers(1, &_vbo); + glGenBuffers(1, &_vboInstances); + glGenVertexArrays(1, &_vao); + + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW); + + glBindVertexArray(_vao); + + glVertexAttribPointer(vVertMat+0, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[0])); + glVertexAttribPointer(vVertMat+1, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[1])); + glVertexAttribPointer(vVertMat+2, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[2])); + glVertexAttribPointer(vVertMat+3, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[3])); + glVertexAttribPointer(vVertVec, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, vec) ); + + glBindBuffer(GL_ARRAY_BUFFER, _vboInstances); + glVertexAttribIPointer(vClip, 4, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, clip)); + glVertexAttribIPointer(vTexColourAtlas, 1, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texColourAtlas)); + glVertexAttribPointer(vTexColourBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texColourBounds)); + glVertexAttribIPointer(vTexMaskAtlas, 1, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texMaskAtlas)); + glVertexAttribPointer(vTexMaskBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texMaskBounds)); + glVertexAttribIPointer(vPalettes, 3, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, palettes)); + glVertexAttribIPointer(vFlags, 1, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, flags)); + glVertexAttribIPointer(vColour, 1, GL_UNSIGNED_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, colour)); + glVertexAttribIPointer(vBounds, 4, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, bounds)); + + glEnableVertexAttribArray(vVertMat+0); + glEnableVertexAttribArray(vVertMat+1); + glEnableVertexAttribArray(vVertMat+2); + glEnableVertexAttribArray(vVertMat+3); + glEnableVertexAttribArray(vVertVec); + + glEnableVertexAttribArray(vClip); + glEnableVertexAttribArray(vTexColourAtlas); + glEnableVertexAttribArray(vTexColourBounds); + glEnableVertexAttribArray(vTexMaskAtlas); + glEnableVertexAttribArray(vTexMaskBounds); + glEnableVertexAttribArray(vPalettes); + glEnableVertexAttribArray(vFlags); + glEnableVertexAttribArray(vColour); + glEnableVertexAttribArray(vBounds); + + glVertexAttribDivisor(vClip, 1); + glVertexAttribDivisor(vTexColourAtlas, 1); + glVertexAttribDivisor(vTexColourBounds, 1); + glVertexAttribDivisor(vTexMaskAtlas, 1); + glVertexAttribDivisor(vTexMaskBounds, 1); + glVertexAttribDivisor(vPalettes, 1); + glVertexAttribDivisor(vFlags, 1); + glVertexAttribDivisor(vColour, 1); + glVertexAttribDivisor(vBounds, 1); + + Use(); + glUniform1i(uTexture, 0); + glUniform1i(uPaletteTex, 1); +} + +DrawRectShader::~DrawRectShader() +{ + glDeleteBuffers(1, &_vbo); + glDeleteBuffers(1, &_vboInstances); + glDeleteVertexArrays(1, &_vao); +} + +void DrawRectShader::GetLocations() +{ + uScreenSize = GetUniformLocation("uScreenSize"); + uTexture = GetUniformLocation("uTexture"); + uPaletteTex = GetUniformLocation("uPaletteTex"); + + vClip = GetAttributeLocation("vClip"); + vTexColourAtlas = GetAttributeLocation("vTexColourAtlas"); + vTexColourBounds = GetAttributeLocation("vTexColourBounds"); + vTexMaskAtlas = GetAttributeLocation("vTexMaskAtlas"); + vTexMaskBounds = GetAttributeLocation("vTexMaskBounds"); + vPalettes = GetAttributeLocation("vPalettes"); + vFlags = GetAttributeLocation("vFlags"); + vColour = GetAttributeLocation("vColour"); + vBounds = GetAttributeLocation("vBounds"); + + vVertMat = GetAttributeLocation("vVertMat"); + vVertVec = GetAttributeLocation("vVertVec"); +} + +void DrawRectShader::SetScreenSize(sint32 width, sint32 height) +{ + glUniform2i(uScreenSize, width, height); +} + +void DrawRectShader::DrawInstances(const RectCommandBatch& instances) +{ + glBindVertexArray(_vao); + + glBindBuffer(GL_ARRAY_BUFFER, _vboInstances); + glBufferData(GL_ARRAY_BUFFER, sizeof(DrawRectCommand) * instances.size(), instances.data(), GL_STREAM_DRAW); + + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei)instances.size()); +} + +#endif /* DISABLE_OPENGL */ diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.h b/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.h similarity index 83% rename from src/openrct2-ui/drawing/engines/opengl/DrawImageShader.h rename to src/openrct2-ui/drawing/engines/opengl/DrawRectShader.h index 578c13eac6..4081d20c02 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawImageShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.h @@ -22,35 +22,36 @@ #include #include -class DrawImageShader final : public OpenGLShaderProgram +class DrawRectShader final : public OpenGLShaderProgram { private: GLuint uScreenSize; GLuint uTexture; + GLuint uPaletteTex; + + GLuint vVertMat; + GLuint vVertVec; - GLuint vIndex; GLuint vClip; GLuint vTexColourAtlas; GLuint vTexColourBounds; GLuint vTexMaskAtlas; GLuint vTexMaskBounds; - GLuint vTexPaletteAtlas; - GLuint vTexPaletteBounds; + GLuint vPalettes; GLuint vFlags; GLuint vColour; GLuint vBounds; - GLuint vMask; GLuint _vbo; GLuint _vboInstances; GLuint _vao; public: - DrawImageShader(); - ~DrawImageShader() override; + DrawRectShader(); + ~DrawRectShader() override; void SetScreenSize(sint32 width, sint32 height); - void DrawInstances(const ImageCommandBatch& instances); + void DrawInstances(const RectCommandBatch& instances); private: void GetLocations(); diff --git a/src/openrct2-ui/drawing/engines/opengl/FillRectShader.cpp b/src/openrct2-ui/drawing/engines/opengl/FillRectShader.cpp deleted file mode 100644 index 7b8931bc64..0000000000 --- a/src/openrct2-ui/drawing/engines/opengl/FillRectShader.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers -/***************************************************************************** - * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. - * - * OpenRCT2 is the work of many authors, a full list can be found in contributors.md - * For more information, visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * A full copy of the GNU General Public License can be found in licence.txt - *****************************************************************************/ -#pragma endregion - -#ifndef DISABLE_OPENGL - -#include "FillRectShader.h" -#include "OpenGLFramebuffer.h" - -FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect") -{ - GetLocations(); - - glGenBuffers(1, &_vbo); - glGenVertexArrays(1, &_vao); - - GLuint vertices[] = { 0, 1, 2, 2, 1, 3 }; - glBindBuffer(GL_ARRAY_BUFFER, _vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glBindVertexArray(_vao); - glEnableVertexAttribArray(vIndex); - glVertexAttribIPointer(vIndex, 1, GL_INT, 0, 0); - - Use(); - SetFlags(0); - glUniform1i(uSourceFramebuffer, 0); -} - -FillRectShader::~FillRectShader() -{ - glDeleteBuffers(1, &_vbo); - glDeleteVertexArrays(1, &_vao); -} - -void FillRectShader::GetLocations() -{ - uScreenSize = GetUniformLocation("uScreenSize"); - uClip = GetUniformLocation("uClip"); - uBounds = GetUniformLocation("uBounds"); - uFlags = GetUniformLocation("uFlags"); - uSourceFramebuffer = GetUniformLocation("uSourceFramebuffer"); - uPaletteRemap = GetUniformLocation("uPaletteRemap"); - - vIndex = GetAttributeLocation("vIndex"); -} - -void FillRectShader::SetScreenSize(sint32 width, sint32 height) -{ - glUniform2i(uScreenSize, width, height); -} - -void FillRectShader::SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom) -{ - glUniform4i(uClip, left, top, right, bottom); -} - -void FillRectShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom) -{ - glUniform4i(uBounds, left, top, right, bottom); -} - -void FillRectShader::SetFlags(uint32 flags) -{ - glUniform1i(uFlags, flags); -} - -void FillRectShader::SetSourceFramebuffer(GLuint texture) -{ - _sourceFramebuffer = texture; - OpenGLAPI::SetTexture(0, GL_TEXTURE_2D, texture); -} - -void FillRectShader::SetPaletteRemap(const GLuint * paletteRemap) -{ - glUniform1uiv(uPaletteRemap, 256, paletteRemap); -} - -void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) -{ - SetBounds(left, top, right, bottom); - - glBindVertexArray(_vao); - glDrawArrays(GL_TRIANGLES, 0, 6); -} - -GLuint FillRectShader::GetSourceFramebuffer() const -{ - return _sourceFramebuffer; -} - -#endif /* DISABLE_OPENGL */ diff --git a/src/openrct2-ui/drawing/engines/opengl/FillRectShader.h b/src/openrct2-ui/drawing/engines/opengl/FillRectShader.h deleted file mode 100644 index eda0794c53..0000000000 --- a/src/openrct2-ui/drawing/engines/opengl/FillRectShader.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers -/***************************************************************************** - * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. - * - * OpenRCT2 is the work of many authors, a full list can be found in contributors.md - * For more information, visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * A full copy of the GNU General Public License can be found in licence.txt - *****************************************************************************/ -#pragma endregion - -#pragma once - -#include "GLSLTypes.h" -#include "OpenGLShaderProgram.h" - -class OpenGLFramebuffer; - -class FillRectShader final : public OpenGLShaderProgram -{ -private: - GLuint uScreenSize; - GLuint uClip; - GLuint uBounds; - GLuint uFlags; - GLuint uSourceFramebuffer; - GLuint uPaletteRemap; - - GLuint vIndex; - - GLuint _vbo; - GLuint _vao; - - GLuint _sourceFramebuffer = 0; - -public: - FillRectShader(); - ~FillRectShader() override; - - void SetScreenSize(sint32 width, sint32 height); - void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom); - void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); - void SetFlags(uint32 flags); - void SetSourceFramebuffer(GLuint texture); - void SetPaletteRemap(const GLuint * filterMap); - - void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom); - - GLuint GetSourceFramebuffer() const; - -private: - void GetLocations(); -}; diff --git a/src/openrct2-ui/drawing/engines/opengl/GLSLTypes.h b/src/openrct2-ui/drawing/engines/opengl/GLSLTypes.h index 515e73a5cb..074f2193fd 100644 --- a/src/openrct2-ui/drawing/engines/opengl/GLSLTypes.h +++ b/src/openrct2-ui/drawing/engines/opengl/GLSLTypes.h @@ -32,6 +32,13 @@ struct vec2f union { float y; float t; float g; }; }; +struct vec3i +{ + union { sint32 x; sint32 s; sint32 r; }; + union { sint32 y; sint32 t; sint32 g; }; + union { sint32 z; sint32 p; sint32 b; }; +}; + struct vec3f { union { float x; float s; float r; }; diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 5e32764ef4..e23c84bd74 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -41,9 +41,8 @@ #include "OpenGLAPI.h" #include "OpenGLFramebuffer.h" #include "CopyFramebufferShader.h" -#include "DrawImageShader.h" #include "DrawLineShader.h" -#include "FillRectShader.h" +#include "DrawRectShader.h" #include "SwapFramebuffer.h" #include "TextureCache.h" #include "DrawCommands.h" @@ -68,9 +67,8 @@ private: OpenGLDrawingEngine * _engine = nullptr; rct_drawpixelinfo * _dpi = nullptr; - DrawImageShader * _drawImageShader = nullptr; DrawLineShader * _drawLineShader = nullptr; - FillRectShader * _fillRectShader = nullptr; + DrawRectShader * _drawRectShader = nullptr; TextureCache * _textureCache = nullptr; @@ -82,9 +80,8 @@ private: sint32 _clipBottom = 0; struct { - RectCommandBatch rectangles; LineCommandBatch lines; - ImageCommandBatch images; + RectCommandBatch rects; } _commandBuffers; public: @@ -109,9 +106,8 @@ public: void FlushCommandBuffers(); - void FlushRectangles(); void FlushLines(); - void FlushImages(); + void FlushRectangles(); void SetDPI(rct_drawpixelinfo * dpi); }; @@ -383,9 +379,6 @@ private: _swapFramebuffer = new SwapFramebuffer(_width, _height); _copyFramebufferShader->Use(); - _copyFramebufferShader->SetScreenSize(_width, _height); - _copyFramebufferShader->SetBounds(0, 0, _width, _height); - _copyFramebufferShader->SetTextureCoordinates(0, 1, 1, 0); } void Display() @@ -406,9 +399,8 @@ OpenGLDrawingContext::OpenGLDrawingContext(OpenGLDrawingEngine * engine) OpenGLDrawingContext::~OpenGLDrawingContext() { - delete _drawImageShader; delete _drawLineShader; - delete _fillRectShader; + delete _drawRectShader; delete _textureCache; } @@ -421,82 +413,67 @@ IDrawingEngine * OpenGLDrawingContext::GetEngine() void OpenGLDrawingContext::Initialise() { _textureCache = new TextureCache(); - _drawImageShader = new DrawImageShader(); + _drawRectShader = new DrawRectShader(); _drawLineShader = new DrawLineShader(); - _fillRectShader = new FillRectShader(); } void OpenGLDrawingContext::Resize(sint32 width, sint32 height) { FlushCommandBuffers(); - _drawImageShader->Use(); - _drawImageShader->SetScreenSize(width, height); + _drawRectShader->Use(); + _drawRectShader->SetScreenSize(width, height); _drawLineShader->Use(); _drawLineShader->SetScreenSize(width, height); - _fillRectShader->Use(); - _fillRectShader->SetScreenSize(width, height); } void OpenGLDrawingContext::ResetPalette() { //FlushCommandBuffers(); - - _textureCache->SetPalette(_engine->Palette); } void OpenGLDrawingContext::Clear(uint8 paletteIndex) { - FillRect(paletteIndex, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight, _clipBottom); + FillRect(paletteIndex, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight - _offsetX, _clipBottom - _offsetY); } void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom) { - // Must be rendered in order, depends on already rendered contents - FlushCommandBuffers(); - left += _offsetX; top += _offsetY; right += _offsetX; bottom += _offsetY; - DrawRectCommand& command = _commandBuffers.rectangles.allocate(); + DrawRectCommand& command = _commandBuffers.rects.allocate(); - command.sourceFramebuffer = _fillRectShader->GetSourceFramebuffer(); + command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom }; + command.texColourAtlas = 0; + command.texColourBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; + command.texMaskAtlas = 0; + command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; + command.palettes = { 0, 0, 0 }; + command.colour = colour & 0xFF; + command.bounds = { left + _offsetX, top + _offsetY, right + 1, bottom + 1 }; + command.flags = DrawRectCommand::FLAG_NO_TEXTURE; if (colour & 0x1000000) { // cross-pattern - command.flags = 1; + command.flags = DrawRectCommand::FLAG_CROSS_HATCH; } else if (colour & 0x2000000) { assert(false); // Should be FilterRect } - else - { - command.flags = 0; - } - - for (size_t i = 0; i < 256; i++) - { - command.paletteRemap[i] = colour & 0xFF; - } - - command.clip[0] = _clipLeft; - command.clip[1] = _clipTop; - command.clip[2] = _clipRight; - command.clip[3] = _clipBottom; - - command.bounds[0] = left; - command.bounds[1] = top; - command.bounds[2] = right + 1; - command.bounds[3] = bottom + 1; } void OpenGLDrawingContext::FilterRect(FILTER_PALETTE_ID palette, sint32 left, sint32 top, sint32 right, sint32 bottom) { + // ignore transparency TODO + return; + + /* // Must be rendered in order, depends on already rendered contents FlushCommandBuffers(); @@ -524,15 +501,13 @@ void OpenGLDrawingContext::FilterRect(FILTER_PALETTE_ID palette, sint32 left, si // END FILTER - command.clip[0] = _clipLeft; - command.clip[1] = _clipTop; - command.clip[2] = _clipRight; - command.clip[3] = _clipBottom; + command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom }; command.bounds[0] = left; command.bounds[1] = top; command.bounds[2] = right + 1; command.bounds[3] = bottom + 1; + */ } void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) @@ -546,10 +521,7 @@ void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 command.colour = colour & 0xFF; - command.clip[0] = _clipLeft; - command.clip[1] = _clipTop; - command.clip[2] = _clipRight; - command.clip[3] = _clipBottom; + command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom }; command.pos[0] = x1; command.pos[1] = y1; @@ -589,13 +561,8 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t uint8 zoomLevel = (1 << _dpi->zoom_level); - sint32 drawOffsetX = g1Element->x_offset; - sint32 drawOffsetY = g1Element->y_offset; - sint32 drawWidth = g1Element->width; - sint32 drawHeight = g1Element->height; - - sint32 left = x + drawOffsetX; - sint32 top = y + drawOffsetY; + sint32 left = x + g1Element->x_offset; + sint32 top = y + g1Element->y_offset; sint32 zoom_mask = 0xFFFFFFFF << _dpi->zoom_level; if (_dpi->zoom_level && g1Element->flags & G1_FLAG_RLE_COMPRESSION){ @@ -609,8 +576,8 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t left &= zoom_mask; - sint32 right = left + drawWidth; - sint32 bottom = top + drawHeight; + sint32 right = left + g1Element->width; + sint32 bottom = top + g1Element->height; if (_dpi->zoom_level && g1Element->flags & G1_FLAG_RLE_COMPRESSION) { bottom += top & ~zoom_mask; @@ -642,46 +609,54 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t auto texture = _textureCache->GetOrLoadImageTexture(image); + int paletteCount; + vec3i palettes{}; bool special = false; - if (!(image & IMAGE_TYPE_REMAP_2_PLUS) && (image & IMAGE_TYPE_REMAP)) { - if (((image >> 19) & 0x7F) == 32) { + if (image & IMAGE_TYPE_REMAP_2_PLUS) + { + palettes.x = TextureCache::PaletteToY((image >> 19) & 0x1F); + palettes.y = TextureCache::PaletteToY((image >> 24) & 0x1F); + if (image & IMAGE_TYPE_REMAP) + { + paletteCount = 2; + } + else + { + paletteCount = 3; + palettes.z = TextureCache::PaletteToY(tertiaryColour & 0xFF); + } + } + else if (image & IMAGE_TYPE_REMAP) + { + paletteCount = 1; + palettes.x = TextureCache::PaletteToY((image >> 19) & 0xFF); + if (palettes.x == 32) + { special = true; } } - - if (!((image & IMAGE_TYPE_REMAP_2_PLUS) && !(image & IMAGE_TYPE_REMAP))) { - tertiaryColour = 0; + else + { + paletteCount = 0; } - auto texture2 = _textureCache->GetOrLoadPaletteTexture(image, tertiaryColour, special); + if (special || (image & IMAGE_TYPE_TRANSPARENT)) + { + // ignore transparecy TODO + return; + } - DrawImageCommand& command = _commandBuffers.images.allocate(); + DrawRectCommand& command = _commandBuffers.rects.allocate(); command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom }; command.texColourAtlas = texture->index; command.texColourBounds = texture->normalizedBounds; command.texMaskAtlas = 0; - command.texMaskBounds = { 0.0f, 0.0f, 0.0f }; - command.texPaletteAtlas = texture2->index; - command.texPaletteBounds = texture2->computedBounds; + command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; + command.palettes = palettes; command.colour = 0; command.bounds = { left, top, right, bottom }; - command.mask = 0; - command.flags = 0; - - if (special) - { - command.flags |= DrawImageCommand::FLAG_TRANSPARENT_SPECIAL; - } - - if (image & IMAGE_TYPE_TRANSPARENT) - { - command.flags |= DrawImageCommand::FLAG_TRANSPARENT; - } - else if (image & (IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_REMAP)) - { - command.flags |= DrawImageCommand::FLAG_REMAP; - } + command.flags = paletteCount; } void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) @@ -728,23 +703,23 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm right += _clipLeft; bottom += _clipTop; - DrawImageCommand& command = _commandBuffers.images.allocate(); + DrawRectCommand& command = _commandBuffers.rects.allocate(); command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom }; command.texColourAtlas = textureColour->index; command.texColourBounds = textureColour->normalizedBounds; command.texMaskAtlas = textureMask->index; command.texMaskBounds = textureMask->normalizedBounds; - command.texPaletteAtlas = 0; - command.texPaletteBounds = {0.0f, 0.0f, 0.0f}; - command.flags = 0; + command.palettes = { 0, 0, 0 }; + command.flags = DrawRectCommand::FLAG_MASK; command.colour = 0; command.bounds = { left, top, right, bottom }; - command.mask = 1; } void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) { + assert((colour & 0xFF) > 0u); + sint32 g1Id = image & 0x7FFFF; rct_g1_element * g1Element = gfx_get_g1_element(g1Id); @@ -774,19 +749,17 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin right += _offsetX; bottom += _offsetY; - DrawImageCommand& command = _commandBuffers.images.allocate(); + DrawRectCommand& command = _commandBuffers.rects.allocate(); command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom }; - command.texColourAtlas = texture->index; - command.texColourBounds = texture->normalizedBounds; - command.texMaskAtlas = 0; - command.texMaskBounds = { 0.0f, 0.0f, 0.0f }; - command.texPaletteAtlas = texture->index; - command.texPaletteBounds = texture->computedBounds; - command.flags = DrawImageCommand::FLAG_COLOUR; + command.texColourAtlas = 0; + command.texColourBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; + command.texMaskAtlas = texture->index; + command.texMaskBounds = texture->normalizedBounds; + command.palettes = { 0, 0, 0 }; + command.flags = DrawRectCommand::FLAG_NO_TEXTURE | DrawRectCommand::FLAG_MASK; command.colour = colour & 0xFF; command.bounds = { left, top, right, bottom }; - command.mask = 0; } void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) @@ -820,43 +793,23 @@ void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * p right += _offsetX; bottom += _offsetY; - DrawImageCommand& command = _commandBuffers.images.allocate(); + DrawRectCommand& command = _commandBuffers.rects.allocate(); command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom }; command.texColourAtlas = texture.index; command.texColourBounds = texture.normalizedBounds; command.texMaskAtlas = 0; - command.texMaskBounds = { 0.0f, 0.0f, 0.0f }; - command.texPaletteAtlas = 0; - command.texPaletteBounds = { 0.0f, 0.0f, 0.0f}; + command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; + command.palettes = { 0, 0, 0 }; command.flags = 0; command.colour = 0; command.bounds = { left, top, right, bottom }; - command.mask = 0; } void OpenGLDrawingContext::FlushCommandBuffers() { - FlushRectangles(); FlushLines(); - FlushImages(); -} - -void OpenGLDrawingContext::FlushRectangles() -{ - for(size_t n = 0; n < _commandBuffers.rectangles.size(); n++) - { - const auto& command = _commandBuffers.rectangles[n]; - - _fillRectShader->Use(); - _fillRectShader->SetFlags(command.flags); - _fillRectShader->SetSourceFramebuffer(command.sourceFramebuffer); - _fillRectShader->SetClip(command.clip[0], command.clip[1], command.clip[2], command.clip[3]); - _fillRectShader->SetPaletteRemap(command.paletteRemap); - _fillRectShader->Draw(command.bounds[0], command.bounds[1], command.bounds[2], command.bounds[3]); - } - - _commandBuffers.rectangles.reset(); + FlushRectangles(); } void OpenGLDrawingContext::FlushLines() @@ -867,23 +820,24 @@ void OpenGLDrawingContext::FlushLines() _drawLineShader->Use(); _drawLineShader->SetColour(command.colour); - _drawLineShader->SetClip(command.clip[0], command.clip[1], command.clip[2], command.clip[3]); + _drawLineShader->SetClip(command.clip.x, command.clip.y, command.clip.z, command.clip.w); _drawLineShader->Draw(command.pos[0], command.pos[1], command.pos[2], command.pos[3]); } _commandBuffers.lines.reset(); } -void OpenGLDrawingContext::FlushImages() +void OpenGLDrawingContext::FlushRectangles() { - if (_commandBuffers.images.size() == 0) return; + if (_commandBuffers.rects.size() == 0) return; OpenGLAPI::SetTexture(0, GL_TEXTURE_2D_ARRAY, _textureCache->GetAtlasesTexture()); + OpenGLAPI::SetTexture(1, GL_TEXTURE_RECTANGLE, _textureCache->GetPaletteTexture()); - _drawImageShader->Use(); - _drawImageShader->DrawInstances(_commandBuffers.images); + _drawRectShader->Use(); + _drawRectShader->DrawInstances(_commandBuffers.rects); - _commandBuffers.images.reset(); + _commandBuffers.rects.reset(); } void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi) diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index fe61ba663d..f6455edaec 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -28,11 +28,6 @@ TextureCache::~TextureCache() FreeTextures(); } -void TextureCache::SetPalette(const SDL_Color * palette) -{ - Memory::CopyArray(_palette, palette, 256); -} - void TextureCache::InvalidateImage(uint32 image) { auto kvp = _imageTextureMap.find(image); @@ -59,42 +54,6 @@ const CachedTextureInfo* TextureCache::GetOrLoadImageTexture(uint32 image) return &(cacheItr.first->second); } -const CachedTextureInfo* TextureCache::GetOrLoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special) -{ - if ((image & (IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_TRANSPARENT)) == 0) - { - static CachedTextureInfo invalidEntry{ 0 }; - return &invalidEntry; - } - - uint32 uniquePaletteId = image & (IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_TRANSPARENT); - if (!(image & IMAGE_TYPE_REMAP_2_PLUS)) { - uniquePaletteId = (image >> 19) & 0xFF; - if (!(image & IMAGE_TYPE_TRANSPARENT)) { - uniquePaletteId &= 0x7F; - } - } - else { - uniquePaletteId |= ((image >> 19) & 0x1F); - uniquePaletteId |= ((image >> 24) & 0x1F) << 8; - - if (!(image & IMAGE_TYPE_REMAP)) { - uniquePaletteId |= tertiaryColour << 16; - } - } - - auto kvp = _paletteTextureMap.find(uniquePaletteId); - if (kvp != _paletteTextureMap.end()) - { - return &kvp->second; - } - - auto cacheInfo = LoadPaletteTexture(image, tertiaryColour, special); - auto cacheItr = _paletteTextureMap.insert(std::make_pair(uniquePaletteId, cacheInfo)); - - return &(cacheItr.first->second); -} - CachedTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * palette) { GlyphId glyphId; @@ -113,9 +72,9 @@ CachedTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * pale return cacheInfo; } -void TextureCache::CreateAtlasesTexture() +void TextureCache::CreateTextures() { - if (!_atlasesTextureInitialised) + if (!_initialized) { // Determine width and height to use for texture atlases glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_atlasesTextureDimensions); @@ -127,26 +86,50 @@ void TextureCache::CreateAtlasesTexture() glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &_atlasesTextureIndicesLimit); if (_atlasesTextureDimensions < _atlasesTextureIndicesLimit) _atlasesTextureIndicesLimit = _atlasesTextureDimensions; - AllocateAtlasesTexture(); + glGenTextures(1, &_atlasesTexture); + glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - _atlasesTextureInitialised = true; + glGenTextures(1, &_paletteTexture); + glBindTexture(GL_TEXTURE_RECTANGLE, _paletteTexture); + glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + GeneratePaletteTexture(); + + _initialized = true; _atlasesTextureIndices = 0; } } -void TextureCache::AllocateAtlasesTexture() +void TextureCache::GeneratePaletteTexture() { - // Create an array texture to hold all of the atlases - glGenTextures(1, &_atlasesTexture); - glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + rct_drawpixelinfo dpi = CreateDPI(256, PALETTE_TO_G1_OFFSET_COUNT + 5); + + // Init no-op palette + for (int i=0; i < 256; ++i) + { + dpi.bits[i] = i; + } + + for (int i=0; i < PALETTE_TO_G1_OFFSET_COUNT; ++i) + { + GLint y = PaletteToY(i); + uint16 image = palette_to_g1_offset[i]; + const rct_g1_element &element = g1Elements[image]; + gfx_draw_sprite_software(&dpi, image, -element.x_offset, y - element.y_offset, 0); + } + + glBindTexture(GL_TEXTURE_RECTANGLE, _paletteTexture); + glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_R8UI, 256, PALETTE_TO_G1_OFFSET_COUNT + 5, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi.bits); + DeleteDPI(dpi); } void TextureCache::EnlargeAtlasesTexture(GLuint newEntries) { - CreateAtlasesTexture(); + CreateTextures(); GLuint newIndices = _atlasesTextureIndices + newEntries; @@ -157,9 +140,7 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries) 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); - AllocateAtlasesTexture(); + glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8UI, _atlasesTextureDimensions, _atlasesTextureDimensions, newIndices, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr); // Restore old data @@ -170,12 +151,12 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries) CachedTextureInfo TextureCache::LoadImageTexture(uint32 image) { - rct_drawpixelinfo * dpi = GetImageAsDPI(image, 0); + rct_drawpixelinfo dpi = GetImageAsDPI(image, 0); - auto cacheInfo = AllocateImage(dpi->width, dpi->height); + auto cacheInfo = AllocateImage(dpi.width, dpi.height); glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture); - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, dpi->width, dpi->height, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi->bits); + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, dpi.width, dpi.height, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi.bits); DeleteDPI(dpi); @@ -190,61 +171,23 @@ CachedTextureInfo TextureCache::LoadImageTexture(uint32 image) return cacheInfo; } -CachedTextureInfo TextureCache::LoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special) +CachedTextureInfo TextureCache::LoadGlyphTexture(uint32 image, uint8 * palette) { - rct_drawpixelinfo dpi; - dpi.bits = gfx_draw_sprite_get_palette(image, tertiaryColour); - dpi.width = 256; - dpi.height = special ? 5 : 1; + rct_drawpixelinfo dpi = GetGlyphAsDPI(image, palette); + auto cacheInfo = AllocateImage(dpi.width, dpi.height); glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture); glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, dpi.width, dpi.height, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi.bits); - cacheInfo.computedBounds = - { - cacheInfo.normalizedBounds.x, - cacheInfo.normalizedBounds.y, - (cacheInfo.normalizedBounds.z - cacheInfo.normalizedBounds.x) / (float)(cacheInfo.bounds.z - cacheInfo.bounds.x), - (cacheInfo.normalizedBounds.w - cacheInfo.normalizedBounds.y) / (float)(cacheInfo.bounds.w - cacheInfo.bounds.y) - }; - - return cacheInfo; -} - -CachedTextureInfo TextureCache::LoadGlyphTexture(uint32 image, uint8 * palette) -{ - rct_drawpixelinfo * dpi = GetGlyphAsDPI(image, palette); - - auto cacheInfo = AllocateImage(dpi->width, dpi->height); - - glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture); - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, dpi->width, dpi->height, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi->bits); - DeleteDPI(dpi); return cacheInfo; } -void * TextureCache::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight) -{ - rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF); - sint32 width = g1Element->width; - sint32 height = g1Element->height; - - rct_drawpixelinfo * dpi = CreateDPI(width, height); - gfx_draw_sprite_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour); - void * pixels32 = ConvertDPIto32bpp(dpi); - DeleteDPI(dpi); - - *outWidth = width; - *outHeight = height; - return pixels32; -} - CachedTextureInfo TextureCache::AllocateImage(sint32 imageWidth, sint32 imageHeight) { - CreateAtlasesTexture(); + CreateTextures(); // Find an atlas that fits this image for (Atlas& atlas : _atlases) @@ -278,73 +221,28 @@ CachedTextureInfo TextureCache::AllocateImage(sint32 imageWidth, sint32 imageHei return _atlases.back().Allocate(imageWidth, imageHeight); } -rct_drawpixelinfo * TextureCache::GetImageAsDPI(uint32 image, uint32 tertiaryColour) +rct_drawpixelinfo TextureCache::GetImageAsDPI(uint32 image, uint32 tertiaryColour) { rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF); sint32 width = g1Element->width; sint32 height = g1Element->height; - rct_drawpixelinfo * dpi = CreateDPI(width, height); - gfx_draw_sprite_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour); + rct_drawpixelinfo dpi = CreateDPI(width, height); + gfx_draw_sprite_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour); return dpi; } -void * TextureCache::GetGlyphAsARGB(uint32 image, uint8 * palette, uint32 * outWidth, uint32 * outHeight) +rct_drawpixelinfo TextureCache::GetGlyphAsDPI(uint32 image, uint8 * palette) { rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF); sint32 width = g1Element->width; sint32 height = g1Element->height; - rct_drawpixelinfo * dpi = CreateDPI(width, height); - gfx_draw_sprite_palette_set_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, palette, nullptr); - void * pixels32 = ConvertDPIto32bpp(dpi); - DeleteDPI(dpi); - - *outWidth = width; - *outHeight = height; - return pixels32; -} - -rct_drawpixelinfo * TextureCache::GetGlyphAsDPI(uint32 image, uint8 * palette) -{ - rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF); - sint32 width = g1Element->width; - sint32 height = g1Element->height; - - rct_drawpixelinfo * dpi = CreateDPI(width, height); - gfx_draw_sprite_palette_set_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, palette, nullptr); + rct_drawpixelinfo dpi = CreateDPI(width, height); + gfx_draw_sprite_palette_set_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, palette, nullptr); return dpi; } -void * TextureCache::ConvertDPIto32bpp(const rct_drawpixelinfo * dpi) -{ - size_t numPixels = dpi->width * dpi->height; - uint8 * pixels32 = Memory::Allocate(numPixels * 4); - uint8 * src = dpi->bits; - uint8 * dst = pixels32; - for (size_t i = 0; i < numPixels; i++) - { - uint8 paletteIndex = *src++; - if (paletteIndex == 0) - { - // Transparent - *dst++ = 0; - *dst++ = 0; - *dst++ = 0; - *dst++ = 0; - } - else - { - SDL_Color colour = _palette[paletteIndex]; - *dst++ = colour.r; - *dst++ = colour.g; - *dst++ = colour.b; - *dst++ = colour.a; - } - } - return pixels32; -} - void TextureCache::FreeTextures() { // Free array texture @@ -352,27 +250,26 @@ void TextureCache::FreeTextures() _imageTextureMap.clear(); } -rct_drawpixelinfo * TextureCache::CreateDPI(sint32 width, sint32 height) +rct_drawpixelinfo TextureCache::CreateDPI(sint32 width, sint32 height) { size_t numPixels = width * height; uint8 * pixels8 = Memory::Allocate(numPixels); Memory::Set(pixels8, 0, numPixels); - rct_drawpixelinfo * dpi = new rct_drawpixelinfo(); - dpi->bits = pixels8; - dpi->pitch = 0; - dpi->x = 0; - dpi->y = 0; - dpi->width = width; - dpi->height = height; - dpi->zoom_level = 0; + rct_drawpixelinfo dpi; + dpi.bits = pixels8; + dpi.pitch = 0; + dpi.x = 0; + dpi.y = 0; + dpi.width = width; + dpi.height = height; + dpi.zoom_level = 0; return dpi; } -void TextureCache::DeleteDPI(rct_drawpixelinfo* dpi) +void TextureCache::DeleteDPI(rct_drawpixelinfo dpi) { - Memory::Free(dpi->bits); - delete dpi; + Memory::Free(dpi.bits); } GLuint TextureCache::GetAtlasesTexture() @@ -380,4 +277,14 @@ GLuint TextureCache::GetAtlasesTexture() return _atlasesTexture; } +GLuint TextureCache::GetPaletteTexture() +{ + return _paletteTexture; +} + +GLint TextureCache::PaletteToY(uint32 palette) +{ + return palette > PALETTE_WATER ? palette + 5 : palette + 1; +} + #endif /* DISABLE_OPENGL */ diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h index 906492cb0e..21879fc27c 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h @@ -188,7 +188,7 @@ private: class TextureCache final { private: - bool _atlasesTextureInitialised = false; + bool _initialized = false; GLuint _atlasesTexture = 0; GLint _atlasesTextureDimensions = 0; @@ -200,34 +200,30 @@ private: std::unordered_map _imageTextureMap; std::unordered_map _paletteTextureMap; - SDL_Color _palette[256]; + GLuint _paletteTexture = 0; public: TextureCache() = default; ~TextureCache(); - void SetPalette(const SDL_Color * palette); void InvalidateImage(uint32 image); const CachedTextureInfo* GetOrLoadImageTexture(uint32 image); CachedTextureInfo GetOrLoadGlyphTexture(uint32 image, uint8 * palette); - const CachedTextureInfo* GetOrLoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special); GLuint GetAtlasesTexture(); + GLuint GetPaletteTexture(); + static GLint PaletteToY(uint32 palette); private: - void CreateAtlasesTexture(); - void AllocateAtlasesTexture(); + void CreateTextures(); + void GeneratePaletteTexture(); void EnlargeAtlasesTexture(GLuint newEntries); CachedTextureInfo LoadImageTexture(uint32 image); CachedTextureInfo LoadGlyphTexture(uint32 image, uint8 * palette); - CachedTextureInfo LoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special); CachedTextureInfo AllocateImage(sint32 imageWidth, sint32 imageHeight); - void * GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight); - rct_drawpixelinfo * GetImageAsDPI(uint32 image, uint32 tertiaryColour); - void * GetGlyphAsARGB(uint32 image, uint8 * palette, uint32 * outWidth, uint32 * outHeight); - rct_drawpixelinfo * GetGlyphAsDPI(uint32 image, uint8 * palette); - void * ConvertDPIto32bpp(const rct_drawpixelinfo * dpi); + rct_drawpixelinfo GetImageAsDPI(uint32 image, uint32 tertiaryColour); + rct_drawpixelinfo GetGlyphAsDPI(uint32 image, uint8 * palette); void FreeTextures(); - static rct_drawpixelinfo * CreateDPI(sint32 width, sint32 height); - static void DeleteDPI(rct_drawpixelinfo * dpi); + static rct_drawpixelinfo CreateDPI(sint32 width, sint32 height); + static void DeleteDPI(rct_drawpixelinfo dpi); };