Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Zone de texte  (Lu 17239 fois)

0 Membres et 2 Invités sur ce sujet

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Zone de texte
« le: Avril 04, 2012, 09:33:22 pm »
Bonjour,

Je code actuellement une zone de texte en SFML.
J'ai presque fini mais je suis confronté à un petit problème : si le texte sf::String est trop long, il dépasse de la zone de texte.
J'aimerais donc le "couper" non pas au caractère près, mais au pixel près.

Auriez-vous une idée de comment procéder?

Cordialement,
Neckara

Orwel

  • Full Member
  • ***
  • Messages: 208
    • Voir le profil
Re: Zone de texte
« Réponse #1 le: Avril 04, 2012, 09:55:55 pm »
Tu utilises quelle version de SFML???

Idée en vrac. Tu dessines dans cette ordre:
-Cadre
-Text
-Bordure

Sinon, tu peux dessiner ton texte dans un sf::RenderTexture et couper les pixels qui dépassent. Après tu affiche cette texture à la place de ton objet sf::Text.

Peut-être qu'avec SFML2 il existe une solution plus efficace et propre  ;D

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re: Zone de texte
« Réponse #2 le: Avril 04, 2012, 10:10:00 pm »
Citer
Peut-être qu'avec SFML2 il existe une solution plus efficace et propre
Pas encore, mais ça arrivera bientôt.

En attendant il faut bidouiller :
- soit via une RenderTexture
- soit via une vue qui a le viewport qui va bien

Les deux sont plus ou moins des hacks, mais en attendant mieux ça fonctionne.
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re: Zone de texte
« Réponse #3 le: Avril 05, 2012, 07:15:34 am »
sf::RenderTexture?

Je n'en ai pas entendu parler dans le tutoriel de la 1.6 (version que j'utilise), qu'est-ce?

J'ai vu vite fait l'en-tête .hpp et j'ai l'impression que c'est un espace où on peut "blitter" dessus comme sur une sf::RenderWindow avec .Daw().

Si je veux mettre cette sf::RenderTexture sur une sf::RenderWindow, je fais 
RenderWindow.Draw(RenderTexture.Display());
?

EDIT : C'est bon, j'ai trouvé comment l'utiliser (http://www.sfml-dev.org/documentation/2.0/classsf_1_1RenderTexture.php#details).

Ces sf::RenderTexture vont vraiment me simplifier mon code, il est vraiment très regrettable qu'on en parle pas dans le tutoriel de la SFML.
« Modifié: Avril 05, 2012, 07:54:15 am par Neckara »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re: Zone de texte
« Réponse #4 le: Avril 05, 2012, 08:41:15 am »
Citer
Ces sf::RenderTexture vont vraiment me simplifier mon code, il est vraiment très regrettable qu'on en parle pas dans le tutoriel de la SFML.
Ben, c'est un peu normal, c'est du SFML 2.0 ;)

Avec SFML 1.6, il y a un autre hack plus simple pour faire ce que tu veux : utiliser glScissors (fonction OpenGL) pour définir une zone rectangulaire de clipping.
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re: Zone de texte
« Réponse #5 le: Avril 05, 2012, 09:57:08 am »
Il me semble que la 2.0 n'est pas encore sortie, savez-vous quand elle sort?


