ref: 1d9446d4258c012f280d3e2d54ce49175f7432cb
parent: 096fa3b578a05687814abdc65107bf05fadaeea7
author: Clownacy <Clownacy@users.noreply.github.com>
date: Mon Sep 7 19:44:51 EDT 2020
Update SDLSurface renderer for new font batcher
--- a/src/Backends/Rendering.h
+++ b/src/Backends/Rendering.h
@@ -27,7 +27,7 @@
RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size);
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_Surface *destination_surface, const unsigned char *colour_channels);
+void RenderBackend_PrepareToDrawGlyphs(RenderBackend_GlyphAtlas *atlas, RenderBackend_Surface *destination_surface, const unsigned char *colour_channels);
void RenderBackend_DrawGlyph(RenderBackend_GlyphAtlas *atlas, long x, long y, size_t glyph_x, size_t glyph_y, size_t glyph_width, size_t glyph_height);
void RenderBackend_FlushGlyphs(void);
void RenderBackend_HandleRenderTargetLoss(void);
--- a/src/Backends/Rendering/OpenGL3.cpp
+++ b/src/Backends/Rendering/OpenGL3.cpp
@@ -899,9 +899,6 @@
void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas)
{
- if (atlas == NULL)
- return;
-
glDeleteTextures(1, &atlas->texture_id);
free(atlas);
}
@@ -908,9 +905,6 @@
void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height)
{
- if (atlas == NULL)
- return;
-
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, atlas->texture_id);
#ifdef USE_OPENGLES2
@@ -922,8 +916,13 @@
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
-void RenderBackend_PrepareToDrawGlyphs(RenderBackend_Surface *destination_surface, const unsigned char *colour_channels)
+void RenderBackend_PrepareToDrawGlyphs(RenderBackend_GlyphAtlas *atlas, RenderBackend_Surface *destination_surface, const unsigned char *colour_channels)
{
+ (void)atlas;
+
+ if (destination_surface == NULL)
+ return;
+
glyph_destination_surface = destination_surface;
memcpy(glyph_colour_channels, colour_channels, sizeof(glyph_colour_channels));
--- a/src/Backends/Rendering/SDLSurface.cpp
+++ b/src/Backends/Rendering/SDLSurface.cpp
@@ -15,10 +15,10 @@
SDL_Surface *sdlsurface;
} RenderBackend_Surface;
-typedef struct RenderBackend_Glyph
+typedef struct RenderBackend_GlyphAtlas
{
SDL_Surface *sdlsurface;
-} RenderBackend_Glyph;
+} RenderBackend_GlyphAtlas;
SDL_Window *window;
@@ -26,7 +26,6 @@
static RenderBackend_Surface framebuffer;
-static unsigned char glyph_colour_channels[3];
static SDL_Surface *glyph_destination_sdlsurface;
static void RectToSDLRect(const RenderBackend_Rect *rect, SDL_Rect *sdl_rect)
@@ -195,28 +194,44 @@
Backend_PrintError("Couldn't fill rectangle with color: %s", SDL_GetError());
}
-RenderBackend_Glyph* RenderBackend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
+RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size)
{
- RenderBackend_Glyph *glyph = (RenderBackend_Glyph*)malloc(sizeof(RenderBackend_Glyph));
+ RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas));
- if (glyph == NULL)
- return NULL;
+ if (atlas != NULL)
+ {
+ atlas->sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, size, size, 0, SDL_PIXELFORMAT_RGBA32);
- glyph->sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 0, SDL_PIXELFORMAT_RGBA32);
+ if (atlas->sdlsurface != NULL)
+ {
+ return atlas;
+ }
+ else
+ {
+ Backend_PrintError("Couldn't create RBG surface: %s", SDL_GetError());
+ }
- if (glyph->sdlsurface == NULL)
- {
- Backend_PrintError("Couldn't create RBG surface: %s", SDL_GetError());
- free(glyph);
- return NULL;
+ free(atlas);
}
- for (unsigned int y = 0; y < height; ++y)
+ return NULL;
+}
+
+void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas)
+{
+ SDL_FreeSurface(atlas->sdlsurface);
+ free(atlas);
+}
+
+void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height)
+{
+ const unsigned char *source_pointer = pixels;
+
+ for (size_t iy = 0; iy < height; ++iy)
{
- const unsigned char *source_pointer = pixels + y * pitch;
- unsigned char *destination_pointer = (unsigned char*)glyph->sdlsurface->pixels + y * glyph->sdlsurface->pitch;
+ unsigned char *destination_pointer = &((unsigned char*)atlas->sdlsurface->pixels)[(y + iy) * atlas->sdlsurface->pitch + x * 4];
- for (unsigned int x = 0; x < width; ++x)
+ for (size_t ix = 0; ix < width; ++ix)
{
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
@@ -224,44 +239,34 @@
*destination_pointer++ = *source_pointer++;
}
}
-
- return glyph;
}
-void RenderBackend_UnloadGlyph(RenderBackend_Glyph *glyph)
+void RenderBackend_PrepareToDrawGlyphs(RenderBackend_GlyphAtlas *atlas, RenderBackend_Surface *destination_surface, const unsigned char *colour_channels)
{
- if (glyph == NULL)
- return;
-
- SDL_FreeSurface(glyph->sdlsurface);
- free(glyph);
-}
-
-void RenderBackend_PrepareToDrawGlyphs(RenderBackend_Surface *destination_surface, const unsigned char *colour_channels)
-{
if (destination_surface == NULL)
return;
glyph_destination_sdlsurface = destination_surface->sdlsurface;
- memcpy(glyph_colour_channels, colour_channels, sizeof(glyph_colour_channels));
+ if (SDL_SetSurfaceColorMod(atlas->sdlsurface, colour_channels[0], colour_channels[1], colour_channels[2]) < 0)
+ Backend_PrintError("Couldn't set color value: %s", SDL_GetError());
}
-void RenderBackend_DrawGlyph(RenderBackend_Glyph *glyph, long x, long y)
+void RenderBackend_DrawGlyph(RenderBackend_GlyphAtlas *atlas, long x, long y, size_t glyph_x, size_t glyph_y, size_t glyph_width, size_t glyph_height)
{
- if (glyph == NULL)
- return;
+ SDL_Rect source_rect;
+ source_rect.x = glyph_x;
+ source_rect.y = glyph_y;
+ source_rect.w = glyph_width;
+ source_rect.h = glyph_height;
- SDL_Rect rect;
- rect.x = x;
- rect.y = y;
- rect.w = glyph->sdlsurface->w;
- rect.h = glyph->sdlsurface->h;
+ SDL_Rect destination_rect;
+ destination_rect.x = x;
+ destination_rect.y = y;
+ destination_rect.w = glyph_width;
+ destination_rect.h = glyph_height;
- if (SDL_SetSurfaceColorMod(glyph->sdlsurface, glyph_colour_channels[0], glyph_colour_channels[1], glyph_colour_channels[2]) < 0)
- Backend_PrintError("Couldn't set color value: %s", SDL_GetError());
-
- if (SDL_BlitSurface(glyph->sdlsurface, NULL, glyph_destination_sdlsurface, &rect) < 0)
+ if (SDL_BlitSurface(atlas->sdlsurface, &source_rect, glyph_destination_sdlsurface, &destination_rect) < 0)
Backend_PrintError("Couldn't blit glyph indivual surface to final glyph surface: %s", SDL_GetError());
}
--- a/src/Backends/Rendering/Software.cpp
+++ b/src/Backends/Rendering/Software.cpp
@@ -301,15 +301,14 @@
void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height)
{
- if (atlas == NULL)
- return;
-
for (size_t i = 0; i < height; ++i)
memcpy(&atlas->pixels[(y + i) * atlas->size + x], &pixels[i * width], width);
}
-void RenderBackend_PrepareToDrawGlyphs(RenderBackend_Surface *destination_surface, const unsigned char *colour_channels)
+void RenderBackend_PrepareToDrawGlyphs(RenderBackend_GlyphAtlas *atlas, RenderBackend_Surface *destination_surface, const unsigned char *colour_channels)
{
+ (void)atlas;
+
if (destination_surface == NULL)
return;
@@ -320,9 +319,6 @@
void RenderBackend_DrawGlyph(RenderBackend_GlyphAtlas *atlas, long x, long y, size_t glyph_x, size_t glyph_y, size_t glyph_width, size_t glyph_height)
{
- if (atlas == NULL)
- return;
-
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph_height, glyph_destination_surface->height); ++iy)
{
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph_width, glyph_destination_surface->width); ++ix)
--- a/src/Font.cpp
+++ b/src/Font.cpp
@@ -1141,7 +1141,7 @@
{
const unsigned char colour_channels[3] = {(unsigned char)colour, (unsigned char)(colour >> 8), (unsigned char)(colour >> 16)};
- RenderBackend_PrepareToDrawGlyphs(surface, colour_channels);
+ RenderBackend_PrepareToDrawGlyphs(font_object->atlas, surface, colour_channels);
unsigned int pen_x = 0;