ref: daa55b1a3c542c7747eb0b845fd9a1675500b8be
parent: 17da39fa14c542d8465c2cefaf98b826ad09a3d2
author: Clownacy <Clownacy@users.noreply.github.com>
date: Mon Sep 14 08:07:52 EDT 2020
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.
--- a/src/Backends/Rendering.h
+++ b/src/Backends/Rendering.h
@@ -24,7 +24,7 @@
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);
--- a/src/Backends/Rendering/OpenGL3.cpp
+++ b/src/Backends/Rendering/OpenGL3.cpp
@@ -40,7 +40,8 @@
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 @@
// 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 @@
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;
--- a/src/Backends/Rendering/SDLSurface.cpp
+++ b/src/Backends/Rendering/SDLSurface.cpp
@@ -197,13 +197,13 @@
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)
{
--- a/src/Backends/Rendering/SDLTexture.cpp
+++ b/src/Backends/Rendering/SDLTexture.cpp
@@ -335,13 +335,13 @@
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)
{
--- a/src/Backends/Rendering/Software.cpp
+++ b/src/Backends/Rendering/Software.cpp
@@ -22,7 +22,8 @@
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 @@
}
}
-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_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 @@
{
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)
{
--- a/src/Backends/Rendering/WiiU.cpp
+++ b/src/Backends/Rendering/WiiU.cpp
@@ -722,7 +722,7 @@
}
}
-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 @@
{
// 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;
--- 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->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)
{