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

Auteur Sujet: Dimension variable d'une texture  (Lu 3981 fois)

0 Membres et 1 Invité sur ce sujet

Phounet

  • Newbie
  • *
  • Messages: 21
    • Voir le profil
Dimension variable d'une texture
« le: Octobre 23, 2017, 07:59:28 pm »
Amis programmeurs,

Je sollicite votre aide pour le point suivant:

Comment gérer efficacement les textures d'une entité dont la taille n'est pas connue à l'avance?

Je m'explique: je souhaite créer une barre de défilement (i.e. Scrollbar) similaire à toutes celles que nous rencontrons habituellement. La taille de cette Scrollbar dépend de la longueur du contenu à afficher. Dès lors, comment puis-je efficacement gérer son apparence à l'écran?

Imaginons qu'au niveau de la texture, j'ai 3 tuiles:

|->

Si je dois créer une barre de dimension égale à 5, je vais avoir ceci:

|--->

On constate donc que j'ai tjs la tuile de "début" (i.e. | ) et la tuile de "fin" (i.e. > ). En fonction de la longueur, je rajoute le nombre de tuiles intermédiaires requis (i.e. - ).

Actuellement, dans mon code, ça fonctionne comme suit:

Je charge la tilesheet qui contient les 3 tuiles.
Je crée 3 sf::RectangleShape (i.e. un pour le début, un pour la fin, et un pour la partie intermédiaire variable). J'applique une tuile par RectangleShape, en m'assurant que ma texture peut se répéter pour la tuile du milieu. Ainsi, la tuile intermédiaire qui mesure 1 se répètera 3 fois dans un RectangleShape de taille 3.

Cela fonctionne, mais ça me semble affreusement lourd, voire tirer par les cheveux. Je voudrais donc savoir si l'un de vous à un meilleur moyen de gérer cela?

PS: Je ne souhaite pas utiliser la méthode "setScale" car si je ne dis pas de bêtise, cela va "étirer" ma texture de base et je risque donc de perdre en qualité de rendu (i.e. les pixels seront plus grossiers).

PS 2: Voici le code, au cas ce serait utile (ne prêtez pas attention aux constantes de taille et de positionnement, elles sont juste là temporairement)


    /* Texture */

    sf::IntRect topText(0, 0, 17, 4);
    sf::IntRect midText(0, 4, 17, 4);
    sf::IntRect lowText(0, 8, 17, 6);

    sf::Texture texture;
    if(!texture.loadFromFile("ScrollbarTexture.png"))
    {
        std::cout << "Erreur de chargement de l'image" << std::endl;
    }

    sf::FloatRect barSize(0.f, 0.f, 17.f, 100.f);
    sf::IntRect textureRect(barSize);
    texture.setRepeated(true);

    /* Sprite de Scrollbar */

    sf::Sprite barSprite;
    barSprite.setPosition(30.f, 30.f);

    /* RenderTexture */

    sf::RenderTexture renderTexture;
    renderTexture.create(barSize.width, barSize.height);

        renderTexture.clear(sf::Color(0, 0, 0, 0));

    sf::RectangleShape topRect;
    topRect.setSize(sf::Vector2f(barSize.width, 4.f));
    topRect.setTexture(&texture);
    topRect.setTextureRect(topText);

    sf::RectangleShape lowRect;
    lowRect.setSize(sf::Vector2f(barSize.width, 6.f));
    lowRect.setTexture(&texture);
    lowRect.setTextureRect(lowText);
    lowRect.setPosition(topRect.getPosition().x, topRect.getPosition().y + 91.f);

    sf::RectangleShape midRect;
    midRect.setSize(sf::Vector2f(barSize.width, barSize.height - topRect.getGlobalBounds().height - lowRect.getGlobalBounds().height));
    midRect.setTexture(&texture);
    midRect.setTextureRect(midText);
    midRect.setPosition(topRect.getPosition().x, topRect.getPosition().y + topRect.getGlobalBounds().height);

    renderTexture.draw(topRect);
    renderTexture.draw(midRect);
    renderTexture.draw(lowRect);

        renderTexture.display();

        /* Application de la RenderTexture au Sprite de Scrollbar */

        barSprite.setTexture(renderTexture.getTexture());
        barSprite.setTextureRect(textureRect);
« Modifié: Octobre 23, 2017, 08:02:41 pm par Phounet »

