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

Auteur Sujet: Système de gestion de résolutions  (Lu 6482 fois)

0 Membres et 1 Invité sur ce sujet

flow10000

  • Newbie
  • *
  • Messages: 29
    • Voir le profil
    • Project Abyss
Système de gestion de résolutions
« le: Octobre 23, 2012, 08:41:20 pm »
Bonjour,
Tout d'abord j'espère exposer mon problème dans la bonne catégorie.

Voilà, j'aimerais pouvoir gérer toutes les résolutions possibles dans mon jeu, et selon ces critères :

- la proportion doit toujours être la même (ici 16:9)
- cela inclut donc de dessiner des bandes noires en haut et en bas de l'image si l'écran du PC n'est pas 16:9
- quelle que soit la résolution, l'image finale devra être toujours strictement la même et donc redimensionnée

J'ai pensé au système suivant mais il me semble quand même lourd.

Mes sprites sont destinés à des écrans 1920/1080
Si la résolution courante en est une autre, tous mes sprites seront redimensionnés et positionnés selon un ratio calculé à partir de la "différence" entre ma résolution 1920/1080 et la résolution courante.
De plus, si le format de l'écran n'est pas 16:9 il faut que je décale tous mes sprites vers le bas...
C'est quand même un sacré bordel tout ça :S


Ma question est donc la suivante : Avant de me lancer dans cette usine à gaz, existe-t'il un moyen plus simple de procéder ?

Merci à vous


Bonne soirée.


EDIT : J'espère avoir été clair, n'hésitez pas à me poser des questions si vous n'avez pas tout saisi.



« Modifié: Octobre 23, 2012, 08:46:00 pm par flow10000 »

mccusti

  • Invité
Re : Système de gestion de résolutions
« Réponse #1 le: Octobre 24, 2012, 02:44:26 pm »
Salut, je te conseillerais d'aller jeter un oeil sur les sf::View, ce qui éviterait de tout recalculer à la main.

flow10000

  • Newbie
  • *
  • Messages: 29
    • Voir le profil
    • Project Abyss
Re : Système de gestion de résolutions
« Réponse #2 le: Octobre 28, 2012, 10:55:16 am »
Bonjour,

J'ai essayé d'utiliser sf::view pour résoudre ce problème mais je ne dois pas les utiliser comme il faut.
Voilà mon code qui doit permettre de répondre aux problématiques que j'ai exposé plus haut :

// Récupération de la résolution de l'écran du client et on crée la fenêtre en conséquence
sf::VideoMode clientVideoMode = sf::VideoMode::getDesktopMode();

// si le format d'écran n'est pas 16:9 on doit rajouter les bandes noires
if(clientVideoMode.width / clientVideoMode.height != 16/9)
{
        // calcul de la taille de la bande noire du dessus
        float decalY = (clientVideoMode.height - (clientVideoMode.width * 9 / 16)) / 2;
        this->mainView = sf::View(sf::FloatRect(0, 0, 1920, 1080));
        // On décale la vue vers le bas
        this->mainView.move(sf::Vector2f(0, decalY));
}
else
{
        this->mainView = sf::View(sf::FloatRect(0, 0, 1920, 1080));
}

// Pour finir on crée la fenêtre et on set la vue.
globals.window.create(clientVideoMode, "Abysses v0.1", sf::Style::Fullscreen);
globals.window.setView(this->mainView);
 


Voilà le code, le problème est que ça ne fonctionne pas du tout...
Quand l'écran est en 16:9 pas de soucis, mais si on tape dans le 16:10 ou le 4:3, pas de bandes noir, l'image prend tout l'écran quand même.

G.

  • Hero Member
  • *****
  • Messages: 1592
    • Voir le profil
Re : Système de gestion de résolutions
« Réponse #3 le: Octobre 28, 2012, 01:18:22 pm »
Par défaut une vue prend toute la fenêtre. Définis un viewport pour ta sf::View.
« Modifié: Octobre 28, 2012, 01:20:14 pm par G. »

