1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-10 09:32:29 +01:00

Fix #21824, #22820: OpenGL draws downscaled and masked sprites wrong

This commit is contained in:
mix
2025-04-03 23:01:40 +01:00
committed by GitHub
parent 9fb0ba0f3d
commit 69016f546e
9 changed files with 119 additions and 88 deletions

View File

@@ -13,14 +13,19 @@ uniform usampler2D uPaletteTex;
uniform sampler2D uPeelingTex; uniform sampler2D uPeelingTex;
uniform bool uPeeling; uniform bool uPeeling;
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord;
flat in int fFlags; flat in int fFlags;
flat in uint fColour; flat in uint fColour;
in vec3 fTexColour; flat in vec4 fTexColour;
in vec3 fTexMask; flat in vec4 fTexMask;
flat in vec3 fPalettes; flat in vec3 fPalettes;
in vec2 fPosition; flat in vec2 fPosition;
in vec3 fPeelPos; in vec3 fPeelPos;
flat in float fZoom;
flat in int fTexColourAtlas;
flat in int fTexMaskAtlas;
// clang-format on // clang-format on
out uint oColour; out uint oColour;
@@ -36,10 +41,14 @@ void main()
} }
} }
vec2 position = (gl_FragCoord.xy - fPosition) * fZoom;
uint texel; uint texel;
if ((fFlags & FLAG_NO_TEXTURE) == 0) if ((fFlags & FLAG_NO_TEXTURE) == 0)
{ {
texel = texture(uTexture, fTexColour).r; float colourU = (fTexColour.x + position.x) / fTexColour.z;
float colourV = (fTexColour.y + position.y) / fTexColour.w;
texel = texture(uTexture, vec3(colourU, colourV, fTexColourAtlas)).r;
if (texel == 0u) if (texel == 0u)
{ {
discard; discard;
@@ -93,8 +102,8 @@ void main()
if ((fFlags & FLAG_CROSS_HATCH) != 0) if ((fFlags & FLAG_CROSS_HATCH) != 0)
{ {
int posSum = int(fPosition.x) + int(fPosition.y); int posSum = int(position.x) + int(position.y);
if ((posSum % 2) == 0) if ((posSum % 2) != 0)
{ {
discard; discard;
} }
@@ -102,7 +111,9 @@ void main()
if ((fFlags & FLAG_MASK) != 0) if ((fFlags & FLAG_MASK) != 0)
{ {
uint mask = texture(uTexture, fTexMask).r; float maskU = (fTexMask.x + position.x) / fTexMask.z;
float maskV = (fTexMask.y + position.y) / fTexMask.w;
uint mask = texture(uTexture, vec3(maskU, maskV, fTexMaskAtlas)).r;
if (mask == 0u) if (mask == 0u)
{ {
discard; discard;

View File

@@ -8,25 +8,29 @@ uniform ivec2 uScreenSize;
// clang-format off // clang-format off
in ivec4 vClip; in ivec4 vClip;
in int vTexColourAtlas; in int vTexColourAtlas;
in vec4 vTexColourBounds; in vec4 vTexColourCoords;
in int vTexMaskAtlas; in int vTexMaskAtlas;
in vec4 vTexMaskBounds; in vec4 vTexMaskCoords;
in ivec3 vPalettes; in ivec3 vPalettes;
in int vFlags; in int vFlags;
in uint vColour; in uint vColour;
in ivec4 vBounds; in ivec4 vBounds;
in int vDepth; in int vDepth;
in float vZoom;
in mat4x2 vVertMat; in mat4x2 vVertMat;
in vec2 vVertVec; in vec2 vVertVec;
out vec2 fPosition; flat out vec2 fPosition;
out vec3 fPeelPos; out vec3 fPeelPos;
flat out int fFlags; flat out int fFlags;
flat out uint fColour; flat out uint fColour;
out vec3 fTexColour; flat out vec4 fTexColour;
out vec3 fTexMask; flat out vec4 fTexMask;
flat out vec3 fPalettes; flat out vec3 fPalettes;
flat out float fZoom;
flat out int fTexColourAtlas;
flat out int fTexMaskAtlas;
// clang-format on // clang-format on
void main() void main()
@@ -35,10 +39,13 @@ void main()
vec2 m = clamp( vec2 m = clamp(
((vVertMat * vec4(vClip)) - (vVertMat * vec4(vBounds))) / vec2(vBounds.zw - vBounds.xy) + vVertVec, 0.0, 1.0); ((vVertMat * vec4(vClip)) - (vVertMat * vec4(vBounds))) / vec2(vBounds.zw - vBounds.xy) + vVertVec, 0.0, 1.0);
vec2 pos = mix(vec2(vBounds.xy), vec2(vBounds.zw), m); vec2 pos = mix(vec2(vBounds.xy), vec2(vBounds.zw), m);
fTexColour = vec3(mix(vTexColourBounds.xy, vTexColourBounds.zw, m), vTexColourAtlas); fTexColour = vTexColourCoords;
fTexMask = vec3(mix(vTexMaskBounds.xy, vTexMaskBounds.zw, m), vTexMaskAtlas); fTexMask = vTexMaskCoords;
fPosition = pos; fPosition = vBounds.xy;
fZoom = vZoom;
fTexColourAtlas = vTexColourAtlas;
fTexMaskAtlas = vTexMaskAtlas;
// Transform screen coordinates to texture coordinates // Transform screen coordinates to texture coordinates
float depth = 1.0 - (float(vDepth) + 1.0) * DEPTH_INCREMENT; float depth = 1.0 - (float(vDepth) + 1.0) * DEPTH_INCREMENT;

View File

@@ -20,7 +20,10 @@
- Fix: [#18169] CJK, Arabic and Vietnamese display all text as ??? on Android. - Fix: [#18169] CJK, Arabic and Vietnamese display all text as ??? on Android.
- Fix: [#18309] Flying and Multi Dimension trains glitch when changing between inverted and uninverted track when uncap fps is on. - Fix: [#18309] Flying and Multi Dimension trains glitch when changing between inverted and uninverted track when uncap fps is on.
- Fix: [#19506] Queue paths can be placed on level crossings by replacing an existing regular path. - Fix: [#19506] Queue paths can be placed on level crossings by replacing an existing regular path.
- Fix: [#21803] The park fence is drawn differently in OpenGL compared to software rendering when zoomed out.
- Fix: [#21824] Some sprites are drawn incorrectly when zoomed out in OpenGL rendering.
- Fix: [#21908] Ride mode warnings when hovering track designs. - Fix: [#21908] Ride mode warnings when hovering track designs.
- Fix: [#22820] OpenGL does not draw masked sprites correctly.
- Fix: [#22961] Clicking on the construction preview places duplicate flat rides and stalls. - Fix: [#22961] Clicking on the construction preview places duplicate flat rides and stalls.
- Fix: [#23359] Scripting: Add car.moveToTrack, an easier API than setting car.trackLocation directly. - Fix: [#23359] Scripting: Add car.moveToTrack, an easier API than setting car.trackLocation directly.
- Fix: [#23443] New GOG version of RCT2 is not extracted correctly. - Fix: [#23443] New GOG version of RCT2 is not extracted correctly.

View File

@@ -112,6 +112,7 @@ namespace OpenRCT2::Ui
GLuint colour; GLuint colour;
ivec4 bounds; ivec4 bounds;
GLint depth; GLint depth;
GLfloat zoom;
enum enum
{ {

View File

@@ -64,12 +64,12 @@ DrawRectShader::DrawRectShader()
vTexColourAtlas, 1, GL_INT, sizeof(DrawRectCommand), vTexColourAtlas, 1, GL_INT, sizeof(DrawRectCommand),
reinterpret_cast<void*>(offsetof(DrawRectCommand, texColourAtlas))); reinterpret_cast<void*>(offsetof(DrawRectCommand, texColourAtlas)));
glVertexAttribPointer( glVertexAttribPointer(
vTexColourBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand), vTexColourCoords, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand),
reinterpret_cast<void*>(offsetof(DrawRectCommand, texColourBounds))); reinterpret_cast<void*>(offsetof(DrawRectCommand, texColourBounds)));
glVertexAttribIPointer( glVertexAttribIPointer(
vTexMaskAtlas, 1, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, texMaskAtlas))); vTexMaskAtlas, 1, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, texMaskAtlas)));
glVertexAttribPointer( glVertexAttribPointer(
vTexMaskBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand), vTexMaskCoords, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand),
reinterpret_cast<void*>(offsetof(DrawRectCommand, texMaskBounds))); reinterpret_cast<void*>(offsetof(DrawRectCommand, texMaskBounds)));
glVertexAttribIPointer( glVertexAttribIPointer(
vPalettes, 3, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, palettes))); vPalettes, 3, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, palettes)));
@@ -81,6 +81,8 @@ DrawRectShader::DrawRectShader()
vBounds, 4, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, bounds))); vBounds, 4, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, bounds)));
glVertexAttribIPointer( glVertexAttribIPointer(
vDepth, 1, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, depth))); vDepth, 1, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, depth)));
glVertexAttribPointer(
vZoom, 1, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, zoom)));
glEnableVertexAttribArray(vVertMat + 0); glEnableVertexAttribArray(vVertMat + 0);
glEnableVertexAttribArray(vVertMat + 1); glEnableVertexAttribArray(vVertMat + 1);
@@ -90,25 +92,27 @@ DrawRectShader::DrawRectShader()
glEnableVertexAttribArray(vClip); glEnableVertexAttribArray(vClip);
glEnableVertexAttribArray(vTexColourAtlas); glEnableVertexAttribArray(vTexColourAtlas);
glEnableVertexAttribArray(vTexColourBounds); glEnableVertexAttribArray(vTexColourCoords);
glEnableVertexAttribArray(vTexMaskAtlas); glEnableVertexAttribArray(vTexMaskAtlas);
glEnableVertexAttribArray(vTexMaskBounds); glEnableVertexAttribArray(vTexMaskCoords);
glEnableVertexAttribArray(vPalettes); glEnableVertexAttribArray(vPalettes);
glEnableVertexAttribArray(vFlags); glEnableVertexAttribArray(vFlags);
glEnableVertexAttribArray(vColour); glEnableVertexAttribArray(vColour);
glEnableVertexAttribArray(vBounds); glEnableVertexAttribArray(vBounds);
glEnableVertexAttribArray(vDepth); glEnableVertexAttribArray(vDepth);
glEnableVertexAttribArray(vZoom);
glVertexAttribDivisor(vClip, 1); glVertexAttribDivisor(vClip, 1);
glVertexAttribDivisor(vTexColourAtlas, 1); glVertexAttribDivisor(vTexColourAtlas, 1);
glVertexAttribDivisor(vTexColourBounds, 1); glVertexAttribDivisor(vTexColourCoords, 1);
glVertexAttribDivisor(vTexMaskAtlas, 1); glVertexAttribDivisor(vTexMaskAtlas, 1);
glVertexAttribDivisor(vTexMaskBounds, 1); glVertexAttribDivisor(vTexMaskCoords, 1);
glVertexAttribDivisor(vPalettes, 1); glVertexAttribDivisor(vPalettes, 1);
glVertexAttribDivisor(vFlags, 1); glVertexAttribDivisor(vFlags, 1);
glVertexAttribDivisor(vColour, 1); glVertexAttribDivisor(vColour, 1);
glVertexAttribDivisor(vBounds, 1); glVertexAttribDivisor(vBounds, 1);
glVertexAttribDivisor(vDepth, 1); glVertexAttribDivisor(vDepth, 1);
glVertexAttribDivisor(vZoom, 1);
Use(); Use();
glUniform1i(uTexture, 0); glUniform1i(uTexture, 0);
@@ -136,14 +140,15 @@ void DrawRectShader::GetLocations()
vClip = GetAttributeLocation("vClip"); vClip = GetAttributeLocation("vClip");
vTexColourAtlas = GetAttributeLocation("vTexColourAtlas"); vTexColourAtlas = GetAttributeLocation("vTexColourAtlas");
vTexColourBounds = GetAttributeLocation("vTexColourBounds"); vTexColourCoords = GetAttributeLocation("vTexColourCoords");
vTexMaskAtlas = GetAttributeLocation("vTexMaskAtlas"); vTexMaskAtlas = GetAttributeLocation("vTexMaskAtlas");
vTexMaskBounds = GetAttributeLocation("vTexMaskBounds"); vTexMaskCoords = GetAttributeLocation("vTexMaskCoords");
vPalettes = GetAttributeLocation("vPalettes"); vPalettes = GetAttributeLocation("vPalettes");
vFlags = GetAttributeLocation("vFlags"); vFlags = GetAttributeLocation("vFlags");
vColour = GetAttributeLocation("vColour"); vColour = GetAttributeLocation("vColour");
vBounds = GetAttributeLocation("vBounds"); vBounds = GetAttributeLocation("vBounds");
vDepth = GetAttributeLocation("vDepth"); vDepth = GetAttributeLocation("vDepth");
vZoom = GetAttributeLocation("vZoom");
vVertMat = GetAttributeLocation("vVertMat"); vVertMat = GetAttributeLocation("vVertMat");
vVertVec = GetAttributeLocation("vVertVec"); vVertVec = GetAttributeLocation("vVertVec");