Phounet

  • Newbie
  • *
  • Messages: 21
    • Voir le profil
Re: Dimension variable d'une texture
« Réponse #1 le: Octobre 26, 2017, 09:11:13 pm »
Personne n'aurait une petite idée svp?

Et si je suis complètement à côté de la plaque, n'hésitez pas à me le dire non plus.

Merci ;)

Guit0x

  • Newbie
  • *
  • Messages: 35
    • Voir le profil
Re: Dimension variable d'une texture
« Réponse #2 le: Octobre 27, 2017, 04:56:44 pm »
Bien le Bonjour,

Donc si je comprends bien, ton but est d'adapter la longueur de la scrollbar selon une dimension Y.

Plutôt qu'un long discours, voici un exemple en utilisant un sf::Sprite et sa méthode scale() :

  //On initialise la texture
  sf::Texture scrollbase;
  scrollbase.loadFromFile("img/scrollbar.png"); //scrollbar.png est un simple carré de 25*25

  //On met ça dans un sprite
  sf::Sprite scrollbar(scrollbase);

  //On fait grandir la dimension Y de scrollbar. X ne change pas car son facteur est de 1
  float facteurY(2);
  scrollbar.setScale(1, facteurY); //Le sprite fait maintenant 25*50

  //...

  window.draw(scrollbar)

Reste plus qu'à établir la relation qui viendra modifier le facteur Y automatiquement.
« Modifié: Octobre 27, 2017, 07:50:36 pm par Guit0x »

Phounet

  • Newbie
  • *
  • Messages: 21
    • Voir le profil
Re: Dimension variable d'une texture
« Réponse #3 le: Octobre 27, 2017, 08:56:34 pm »
Je te remercie pour ta réponse !

J'ai toutefois une question par rapport au code que tu proposes:

Le fait d'utiliser la méthode "setScale" ne va-t-il pas entraîner l'étirement de la texture d'origine, et donc réduire la qualité de rendu à l'écran?

Très bonne soirée à toi,

Phounet
« Modifié: Octobre 28, 2017, 01:09:48 am par Phounet »

Guit0x

  • Newbie
  • *
  • Messages: 35
    • Voir le profil
Re: Dimension variable d'une texture
« Réponse #4 le: Octobre 28, 2017, 03:46:11 am »
Le fait d'utiliser la méthode "setScale" ne va-t-il pas entraîner l'étirement de la texture d'origine, et donc réduire la qualité de rendu à l'écran?

Alors oui tu n'as pas tord sur ce point. Mais selon comment la texture se présente, l'étirement peu se voir ou non.

Par exemple, si t'as scrollbar  contient un dégradé vertical (donc de gauche à droite ou inversement), et bien le dégradé ne sera pas perdu si il y a agrandissement sur l'axe Y car tu "étires" des pixels qui ne changent pas de couleur sur l'axe X. On peut voir ça comme une sorte de répétion. Et la texture peut même faire 1px de haut, donc avec un facteur de 100 par exemple, le sprite fera 100px de haut (ça peut faciliter les calculs).

C'est peu "tricky" je te l'accorde, je vais essayer d'illustrer ça :

/*

 clair-----------foncé
 [B][B][B][B][B][B][B] |
 [B]...............[B] |
 [B]...............[B] | On étire
 [B]...............[B] |
 [B]...............[B] |
 [B]...............[B] V

*/

Les pixels de gauche à droite vont du bleu clair au bleu foncé, donc le dégradé est conservé si on étire le Sprite vers le bas.

Après comme dit plus haut, tout dépend de ta texture :).
« Modifié: Octobre 28, 2017, 03:48:42 am par Guit0x »

Phounet

  • Newbie
  • *
  • Messages: 21
    • Voir le profil
Re: Dimension variable d'une texture
« Réponse #5 le: Octobre 29, 2017, 11:02:35 am »
Je comprends ce que tu veux dire et te remercie encore pour ta réponse.

Si c'est la manière de faire alors je vais procéder ainsi.

Bon dimanche à tous,

Phounet

Guit0x

  • Newbie
  • *
  • Messages: 35
    • Voir le profil
Re: Dimension variable d'une texture
« Réponse #6 le: Octobre 29, 2017, 06:36:58 pm »
Si c'est la manière de faire alors je vais procéder ainsi.

