diff --git a/data/shaders/drawimage.frag b/data/shaders/drawimage.frag index 7e6fb568f3..a18e81433d 100644 --- a/data/shaders/drawimage.frag +++ b/data/shaders/drawimage.frag @@ -1,6 +1,8 @@ #version 330 uniform ivec4 uClip; +uniform int uFlags; +uniform vec4 uColour; uniform sampler2D uTexture; in vec2 fPosition; @@ -16,5 +18,13 @@ void main() discard; } - oColour = texture(uTexture, fTextureCoordinate); + vec4 texel = texture(uTexture, fTextureCoordinate); + if ((uFlags & 1) != 0) + { + oColour = vec4(uColour.rgb, uColour.a * texel.a); + } + else + { + oColour = texel; + } } diff --git a/src/drawing/IDrawingContext.h b/src/drawing/IDrawingContext.h index 9fecefbe6f..17bfb84505 100644 --- a/src/drawing/IDrawingContext.h +++ b/src/drawing/IDrawingContext.h @@ -32,4 +32,5 @@ interface IDrawingContext virtual void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) abstract; virtual void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) abstract; virtual void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) abstract; + virtual void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) abstract; }; diff --git a/src/drawing/NewDrawing.cpp b/src/drawing/NewDrawing.cpp index 3e0b9795e5..acc84b6647 100644 --- a/src/drawing/NewDrawing.cpp +++ b/src/drawing/NewDrawing.cpp @@ -227,6 +227,15 @@ extern "C" } } + void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 colour) + { + if (_drawingEngine != nullptr) + { + IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi); + dc->DrawSpriteSolid(image, x, y, colour); + } + } + int screenshot_dump() { if (_drawingEngine != nullptr) diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index 9e4f311611..4c0bbc0110 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -148,6 +148,7 @@ void FASTCALL gfx_rle_sprite_to_buffer(const uint8* RESTRICT source_bits_pointer void FASTCALL gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour); void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo *dpi, int x, int y, int maskImage, int colourImage); +void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 colour); void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour); void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); diff --git a/src/drawing/engines/SoftwareDrawingEngine.cpp b/src/drawing/engines/SoftwareDrawingEngine.cpp index 7efa5b3ceb..abb3423579 100644 --- a/src/drawing/engines/SoftwareDrawingEngine.cpp +++ b/src/drawing/engines/SoftwareDrawingEngine.cpp @@ -172,6 +172,7 @@ public: void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) override; void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) override; void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) override; + void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour); void SetDPI(rct_drawpixelinfo * dpi); }; @@ -1016,6 +1017,17 @@ void SoftwareDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 mask gfx_draw_sprite_raw_masked_software(_dpi, x, y, maskImage, colourImage); } +void SoftwareDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) +{ + uint8 palette[256]; + memset(palette, colour, 256); + palette[0] = 0; + + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + image &= 0x7FFFF; + gfx_draw_sprite_palette_set_software(_dpi, image | 0x20000000, x, y, palette, nullptr); +} + void SoftwareDrawingContext::SetDPI(rct_drawpixelinfo * dpi) { _dpi = dpi; diff --git a/src/drawing/engines/opengl/DrawImageShader.cpp b/src/drawing/engines/opengl/DrawImageShader.cpp index b45a52d0e8..8c2487ea96 100644 --- a/src/drawing/engines/opengl/DrawImageShader.cpp +++ b/src/drawing/engines/opengl/DrawImageShader.cpp @@ -34,6 +34,7 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage") glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr); Use(); + SetFlags(0); SetTextureCoordinates(0, 0, 1, 1); } @@ -52,6 +53,8 @@ void DrawImageShader::GetLocations() uBounds = GetUniformLocation("uBounds"); uTextureCoordinates = GetUniformLocation("uTextureCoordinates"); uTexture = GetUniformLocation("uTexture"); + uColour = GetUniformLocation("uColour"); + uFlags = GetUniformLocation("uFlags"); vIndex = GetAttributeLocation("vIndex"); } @@ -83,6 +86,16 @@ void DrawImageShader::SetTexture(GLuint texture) glUniform1i(uTexture, 0); } +void DrawImageShader::SetColour(vec4f colour) +{ + glUniform4f(uColour, colour.r, colour.g, colour.b, colour.a); +} + +void DrawImageShader::SetFlags(uint32 flags) +{ + glUniform1i(uFlags, flags); +} + void DrawImageShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) { SetBounds(left, top, right, bottom); diff --git a/src/drawing/engines/opengl/DrawImageShader.h b/src/drawing/engines/opengl/DrawImageShader.h index 534d3efa02..8c9b2756b0 100644 --- a/src/drawing/engines/opengl/DrawImageShader.h +++ b/src/drawing/engines/opengl/DrawImageShader.h @@ -27,6 +27,8 @@ private: GLuint uBounds; GLuint uTextureCoordinates; GLuint uTexture; + GLuint uColour; + GLuint uFlags; GLuint vIndex; @@ -42,6 +44,8 @@ public: void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetTexture(GLuint texture); + void SetColour(vec4f colour); + void SetFlags(uint32 flags); void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom); diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 8ce77e2cda..abfcf329c1 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -198,6 +198,7 @@ public: void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) override; void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) override; void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) override; + void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) override; void SetDPI(rct_drawpixelinfo * dpi); void InvalidateImage(uint32 image); @@ -648,6 +649,49 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm _drawImageMaskedShader->Draw(left, top, right, bottom); } +void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) +{ + vec4f paletteColour = _engine->GLPalette[colour & 0xFF]; + + int g1Id = image & 0x7FFFF; + rct_g1_element * g1Element = gfx_get_g1_element(g1Id); + + GLuint texture = GetOrLoadImageTexture(image); + + sint32 drawOffsetX = g1Element->x_offset; + sint32 drawOffsetY = g1Element->y_offset; + sint32 drawWidth = (uint16)g1Element->width; + sint32 drawHeight = (uint16)g1Element->height; + + sint32 left = x + drawOffsetX; + sint32 top = y + drawOffsetY; + sint32 right = left + drawWidth; + sint32 bottom = top + drawHeight; + + if (left > right) + { + std::swap(left, right); + } + if (top > bottom) + { + std::swap(top, bottom); + } + + left += _offsetX; + top += _offsetY; + right += _offsetX; + bottom += _offsetY; + + _drawImageShader->Use(); + _drawImageShader->SetScreenSize(gScreenWidth, gScreenHeight); + _drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); + _drawImageShader->SetTexture(texture); + _drawImageShader->SetFlags(1); + _drawImageShader->SetColour(paletteColour); + _drawImageShader->Draw(left, top, right, bottom); + _drawImageShader->SetFlags(0); +} + void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi) { rct_drawpixelinfo * screenDPI = _engine->GetDPI(); diff --git a/src/interface/widget.c b/src/interface/widget.c index eac3ecc77b..f1298846bc 100644 --- a/src/interface/widget.c +++ b/src/interface/widget.c @@ -859,23 +859,12 @@ static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetI // Draw greyed out (light border bottom right shadow) colour = w->colours[widget->colour]; colour = ColourMapA[colour & 0x7F].lighter; - - uint8 palette[256]; - memset(palette, colour, 256); - palette[0] = 0; - - RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; - image &= 0x7FFFF; - gfx_draw_sprite_palette_set(dpi, image | 0x20000000, l + 1, t + 1, palette, NULL); + gfx_draw_sprite_solid(dpi, image, l + 1, t + 1, colour); // Draw greyed out (dark) colour = w->colours[widget->colour]; colour = ColourMapA[colour & 0x7F].mid_light; - memset(palette, colour, 256); - palette[0] = 0; - - RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; - gfx_draw_sprite_palette_set(dpi, image | 0x20000000, l, t, palette, NULL); + gfx_draw_sprite_solid(dpi, image, l, t, colour); } else { if (image & 0x80000000) { // ?