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

Auteur Sujet: [Résolu] Dessinner un objet à une taille constante  (Lu 3429 fois)

0 Membres et 1 Invité sur ce sujet

brunnerant

  • Newbie
  • *
  • Messages: 18
    • Voir le profil
    • E-mail
[Résolu] Dessinner un objet à une taille constante
« le: Septembre 30, 2016, 04:09:06 pm »
Comment peut-on dessiner un objet qui ne grossit pas quand on zoome ?

J'ai récemment créé une classe qui permet de dessiner une flèche à l'écran qui peut alors représenter un vecteur (vecteur vitesse ou accélération dans mon cas). Cette flèche est constituée de deux parties : son "corps" ( ----- ), et sa "tête" ( > ).

Lorsque je suis à un niveau de zoom normal, tout va bien et la tête de la flèche est de la bonne taille. Mais dès que je zoom dessus en utilisant sf::View par exemple, la tête de la flèche grossit, ce qui est parfaitement normal. Mais ce n'est pas ce que je veux. Ce que je veux, c'est que la tête de la flèche soit toujours de la même taille, peut importe le zoom. Car quand je zoom 10X la tète de la flèche devient énorme, ce qui est assez gênant à l'écran :-\ .

Voici le code qui permet la flèche d'être rendue à l'écran :
void Arrow::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    sf::Transform transform;
    transform.translate(mPos.x, mPos.y).rotate(mAngle).translate(-mArrow[0].position.x, 0);
    states.transform *= transform;

    target.draw(&mArrow[0], 6, sf::Lines, states);
}

Dans cette fonction je dessine pour l'instant toute la flèche d'un coup (stockée dans un tableau de sf::Vertex). Ce que je voudrais donc à terme, c'est dessiner le corps et la tête de la flèche séparément à une différente échelle. Et pour cela, il faudrait pouvoir faire quelque chose comme "states.transform.scale". J'ai beaucoup recherché, et ce n'est malheureusement pas possible, alors dites-moi comment résoudre ce problème.

Merci d'avance de vos réponses !
« Modifié: Octobre 16, 2016, 03:17:34 pm par brunnerant »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Dessinner un objet à une échelle constante
« Réponse #1 le: Septembre 30, 2016, 04:23:19 pm »
C'est bien  ;D
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Dessinner un objet à une taille constante
« Réponse #2 le: Octobre 16, 2016, 08:53:26 am »
En ce qui me concerne, la dernière fois que j'ai consulté ton post, il ne comportait que le texte suivant :

Citer
J'ai récemment créé une classe qui permet de dessiner une flèche à l'écran qui peut alors représenter un vecteur

... ce qui explique ma réponse d'ailleurs. Et si j'en juge par les infos donnés par le forum, tu n'as ajouté la suite qu'hier. Donc ta remarque est assez mal venue, si tel est le cas. Et si tu veux de la fréquentation, c'est clair qu'il faut aller côté anglophone, ici c'est un peu mort ;)

Tu as deux solutoins :
- utilise un scale inverse du niveau de zoom
- utilise une autre sf::View qui ne change jamais
« Modifié: Octobre 16, 2016, 08:56:50 am par Laurent »
Laurent Gomila - SFML developer

brunnerant

  • Newbie
  • *
  • Messages: 18
    • Voir le profil
    • E-mail
Re : Dessinner un objet à une taille constante
« Réponse #3 le: Octobre 16, 2016, 11:11:42 am »
C'est bizarre, parce que j'ai ajouté la suite une heure ou deux après le début. Peu importe, merci de ta réponse !

Merci de me faire penser aux vues. En fait je pensait qu'une vue passait simplement un sf::Transform au objets pour les dessiner, mais en fait, c'est différent et c'est pour cela que ça ne marche pas, car je ne prend en compte que le sf::Transform passé en paramètre à la fonction draw

Comment récupérer le niveau de zoom d'une vue ?
« Modifié: Octobre 16, 2016, 12:10:57 pm par brunnerant »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Dessinner un objet à une taille constante
« Réponse #4 le: Octobre 16, 2016, 01:17:40 pm »
Citer
C'est bizarre, parce que j'ai ajouté la suite une heure ou deux après le début. Peu importe, merci de ta réponse !
Bizarre, normalement les posts édités repassent en "non-lu", le tien n'y est pas repassé depuis que j'y ai répondu. Et la date d'édition est au 15 octobre. Bref, s'il n'est pas remonté après que tu l'aies édité, ça peut expliquer pourquoi tu n'as pas eu beaucoup de réponses ;)

