Overhauled graphics system

Along with being more accurate to the original, this fixes switching out
of fullscreen causing textures to disappear. This was caused by DirectX
destroying textures that are marked as render-targets when a device-loss
occurs. SDL2 doesn't do anything to recover them, unlike regular
textures, so my solution is just to avoid render-target textures
entirely.

On the upside, this should make drawing text to surfaces much faster,
since we're not reading back bitmaps from the GPU.
This commit is contained in:
Clownacy 2019-01-30 14:56:17 +00:00
parent ba13b8aeea
commit 4f7db164d6
4 changed files with 233 additions and 220 deletions

View file

@ -64,101 +64,157 @@ bool Flip_SystemTask()
return true;
}
bool StartDirectDraw()
static bool IsEnableBitmap(SDL_RWops *fp)
{
//Create renderer
gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE);
return true;
}
char str[16];
const char *extra_text = "(C)Pixel";
void EndDirectDraw()
{
//Release all surfaces
for (int i = 0; i < SURFACE_ID_MAX; i++)
{
if (surf[i].texture)
{
SDL_DestroyTexture(surf[i].texture);
surf[i].texture = NULL;
}
}
const size_t len = strlen(extra_text);
fp->seek(fp, -len, RW_SEEK_END);
fp->read(fp, str, 1, len);
fp->seek(fp, 0, RW_SEEK_SET);
return memcmp(str, extra_text, len) == 0;
}
void ReleaseSurface(int s)
{
//Release the surface we want to release
if (surf[s].texture)
if (surf[s].in_use)
{
SDL_DestroyTexture(surf[s].texture);
surf[s].texture = NULL;
SDL_FreeSurface(surf[s].surface);
surf[s].in_use = false;
}
}
bool MakeSurface(SDL_RWops *fp, int surf_no)
bool MakeSurface_Generic(int bxsize, int bysize, int surf_no)
{
//Check if surf_no can be used
if (surf_no > SURFACE_ID_MAX)
{
printf("Tried to create surface with invalid id %d\n", surf_no);
return false;
}
if (surf[surf_no].texture)
{
printf("Tried to create surface at id %d, but there's already a texture there\n", surf_no);
return false;
}
//Load surface from file
SDL_Surface *surface = SDL_LoadBMP_RW(fp, 1);
if (!surface)
{
printf("Couldn't load bitmap for surface id %d\nSDL Error: %s\n", surf_no, SDL_GetError());
return false;
}
//Make sure surface has color key on
SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, 0, 0, 0));
//Get texture from surface
SDL_Texture *texture = SDL_CreateTextureFromSurface(gRenderer, surface);
if (!texture)
{
printf("Failed to convert SDL_Surface to SDL_Texture for surface id %d\nSDL Error: %s\n", surf_no, SDL_GetError());
return false;
}
//Create real texture, and copy loaded texture here (has texture target access)
int w, h;
SDL_QueryTexture(texture, NULL, NULL, &w, &h);
bool success = false;
SDL_Texture *textureAccessible = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, w * gWindowScale, h * gWindowScale);
if (!textureAccessible)
#ifdef FIX_BUGS
if (surf_no >= SURFACE_ID_MAX)
#else
if (surf_no > SURFACE_ID_MAX) // OOPS (should be '>=')
#endif
{
printf("Failed to create real texture for surface id %d\nSDL Error: %s\n", surf_no, SDL_GetError());
return false;
printf("Tried to create drawable surface at invalid slot (%d - maximum is %d)\n", surf_no, SURFACE_ID_MAX);
}
SDL_SetTextureBlendMode(textureAccessible, SDL_BLENDMODE_BLEND);
SDL_SetRenderTarget(gRenderer, textureAccessible);
SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 0);
SDL_RenderClear(gRenderer);
SDL_RenderCopy(gRenderer, texture, NULL, NULL);
SDL_SetRenderTarget(gRenderer, NULL);
//Set surface's metadata
surf[surf_no].texture = textureAccessible;
//Free surface and texture
SDL_DestroyTexture(texture);
SDL_FreeSurface(surface);
printf(" ^ Successfully loaded\n");
return true;
else
{
if (surf[surf_no].in_use == true)
{
printf("Tried to create drawable surface at occupied slot (%d)\n", surf_no);
}
else
{
//Create surface
surf[surf_no].surface = SDL_CreateRGBSurfaceWithFormat(0, bxsize * gWindowScale, bysize * gWindowScale, 0, SDL_PIXELFORMAT_RGBA32);
if (surf[surf_no].surface == NULL)
{
printf("Failed to create drawable surface %d (SDL_CreateRGBSurfaceWithFormat)\nSDL Error: %s\n", surf_no, SDL_GetError());
}
else
{
surf[surf_no].texture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, bxsize * gWindowScale, bysize * gWindowScale);
if (surf[surf_no].texture == NULL)
{
printf("Failed to create drawable surface %d (SDL_CreateTexture)\nSDL Error: %s\n", surf_no, SDL_GetError());
SDL_FreeSurface(surf[surf_no].surface);
}
else
{
surf[surf_no].in_use = true;
success = true;
}
}
}
}
return success;
}
bool MakeSurface_File(const char *name, int surf_no)
static void FlushSurface(int surf_no)
{
unsigned char *raw_pixels;
int pitch;
SDL_LockTexture(surf[surf_no].texture, NULL, (void**)&raw_pixels, &pitch);
unsigned char (*src_pixels)[surf[surf_no].surface->pitch / 4][4] = (unsigned char (*)[surf[surf_no].surface->pitch/ 4][4])surf[surf_no].surface->pixels;
unsigned char (*dst_pixels)[pitch / 4][4] = (unsigned char (*)[pitch/ 4][4])raw_pixels;
for (unsigned int h = 0; h < surf[surf_no].surface->h; ++h)
{
for (unsigned int w = 0; w < surf[surf_no].surface->w; ++w)
{
dst_pixels[h][w][0] = src_pixels[h][w][0];
dst_pixels[h][w][1] = src_pixels[h][w][1];
dst_pixels[h][w][2] = src_pixels[h][w][2];
if (src_pixels[h][w][0] || src_pixels[h][w][1] || src_pixels[h][w][2]) // Colour-key
dst_pixels[h][w][3] = 0xFF;
else
dst_pixels[h][w][3] = 0;
}
}
SDL_UnlockTexture(surf[surf_no].texture);
}
static bool LoadBitmap(SDL_RWops *fp, int surf_no, bool create_surface)
{
bool success = false;
if (surf_no >= SURFACE_ID_MAX)
{
printf("Tried to load bitmap at invalid slot (%d - maximum is %d\n", surf_no, SURFACE_ID_MAX);
}
else
{
if (create_surface && surf[surf_no].in_use)
{
printf("Tried to create drawable surface at occupied slot (%d)\n", surf_no);
}
else
{
SDL_Surface *surface = SDL_LoadBMP_RW(fp, 1);
if (surface == NULL)
{
printf("Couldn't load bitmap for surface id %d\nSDL Error: %s\n", surf_no, SDL_GetError());
}
else
{
if (create_surface == false || MakeSurface_Generic(surface->w, surface->h, surf_no))
{
SDL_Surface *converted_surface = SDL_ConvertSurface(surface, surf[surf_no].surface->format, 0);
if (converted_surface == NULL)
{
printf("Couldn't convert bitmap to surface format (surface id %d)\nSDL Error: %s\n", surf_no, SDL_GetError());
}
else
{
SDL_Rect dst_rect = {0, 0, converted_surface->w * gWindowScale, converted_surface->h * gWindowScale};
SDL_BlitScaled(converted_surface, NULL, surf[surf_no].surface, &dst_rect);
SDL_FreeSurface(converted_surface);
surf[surf_no].needs_updating = true;
printf(" ^ Successfully loaded\n");
success = true;
}
}
SDL_FreeSurface(surface);
}
}
}
return success;
}
static bool LoadBitmap_File(const char *name, int surf_no, bool create_surface)
{
char path[PATH_LENGTH];
SDL_RWops *fp;
@ -168,9 +224,16 @@ bool MakeSurface_File(const char *name, int surf_no)
fp = SDL_RWFromFile(path, "rb");
if (fp)
{
printf("Loading surface (as .pbm) from %s for surface id %d\n", path, surf_no);
if (MakeSurface(fp, surf_no))
return true;
if (!IsEnableBitmap(fp))
{
printf("Tried to load bitmap to surface %d, but it's missing the '(C)Pixel' string\n", surf_no);
}
else
{
printf("Loading surface (as .pbm) from %s for surface id %d\n", path, surf_no);
if (LoadBitmap(fp, surf_no, create_surface))
return true;
}
}
//Attempt to load BMP
@ -178,23 +241,31 @@ bool MakeSurface_File(const char *name, int surf_no)
fp = SDL_RWFromFile(path, "rb");
if (fp)
{
printf("Loading surface (as .bmp) from %s for surface id %d\n", path, surf_no);
if (MakeSurface(fp, surf_no))
return true;
if (!IsEnableBitmap(fp))
{
printf("Tried to load bitmap to surface %d, but it's missing the '(C)Pixel' string\n", surf_no);
}
else
{
printf("Loading surface (as .bmp) from %s for surface id %d\n", path, surf_no);
if (LoadBitmap(fp, surf_no, create_surface))
return true;
}
}
printf("Failed to open file %s\n", name);
return false;
}
bool MakeSurface_Resource(const char *res, int surf_no)
static bool LoadBitmap_Resource(const char *res, int surf_no, bool create_surface)
{
SDL_RWops *fp = FindResource(res);
if (fp)
{
printf("Loading surface from resource %s for surface id %d\n", res, surf_no);
if (MakeSurface(fp, surf_no))
if (LoadBitmap(fp, surf_no, create_surface))
return true;
}
@ -202,34 +273,24 @@ bool MakeSurface_Resource(const char *res, int surf_no)
return false;
}
bool MakeSurface_File(const char *name, int surf_no)
{
return LoadBitmap_File(name, surf_no, true);
}
bool MakeSurface_Resource(const char *res, int surf_no)
{
return LoadBitmap_Resource(res, surf_no, true);
}
bool ReloadBitmap_File(const char *name, int surf_no)
{
ReleaseSurface(surf_no);
return MakeSurface_File(name, surf_no);
return LoadBitmap_File(name, surf_no, false);
}
bool ReloadBitmap_Resource(const char *res, int surf_no)
{
ReleaseSurface(surf_no);
return MakeSurface_Resource(res, surf_no);
}
bool MakeSurface_Generic(int bxsize, int bysize, int surf_no)
{
//Delete old surface
ReleaseSurface(surf_no);
//Create surface
surf[surf_no].texture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, bxsize * gWindowScale, bysize * gWindowScale);
if (!surf[surf_no].texture)
{
printf("Failed to create drawable surface %d\nSDL Error: %s\n", surf_no, SDL_GetError());
return false;
}
SDL_SetTextureBlendMode(surf[surf_no].texture, SDL_BLENDMODE_BLEND);
return true;
return LoadBitmap_Resource(res, surf_no, false);
}
SDL_Rect RectToSDLRect(RECT *rect)
@ -246,42 +307,27 @@ void BackupSurface(int surf_no, RECT *rect)
//Get texture of what's currently rendered on screen
SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, SDL_PIXELFORMAT_RGBA32);
SDL_RenderReadPixels(gRenderer, nullptr, SDL_PIXELFORMAT_RGBA32, surface->pixels, surface->pitch);
SDL_RenderReadPixels(gRenderer, NULL, SDL_PIXELFORMAT_RGBA32, surface->pixels, surface->pitch);
SDL_Texture *screenTexture = SDL_CreateTextureFromSurface(gRenderer, surface);
//Free surface
SDL_FreeSurface(surface);
//Get rects
SDL_Rect frameRect = RectToSDLRect(rect);
frameRect = {frameRect.x * gWindowScale, frameRect.y * gWindowScale, frameRect.w * gWindowScale, frameRect.h * gWindowScale};
SDL_Texture *textureAccessible = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, frameRect.w, frameRect.h);
if (!textureAccessible)
{
printf("Failed to create real texture for surface id %d\nSDL Error: %s\n", surf_no, SDL_GetError());
return;
}
SDL_SetTextureBlendMode(textureAccessible, SDL_BLENDMODE_BLEND);
SDL_SetRenderTarget(gRenderer, textureAccessible);
SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 0);
SDL_RenderClear(gRenderer);
SDL_RenderCopy(gRenderer, screenTexture, &frameRect, NULL);
SDL_SetRenderTarget(gRenderer, NULL);
//Set surface's metadata
surf[surf_no].texture = textureAccessible;
//Free stuff
SDL_DestroyTexture(screenTexture);
SDL_BlitSurface(surface, &frameRect, surf[surf_no].surface, &frameRect);
surf[surf_no].needs_updating = true;
//Free surface
SDL_FreeSurface(surface);
}
void PutBitmap3(RECT *rcView, int x, int y, RECT *rect, int surf_no) //Transparency
static void DrawBitmap(RECT *rcView, int x, int y, RECT *rect, int surf_no, bool transparent)
{
if (surf[surf_no].needs_updating)
{
FlushSurface(surf_no);
surf[surf_no].needs_updating = false;
}
//Get SDL_Rects
SDL_Rect clipRect = RectToSDLRect(rcView);
@ -295,6 +341,8 @@ void PutBitmap3(RECT *rcView, int x, int y, RECT *rect, int surf_no) //Transpare
clipRect = {clipRect.x * gWindowScale, clipRect.y * gWindowScale, clipRect.w * gWindowScale, clipRect.h * gWindowScale};
SDL_RenderSetClipRect(gRenderer, &clipRect);
SDL_SetTextureBlendMode(surf[surf_no].texture, transparent ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
//Draw to screen
if (SDL_RenderCopy(gRenderer, surf[surf_no].texture, &frameRect, &destRect) < 0)
printf("Failed to draw texture %d\nSDL Error: %s\n", surf_no, SDL_GetError());
@ -303,36 +351,14 @@ void PutBitmap3(RECT *rcView, int x, int y, RECT *rect, int surf_no) //Transpare
SDL_RenderSetClipRect(gRenderer, NULL);
}
void PutBitmap3(RECT *rcView, int x, int y, RECT *rect, int surf_no) //Transparency
{
DrawBitmap(rcView, x, y, rect, surf_no, true);
}
void PutBitmap4(RECT *rcView, int x, int y, RECT *rect, int surf_no) //No Transparency
{
//Get SDL_Rects
SDL_Rect clipRect = RectToSDLRect(rcView);
SDL_Rect frameRect = RectToSDLRect(rect);
frameRect = {frameRect.x * gWindowScale, frameRect.y * gWindowScale, frameRect.w * gWindowScale, frameRect.h * gWindowScale};
//Get dest rect
SDL_Rect destRect = {x * gWindowScale, y * gWindowScale, frameRect.w, frameRect.h};
//Set cliprect
clipRect = {clipRect.x * gWindowScale, clipRect.y * gWindowScale, clipRect.w * gWindowScale, clipRect.h * gWindowScale};
SDL_RenderSetClipRect(gRenderer, &clipRect);
//Get original drawing colour
uint8_t origR, origG, origB, origA;
SDL_GetRenderDrawColor(gRenderer, &origR, &origG, &origB, &origA);
//Draw black behind texture
SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 0xFF);
SDL_RenderFillRect(gRenderer, &destRect);
//Draw texture
if (SDL_RenderCopy(gRenderer, surf[surf_no].texture, &frameRect, &destRect) < 0)
printf("Failed to draw texture %d\nSDL Error: %s\n", surf_no, SDL_GetError());
//Restore original colour, and undo cliprect
SDL_RenderSetClipRect(gRenderer, NULL);
SDL_SetRenderDrawColor(gRenderer, origR, origG, origB, origA);
DrawBitmap(rcView, x, y, rect, surf_no, false);
}
void Surface2Surface(int x, int y, RECT *rect, int to, int from)
@ -341,22 +367,9 @@ void Surface2Surface(int x, int y, RECT *rect, int to, int from)
SDL_Rect rcSet = {x * gWindowScale, y * gWindowScale, (rect->right - rect->left) * gWindowScale, (rect->bottom - rect->top) * gWindowScale};
SDL_Rect frameRect = RectToSDLRect(rect);
frameRect = {frameRect.x * gWindowScale, frameRect.y * gWindowScale, frameRect.w * gWindowScale, frameRect.h * gWindowScale};
//Target surface
if (!surf[to].texture)
{
printf("Tried to draw to surface %d, which doesn't exist\n", to);
return;
}
SDL_SetRenderTarget(gRenderer, surf[to].texture);
//Draw texture
if (SDL_RenderCopy(gRenderer, surf[from].texture, &frameRect, &rcSet) < 0)
printf("Failed to draw texture %d to %d\nSDL Error: %s\n", from, to, SDL_GetError());
//Stop targetting surface
SDL_SetRenderTarget(gRenderer, NULL);
SDL_BlitSurface(surf[from].surface, &frameRect, surf[to].surface, &rcSet);
surf[to].needs_updating = true;
}
void CortBox(RECT *rect, uint32_t col)
@ -375,27 +388,12 @@ void CortBox2(RECT *rect, uint32_t col, int surf_no)
//Get rect
SDL_Rect destRect = RectToSDLRect(rect);
destRect = {destRect.x * gWindowScale, destRect.y * gWindowScale, destRect.w * gWindowScale, destRect.h * gWindowScale};
//Target surface
if (!surf[surf_no].texture)
{
printf("Tried to draw a rectangle to surface %d, which doesn't exist\n", surf_no);
return;
}
SDL_SetRenderTarget(gRenderer, surf[surf_no].texture);
const unsigned char col_red = (col & 0xFF0000) >> 16;
const unsigned char col_green = (col & 0x00FF00) >> 8;
const unsigned char col_blue = col & 0x0000FF;
const unsigned char col_alpha = (col_red || col_green || col_blue) ? 0xFF : 0;
//Set colour and draw
SDL_SetRenderDrawColor(gRenderer, col_red, col_green, col_blue, col_alpha);
SDL_RenderFillRect(gRenderer, &destRect);
//Stop targetting surface
SDL_SetRenderTarget(gRenderer, NULL);
SDL_FillRect(surf[surf_no].surface, &destRect, SDL_MapRGB(surf[surf_no].surface->format, col_red, col_green, col_blue));
surf[surf_no].needs_updating = true;
}
#ifdef WINDOWS
@ -491,12 +489,24 @@ void InitTextObject(const char *font_name)
void PutText(int x, int y, const char *text, uint32_t color)
{
DrawText(gFont, gRenderer, NULL, x * gWindowScale, y * gWindowScale, color, text, strlen(text));
int surface_width, surface_height;
SDL_GetRendererOutputSize(gRenderer, &surface_width, &surface_height);
SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, surface_width, surface_height, 0, SDL_PIXELFORMAT_RGBA32);
SDL_RenderReadPixels(gRenderer, NULL, SDL_PIXELFORMAT_RGBA32, surface->pixels, surface->pitch);
DrawText(gFont, surface, x * gWindowScale, y * gWindowScale, color, text, strlen(text));
SDL_Texture *screen_texture = SDL_CreateTextureFromSurface(gRenderer, surface);
SDL_FreeSurface(surface);
SDL_RenderCopy(gRenderer, screen_texture, NULL, NULL);
SDL_DestroyTexture(screen_texture);
}
void PutText2(int x, int y, const char *text, uint32_t color, int surf_no)
{
DrawText(gFont, gRenderer, surf[surf_no].texture, x * gWindowScale, y * gWindowScale, color, text, strlen(text));
DrawText(gFont, surf[surf_no].surface, x * gWindowScale, y * gWindowScale, color, text, strlen(text));
surf[surf_no].needs_updating = true;
}
void EndTextObject()
@ -505,3 +515,17 @@ void EndTextObject()
UnloadFont(gFont);
gFont = nullptr;
}
bool StartDirectDraw()
{
//Create renderer
gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
return true;
}
void EndDirectDraw()
{
//Release all surfaces
for (int i = 0; i < SURFACE_ID_MAX; i++)
ReleaseSurface(i);
}

