From daa55b1a3c542c7747eb0b845fd9a1675500b8be Mon Sep 17 00:00:00 2001 From: Clownacy Date: Mon, 14 Sep 2020 12:07:52 +0100 Subject: [PATCH] Allow font atlases to be non-square Saves a little memory in some cases. It's the backend's job to decide if this is a problem or not, and pad it if it has to. --- src/Backends/Rendering.h | 2 +- src/Backends/Rendering/OpenGL3.cpp | 20 +++++++++++--------- src/Backends/Rendering/SDLSurface.cpp | 4 ++-- src/Backends/Rendering/SDLTexture.cpp | 4 ++-- src/Backends/Rendering/Software.cpp | 14 ++++++++------ src/Backends/Rendering/WiiU.cpp | 6 +++--- src/Font.cpp | 4 +--- 7 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/Backends/Rendering.h b/src/Backends/Rendering.h index b9664c0f..51edfde2 100644 --- a/src/Backends/Rendering.h +++ b/src/Backends/Rendering.h @@ -24,7 +24,7 @@ unsigned char* RenderBackend_LockSurface(RenderBackend_Surface *surface, size_t void RenderBackend_UnlockSurface(RenderBackend_Surface *surface, size_t width, size_t height); void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RenderBackend_Rect *rect, RenderBackend_Surface *destination_surface, long x, long y, bool colour_key); void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBackend_Rect *rect, unsigned char red, unsigned char green, unsigned char blue); -RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size); +RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height); void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas); void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height); void RenderBackend_PrepareToDrawGlyphs(RenderBackend_GlyphAtlas *atlas, RenderBackend_Surface *destination_surface, unsigned char red, unsigned char green, unsigned char blue); diff --git a/src/Backends/Rendering/OpenGL3.cpp b/src/Backends/Rendering/OpenGL3.cpp index 8398798e..14d43582 100644 --- a/src/Backends/Rendering/OpenGL3.cpp +++ b/src/Backends/Rendering/OpenGL3.cpp @@ -40,7 +40,8 @@ typedef struct RenderBackend_Surface typedef struct RenderBackend_GlyphAtlas { GLuint texture_id; - size_t size; + size_t width; + size_t height; } RenderBackend_GlyphAtlas; typedef struct Coordinate2D @@ -866,21 +867,22 @@ void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBacken // Glyph management // ////////////////////// -RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size) +RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height) { RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas)); if (atlas != NULL) { - atlas->size = size; + atlas->width = width; + atlas->height = height; glGenTextures(1, &atlas->texture_id); glBindTexture(GL_TEXTURE_2D, atlas->texture_id); #ifdef USE_OPENGLES2 - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, size, size, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); #else - glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size, size, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); #endif glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -986,10 +988,10 @@ void RenderBackend_DrawGlyph(RenderBackend_GlyphAtlas *atlas, long x, long y, si vertex_buffer_slot->vertices[1][2].position.x = vertex_left; vertex_buffer_slot->vertices[1][2].position.y = vertex_bottom; - const GLfloat texture_left = glyph_x / (GLfloat)atlas->size; - const GLfloat texture_top = glyph_y / (GLfloat)atlas->size; - const GLfloat texture_right = (glyph_x + glyph_width) / (GLfloat)atlas->size; - const GLfloat texture_bottom = (glyph_y + glyph_height) / (GLfloat)atlas->size; + const GLfloat texture_left = glyph_x / (GLfloat)atlas->width; + const GLfloat texture_top = glyph_y / (GLfloat)atlas->height; + const GLfloat texture_right = (glyph_x + glyph_width) / (GLfloat)atlas->width; + const GLfloat texture_bottom = (glyph_y + glyph_height) / (GLfloat)atlas->height; vertex_buffer_slot->vertices[0][0].texture.x = texture_left; vertex_buffer_slot->vertices[0][0].texture.y = texture_top; diff --git a/src/Backends/Rendering/SDLSurface.cpp b/src/Backends/Rendering/SDLSurface.cpp index 87f067e9..c9e121fa 100644 --- a/src/Backends/Rendering/SDLSurface.cpp +++ b/src/Backends/Rendering/SDLSurface.cpp @@ -197,13 +197,13 @@ void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBacken Backend_PrintError("Couldn't fill rectangle with color: %s", SDL_GetError()); } -RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size) +RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height) { RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas)); if (atlas != NULL) { - atlas->sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, size, size, 0, SDL_PIXELFORMAT_RGBA32); + atlas->sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 0, SDL_PIXELFORMAT_RGBA32); if (atlas->sdlsurface != NULL) { diff --git a/src/Backends/Rendering/SDLTexture.cpp b/src/Backends/Rendering/SDLTexture.cpp index a7919e03..6b2b86f6 100644 --- a/src/Backends/Rendering/SDLTexture.cpp +++ b/src/Backends/Rendering/SDLTexture.cpp @@ -335,13 +335,13 @@ void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBacken Backend_PrintError("Couldn't enable alpha blending for drawing operations: %s", SDL_GetError()); } -RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size) +RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height) { RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas)); if (atlas != NULL) { - atlas->texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, size, size); + atlas->texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, width, height); if (atlas->texture != NULL) { diff --git a/src/Backends/Rendering/Software.cpp b/src/Backends/Rendering/Software.cpp index ca8125a5..0463913e 100644 --- a/src/Backends/Rendering/Software.cpp +++ b/src/Backends/Rendering/Software.cpp @@ -22,7 +22,8 @@ typedef struct RenderBackend_Surface typedef struct RenderBackend_GlyphAtlas { unsigned char *pixels; - size_t size; + size_t width; + size_t height; } RenderBackend_GlyphAtlas; static RenderBackend_Surface framebuffer; @@ -258,17 +259,18 @@ ATTRIBUTE_HOT void RenderBackend_ColourFill(RenderBackend_Surface *surface, cons } } -RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size) +RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height) { RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas)); if (atlas != NULL) { - atlas->pixels = (unsigned char*)malloc(size * size); + atlas->pixels = (unsigned char*)malloc(width * height); if (atlas->pixels != NULL) { - atlas->size = size; + atlas->width = width; + atlas->height = height; return atlas; } @@ -288,7 +290,7 @@ void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas) void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height) { for (size_t i = 0; i < height; ++i) - memcpy(&atlas->pixels[(y + i) * atlas->size + x], &pixels[i * width], width); + memcpy(&atlas->pixels[(y + i) * atlas->width + x], &pixels[i * width], width); } void RenderBackend_PrepareToDrawGlyphs(RenderBackend_GlyphAtlas *atlas, RenderBackend_Surface *destination_surface, unsigned char red, unsigned char green, unsigned char blue) @@ -311,7 +313,7 @@ void RenderBackend_DrawGlyph(RenderBackend_GlyphAtlas *atlas, long x, long y, si { for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph_width, glyph_destination_surface->width); ++ix) { - const unsigned char alpha_int = atlas->pixels[(glyph_y + iy) * atlas->size + (glyph_x + ix)]; + const unsigned char alpha_int = atlas->pixels[(glyph_y + iy) * atlas->width + (glyph_x + ix)]; if (alpha_int != 0) { diff --git a/src/Backends/Rendering/WiiU.cpp b/src/Backends/Rendering/WiiU.cpp index ecf01d81..11f4ad7a 100644 --- a/src/Backends/Rendering/WiiU.cpp +++ b/src/Backends/Rendering/WiiU.cpp @@ -722,7 +722,7 @@ void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBacken } } -RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size) +RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height) { RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas)); @@ -730,8 +730,8 @@ RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size) { // Initialise texture memset(&atlas->texture, 0, sizeof(atlas->texture)); - atlas->texture.surface.width = size; - atlas->texture.surface.height = size; + atlas->texture.surface.width = width; + atlas->texture.surface.height = height; atlas->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8; atlas->texture.surface.depth = 1; atlas->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; diff --git a/src/Font.cpp b/src/Font.cpp index 8fa77b18..fb9251a7 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -12,8 +12,6 @@ #include "File.h" #include "Backends/Rendering.h" -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // Cave Story wasn't intended to use font anti-aliasing. It's only because Microsoft enabled it // by default from Windows Vista onwards that the game started using it. // Font anti-aliasing conflicts with the game's colour-keying, causing ugly artifacting around @@ -1087,7 +1085,7 @@ Font* LoadFontFromData(const unsigned char *data, size_t data_size, size_t cell_ font->atlas_row_length = atlas_columns; - font->atlas = RenderBackend_CreateGlyphAtlas(MAX(atlas_columns * atlas_entry_width, atlas_rows * atlas_entry_height)); + font->atlas = RenderBackend_CreateGlyphAtlas(atlas_columns * atlas_entry_width, atlas_rows * atlas_entry_height); if (font->atlas != NULL) {