c++ - game - sdl tutorial
¿Cómo renderizar texto en SDL2? (3)
Sí lo es. Crea una superficie con el texto que desea y luego la convierte en una textura que puede representar.
Algunos ejemplos de código de uno de mis proyectos:
std::string score_text = "score: " + std::to_string(score);
SDL_Color textColor = { 255, 255, 255, 0 };
SDL_Surface* textSurface = TTF_RenderText_Solid(font, score_text.c_str(), textColor);
SDL_Texture* text = SDL_CreateTextureFromSurface(renderer, textSurface);
int text_width = textSurface->w;
int text_height = textSurface->h;
SDL_FreeSurface(textSurface);
SDL_Rect renderQuad = { 20, win_height - 30, text_width, text_height };
SDL_RenderCopy(renderer, text, NULL, &renderQuad);
SDL_DestroyTexture(text);
Esto supone que has inicializado correctamente SDL_ttf y cargado una fuente. En el ejemplo de score
es un int. La pantalla se borra y se representa en otro lugar (no incluí esa parte).
Para ver un ejemplo completo, consulte el tutorial para SDL_ttf en SDL2 en Lazy Foo .
Me preguntaba cómo renderizar texto con SDL2. Encontré una API llamada SDL_TTF
y algunos tutoriales, sin embargo, no funcionan con mi situación.
Estoy usando un SDL_Window
y SDL_Renderer
, mientras que los tutoriales son específicos de SDL_Surface
.
¿Es posible utilizar SDL_TTF
con SDL_Render/SDL_Window
? ¿Si es así, cómo?
Sí, es posible, dado que tienes un renderizador y una ventana, además de que realmente no tienes ninguna idea sobre cómo incursionar en las superficies, entonces es posible que te interese crear una textura, aquí hay un código de muestra.
TTF_Font* Sans = TTF_OpenFont("Sans.ttf", 24); //this opens a font style and sets a size
SDL_Color White = {255, 255, 255}; // this is the color in rgb format, maxing out all would give you the color white, and it will be your text''s color
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(Sans, "put your text here", White); // as TTF_RenderText_Solid could only be used on SDL_Surface then you have to create the surface first
SDL_Texture* Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage); //now you can convert it into a texture
SDL_Rect Message_rect; //create a rect
Message_rect.x = 0; //controls the rect''s x coordinate
Message_rect.y = 0; // controls the rect''s y coordinte
Message_rect.w = 100; // controls the width of the rect
Message_rect.h = 100; // controls the height of the rect
//Mind you that (0,0) is on the top left of the window/screen, think a rect as the text''s box, that way it would be very simple to understance
//Now since it''s a texture, you have to put RenderCopy in your game loop area, the area where the whole code executes
SDL_RenderCopy(renderer, Message, NULL, &Message_rect); //you put the renderer''s name first, the Message, the crop size(you can ignore this if you don''t want to dabble with cropping), and the rect which is the size and coordinate of your texture
//Don''t forget too free your surface and texture
Intenté explicar el código línea por línea, no ve ninguna ventana allí mismo, ya que asumí que sabía cómo inicializar un renderizador, lo que me daría una idea de que también sabe cómo inicializar una ventana. La necesidad es la idea de cómo inicializar una textura.
Preguntas menores aquí, ¿se abrió su ventana? era de color negro? si es así, mis pensamientos fueron correctos, si no, entonces puedes preguntarme y puedo cambiar este código para implementar toda la sección que consiste en un renderizador y una ventana.
Ejemplo ejecutable mínimo de SDL_ttf
No super eficiente, pero fácil de integrar. Para mayor eficiencia, consulte: Representación eficiente de fuentes y texto con SDL2
Mantenido en un repositorio separado de la fuente principal de SDL, pero alojado en el mismo servidor oficial, por lo que debería estar bien: http://hg.libsdl.org/SDL_ttf/
Las líneas nuevas no funcionarán. Tienes que trabajar con alturas de linea.
Debe pasar la ruta de un archivo de fuente TTF al programa como:
./ttf /usr/share/fonts/truetype/freefont/FreeMonoOblique.ttf
Compilar con:
sudo apt-get install -y libsdl2-dev
gcc -lSDL2 -lSDL2_ttf -o ttf ttf.c
Probado en Ubuntu 16.04, SDL 2.0.4.
Código en un repositorio de GitHub: https://github.com/cirosantilli/cpp-cheat/blob/e52ed4b838e2697d8f44ab5bef3e7a170705d48e/sdl/ttf.c
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#define WINDOW_WIDTH 300
#define WINDOW_HEIGHT (WINDOW_WIDTH)
/*
- x, y: upper left corner.
- texture, rect: outputs.
*/
void get_text_and_rect(SDL_Renderer *renderer, int x, int y, char *text,
TTF_Font *font, SDL_Texture **texture, SDL_Rect *rect) {
int text_width;
int text_height;
SDL_Surface *surface;
SDL_Color textColor = {255, 255, 255, 0};
surface = TTF_RenderText_Solid(font, text, textColor);
*texture = SDL_CreateTextureFromSurface(renderer, surface);
text_width = surface->w;
text_height = surface->h;
SDL_FreeSurface(surface);
rect->x = x;
rect->y = y;
rect->w = text_width;
rect->h = text_height;
}
int main(int argc, char **argv) {
SDL_Event event;
SDL_Rect rect1, rect2;
SDL_Renderer *renderer;
SDL_Texture *texture1, *texture2;
SDL_Window *window;
char *font_path;
int quit;
if (argc == 1) {
font_path = "FreeSans.ttf";
} else if (argc == 2) {
font_path = argv[1];
} else {
fprintf(stderr, "error: too many arguments/n");
exit(EXIT_FAILURE);
}
/* Inint TTF. */
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_WIDTH, 0, &window, &renderer);
TTF_Init();
TTF_Font *font = TTF_OpenFont(font_path, 24);
if (font == NULL) {
fprintf(stderr, "error: font not found/n");
exit(EXIT_FAILURE);
}
get_text_and_rect(renderer, 0, 0, "hello", font, &texture1, &rect1);
get_text_and_rect(renderer, 0, rect1.y + rect1.h, "world", font, &texture2, &rect2);
quit = 0;
while (!quit) {
while (SDL_PollEvent(&event) == 1) {
if (event.type == SDL_QUIT) {
quit = 1;
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
/* Use TTF textures. */
SDL_RenderCopy(renderer, texture1, NULL, &rect1);
SDL_RenderCopy(renderer, texture2, NULL, &rect2);
SDL_RenderPresent(renderer);
}
/* Deinit TTF. */
SDL_DestroyTexture(texture1);
SDL_DestroyTexture(texture2);
TTF_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}