View file

@ -45,6 +45,9 @@ enum Surface_Ids
struct SURFACE
{
bool in_use;
bool needs_updating;
SDL_Surface *surface;
SDL_Texture *texture;
};

View file

@ -175,20 +175,12 @@ FontObject* LoadFont(const char *font_filename, unsigned int cell_width, unsigne
return font_object;
}
void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *texture, int x, int y, unsigned long colour, const char *string, size_t string_length)
void DrawText(FontObject *font_object, SDL_Surface *surface, int x, int y, unsigned long colour, const char *string, size_t string_length)
{
if (font_object != NULL)
{
const unsigned char colours[3] = {(unsigned char)(colour >> 16), (unsigned char)(colour >> 8), (unsigned char)colour};
SDL_Texture *old_render_target = SDL_GetRenderTarget(renderer);
SDL_SetRenderTarget(renderer, texture);
int surface_width, surface_height;
SDL_GetRendererOutputSize(renderer, &surface_width, &surface_height);
SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, surface_width, surface_height, 0, SDL_PIXELFORMAT_RGBA32);
SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_RGBA32, surface->pixels, surface->pitch);
unsigned char (*surface_buffer)[surface->pitch / 4][4] = (unsigned char (*)[surface->pitch / 4][4])surface->pixels;
FT_Face face = font_object->face;
@ -238,11 +230,11 @@ void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *text
const int letter_x = x + pen_x + face->glyph->bitmap_left;
const int letter_y = y + ((FT_MulFix(face->ascender, face->size->metrics.y_scale) + (64 - 1)) / 64) - (face->glyph->metrics.horiBearingY / 64);
for (int iy = MAX(-letter_y, 0); letter_y + iy < MIN(letter_y + converted.rows, surface_height); ++iy)
for (int iy = MAX(-letter_y, 0); letter_y + iy < MIN(letter_y + converted.rows, surface->h); ++iy)
{
if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD)
{
for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width / 3, surface_width); ++ix)
for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width / 3, surface->w); ++ix)
{
const unsigned char (*font_buffer)[converted.pitch / 3][3] = (unsigned char (*)[converted.pitch / 3][3])converted.buffer;
@ -263,7 +255,7 @@ void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *text
}
else if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
{
for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width, surface_width); ++ix)
for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width, surface->w); ++ix)
{
unsigned char (*font_buffer)[converted.pitch] = (unsigned char (*)[converted.pitch])converted.buffer;
@ -282,7 +274,7 @@ void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *text
}
else if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO)
{
for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width, surface_width); ++ix)
for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width, surface->w); ++ix)
{
unsigned char (*font_buffer)[converted.pitch] = (unsigned char (*)[converted.pitch])converted.buffer;
@ -303,12 +295,6 @@ void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *text
pen_x += face->glyph->advance.x / 64;
}
SDL_Texture *screen_texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
SDL_RenderCopy(renderer, screen_texture, NULL, NULL);
SDL_DestroyTexture(screen_texture);
SDL_SetRenderTarget(renderer, old_render_target);
}
}

View file

@ -8,5 +8,5 @@ typedef struct FontObject FontObject;
FontObject* LoadFontFromData(const unsigned char *data, size_t data_size, unsigned int cell_width, unsigned int cell_height);
FontObject* LoadFont(const char *font_filename, unsigned int cell_width, unsigned int cell_height);
void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *texture, int x, int y, unsigned long colour, const char *string, size_t string_length);
void DrawText(FontObject *font_object, SDL_Surface *surface, int x, int y, unsigned long colour, const char *string, size_t string_length);
void UnloadFont(FontObject *font_object);