Update SDLSurface renderer for new font batcher
This commit is contained in:
parent
096fa3b578
commit
1d9446d425
5 changed files with 60 additions and 60 deletions
|
@ -27,7 +27,7 @@ void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBacken
|
||||||
RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size);
|
RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size);
|
||||||
void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas);
|
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_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_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_FlushGlyphs(void);
|
||||||
void RenderBackend_HandleRenderTargetLoss(void);
|
void RenderBackend_HandleRenderTargetLoss(void);
|
||||||
|
|
|
@ -899,18 +899,12 @@ RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size)
|
||||||
|
|
||||||
void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas)
|
void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas)
|
||||||
{
|
{
|
||||||
if (atlas == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
glDeleteTextures(1, &atlas->texture_id);
|
glDeleteTextures(1, &atlas->texture_id);
|
||||||
free(atlas);
|
free(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_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);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
glBindTexture(GL_TEXTURE_2D, atlas->texture_id);
|
glBindTexture(GL_TEXTURE_2D, atlas->texture_id);
|
||||||
#ifdef USE_OPENGLES2
|
#ifdef USE_OPENGLES2
|
||||||
|
@ -922,8 +916,13 @@ void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
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;
|
glyph_destination_surface = destination_surface;
|
||||||
|
|
||||||
memcpy(glyph_colour_channels, colour_channels, sizeof(glyph_colour_channels));
|
memcpy(glyph_colour_channels, colour_channels, sizeof(glyph_colour_channels));
|
||||||
|
|
|
@ -15,10 +15,10 @@ typedef struct RenderBackend_Surface
|
||||||
SDL_Surface *sdlsurface;
|
SDL_Surface *sdlsurface;
|
||||||
} RenderBackend_Surface;
|
} RenderBackend_Surface;
|
||||||
|
|
||||||
typedef struct RenderBackend_Glyph
|
typedef struct RenderBackend_GlyphAtlas
|
||||||
{
|
{
|
||||||
SDL_Surface *sdlsurface;
|
SDL_Surface *sdlsurface;
|
||||||
} RenderBackend_Glyph;
|
} RenderBackend_GlyphAtlas;
|
||||||
|
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ static SDL_Surface *window_sdlsurface;
|
||||||
|
|
||||||
static RenderBackend_Surface framebuffer;
|
static RenderBackend_Surface framebuffer;
|
||||||
|
|
||||||
static unsigned char glyph_colour_channels[3];
|
|
||||||
static SDL_Surface *glyph_destination_sdlsurface;
|
static SDL_Surface *glyph_destination_sdlsurface;
|
||||||
|
|
||||||
static void RectToSDLRect(const RenderBackend_Rect *rect, SDL_Rect *sdl_rect)
|
static void RectToSDLRect(const RenderBackend_Rect *rect, SDL_Rect *sdl_rect)
|
||||||
|
@ -195,28 +194,44 @@ void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBacken
|
||||||
Backend_PrintError("Couldn't fill rectangle with color: %s", SDL_GetError());
|
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)
|
if (atlas != NULL)
|
||||||
return NULL;
|
|
||||||
|
|
||||||
glyph->sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 0, SDL_PIXELFORMAT_RGBA32);
|
|
||||||
|
|
||||||
if (glyph->sdlsurface == NULL)
|
|
||||||
{
|
{
|
||||||
Backend_PrintError("Couldn't create RBG surface: %s", SDL_GetError());
|
atlas->sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, size, size, 0, SDL_PIXELFORMAT_RGBA32);
|
||||||
free(glyph);
|
|
||||||
return NULL;
|
if (atlas->sdlsurface != NULL)
|
||||||
|
{
|
||||||
|
return atlas;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Couldn't create RBG surface: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
free(atlas);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
return NULL;
|
||||||
{
|
}
|
||||||
const unsigned char *source_pointer = pixels + y * pitch;
|
|
||||||
unsigned char *destination_pointer = (unsigned char*)glyph->sdlsurface->pixels + y * glyph->sdlsurface->pitch;
|
|
||||||
|
|
||||||
for (unsigned int x = 0; x < width; ++x)
|
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)
|
||||||
|
{
|
||||||
|
unsigned char *destination_pointer = &((unsigned char*)atlas->sdlsurface->pixels)[(y + iy) * atlas->sdlsurface->pitch + x * 4];
|
||||||
|
|
||||||
|
for (size_t ix = 0; ix < width; ++ix)
|
||||||
{
|
{
|
||||||
*destination_pointer++ = 0xFF;
|
*destination_pointer++ = 0xFF;
|
||||||
*destination_pointer++ = 0xFF;
|
*destination_pointer++ = 0xFF;
|
||||||
|
@ -224,44 +239,34 @@ RenderBackend_Glyph* RenderBackend_LoadGlyph(const unsigned char *pixels, unsign
|
||||||
*destination_pointer++ = *source_pointer++;
|
*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)
|
if (destination_surface == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glyph_destination_sdlsurface = destination_surface->sdlsurface;
|
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)
|
SDL_Rect source_rect;
|
||||||
return;
|
source_rect.x = glyph_x;
|
||||||
|
source_rect.y = glyph_y;
|
||||||
|
source_rect.w = glyph_width;
|
||||||
|
source_rect.h = glyph_height;
|
||||||
|
|
||||||
SDL_Rect rect;
|
SDL_Rect destination_rect;
|
||||||
rect.x = x;
|
destination_rect.x = x;
|
||||||
rect.y = y;
|
destination_rect.y = y;
|
||||||
rect.w = glyph->sdlsurface->w;
|
destination_rect.w = glyph_width;
|
||||||
rect.h = glyph->sdlsurface->h;
|
destination_rect.h = glyph_height;
|
||||||
|
|
||||||
if (SDL_SetSurfaceColorMod(glyph->sdlsurface, glyph_colour_channels[0], glyph_colour_channels[1], glyph_colour_channels[2]) < 0)
|
if (SDL_BlitSurface(atlas->sdlsurface, &source_rect, glyph_destination_sdlsurface, &destination_rect) < 0)
|
||||||
Backend_PrintError("Couldn't set color value: %s", SDL_GetError());
|
|
||||||
|
|
||||||
if (SDL_BlitSurface(glyph->sdlsurface, NULL, glyph_destination_sdlsurface, &rect) < 0)
|
|
||||||
Backend_PrintError("Couldn't blit glyph indivual surface to final glyph surface: %s", SDL_GetError());
|
Backend_PrintError("Couldn't blit glyph indivual surface to final glyph surface: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,15 +301,14 @@ 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_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)
|
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->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)
|
if (destination_surface == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -320,9 +319,6 @@ void RenderBackend_PrepareToDrawGlyphs(RenderBackend_Surface *destination_surfac
|
||||||
|
|
||||||
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_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 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)
|
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph_width, glyph_destination_surface->width); ++ix)
|
||||||
|
|
|
@ -1141,7 +1141,7 @@ void DrawText(FontObject *font_object, RenderBackend_Surface *surface, int x, in
|
||||||
{
|
{
|
||||||
const unsigned char colour_channels[3] = {(unsigned char)colour, (unsigned char)(colour >> 8), (unsigned char)(colour >> 16)};
|
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;
|
unsigned int pen_x = 0;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue