Get basic TTF support working in OpenGL

co-authored-by: Michael Steenbeek <m.o.steenbeek@gmail.com>
This commit is contained in:
Ted John 2019-08-03 12:47:29 +01:00 committed by ζeh Matt
parent 008f106242
commit 6e2b79a895
No known key found for this signature in database
GPG key ID: 18CE582C71A225B0
6 changed files with 131 additions and 4 deletions

View file

@ -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<uint16_t>(width);
int32_t drawHeight = static_cast<uint16_t>(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);

View file

@ -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<const GLvoid*>(pixels));
return cacheInfo;
}
AtlasTextureInfo TextureCache::AllocateImage(int32_t imageWidth, int32_t imageHeight)
{
CreateTextures();

View file

@ -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();

View file

@ -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<uint8_t*>(const_cast<void*>(surface->pixels));
auto pixelsLen = static_cast<size_t>(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)

View file

@ -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

View file

@ -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);
};