Pour openGL, je ne sais pas du tout l'utiliser, que vais-je devoir faire exactement?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re: Zone de texte
« Réponse #6 le: Avril 05, 2012, 10:01:38 am »
Citer
Il me semble que la 2.0 n'est pas encore sortie, savez-vous quand elle sort?
Elle est finalisée (tu peux déjà l'utiliser), elle sortira très très bientôt.

Citer
Pour openGL, je ne sais pas du tout l'utiliser, que vais-je devoir faire exactement?
Rien de bien compliqué :
- l'en-tête OpenGL est déjà inclus par <SFML/Window.hpp> dans SFML 1.6
- il faut lier à la bibliothèque OpenGL ("opengl32" sous Windows)
- il faut appeler glScissor(x, y, width, height) pour définir la zone de clipping
- il faut appeler glEnable(GL_SCISSOR_TEST) pour activer le clipping, glDisable(GL_SCISSOR_TEST) pour le désactiver
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re: Zone de texte
« Réponse #7 le: Avril 05, 2012, 10:12:45 am »
Je pense que je vais utiliser la 2.0 si j'y arrive.

Les sf::RenderTexture me semblent très pratique et plutôt que de faire des :
void getImage(sf::RenderWindow &app);
je pourrais faire :
sf::RenderTexture getImage();
Pour dessiner sur ma sf::RenderWindow.

Je vais donc essayer de voir comment installer la 2.0

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re: Zone de texte
« Réponse #8 le: Avril 05, 2012, 10:24:10 am »
Les sf::RenderTexture me semblent très pratique et plutôt que de faire des :
void getImage(sf::RenderWindow &app);
je pourrais faire :
sf::RenderTexture getImage();
Pour dessiner sur ma sf::RenderWindow.
Ce que tu proposes m'a l'air moins bien que ce que tu as.

Typiquement on demande à un truc de se dessiner dans une target, plutôt que de lui demander de retourner un truc graphique qu'on pourra dessiner. En d'autre terme, une classe doit fournir des services et non des données.
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re: Zone de texte
« Réponse #9 le: Avril 05, 2012, 01:35:12 pm »
En fait j'ai une paquage (Event) qui sert d'interface homme / application qui gère le clavier et l'affichage.

Et j'ai à côté une classe fenêtre (Fenetre) qui représente une fenêtre à l'intérieur de la fenêtre principale.

Donc Event va chercher la Fenetre cible de chaque évènement clavier/souris ou autre et lui transmettre cet évènement.

A la classe Fenetre de gérer le reste.

Ensuite, à chaque "rechargement" de la page, Event va demander le sf::RenderTexture de la Fenetre pour la blitter sur la fentre principale (sf::RenderWindow).

Ceci permet de ne pas à avoir à tout dessiner sur la sf::RenderWindow toutes les 1/60 sec alors qu'il suffit de dessiner sur la sf::RenderTexture à chaque modification (pour les zones de textes) et toute les 1/60 sec de dessiner la sf::RenderTexture sur la sf::RenderWindow ce qui fait gagner énormément de ressources.

Fenetre rend donc bel et bien un service : celui de gérer totalement une "fenetre"

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re: Zone de texte
« Réponse #10 le: Avril 05, 2012, 02:15:02 pm »
Déjà c'est bizarre qu'une classe nommée Event gère l'affichage :)

Ensuite ce serait plus logique que Fenetre se dessine toute seule lorsque "Event" lui demande. Comme ça les petits détails internes (passer par une RenderTexture, rafraîchir que lorsque c'est nécessaire, etc.) restent... internes.

Là tu as une approche hybride où Fenetre sait se dessiner, mais sur un truc intermédiaire qu'il faut lui-même encore dessiner ailleurs. Conceptuellement c'est pas bon :)
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re: Zone de texte
« Réponse #11 le: Avril 05, 2012, 06:23:15 pm »
Je ne pense pas car une fenêtre sait de quoi elle est composée et sait faire une image d'elle-même.

Mais elle n'a pas à connaitre de qui la contient.
C'est à son contenant de prendre l'image de cette fenêtre et de l'afficher.

Si la fenêtre peut se dessiner elle-même, c'est comme mettre la sf::RenderWindow en attribut public.
Elle sera totalement libre de dessiner là où elle ne devrait pas dessiner.

Koryushin

  • Jr. Member
  • **
  • Messages: 93
    • Voir le profil
Re: Zone de texte
« Réponse #12 le: Avril 05, 2012, 07:00:56 pm »
En fait je pense que ce que veut dire laurent c'est que ta classe fenêtre doit être autonome. C'est la toute la puissance de l'encapsulation. admettons le petit bout de code suivant comme exemple:
class Event
{
   //blabla
};
class fenetre
{
   //blabla
   public:
   void Draw(sf::RenderWindow& app);

   private:
   Event monEvent;
};

int main()
{
   //creation de la fenetre
   sf::RenderWindow window(...);

   sf::Event event;
   //boucle d'event
   while(...)
   {
      fenetre.Update(&event);
   }

   fenetre.Draw(&window);
}

En gros tu appelles la méthode draw() de ta classe fenêtre en lui passant en paramètre la renderwindow sur laquelle tu travailles. dans ta boucle d'évènement tu mets a jour les évènement de ta classe fenêtre.
Et la méthode draw() se débrouille pour dessiner la fenêtre en fonction des évènements associés.

De cette maniere quelle que soit la manière utilisée pour afficher ta fenêtre, c'est géré en interne et pour mettre a jour ton code c'est beaucoup plus facile.


« Modifié: Avril 05, 2012, 07:02:43 pm par Koryushin »

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re: Zone de texte
« Réponse #13 le: Avril 05, 2012, 08:24:18 pm »
Le principe de l'encapsulation est aussi de garantir une intégrité des données.

Si je donne accès à la sf::RenderWindow, je ne peux plus garantir son intégrité.

Pour les changements, cela se passe du côté de la classe Fenetre qui dessine dans une sf::RenderTexture.

Par ce que en fait ce qui change c'est juste ce petit bout de code :
Ma_renderWindow.Draw(Ma_Fenetre.getTexteture());
qui au lieu d'être dans Event se retrouvera (un peu modifié) dans Fenetre.

Mais quels que soit les modifications, ce bout de code sera inchangeable et elles se feront soit dans Fenetre

Koryushin

  • Jr. Member
  • **
  • Messages: 93
    • Voir le profil
Re: Zone de texte
« Réponse #14 le: Avril 05, 2012, 09:05:12 pm »
Le principe de l'encapsulation est aussi de garantir une intégrité des données.

Si je donne accès à la sf::RenderWindow, je ne peux plus garantir son intégrité.

Pour les changements, cela se passe du côté de la classe Fenetre qui dessine dans une sf::RenderTexture.


Je comprends, mais si tu la passes en reference constante le probleme de l'integrite n'est plus. Et de ce fait ca te permet de cacher le code de rendu dans fenetre.
void fenetre::Draw(const sf::RenderWindow &app) const
{}

De ce fait tout ce qui se trouve dans draw() ne pourra modifier ta reference.