1
0
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:
Ted John
2016-06-11 23:14:22 +01:00
parent 4896d14940
commit f796ef5122
8 changed files with 190 additions and 49 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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