View File

@@ -31,14 +31,15 @@ namespace OpenRCT2::Ui
GLuint vClip; GLuint vClip;
GLuint vTexColourAtlas; GLuint vTexColourAtlas;
GLuint vTexColourBounds; GLuint vTexColourCoords;
GLuint vTexMaskAtlas; GLuint vTexMaskAtlas;
GLuint vTexMaskBounds; GLuint vTexMaskCoords;
GLuint vPalettes; GLuint vPalettes;
GLuint vFlags; GLuint vFlags;
GLuint vColour; GLuint vColour;
GLuint vBounds; GLuint vBounds;
GLuint vDepth; GLuint vDepth;
GLuint vZoom;
GLuint _vbo; GLuint _vbo;
GLuint _vboInstances; GLuint _vboInstances;

View File

@@ -534,6 +534,7 @@ void OpenGLDrawingContext::FillRect(
command.bounds = { left, top, right + 1, bottom + 1 }; command.bounds = { left, top, right + 1, bottom + 1 };
command.flags = DrawRectCommand::FLAG_NO_TEXTURE; command.flags = DrawRectCommand::FLAG_NO_TEXTURE;
command.depth = _drawCount++; command.depth = _drawCount++;
command.zoom = 1.0f;
if (colour & 0x1000000) if (colour & 0x1000000)
{ {
@@ -569,6 +570,7 @@ void OpenGLDrawingContext::FilterRect(
command.bounds = { left, top, right + 1, bottom + 1 }; command.bounds = { left, top, right + 1, bottom + 1 };
command.flags = DrawRectCommand::FLAG_NO_TEXTURE; command.flags = DrawRectCommand::FLAG_NO_TEXTURE;
command.depth = _drawCount++; command.depth = _drawCount++;
command.zoom = 1.0f;
} }
// Compute the bit code for a point p relative to the clip rectangle defined by topLeft and bottomRight // Compute the bit code for a point p relative to the clip rectangle defined by topLeft and bottomRight
@@ -676,7 +678,13 @@ void OpenGLDrawingContext::DrawLine(DrawPixelInfo& dpi, uint32_t colour, const S
command.depth = _drawCount++; command.depth = _drawCount++;
} }
void OpenGLDrawingContext::DrawSprite(DrawPixelInfo& dpi, const ImageId imageId, int32_t x, int32_t y) static auto EuclideanRemainder(const auto a, const auto b)
{
const auto r = a % b;
return r >= 0 ? r : r + b;
};
void OpenGLDrawingContext::DrawSprite(DrawPixelInfo& dpi, const ImageId imageId, const int32_t x, const int32_t y)
{ {
auto g1Element = GfxGetG1Element(imageId); auto g1Element = GfxGetG1Element(imageId);
if (g1Element == nullptr) if (g1Element == nullptr)
@@ -705,48 +713,33 @@ void OpenGLDrawingContext::DrawSprite(DrawPixelInfo& dpi, const ImageId imageId,
} }
} }
auto texture = _textureCache->GetOrLoadImageTexture(imageId);
int32_t left = x + g1Element->x_offset; int32_t left = x + g1Element->x_offset;
int32_t top = y + g1Element->y_offset; int32_t top = y + g1Element->y_offset;
int32_t zoom_mask; int32_t xModifier = 0;
if (dpi.zoom_level >= ZoomLevel{ 0 }) int32_t yModifier = 0;
zoom_mask = dpi.zoom_level.ApplyTo(0xFFFFFFFF); int32_t widthModifier = 0;
else
zoom_mask = 0xFFFFFFFF; if (dpi.zoom_level > ZoomLevel{ 0 })
if (dpi.zoom_level != ZoomLevel{ 0 } && (g1Element->flags & G1_FLAG_RLE_COMPRESSION))
{ {
top -= ~zoom_mask; const int32_t interval = dpi.zoom_level.ApplyTo(1);
xModifier = EuclideanRemainder(left, interval);
xModifier = xModifier ? interval - xModifier : 0;
yModifier = EuclideanRemainder(top, interval);
widthModifier = EuclideanRemainder(left + g1Element->width, interval);
widthModifier = widthModifier ? interval - widthModifier : 0;
texture.coords.x += xModifier;
texture.coords.y += (interval - 1) - yModifier;
} }
if (!(g1Element->flags & G1_FLAG_RLE_COMPRESSION)) left = dpi.zoom_level.ApplyInversedTo(left + xModifier);
{
top &= zoom_mask;
left += ~zoom_mask;
}
left &= zoom_mask;
int32_t right = left + g1Element->width;
int32_t bottom = top + g1Element->height;
if (dpi.zoom_level != ZoomLevel{ 0 } && (g1Element->flags & G1_FLAG_RLE_COMPRESSION))
{
bottom += top & ~zoom_mask;
}
if (left > right)
{
std::swap(left, right);
}
if (top > bottom)
{
std::swap(top, bottom);
}
left = dpi.zoom_level.ApplyInversedTo(left);
top = dpi.zoom_level.ApplyInversedTo(top); top = dpi.zoom_level.ApplyInversedTo(top);
right = dpi.zoom_level.ApplyInversedTo(right); int32_t right = left + dpi.zoom_level.ApplyInversedTo(g1Element->width + widthModifier);
bottom = dpi.zoom_level.ApplyInversedTo(bottom); int32_t bottom = top + dpi.zoom_level.ApplyInversedTo(g1Element->height + yModifier);
const ScreenRect clip = CalculateClipping(dpi); const ScreenRect clip = CalculateClipping(dpi);
left += clip.GetLeft() - dpi.x; left += clip.GetLeft() - dpi.x;
@@ -754,7 +747,8 @@ void OpenGLDrawingContext::DrawSprite(DrawPixelInfo& dpi, const ImageId imageId,
right += clip.GetLeft() - dpi.x; right += clip.GetLeft() - dpi.x;
bottom += clip.GetTop() - dpi.y; bottom += clip.GetTop() - dpi.y;
const auto texture = _textureCache->GetOrLoadImageTexture(imageId); const float zoom = dpi.zoom_level >= ZoomLevel{ 0 } ? static_cast<float>(dpi.zoom_level.ApplyTo(1))
: 1.0f / static_cast<float>(dpi.zoom_level.ApplyInversedTo(1));
int paletteCount; int paletteCount;
ivec3 palettes{}; ivec3 palettes{};
@@ -794,14 +788,15 @@ void OpenGLDrawingContext::DrawSprite(DrawPixelInfo& dpi, const ImageId imageId,
command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() }; command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() };
command.texColourAtlas = texture.index; command.texColourAtlas = texture.index;
command.texColourBounds = texture.normalizedBounds; command.texColourBounds = texture.coords;
command.texMaskAtlas = texture.index; command.texMaskAtlas = texture.index;
command.texMaskBounds = texture.normalizedBounds; command.texMaskBounds = texture.coords;
command.palettes = palettes; command.palettes = palettes;
command.colour = palettes.x - (special ? 1 : 0); command.colour = palettes.x - (special ? 1 : 0);
command.bounds = { left, top, right, bottom }; command.bounds = { left, top, right, bottom };
command.flags = special ? 0 : DrawRectCommand::FLAG_NO_TEXTURE | DrawRectCommand::FLAG_MASK; command.flags = special ? 0 : DrawRectCommand::FLAG_NO_TEXTURE | DrawRectCommand::FLAG_MASK;
command.depth = _drawCount++; command.depth = _drawCount++;
command.zoom = zoom;
} }
else else
{ {
@@ -809,14 +804,15 @@ void OpenGLDrawingContext::DrawSprite(DrawPixelInfo& dpi, const ImageId imageId,
command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() }; command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() };
command.texColourAtlas = texture.index; command.texColourAtlas = texture.index;
command.texColourBounds = texture.normalizedBounds; command.texColourBounds = texture.coords;
command.texMaskAtlas = 0; command.texMaskAtlas = 0;
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; command.texMaskBounds = { 0.0f, 0.0f, texture.coords.z, texture.coords.w };
command.palettes = palettes; command.palettes = palettes;
command.colour = 0; command.colour = 0;
command.bounds = { left, top, right, bottom }; command.bounds = { left, top, right, bottom };
command.flags = paletteCount; command.flags = paletteCount;
command.depth = _drawCount++; command.depth = _drawCount++;
command.zoom = zoom;
} }
} }
@@ -863,18 +859,22 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(
right += clip.GetLeft() - dpi.x; right += clip.GetLeft() - dpi.x;
bottom += clip.GetTop() - dpi.y; bottom += clip.GetTop() - dpi.y;
const float zoom = dpi.zoom_level >= ZoomLevel{ 0 } ? static_cast<float>(dpi.zoom_level.ApplyTo(1))
: 1.0f / static_cast<float>(dpi.zoom_level.ApplyInversedTo(1));
DrawRectCommand& command = _commandBuffers.rects.allocate(); DrawRectCommand& command = _commandBuffers.rects.allocate();
command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() }; command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() };
command.texColourAtlas = textureColour.index; command.texColourAtlas = textureColour.index;
command.texColourBounds = textureColour.normalizedBounds; command.texColourBounds = textureColour.coords;
command.texMaskAtlas = textureMask.index; command.texMaskAtlas = textureMask.index;
command.texMaskBounds = textureMask.normalizedBounds; command.texMaskBounds = textureMask.coords;
command.palettes = { 0, 0, 0 }; command.palettes = { 0, 0, 0 };
command.flags = DrawRectCommand::FLAG_MASK; command.flags = DrawRectCommand::FLAG_MASK;
command.colour = 0; command.colour = 0;
command.bounds = { left, top, right, bottom }; command.bounds = { left, top, right, bottom };
command.depth = _drawCount++; command.depth = _drawCount++;
command.zoom = zoom;
} }
void OpenGLDrawingContext::DrawSpriteSolid(DrawPixelInfo& dpi, const ImageId image, int32_t x, int32_t y, uint8_t colour) void OpenGLDrawingContext::DrawSpriteSolid(DrawPixelInfo& dpi, const ImageId image, int32_t x, int32_t y, uint8_t colour)
@@ -918,12 +918,13 @@ void OpenGLDrawingContext::DrawSpriteSolid(DrawPixelInfo& dpi, const ImageId ima
command.texColourAtlas = 0; command.texColourAtlas = 0;
command.texColourBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; command.texColourBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
command.texMaskAtlas = texture.index; command.texMaskAtlas = texture.index;
command.texMaskBounds = texture.normalizedBounds; command.texMaskBounds = texture.coords;
command.palettes = { 0, 0, 0 }; command.palettes = { 0, 0, 0 };
command.flags = DrawRectCommand::FLAG_NO_TEXTURE | DrawRectCommand::FLAG_MASK; command.flags = DrawRectCommand::FLAG_NO_TEXTURE | DrawRectCommand::FLAG_MASK;
command.colour = colour & 0xFF; command.colour = colour & 0xFF;
command.bounds = { left, top, right, bottom }; command.bounds = { left, top, right, bottom };
command.depth = _drawCount++; command.depth = _drawCount++;
command.zoom = 1.0f;
} }
void OpenGLDrawingContext::DrawGlyph(DrawPixelInfo& dpi, const ImageId image, int32_t x, int32_t y, const PaletteMap& palette) void OpenGLDrawingContext::DrawGlyph(DrawPixelInfo& dpi, const ImageId image, int32_t x, int32_t y, const PaletteMap& palette)
@@ -961,11 +962,14 @@ void OpenGLDrawingContext::DrawGlyph(DrawPixelInfo& dpi, const ImageId image, in
right += clip.GetLeft() - dpi.x; right += clip.GetLeft() - dpi.x;
bottom += clip.GetTop() - dpi.y; bottom += clip.GetTop() - dpi.y;
const float zoom = dpi.zoom_level >= ZoomLevel{ 0 } ? static_cast<float>(dpi.zoom_level.ApplyTo(1))
: 1.0f / static_cast<float>(dpi.zoom_level.ApplyInversedTo(1));
DrawRectCommand& command = _commandBuffers.rects.allocate(); DrawRectCommand& command = _commandBuffers.rects.allocate();
command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() }; command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() };
command.texColourAtlas = texture.index; command.texColourAtlas = texture.index;
command.texColourBounds = texture.normalizedBounds; command.texColourBounds = texture.coords;
command.texMaskAtlas = 0; command.texMaskAtlas = 0;
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
command.palettes = { 0, 0, 0 }; command.palettes = { 0, 0, 0 };
@@ -973,6 +977,7 @@ void OpenGLDrawingContext::DrawGlyph(DrawPixelInfo& dpi, const ImageId image, in
command.colour = 0; command.colour = 0;
command.bounds = { left, top, right, bottom }; command.bounds = { left, top, right, bottom };
command.depth = _drawCount++; command.depth = _drawCount++;
command.zoom = zoom;
} }
void OpenGLDrawingContext::DrawTTFBitmap( void OpenGLDrawingContext::DrawTTFBitmap(
@@ -1027,7 +1032,7 @@ void OpenGLDrawingContext::DrawTTFBitmap(
DrawRectCommand& command = _commandBuffers.rects.allocate(); DrawRectCommand& command = _commandBuffers.rects.allocate();
command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() }; command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() };
command.texColourAtlas = texture.index; command.texColourAtlas = texture.index;
command.texColourBounds = texture.normalizedBounds; command.texColourBounds = texture.coords;
command.texMaskAtlas = 0; command.texMaskAtlas = 0;
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
command.palettes = { 0, 0, 0 }; command.palettes = { 0, 0, 0 };
@@ -1035,6 +1040,7 @@ void OpenGLDrawingContext::DrawTTFBitmap(
command.colour = info->palette[3]; command.colour = info->palette[3];
command.bounds = b; command.bounds = b;
command.depth = _drawCount++; command.depth = _drawCount++;
command.zoom = 1.0f;
} }
} }
if (info->flags & TEXT_DRAW_FLAG_INSET) if (info->flags & TEXT_DRAW_FLAG_INSET)
@@ -1042,7 +1048,7 @@ void OpenGLDrawingContext::DrawTTFBitmap(
DrawRectCommand& command = _commandBuffers.rects.allocate(); DrawRectCommand& command = _commandBuffers.rects.allocate();
command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() }; command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() };
command.texColourAtlas = texture.index; command.texColourAtlas = texture.index;
command.texColourBounds = texture.normalizedBounds; command.texColourBounds = texture.coords;
command.texMaskAtlas = 0; command.texMaskAtlas = 0;
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
command.palettes = { 0, 0, 0 }; command.palettes = { 0, 0, 0 };
@@ -1050,12 +1056,13 @@ void OpenGLDrawingContext::DrawTTFBitmap(
command.colour = info->palette[3]; command.colour = info->palette[3];
command.bounds = { left + 1, top + 1, right + 1, bottom + 1 }; command.bounds = { left + 1, top + 1, right + 1, bottom + 1 };
command.depth = _drawCount++; command.depth = _drawCount++;
command.zoom = 1.0f;
} }
auto& cmdBuf = hintingThreshold > 0 ? _commandBuffers.transparent : _commandBuffers.rects; auto& cmdBuf = hintingThreshold > 0 ? _commandBuffers.transparent : _commandBuffers.rects;
DrawRectCommand& command = cmdBuf.allocate(); DrawRectCommand& command = cmdBuf.allocate();
command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() }; command.clip = { clip.GetLeft(), clip.GetTop(), clip.GetRight(), clip.GetBottom() };
command.texColourAtlas = texture.index; command.texColourAtlas = texture.index;
command.texColourBounds = texture.normalizedBounds; command.texColourBounds = texture.coords;
command.texMaskAtlas = 0; command.texMaskAtlas = 0;
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f }; command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
command.palettes = { 0, 0, 0 }; command.palettes = { 0, 0, 0 };
@@ -1063,6 +1070,7 @@ void OpenGLDrawingContext::DrawTTFBitmap(
command.colour = info->palette[1]; command.colour = info->palette[1];
command.bounds = { left, top, right, bottom }; command.bounds = { left, top, right, bottom };
command.depth = _drawCount++; command.depth = _drawCount++;
command.zoom = 1.0f;
#endif // NO_TTF #endif // NO_TTF
} }

