optimise text drawing function by only creating a new texture when necessary

This commit is contained in:
2025-02-16 23:44:27 +01:00
parent 2c5be9685c
commit f30b8182b1
2 changed files with 37 additions and 12 deletions

View File

@@ -9,6 +9,7 @@
#include <SDL_video.h> #include <SDL_video.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "../errors.h" #include "../errors.h"
#include "../game/game.h" #include "../game/game.h"
@@ -35,6 +36,7 @@ void renderer_init(render_data* const render_dat, game_data const* const game_da
window, window,
renderer, renderer,
font, font,
calloc(1, sizeof(struct render_cache)), // zero-initialize the memory as we read from it
}; };
} }
@@ -46,21 +48,34 @@ static inline int32_t get_row_pos(uint8_t row) {
return row * BLOCK_HEIGHT + 1 + TET_PADDING; return row * BLOCK_HEIGHT + 1 + TET_PADDING;
} }
static void draw_score_text(SDL_Renderer* const renderer, TTF_Font* const font, uint16_t const score) { static void draw_score_text(render_data const* dat) {
char score_text[5]; // max digits of a uint16 struct render_cache* const cache = dat->cache;
uint16_t const score = dat->game_dat->score;
if (!score) sprintf(score_text, "0"); SDL_Renderer* const renderer = dat->renderer;
else sprintf(score_text, "%hu0", score); TTF_Font* const font = dat->font;
SDL_Surface* const txt_surface = TTF_RenderText_Solid(font, score_text, (SDL_Colour){colour8_red32(COLOUR_SCORE), colour8_green32(COLOUR_SCORE), colour8_blue32(COLOUR_SCORE), 0xFF}); if (!(cache->prevscore != score && cache->score_texture != NULL)) {
SDL_Texture* const txt_texture = SDL_CreateTextureFromSurface(renderer, txt_surface); char score_text[6]; // max digits of a uint16 + \0 terminator
if (!score) sprintf(score_text, "0");
else sprintf(score_text, "%hu0", score);
SDL_Rect text_rect = {get_column_pos(COLUMNS + 1), get_row_pos(0), txt_surface->w, txt_surface->h}; SDL_Surface* const txt_surface = TTF_RenderText_Solid(font, score_text, (SDL_Colour){colour8_red32(COLOUR_SCORE), colour8_green32(COLOUR_SCORE), colour8_blue32(COLOUR_SCORE), 0xFF});
SDL_RenderCopy(renderer, txt_texture, NULL, &text_rect); SDL_Texture* const txt_texture = SDL_CreateTextureFromSurface(renderer, txt_surface);
// free data if (cache->score_texture != NULL) {
SDL_FreeSurface(txt_surface); // free old data
SDL_DestroyTexture(txt_texture); SDL_FreeSurface(cache->score_surface);
SDL_DestroyTexture(cache->score_texture);
}
// write data to cache
cache->score_surface = txt_surface;
cache->score_texture = txt_texture;
}
SDL_Rect text_rect = {get_column_pos(COLUMNS + 1), get_row_pos(0), cache->score_surface->w, cache->score_surface->h};
SDL_RenderCopy(renderer, cache->score_texture, NULL, &text_rect);
} }
// draws a block at the specified position // draws a block at the specified position
@@ -122,7 +137,7 @@ void renderer_update(render_data const* const dat) {
SDL_RenderDrawRect(renderer, &field_size); SDL_RenderDrawRect(renderer, &field_size);
draw_shape(renderer, game_data->nxt[game_data->curr_idx + 1], COLUMNS + 1, 3); // draw the next shape draw_shape(renderer, game_data->nxt[game_data->curr_idx + 1], COLUMNS + 1, 3); // draw the next shape
draw_score_text(renderer, dat->font, dat->game_dat->score); draw_score_text(dat);
render_level(renderer, dat->game_dat); render_level(renderer, dat->game_dat);
draw_shape(renderer, game_data->nxt[game_data->curr_idx], game_data->sel_x, game_data->sel_y); // draw the current shape draw_shape(renderer, game_data->nxt[game_data->curr_idx], game_data->sel_x, game_data->sel_y); // draw the current shape
@@ -139,7 +154,9 @@ void renderer_free(render_data* const render_data) {
SDL_DestroyRenderer(render_data->renderer); SDL_DestroyRenderer(render_data->renderer);
SDL_DestroyWindow(render_data->window); SDL_DestroyWindow(render_data->window);
TTF_CloseFont(render_data->font); TTF_CloseFont(render_data->font);
free(render_data->cache);
render_data->renderer = NULL; render_data->renderer = NULL;
render_data->window = NULL; render_data->window = NULL;
render_data->font = NULL; render_data->font = NULL;
render_data->cache = NULL;
} }

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <SDL_render.h> #include <SDL_render.h>
#include <SDL_surface.h>
#include <SDL_ttf.h> #include <SDL_ttf.h>
#include <SDL_video.h> #include <SDL_video.h>
#include <stdint.h> #include <stdint.h>
@@ -15,11 +16,18 @@
#define BLOCK_WIDTH (TET_WIDTH / COLUMNS) // width of a block #define BLOCK_WIDTH (TET_WIDTH / COLUMNS) // width of a block
#define BLOCK_HEIGHT (TET_HEIGHT / ROWS) // height of a block #define BLOCK_HEIGHT (TET_HEIGHT / ROWS) // height of a block
struct render_cache {
SDL_Texture* score_texture;
SDL_Surface* score_surface;
uint16_t prevscore;
};
typedef struct { typedef struct {
game_data const* game_dat; game_data const* game_dat;
SDL_Window* window; SDL_Window* window;
SDL_Renderer* renderer; SDL_Renderer* renderer;
TTF_Font* font; TTF_Font* font;
struct render_cache* cache;
} render_data; } render_data;
void renderer_init(render_data* render_dat, game_data const* game_dat); void renderer_init(render_data* render_dat, game_data const* game_dat);