flow10000

  • Newbie
  • *
  • Messages: 29
    • Voir le profil
    • Project Abyss
Re : Système de gestion de résolutions
« Réponse #4 le: Octobre 28, 2012, 01:28:46 pm »
hmmm et quand je fais sf::View(sf::FloatRect(0, 0, 1920, 1080));
ça ne définie pas de ViewPort ?

G.

  • Hero Member
  • *****
  • Messages: 1592
    • Voir le profil
Re : Système de gestion de résolutions
« Réponse #5 le: Octobre 28, 2012, 01:41:45 pm »
Ben non, comme le dit la doc ce rectangle définit la zone à afficher.
Le viewport définit l'endroit de ta fenêtre où tu vas afficher le contenu de ta vue.

Tu peux aussi jeter un oeil à ce tutorial sur les vues qui aborde rapidement les viewports pour faire un écran splitté ou une minimap.
Je pense que tu devrais trouver comment arriver à ce que tu veux une fois que t'auras joué un peu avec le viewport en en définissant un différent de 0, 0, 1, 1
« Modifié: Octobre 28, 2012, 01:43:36 pm par G. »

kimci86

  • Full Member
  • ***
  • Messages: 124
    • Voir le profil
Re : Système de gestion de résolutions
« Réponse #6 le: Octobre 28, 2012, 05:38:52 pm »
Attention à ce test:
Citer
// si le format d'écran n'est pas 16:9 on doit rajouter les bandes noires
if(clientVideoMode.width / clientVideoMode.height != 16/9)

Tu fais des opérations sur des entiers.
Ainsi, avec un VideoMode en 16/9, en 10/9 ou 4/3,  ça correspond à ceci:
if(1 != 1)
ce qui sera toujours évalué comme étant false.

Tu peux résoudre le problème en remplaçant les quotients par des produits comme ceci:
if(9 * clientVideoMode.width != 16 * clientVideoMode.height)

Pour ce qui est de créer la vue, voilà comment je ferais avec un viewport:
// Récupération de la résolution de l'écran du client et on crée la fenêtre en conséquence
sf::VideoMode clientVideoMode = sf::VideoMode::getDesktopMode();

// ceci est à faire de toute façon, donc je le mets hors du if
this->mainView = sf::View(sf::FloatRect(0, 0, 1920, 1080));

// si le format d'écran n'est pas 16:9 on doit rajouter les bandes noires
if(9 * clientVideoMode.width != 16 * clientVideoMode.height)
{
    // calcul de la taille de la bande noire du dessus
    float decalY = (clientVideoMode.height - (clientVideoMode.width * 9 / 16)) / 2;
    // on l'exprime par rapport à la hauteur totale
    float rapport = decalY / clientVideoMode.height;
    // On applique le viewport
    this->mainView.setViewport(sf::FloatRect(0.f, rapport, 1.f, 1.f-rapport*2));
}

// Pour finir on crée la fenêtre et on set la vue.
globals.window.create(clientVideoMode, "Abysses v0.1", sf::Style::Fullscreen);
globals.window.setView(this->mainView);

flow10000

  • Newbie
  • *
  • Messages: 29
    • Voir le profil
    • Project Abyss
Re : Système de gestion de résolutions
« Réponse #7 le: Octobre 28, 2012, 08:00:36 pm »
Holàlà oui effectivement...
Le test foirait à chaque fois, je pouvais attendre longtemps pour que ça marche...

Merci à vous deux en tout cas :)


gyscos

  • Jr. Member
  • **
  • Messages: 69
    • Voir le profil
Re : Système de gestion de résolutions
« Réponse #8 le: Novembre 14, 2012, 05:21:16 pm »
Plutôt que de faire un test d'égalité avec 16/9, fais plutôt une comparaison : la fenêtre pourrait être encore plus longue que 16/9 ; du coup, il ne faut pas des barres noires en haut et en bas mais à droite et à gauche.

