diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 3617123463..ad808f966f 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -109,6 +109,7 @@ public: void DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) override; void DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour) override; void DrawGlyph(uint32_t image, int32_t x, int32_t y, const PaletteMap& palette) override; + void DrawBitmap(uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y) override; void FlushCommandBuffers(); @@ -922,6 +923,48 @@ void OpenGLDrawingContext::DrawGlyph(uint32_t image, int32_t x, int32_t y, const command.depth = _drawCount++; } +void OpenGLDrawingContext::DrawBitmap(uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y) +{ + const auto texture = _textureCache->GetOrLoadBitmapTexture(image, pixels, width, height); + + int32_t drawOffsetX = 0; + int32_t drawOffsetY = 0; + int32_t drawWidth = static_cast(width); + int32_t drawHeight = static_cast(height); + + int32_t left = x + drawOffsetX; + int32_t top = y + drawOffsetY; + int32_t right = left + drawWidth; + int32_t 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; + + 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, 0.0f }; + command.palettes = { 0, 0, 0 }; + command.flags = 0; + command.colour = 0; + command.bounds = { left, top, right, bottom }; + command.depth = _drawCount++; +} + void OpenGLDrawingContext::FlushCommandBuffers() { glEnable(GL_DEPTH_TEST); diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index fbd919d337..b762f293ec 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -134,6 +134,40 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32_t image, const Palet return (*it.first).second; } +BasicTextureInfo TextureCache::GetOrLoadBitmapTexture(uint32_t image, const void* pixels, size_t width, size_t height) +{ + uint32_t index; + + image &= 0x7FFFF; + + // Try to read cached texture first. + { + shared_lock lock(_mutex); + + index = _indexMap[image]; + if (index != UNUSED_INDEX) + { + const auto& info = _textureCache[index]; + return { + info.index, + info.normalizedBounds, + }; + } + } + + // Load new texture. + unique_lock lock(_mutex); + + index = uint32_t(_textureCache.size()); + + AtlasTextureInfo info = LoadBitmapTexture(image, pixels, width, height); + + _textureCache.push_back(info); + _indexMap[image] = index; + + return info; +} + void TextureCache::CreateTextures() { if (!_initialized) @@ -270,6 +304,17 @@ AtlasTextureInfo TextureCache::LoadGlyphTexture(uint32_t image, const PaletteMap return cacheInfo; } +AtlasTextureInfo TextureCache::LoadBitmapTexture(uint32_t image, const void* pixels, size_t width, size_t height) +{ + auto cacheInfo = AllocateImage(int32_t(width), int32_t(height)); + cacheInfo.image = image; + glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture); + glTexSubImage3D( + GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, GLsizei(width), GLsizei(height), 1, + GL_RED_INTEGER, GL_UNSIGNED_BYTE, reinterpret_cast(pixels)); + return cacheInfo; +} + AtlasTextureInfo TextureCache::AllocateImage(int32_t imageWidth, int32_t imageHeight) { CreateTextures(); diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h index f624da0df7..474092769a 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h @@ -221,6 +221,7 @@ public: void InvalidateImage(uint32_t image); BasicTextureInfo GetOrLoadImageTexture(uint32_t image); BasicTextureInfo GetOrLoadGlyphTexture(uint32_t image, const PaletteMap& paletteMap); + BasicTextureInfo GetOrLoadBitmapTexture(uint32_t image, const void* pixels, size_t width, size_t height); GLuint GetAtlasesTexture(); GLuint GetPaletteTexture(); @@ -233,6 +234,7 @@ private: AtlasTextureInfo LoadImageTexture(uint32_t image); AtlasTextureInfo LoadGlyphTexture(uint32_t image, const PaletteMap& paletteMap); AtlasTextureInfo AllocateImage(int32_t imageWidth, int32_t imageHeight); + AtlasTextureInfo LoadBitmapTexture(uint32_t image, const void* pixels, size_t width, size_t height); static rct_drawpixelinfo GetImageAsDPI(uint32_t image, uint32_t tertiaryColour); static rct_drawpixelinfo GetGlyphAsDPI(uint32_t image, const PaletteMap& paletteMap); void FreeTextures(); diff --git a/src/openrct2/drawing/Drawing.String.cpp b/src/openrct2/drawing/Drawing.String.cpp index 4d8772ded8..934c26e62f 100644 --- a/src/openrct2/drawing/Drawing.String.cpp +++ b/src/openrct2/drawing/Drawing.String.cpp @@ -7,10 +7,13 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "../Context.h" #include "../common.h" #include "../config/Config.h" #include "../core/String.hpp" #include "../drawing/Drawing.h" +#include "../drawing/IDrawingContext.h" +#include "../drawing/IDrawingEngine.h" #include "../interface/Viewport.h" #include "../localisation/Formatting.h" #include "../localisation/Localisation.h" @@ -525,6 +528,7 @@ static void ttf_draw_string_raw_sprite(rct_drawpixelinfo* dpi, std::string_view #ifndef NO_TTF +static int _ttfGlId = 0; static void ttf_draw_string_raw_ttf(rct_drawpixelinfo* dpi, std::string_view text, text_draw_info* info) { if (!ttf_initialise()) @@ -554,6 +558,37 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo* dpi, std::string_view tex int32_t width = surface->w; int32_t height = surface->h; + if (OpenRCT2::GetContext()->GetDrawingEngineType() == DrawingEngine::OpenGL) + { + auto pixels = reinterpret_cast(const_cast(surface->pixels)); + auto pixelsLen = static_cast(surface->pitch) * surface->h; + for (size_t pp = 0; pp < pixelsLen; pp++) + { + if (pixels[pp] != 0) + { + pixels[pp] = colour; + } + else + { + pixels[pp] = PALETTE_INDEX_0; + } + } + + auto baseId = uint32_t(0x7FFFF) - 1024; + auto imageId = baseId + _ttfGlId; + auto drawingEngine = dpi->DrawingEngine; + auto drawingContext = drawingEngine->GetDrawingContext(dpi); + drawingEngine->InvalidateImage(imageId); + drawingContext->DrawBitmap(imageId, surface->pixels, surface->pitch, surface->h, drawX, drawY); + + _ttfGlId++; + if (_ttfGlId >= 1023) + { + _ttfGlId = 0; + } + return; + } + int32_t overflowX = (dpi->x + dpi->width) - (drawX + width); int32_t overflowY = (dpi->y + dpi->height) - (drawY + height); if (overflowX < 0) diff --git a/src/openrct2/drawing/IDrawingContext.h b/src/openrct2/drawing/IDrawingContext.h index 2fe2aef713..e8fbadc702 100644 --- a/src/openrct2/drawing/IDrawingContext.h +++ b/src/openrct2/drawing/IDrawingContext.h @@ -18,10 +18,7 @@ namespace OpenRCT2::Drawing struct IDrawingContext { - virtual ~IDrawingContext() - { - } - + virtual ~IDrawingContext() = default; virtual OpenRCT2::Drawing::IDrawingEngine* GetEngine() abstract; virtual void Clear(uint8_t paletteIndex) abstract; @@ -32,5 +29,7 @@ namespace OpenRCT2::Drawing virtual void DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) abstract; virtual void DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour) abstract; virtual void DrawGlyph(uint32_t image, int32_t x, int32_t y, const PaletteMap& palette) abstract; + virtual void DrawBitmap( + uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y) abstract; }; } // namespace OpenRCT2::Drawing diff --git a/src/openrct2/drawing/X8DrawingEngine.h b/src/openrct2/drawing/X8DrawingEngine.h index e462871162..b655cac749 100644 --- a/src/openrct2/drawing/X8DrawingEngine.h +++ b/src/openrct2/drawing/X8DrawingEngine.h @@ -150,6 +150,9 @@ namespace OpenRCT2 void DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) override; void DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour) override; void DrawGlyph(uint32_t image, int32_t x, int32_t y, const PaletteMap& paletteMap) override; + void DrawBitmap(uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y) override + { + } void SetDPI(rct_drawpixelinfo* dpi); };