Partage
  • Partager sur Facebook
  • Partager sur Twitter

TTF empêche toute modification de l'écran

Impossible de dessiner après avoir collé du texte avec TTF

    23 janvier 2021 à 23:44:19

    Bonjour,

    J'utilise la SDL2 et TTF2 pour afficher du texte sur ma fenêtre.
    Après avoir généré une surface avec TTF_RenderText_Blended et l'avoir collée sur l'écran, je ne peut plus dessiner quoi que ce soit sur ma fenêtre tant que je ne l'ai pas réinitialisée avec SDL_RenderClear.

    Voici un exemple (édité)

    /* rendre l'écran tout noir */
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);
    
    /* écrire "hello world" en blanc sur tout l'écran */
    TTF_Font* font = TTF_OpenFont("fonts/arial.ttf", 300);
    SDL_Color textColor = {255, 255, 255, 255};
    SDL_Surface* textSurface = TTF_RenderText_Blended(font, "hello world", textColor);
    SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
    SDL_RenderCopy(renderer, textTexture, NULL, NULL);
    SDL_DestroyTexture(textTexture);
    SDL_FreeSurface(textSurface);
    TTF_CloseFont(font);
    
    /* dessiner une ligne diagonale blanche par dessus le texte (ne fonctionne pas) */
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    int width, height;
    SDL_GetRendererOutputSize(renderer, &width, &height);
    SDL_RenderDrawLine(renderer, 0, 0, width, height);
    
    /* actualiser l'écran */
    SDL_RenderPresent(renderer);

    Je devrais obtenir une ligne diagonale blanche, par dessus le texte, qui traverse tout l'écran, mais à la place j'ai ça:

    Et si je commente la ligne

    SDL_RenderCopy(renderer, textTexture, NULL, NULL);


    La ligne se trace bien

    Sauriez d'où ça viens, et comment afficher du texte sans que ça casse tout ?
    Merci d'avance.

    -
    Edité par WatashiGaKita 24 janvier 2021 à 11:05:27

    • Partager sur Facebook
    • Partager sur Twitter
      24 janvier 2021 à 1:13:42

      Salut,

      D'abord SDL_DrawColor() ne rend pas l'écran tout noir mais sélectionne la couleur utilisée pour "dessiner", ensuite pour "effacer" l'écran avec cette même couleur, c'est SDL_RenderClear().

      En dehors de ça, ce code fonctionne parfaitement tel quel chez moi. Si ce n'est qu'il serait plus logique d'utiliser SDL_RenderGetLogicalSize() à la ligne 17, mais c'est vraiment pour chipoter.

      Bonne continuation.

      • Partager sur Facebook
      • Partager sur Twitter

      Bonhomme !! | Jeu de plateforme : Prototype.

        24 janvier 2021 à 11:04:40

        Oui pardon j'ai oublié de faire un SDL_RenderClear(renderer) après SDL_SetRenderDrawColor
        J'édite mon code.

        Mais même avec ça, le problème persiste.
        • Partager sur Facebook
        • Partager sur Twitter
          24 janvier 2021 à 12:06:41

          Salut,

          En tout cas, le problème ne semble pas venir du code qui fonctionne chez moi. Es-tu certain d'avoir posté le code exactement comme tu l'as écrit dans ton fichier ? Sinon, efface cette section de ton code et copie colle celle que tu as postée sur le site. Il arrive parfois que des caractères fantômes se retrouvent dans l'éditeur. Supprime également les espaces / tabulations qui sont derrière la fin de commande ';' ou dans les lignes vides.

          Au-delà de ça, il va être difficile de dépanner un code qui fonctionne.

          Bonne continuation.

          • Partager sur Facebook
          • Partager sur Twitter

          Bonhomme !! | Jeu de plateforme : Prototype.

            24 janvier 2021 à 14:29:18

            Oui j'en suis sur le code est exactement comme dans mon fichier. Et pour être sur j'ai copié collé ce que j'ai publié plus haut, et j'ai vérifié qu'il n'y a pas d'espaces ou de tabulations en trop.

            EDIT : Quand je déplace les lignes suivantes à la fin du code

            SDL_DestroyTexture(textTexture);
            SDL_FreeSurface(textSurface);
            TTF_CloseFont(font);


            ça fonctionne.

            Une fois que la texture a été collée sur le SDL_Renderer, on dirais qu'il ne faut pas encore la libérer de la mémoire. Savez vous pourquoi ?

            -
            Edité par WatashiGaKita 24 janvier 2021 à 15:19:27

            • Partager sur Facebook
            • Partager sur Twitter
              26 janvier 2021 à 9:10:46

              Juste une chose avant :

              Ouvrir la police à chaque fois est un peu violent. Charge la une bonne fois pour toute au début du programme (ou l'état actuel qui en a besoin).

              Pour ta question, quelle version exacte de SDL as-tu ? Si je me souviens bien il y a une version qui ne dessine pas si les objets ont été détruits avant l'appel à SDL_RenderPresent, ainsi le plus simple est de supprimer la texture après mais normalement les versions récentes n'ont plus besoin de ça.

              • Partager sur Facebook
              • Partager sur Twitter

              git is great because Linus did it, mercurial is better because he didn't.

                29 janvier 2021 à 9:51:14

                J'utilise la version 2.0.10

                Et je n'ouvre pas la police à chaque fois, le code plus haut est un exemple, sans boucle while, où la fenêtre n'est affichée qu'une seule fois.

                Dans mon programme final beaucoup plus long, j'ouvre la police au début et je la ferme quand l'utilisateur quitte le programme.

                Donc le problème n'est pas d'ouvrir la police à chaque fois.

                -
                Edité par WatashiGaKita 29 janvier 2021 à 9:57:43

                • Partager sur Facebook
                • Partager sur Twitter
                  29 janvier 2021 à 13:15:11

                  Moi je viens d'adapter ton code (juste pour faire une boucle principale et changer la police) et j'ai bien le résultat attendu :

                  #include <err.h>
                  
                  #include <SDL.h>
                  #include <SDL_ttf.h>
                  
                  int
                  main(int argc, char **argv)
                  {
                  	SDL_Window *win;
                  	SDL_Renderer *renderer;
                  
                  	SDL_Init(SDL_INIT_VIDEO);
                  	TTF_Init();
                  
                  	SDL_CreateWindowAndRenderer(640, 480, SDL_WINDOW_OPENGL, &win, &renderer);
                  	TTF_Font* font = TTF_OpenFont("/Users/markand/Dev/molko/libmlk-data/fonts/lato.ttf", 300);
                  
                  	if (!font)
                  		errx(1, "%s", SDL_GetError());
                  
                  	/* rendre l'écran tout noir */
                  
                  	for (;;) {
                  		SDL_Event ev;
                  
                  		while (SDL_PollEvent(&ev)) {
                  			switch (ev.type) {
                  			case SDL_QUIT:
                  				return 0;
                  			default:
                  				break;
                  			}
                  		}
                  
                  		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
                  		SDL_RenderClear(renderer);
                  		SDL_Color textColor = {255, 255, 255, 255};
                  		SDL_Surface* textSurface = TTF_RenderText_Blended(font, "hello world", textColor);
                  
                  		if (!textSurface)
                  			errx(1, "%s", SDL_GetError());
                  
                  		SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
                  
                  		if (!textTexture)
                  			errx(1, "%s", SDL_GetError());
                  
                  		SDL_RenderCopy(renderer, textTexture, NULL, NULL);
                  		SDL_DestroyTexture(textTexture);
                  		SDL_FreeSurface(textSurface);
                  		/* dessiner une ligne diagonale blanche par dessus le texte (ne fonctionne pas) */
                  		SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
                  		int width, height;
                  		SDL_GetRendererOutputSize(renderer, &width, &height);
                  		SDL_RenderDrawLine(renderer, 0, 0, width, height);
                  		/* actualiser l'écran */
                  		SDL_RenderPresent(renderer);
                  	}
                  }

                  Et voici l'image :


                  Peux tu essayer mon code (change juste la ligne de la police) et vérifier que ça produise toujours le problème ?

                  Tu nous as pas dit sur quel système tu es. La fonction errx est une extension BSD, si elle n'existe pas remplace la simplement par un printf + un exit.

                  Par contre moi j'ai SDL 2.0.12.

                  -
                  Edité par markand 29 janvier 2021 à 13:19:10

                  • Partager sur Facebook
                  • Partager sur Twitter

                  git is great because Linus did it, mercurial is better because he didn't.

                    30 janvier 2021 à 12:00:35

                    Effectivement merci j'ai pu me rendre compte de ce qui n'allais pas, après avoir initialisé la SDL j'ai fait

                    SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);

                    En retirant cette ligne ça marche, mais c'est bizarre... Pourquoi provoque t'elle ce comportement ?

                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 janvier 2021 à 14:13:13

                      Hello,

                      Alors de ce que je comprends en lisant la doc, le calcul de destA est 255+(255*(1-255)), ce qui donne -64515, et -64515 modulo 255 donne 0, ce qui signifie un alpha transparent.

                      Que ceux qui connaissent bien sdl2 me corrigent si je me trompe. Merci.

                      -
                      Edité par edgarjacobs 30 janvier 2021 à 14:20:47

                      • Partager sur Facebook
                      • Partager sur Twitter

                      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                        30 janvier 2021 à 20:02:44

                        Bah si tu nous donnes pas tout le code on ne peut pas t'aider ! Quand tu vas sur un forum il faut toujours faire un programme minimal reproduisant le problème.

                        La fonction SDL_SetRenderDrawBlendMode est principalement utilisée pour changer le rendu de la transparence pour les prochaines opérations, mais il faut que la texture le supporte aussi. C'est un peu compliqué à utiliser au début.

                        • Partager sur Facebook
                        • Partager sur Twitter

                        git is great because Linus did it, mercurial is better because he didn't.

                        TTF empêche toute modification de l'écran

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                        • Editeur
                        • Markdown