View File

@@ -83,7 +83,7 @@ BasicTextureInfo TextureCache::GetOrLoadImageTexture(const ImageId imageId)
const auto& info = _textureCache[index]; const auto& info = _textureCache[index];
return { return {
info.index, info.index,
info.normalizedBounds, info.coords,
}; };
} }
} }
@@ -123,7 +123,7 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(const ImageId imageId, cons
const auto& info = kvp->second; const auto& info = kvp->second;
return { return {
info.index, info.index,
info.normalizedBounds, info.coords,
}; };
} }
} }
@@ -151,7 +151,7 @@ BasicTextureInfo TextureCache::GetOrLoadBitmapTexture(ImageIndex image, const vo
const auto& info = _textureCache[index]; const auto& info = _textureCache[index];
return { return {
info.index, info.index,
info.normalizedBounds, info.coords,
}; };
} }
} }

View File

@@ -63,7 +63,7 @@ namespace OpenRCT2::Ui
struct BasicTextureInfo struct BasicTextureInfo
{ {
GLuint index; GLuint index;
vec4 normalizedBounds; vec4 coords;
}; };
// Location of an image (texture atlas index, slot and normalized coordinates) // Location of an image (texture atlas index, slot and normalized coordinates)
@@ -124,7 +124,12 @@ namespace OpenRCT2::Ui
info.index = _index; info.index = _index;
info.slot = slot; info.slot = slot;
info.bounds = bounds; info.bounds = bounds;
info.normalizedBounds = NormalizeCoordinates(bounds); info.coords = vec4{
static_cast<float>(bounds.x),
static_cast<float>(bounds.y),
static_cast<float>(_atlasWidth),
static_cast<float>(_atlasHeight),
};
return info; return info;
} }
@@ -176,16 +181,6 @@ namespace OpenRCT2::Ui
_imageSize * row + actualHeight, _imageSize * row + actualHeight,
}; };
} }
[[nodiscard]] vec4 NormalizeCoordinates(const ivec4& coords) const
{
return vec4{
coords.x / static_cast<float>(_atlasWidth),
coords.y / static_cast<float>(_atlasHeight),
coords.z / static_cast<float>(_atlasWidth),
coords.w / static_cast<float>(_atlasHeight),
};
}
}; };
class TextureCache final class TextureCache final