Non ce n'est pas LA manière de faire, c'est UNE façon de faire. Il en existe d'autres c'est sûr :).

Phounet

  • Newbie
  • *
  • Messages: 21
    • Voir le profil
Re: Dimension variable d'une texture
« Réponse #7 le: Octobre 30, 2017, 07:51:43 pm »
En effet, il doit en exister d'autres, car après avoir utilisé "setScale", j'ai constaté que la qualité du rendu n'était pas acceptable. Je préfère donc utiliser la méthode que j'ai décrite plus haut, même si elle demande un peu plus de lignes de code.

Si quelqu'un a une idée de code qui pourrait fonctionner, je suis tout ouïe.

Bien à vous,

Phounet
« Modifié: Décembre 10, 2017, 10:02:34 pm par Phounet »

Guit0x

  • Newbie
  • *
  • Messages: 35
    • Voir le profil
Re: Dimension variable d'une texture
« Réponse #8 le: Octobre 30, 2017, 09:14:30 pm »
Ta texture ressemble à quoi ? Tout va partir de là.

Edit: J'imagine que c'est un rectangle qui doit se répéter si tu ne veux pas perdre la qualité de base de ta texture ?

Edit2: Autant pour moi, j'ai relu ton premier message et tu y expliques ce que tu veux faire :). Je vais tester ça de mon côté.
« Modifié: Octobre 30, 2017, 09:46:56 pm par Guit0x »

Guit0x

  • Newbie
  • *
  • Messages: 35
    • Voir le profil
Re: Dimension variable d'une texture
« Réponse #9 le: Octobre 31, 2017, 12:55:05 am »
Bon j'ai regardé un peu et rien de compliqué ni de lourd. Je vais t'expliquer comment j'ai procédé, après libre à toi de t'en inspirer  :).

(Note: je ne me suis pas cassé la tête avec les vérifications etc... c'est juste un exemple, et je me suis servi d'une classe Scrollbar pour stocker les textures, les sprites et manipuler le tout. Je vais t'éviter le superflue et te montrer l'essentiel)

D'abord j'ai choisi d'utiliser 3 textures séparées (je trouvais ça plus clair et pratique) :

//Les 3 .png font tous 25*25
m_textureTop.loadFromFile("img/scroll_top.png");
m_textureMiddle.loadFromFile("img/scroll_middle.png");
m_textureMiddle.setRepeated(true); //Sans oublier d'activer le 'repeated' sur la texture centrale
m_textureBottom.loadFromFile("img/scroll_bottom.png");

Ensuite 3 sprites contenant les textures que j'ai placé dans un vector de pointeur "sauvage" (par habitude) :

m_vSprite.push_back(new sf::Sprite(m_textureTop));
m_vSprite.push_back(new sf::Sprite(m_textureMiddle));
m_vSprite.push_back(new sf::Sprite(m_textureBottom));

Pour finir, ne reste plus qu'à faire varier la hauteur pour la barre du milieu. Pour ça il suffit d'augmenter le Rectangle de la Texture du Sprite contenant la texture du milieu :

void setHauteur(int hauteur)
{
    //Valeurs arbitraires dans le lot

    //Top
    m_vSprite[0]->setPosition(m_x, 0);

    //Middle
    m_vSprite[1]->setPosition(m_x, 25);
    //On augmente la hauteur du Rectangle contenant la Texture
    //La texture se répetera autant de fois qu'il le faut pour combler l'espace du rectangle
    m_vSprite[1]->setTextureRect(sf::IntRect(0, 0, 25, hauteur+25));

    //Bottom
    //Ici c'est un test pour savoir si le bottom doit être attaché ou non au middle (juste pour moi pour tester)
    float bottomY(0);
    m_attachBottom ? bottomY = (m_vSprite[1]->getPosition().y + hauteur) + 25 : bottomY = 470;
    m_vSprite[2]->setPosition(m_x, bottomY);
}

Voilà pour le principal, j'espère avoir éclairé ta lanterne.

« Modifié: Octobre 31, 2017, 02:03:10 pm par Guit0x »

Phounet

  • Newbie
  • *
  • Messages: 21
    • Voir le profil
Re: Dimension variable d'une texture
« Réponse #10 le: Novembre 03, 2017, 11:59:33 pm »
Merci pour ton aide. Cela m'a été utile ;)

Bonne soirée à toi,

Phounet