Ça peut arriver si l'utilisateur rétrécit verticalement la fenêtre (ou simplement si la barre de titre prend plus d'espace vertical que les bordures latérales), ou s'il utilise un des (encore rares) écrans super-larges, comme le toshiba U845W.

flow10000

  • Newbie
  • *
  • Messages: 29
    • Voir le profil
    • Project Abyss
Re : Système de gestion de résolutions
« Réponse #9 le: Novembre 14, 2012, 06:10:08 pm »
Ha oui exact. Merci, je n'avais pas pensé à ces cas là ^^

Basta

  • Newbie
  • *
  • Messages: 48
    • Voir le profil
    • E-mail
Re : Système de gestion de résolutions
« Réponse #10 le: Novembre 15, 2012, 12:58:21 pm »
bonjour, je me suis inspiré de cette discussion pour faire ma propre gestion, seulement ça n'as pas l'air de marcher  :-\.
Cela viens peut-être de ma compréhension douteuse de sf::View ou alors d'une faute banale que je ne décèle pas.

#include<SFML/Graphics.hpp>

int main()
{
    sf::VideoMode videoMode = sf::VideoMode(500,500);//sf::VideoMode::getDesktopMode();
    float ratio = 16/10;

    sf::View view(sf::FloatRect(0, 0, 1600, 1000));

    if( float(videoMode.width/videoMode.height) > ratio )
    {
        // marges verticales
        float padX( ( videoMode.width - (videoMode.height*ratio) )/2 );
        float relative( padX/videoMode.width );
        view.setViewport(sf::FloatRect(relative, 0.f, 1.f-relative*2, 1.f));
    }
    else if( float(videoMode.width/videoMode.height) < ratio )
    {
        // marges horizontales
        float padY( ( videoMode.height - (videoMode.width/ratio) )/2 );
        float relative( padY/videoMode.height );
        view.setViewport(sf::FloatRect(0.f, relative, 1.f, 1.f-relative*2));
    }

    sf::RenderWindow win(videoMode, "SANDBOX", sf::Style::Titlebar);
    win.setView(view);

    while(win.isOpen())
    {
        sf::Event event;
        while(win.pollEvent(event))
        {
            switch(event.type)
            {
            case sf::Event::Closed:
                win.close();
                break;

            default:
                break;
            }
        }

        sf::RectangleShape rectangle(sf::Vector2f(500,500));
        rectangle.setFillColor(sf::Color::Green);
        rectangle.setPosition(100, 50);

        win.clear(sf::Color::White);
        win.draw(rectangle);
        win.display();
    }
}
 

Je suis censé voir un carré et je vois un rectangle.
« Modifié: Novembre 15, 2012, 01:01:36 pm par Basta »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Système de gestion de résolutions
« Réponse #11 le: Novembre 15, 2012, 01:15:06 pm »
Citer
float(videoMode.width/videoMode.height)
Ca te donnera toujours un entier. Fais plutôt ça
float(videoMode.width) / videoMode.height
Laurent Gomila - SFML developer

gyscos

  • Jr. Member
  • **
  • Messages: 69
    • Voir le profil
Re : Système de gestion de résolutions
« Réponse #12 le: Novembre 15, 2012, 03:44:49 pm »
pareil pour le 16/10 au début ;)
Fais plutôt :
16/10.0f

Basta

  • Newbie
  • *
  • Messages: 48
    • Voir le profil
    • E-mail
Re : Système de gestion de résolutions
« Réponse #13 le: Novembre 15, 2012, 04:14:48 pm »
Ah les floats  je tombe toujours dans le piège :o

PS : ça marche à merveille, <3 sf::View.
« Modifié: Novembre 15, 2012, 04:16:23 pm par Basta »