Citer
En fait je pensait qu'une vue passait simplement un sf::Transform au objets pour les dessiner
C'est le cas. Mais c'est une transformation interne, en plus de celle qui se trouve dans sf::RenderStates et dans sf::Transformable, et à laquelle tu n'as pas accès directement.

Citer
Comment récupérer le niveau de zoom d'une vue ?
A priori c'est toi qui l'a spécifié non ? Et si tu as plutôt donné une taille, alors il suffit de faire taille_actuelle / taille_initiale pour retrouver le facteur d'échelle.
Laurent Gomila - SFML developer

brunnerant

  • Newbie
  • *
  • Messages: 18
    • Voir le profil
    • E-mail
Re : Dessinner un objet à une taille constante
« Réponse #5 le: Octobre 16, 2016, 03:17:04 pm »
Ce que tu me propose marcherait très bien je te remercie, mais je suis un peu maniaque  ;).
Ce que je veux, c'est que tout soit automatisé et intelligent, et qu'un seul appel à la fonction sf::Draw s'occupe de tout. Ainsi, l'utilisateur est loin de tout ça et peut se soucier d'autres choses.
Au passage, merci de m'avoir clarifié le fonctionnement des vues, je n'était pas au clair sur ce point, et cela m'a permit de résoudre le problème.

La fonction sf::Draw est peut-être un peu "time-consuming", mais je ne dessine pas 10'000 flèches à chaque rafraîchissement d'écran donc ça devrait tenir le coup :

void Arrow::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    //Transformation interne à la classe
    sf::Transform internalTransform;
    internalTransform.translate(mPos.x, mPos.y).rotate(mAngle).translate(-mArrow[0].position.x, 0);

    //On combine la transformation interne à la transformation passée en paramètre
    sf::Transform fullTransform = states.transform * internalTransform;

    //On dessine le corps de la flèche
    target.draw(&mArrow[0], 2, sf::Lines, fullTransform);

    //Vecteurs représantant le corps de la flèche avant transformation et après
    sf::Vector2f defaultBody = internalTransform.transformPoint(mArrow[1].position) -
                               internalTransform.transformPoint(mArrow[0].position);

    sf::Vector2f transformedBody = fullTransform.transformPoint(mArrow[1].position) -
                                   fullTransform.transformPoint(mArrow[0].position);

    //Facteur de mise à l'échelle de la fenêtre
    sf::Vector2f viewFactor = target.getView().getSize();
    viewFactor.x /= target.getView().getViewport().width * target.getSize().x;
    viewFactor.y /= target.getView().getViewport().height * target.getSize().y;

    //On peut finalement annuler la mise à l'échelle grâce à ces deux facteurs
    fullTransform.scale(defaultBody.x/transformedBody.x * viewFactor.x,
                        defaultBody.y/transformedBody.y * viewFactor.y);

    //Et dessiner la tête de la flèche à l'écran - qui aura donc une taille constante
    target.draw(&mArrow[2], 4, sf::Lines, fullTransform);
}

Merci de ton aide, la prochaine fois j'essaierai de ne pas m'emmêler avec mon post ;D

janf

  • Newbie
  • *
  • Messages: 45
    • Voir le profil
Re : [Résolu] Dessinner un objet à une taille constante
« Réponse #6 le: Novembre 09, 2016, 02:50:48 am »
Je pense que tu pourrais de manière beaucoup plus simple créer une view, que tu appliques à la fenêtre et tu affiches tout ce que tu as à afficher, sauf ta flèche. Le niveau de zoom est appliqué à cette view.
Ensuite tu appliques à la fenêtre à nouveau sa view par défaut et tu y dessines ta flèche, qui aura donc une taille constante non affectée par le zoom de l'autre view. Tu fais cela à chaque tour de boucle, c'est une façon performante de procéder.
Ou alors j'ai rien compris à ton problème.

brunnerant

  • Newbie
  • *
  • Messages: 18
    • Voir le profil
    • E-mail
Re : [Résolu] Dessinner un objet à une taille constante
« Réponse #7 le: Novembre 09, 2016, 09:35:46 pm »
En fait, il faut que la position de la flèche soit affectée par le niveau de zoom, mais que sa taille non, ce qui complique beaucoup les choses. Je pense donc que la méthode que tu m'as proposé ne fonctionnerait pas :(. Je pourrais tester, mais étant donné que j'ai quelque chose qui fonctionne, inutile d'aller plus loin, surtout que cela n'a pas trop besoin d'optimisations et que je dessine qu'une dizaine de flèches à la fois à l'écran.
Mais merci de ton aide, j'apprécie quand des gens s'intéressent à ce que j'ai fait :D !

 

anything