Comment rendre du texte dans SDL2?

je me demandais comment rendre un texte avec SDL2. J'ai trouvé une API appelée SDL_TTF et quelques tutoriels, cependant ils ne fonctionnent pas avec ma situation.

j'utilise un SDL_Window et SDL_Renderer , alors que les tutoriels sont spécifiques à SDL_Surface .

Est-il possible d'utiliser SDL_TTF avec SDL_Render/SDL_Window ? Si oui, comment?

29
demandé sur genpfault 2014-04-06 00:39:54

3 réponses

ouais, c'est possible, étant donné que vous disposez d'un moteur de rendu et une fenêtre de plus, vous n'avez pas vraiment besoin de vos réflexions sur la surface avec des surfaces, alors vous pourriez vouloir de l'esprit sur la création de la texture, voici un exemple de code

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

j'ai essayé d'expliquer le code ligne par ligne, vous ne voyez pas de fenêtre juste là puisque j'ai déjà supposé que vous saviez initialiser un renderer qui me donnerait une idée que vous savez aussi initialiser une fenêtre, puis tout ce dont vous avez besoin c'est l'idée sur la façon d'initialiser une texture.

questions mineures ici, est-ce que votre fenêtre s'est ouverte? il était de couleur noire? si c'est le cas, alors mes pensées étaient bonnes, si non, alors vous pouvez juste me demander et je pourrais changer ce code pour implémenter toute la section qui se compose d'un renderer et d'une fenêtre.

36
répondu kdyz 2017-05-16 15:55:20

SDL_ttf minimum praticable exemple

enter image description here

Pas super efficace, mais facile à intégrer. Pour plus d'efficacité, voir: , le Rendu des polices et le texte avec SDL2 efficacement

conservé dans un repo séparé de la source SDL principale, mais hébergé sur le même serveur officiel, donc devrait être très bien: http://hg.libsdl.org/SDL_ttf /

les nouvelles lignes ne marchent pas. Tu dois travailler avec line heights.

vous devez passer le chemin d'un fichier de police TTF au programme comme:

./ttf /usr/share/fonts/truetype/freefont/FreeMonoOblique.ttf

compiler avec:

sudo apt-get install -y libsdl2-dev
gcc -lSDL2 -lSDL2_ttf -o ttf ttf.c

testé sur Ubuntu 16.04, SDL 2.0.4.

Code sur un dépôt 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;
}
10

Oui. Vous créez une surface avec le texte que vous voulez et le convertissez en une texture que vous pouvez rendre.

un exemple de code d'un de mes projets:

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);

cela suppose que vous avez correctement initialisé SDL_ttf et chargé une police. Dans l'exemple score est un int. L'écran est effacé et rendu à un autre endroit (je n'ai pas inclus cette partie).

pour un exemple de fonctionnement complet, consultez le tutoriel pour SDL_ttf en SDL2 au Paresseux Foo .

9
répondu jpw 2014-04-05 21:24:35