mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 11:03:00 +01:00
fix drawing of text
This commit is contained in:
@@ -30,7 +30,7 @@ interface IDrawingContext
|
||||
virtual void FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom) abstract;
|
||||
virtual void DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) abstract;
|
||||
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;
|
||||
virtual void DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) abstract;
|
||||
};
|
||||
|
||||
@@ -209,12 +209,12 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 * palette, uint8 * unknown)
|
||||
void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 * palette)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
{
|
||||
IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi);
|
||||
dc->DrawSpritePaletteSet(image, x, y, palette, unknown);
|
||||
dc->DrawGlyph(image, x, y, palette);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ rct_g1_element* gfx_get_g1_element(int image_id);
|
||||
void sub_68371D();
|
||||
void FASTCALL gfx_rle_sprite_to_buffer(const uint8* RESTRICT source_bits_pointer, uint8* RESTRICT dest_bits_pointer, const uint8* RESTRICT palette_pointer, const rct_drawpixelinfo * RESTRICT dpi, int image_type, int source_y_start, int height, int source_x_start, int width);
|
||||
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_glpyh(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8 * palette);
|
||||
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);
|
||||
|
||||
|
||||
@@ -170,9 +170,9 @@ public:
|
||||
void FillRect(uint32 colour, sint32 x, sint32 y, sint32 w, sint32 h) override;
|
||||
void DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) override;
|
||||
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 DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) override;
|
||||
void DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) override;
|
||||
|
||||
void SetDPI(rct_drawpixelinfo * dpi);
|
||||
};
|
||||
@@ -1007,11 +1007,6 @@ void SoftwareDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32
|
||||
gfx_draw_sprite_software(_dpi, image, x, y, tertiaryColour);
|
||||
}
|
||||
|
||||
void SoftwareDrawingContext::DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown)
|
||||
{
|
||||
gfx_draw_sprite_palette_set_software(_dpi, image, x, y, palette, unknown);
|
||||
}
|
||||
|
||||
void SoftwareDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage)
|
||||
{
|
||||
gfx_draw_sprite_raw_masked_software(_dpi, x, y, maskImage, colourImage);
|
||||
@@ -1028,6 +1023,11 @@ void SoftwareDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, u
|
||||
gfx_draw_sprite_palette_set_software(_dpi, image | 0x20000000, x, y, palette, nullptr);
|
||||
}
|
||||
|
||||
void SoftwareDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette)
|
||||
{
|
||||
gfx_draw_sprite_palette_set_software(_dpi, image, x, y, palette, nullptr);
|
||||
}
|
||||
|
||||
void SoftwareDrawingContext::SetDPI(rct_drawpixelinfo * dpi)
|
||||
{
|
||||
_dpi = dpi;
|
||||
|
||||
@@ -176,8 +176,6 @@ private:
|
||||
|
||||
TextureCache * _textureCache = nullptr;
|
||||
|
||||
GLuint _vbo;
|
||||
|
||||
sint32 _offsetX;
|
||||
sint32 _offsetY;
|
||||
sint32 _clipLeft;
|
||||
@@ -198,9 +196,9 @@ public:
|
||||
void FillRect(uint32 colour, sint32 x, sint32 y, sint32 w, sint32 h) override;
|
||||
void DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) override;
|
||||
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 DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) override;
|
||||
|
||||
void SetDPI(rct_drawpixelinfo * dpi);
|
||||
};
|
||||
@@ -605,11 +603,6 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
||||
_drawImageShader->Draw(left, top, right, bottom);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown)
|
||||
{
|
||||
DrawSprite(image, x, y, 0);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage)
|
||||
{
|
||||
rct_g1_element * g1ElementMask = gfx_get_g1_element(maskImage & 0x7FFFF);
|
||||
@@ -693,6 +686,45 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin
|
||||
_drawImageShader->SetFlags(0);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette)
|
||||
{
|
||||
int g1Id = image & 0x7FFFF;
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(g1Id);
|
||||
|
||||
GLuint texture = _textureCache->GetOrLoadGlyphTexture(image, palette);
|
||||
|
||||
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->Draw(left, top, right, bottom);
|
||||
_drawImageShader->SetFlags(0);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi)
|
||||
{
|
||||
rct_drawpixelinfo * screenDPI = _engine->GetDPI();
|
||||
|
||||
@@ -59,10 +59,23 @@ GLuint TextureCache::GetOrLoadImageTexture(uint32 image)
|
||||
GLuint texture = LoadImageTexture(image);
|
||||
_imageTextureMap[image] = texture;
|
||||
|
||||
// if ((_textures.size() % 100) == 0)
|
||||
// {
|
||||
// printf("Textures: %d\n", _textures.size());
|
||||
// }
|
||||
return texture;
|
||||
}
|
||||
|
||||
GLuint TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * palette)
|
||||
{
|
||||
GlyphId glyphId;
|
||||
glyphId.Image = image;
|
||||
Memory::Copy<void>(&glyphId.Palette, palette, sizeof(glyphId.Palette));
|
||||
|
||||
auto kvp = _glyphTextureMap.find(glyphId);
|
||||
if (kvp != _glyphTextureMap.end())
|
||||
{
|
||||
return kvp->second;
|
||||
}
|
||||
|
||||
GLuint texture = LoadGlyphTexture(image, palette);
|
||||
_glyphTextureMap[glyphId] = texture;
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -80,35 +93,66 @@ GLuint TextureCache::LoadImageTexture(uint32 image)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels32);
|
||||
|
||||
delete [] (uint8 *) pixels32;
|
||||
Memory::Free(pixels32);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
void * TextureCache::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32* outWidth, uint32* outHeight)
|
||||
GLuint TextureCache::LoadGlyphTexture(uint32 image, uint8 * palette)
|
||||
{
|
||||
int g1Id = image & 0x7FFFF;
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(g1Id);
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
|
||||
uint32 width = (uint32)g1Element->width;
|
||||
uint32 height = (uint32)g1Element->height;
|
||||
uint32 width, height;
|
||||
void * pixels32 = GetGlyphAsARGB(image, palette, &width, &height);
|
||||
|
||||
size_t numPixels = width * height;
|
||||
uint8 * pixels8 = new uint8[numPixels];
|
||||
Memory::Set(pixels8, 0, numPixels);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels32);
|
||||
|
||||
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;
|
||||
gfx_draw_sprite_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
|
||||
Memory::Free(pixels32);
|
||||
|
||||
uint8 * pixels32 = new uint8[width * height * 4];
|
||||
uint8 * src = pixels8;
|
||||
return texture;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void * TextureCache::GetGlyphAsARGB(uint32 image, uint8 * palette, 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_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;
|
||||
}
|
||||
|
||||
void * TextureCache::ConvertDPIto32bpp(const rct_drawpixelinfo * dpi)
|
||||
{
|
||||
size_t numPixels = dpi->width * dpi->height;
|
||||
uint8 * pixels32 = Memory::Allocate<uint8>(numPixels * 4);
|
||||
uint8 * src = dpi->bits;
|
||||
uint8 * dst = pixels32;
|
||||
for (size_t i = 0; i < numPixels; i++)
|
||||
{
|
||||
@@ -130,22 +174,50 @@ void * TextureCache::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32*
|
||||
*dst++ = colour.a;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] pixels8;
|
||||
|
||||
*outWidth = width;
|
||||
*outHeight = height;
|
||||
return pixels32;
|
||||
}
|
||||
|
||||
void TextureCache::FreeTextures()
|
||||
{
|
||||
// Free images
|
||||
size_t numTextures = _imageTextureMap.size();
|
||||
auto textures = std::vector<GLuint>(numTextures);
|
||||
for (auto kvp : _imageTextureMap)
|
||||
{
|
||||
textures.push_back(kvp.second);
|
||||
}
|
||||
glDeleteTextures(textures.size(), textures.data());
|
||||
|
||||
// Free glyphs
|
||||
numTextures = _glyphTextureMap.size();
|
||||
textures.clear();
|
||||
textures.reserve(numTextures);
|
||||
for (auto kvp : _glyphTextureMap)
|
||||
{
|
||||
textures.push_back(kvp.second);
|
||||
}
|
||||
glDeleteTextures(textures.size(), textures.data());
|
||||
}
|
||||
|
||||
rct_drawpixelinfo * TextureCache::CreateDPI(sint32 width, sint32 height)
|
||||
{
|
||||
size_t numPixels = width * height;
|
||||
uint8 * pixels8 = Memory::Allocate<uint8>(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;
|
||||
return dpi;
|
||||
}
|
||||
|
||||
void TextureCache::DeleteDPI(rct_drawpixelinfo* dpi)
|
||||
{
|
||||
Memory::Free(dpi->bits);
|
||||
delete dpi;
|
||||
}
|
||||
|
||||
@@ -21,10 +21,40 @@
|
||||
#include "../../../common.h"
|
||||
#include "OpenGLAPI.h"
|
||||
|
||||
struct rct_drawpixelinfo;
|
||||
|
||||
struct GlyphId
|
||||
{
|
||||
uint32 Image;
|
||||
uint64 Palette;
|
||||
|
||||
struct Hash
|
||||
{
|
||||
size_t operator()(const GlyphId &k) const
|
||||
{
|
||||
size_t hash = 0x3154A85E;
|
||||
hash = k.Image * 7;
|
||||
hash += (k.Palette & 0xFFFFFFFF) * 13;
|
||||
hash += (k.Palette >> 32) * 23;
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
struct Equal
|
||||
{
|
||||
bool operator()(const GlyphId &lhs, const GlyphId &rhs) const
|
||||
{
|
||||
return lhs.Image == rhs.Image &&
|
||||
lhs.Palette == rhs.Palette;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class TextureCache
|
||||
{
|
||||
private:
|
||||
std::unordered_map<uint32, GLuint> _imageTextureMap;
|
||||
std::unordered_map<GlyphId, GLuint, GlyphId::Hash, GlyphId::Equal> _glyphTextureMap;
|
||||
SDL_Color _palette[256];
|
||||
|
||||
public:
|
||||
@@ -33,9 +63,16 @@ public:
|
||||
void SetPalette(const SDL_Color * palette);
|
||||
void InvalidateImage(uint32 image);
|
||||
GLuint GetOrLoadImageTexture(uint32 image);
|
||||
GLuint GetOrLoadGlyphTexture(uint32 image, uint8 * palette);
|
||||
|
||||
private:
|
||||
GLuint LoadImageTexture(uint32 image);
|
||||
GLuint LoadGlyphTexture(uint32 image, uint8 * palette);
|
||||
void * GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight);
|
||||
void * GetGlyphAsARGB(uint32 image, uint8 * palette, uint32 * outWidth, uint32 * outHeight);
|
||||
void * ConvertDPIto32bpp(const rct_drawpixelinfo * dpi);
|
||||
void FreeTextures();
|
||||
|
||||
static rct_drawpixelinfo * CreateDPI(sint32 width, sint32 height);
|
||||
static void DeleteDPI(rct_drawpixelinfo * dpi);
|
||||
};
|
||||
|
||||
@@ -924,7 +924,7 @@ static void ttf_draw_character_sprite(rct_drawpixelinfo *dpi, int codepoint, tex
|
||||
if (info->flags & TEXT_DRAW_FLAG_Y_OFFSET_EFFECT) {
|
||||
y += *info->y_offset++;
|
||||
}
|
||||
gfx_draw_sprite_palette_set(dpi, sprite, x, y, info->palette, NULL);
|
||||
gfx_draw_glpyh(dpi, sprite, x, y, info->palette);
|
||||
}
|
||||
|
||||
info->x += characterWidth;
|
||||
|
||||
Reference in New Issue
Block a user