Minimaler ausführbarer Beispiel
Der Zähler wird alle Sekunde aktualisiert.
Ubuntu 16.10, SDL 2.0.4:
sudo apt-get install libsdl2-dev libsdl2-ttf-dev
./main /path/to/my.ttf
Diese Methode ist einfach zu integrieren, aber nicht sehr effizient, da sie ständig neu erstellt Texturen und Raster-Bilder. Wenn Sie auch Effizienz wünschen, siehe: Schriftarten und Texte mit SDL2 effizient rendern Ich bekomme 4k FPS, also könnte es für einfache Anwendungen in Ordnung sein.
GitHub upstream mit einer ttf-Datei zum Testen: https://github.com/cirosantilli/cpp-cheat/blob/d36527fe4977bb9ef4b885b1ec92bd0cd3444a98/sdl/ttf.c:
#include
#include
#include
#include
#include
#define COMMON_COLOR_MAX 255
#define COMMON_WINDOW_WIDTH 500
#define COMMON_WINDOW_HEIGHT (COMMON_WINDOW_WIDTH)
double common_get_secs(void) {
struct timespec ts;
timespec_get(&ts, TIME_UTC);
return ts.tv_sec + (1e-9 * ts.tv_nsec);
}
const double COMMON_FPS_GRANULARITY_S = 0.5;
double common_fps_last_time_s;
unsigned int common_fps_nframes;
void common_fps_init() {
common_fps_nframes = 0;
common_fps_last_time_s = common_get_secs();
}
void common_fps_update_and_print() {
double dt, current_time_s;
current_time_s = common_get_secs();
common_fps_nframes++;
dt = current_time_s - common_fps_last_time_s;
if (dt > COMMON_FPS_GRANULARITY_S) {
printf("FPS = %f\n", common_fps_nframes / dt);
common_fps_last_time_s = current_time_s;
common_fps_nframes = 0;
}
}
#define MAX_STRING_LEN 4
/*
- x, y: obere linke Ecke des Strings
- Rechteck-Ausgabebreite und -höhe enthalten die gerenderten Abmessungen.
*/
void render_text(
SDL_Renderer *renderer,
int x,
int y,
const char *text,
TTF_Font *font,
SDL_Rect *rect,
SDL_Color *color
) {
SDL_Surface *surface;
SDL_Texture *texture;
surface = TTF_RenderText_Solid(font, text, *color);
texture = SDL_CreateTextureFromSurface(renderer, surface);
rect->x = x;
rect->y = y;
rect->w = surface->w;
rect->h = surface->h;
/* Dies ist für Texturen, die gleich bleiben, verschwenderisch.
* Macht die Dinge jedoch weniger zustandsbehaftet und einfacher zu verwenden.
* Werden wir hier eine Atlaslösung kodieren...? */
SDL_FreeSurface(surface);
SDL_RenderCopy(renderer, texture, NULL, rect);
SDL_DestroyTexture(texture);
}
int main(int argc, char **argv) {
SDL_Color color;
SDL_Event event;
SDL_Rect rect;
SDL_Renderer *renderer;
SDL_Window *window;
char *font_path, text[MAX_STRING_LEN];
/* Befehlszeilenargumente. */
if (argc == 1) {
font_path = "FreeSans.ttf";
} else if (argc == 2) {
font_path = argv[1];
} else {
fprintf(stderr, "Fehler: Zu viele Argumente\n");
exit(EXIT_FAILURE);
}
/* Variablen initialisieren. */
color.r = COMMON_COLOR_MAX;
color.g = COMMON_COLOR_MAX;
color.b = COMMON_COLOR_MAX;
color.a = COMMON_COLOR_MAX;
/* Fenster initialisieren. */
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(
COMMON_WINDOW_WIDTH,
COMMON_WINDOW_WIDTH,
0,
&window,
&renderer
);
/* TTF initialisieren. */
TTF_Init();
TTF_Font *font = TTF_OpenFont(font_path, 24);
if (font == NULL) {
fprintf(stderr, "Fehler: Schriftart nicht gefunden\n");
exit(EXIT_FAILURE);
}
/* Hauptschleife. */
common_fps_init();
while (1) {
if (SDL_PollEvent(&event) && event.type == SDL_QUIT) {
break;
}
/* TTF verwenden. */
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
render_text(renderer, 0, 0, "Hallo", font, &rect, &color);
render_text(renderer, 0, rect.y + rect.h, "Welt", font, &rect, &color);
snprintf(text, MAX_STRING_LEN, "%u", (unsigned int)(time(NULL) % 1000));
render_text(renderer, 0, rect.y + rect.h, text, font, &rect, &color);
SDL_RenderPresent(renderer);
common_fps_update_and_print();
}
/* Aufräumen. */
TTF_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}