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

Auteur Sujet: Définir un ordre d'affichage par vertex.  (Lu 13578 fois)

0 Membres et 1 Invité sur ce sujet

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #45 le: Juillet 20, 2013, 10:09:04 pm »
Ouiais c'était ça, j'avais oublié que j'avais de la semi-transparence pour les tiles au sol.
Bref, c'est pas grâve, j'ai retiré le z pour les tiles au sol, je n'en ai de toute façon pas besoin, là je peux m'arranger facilement pour avoir un type de tile pour le sol par tileset et les ordres d'affichage ne changent pas pour le sol. (L'herbe s'affiche toujours au dessus de la pière pour bien faire la transition entre les tiles.)

Par contre pour toutes les autres tiles (bâtiments, murs, personnage, arbres, etc...), j'ai besoin du depthtest absolument si j'utilise des tilemaps car le personnage peut être devant ou derrière les murs, bâtiments, etc..., les murs peuvent eux aussi être devant ou derrière les bâtiments, etc...)
Mais bon ça ne me pose pas de problème car il n'y a que les tiles du sol qui contiennent de la semi-tranparence. (Dont les bords qui ont des pixels avec une valeur de alpha très petites du coups bah ça se mélangeais avec la couleur de fond et non pas avec la tile du dessous.)

Bref j'ai trouvé la solution en retirant le z pour les couches du sol donc mon problème est résolu et ça tourne plus vite, il faudra juste que je ne fasse pas de semi-transparence pour les autres tiles que celles au sol.
Sinon je suis reparti pour faire de l'affichage sprite par sprite. (Sauf peut être si j'utilise une render texture..., mais je ne sais pas exactement comment ça marche ça, mais il me semble que ça fait aussi appel à plusieurs draw pour dessiner tout sur la rendertexture donc..., je n'y gagnerai pas au niveau des perfs.)


Performances qui ont besoin d'être très bonne surtout dans mon cas.
« Modifié: Juillet 20, 2013, 10:16:57 pm par Lolilolight »

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #46 le: Juillet 22, 2013, 11:31:10 am »
Bon finalement j'en suis revenu à un système de draw sprite par sprite pour les raisons suivantes :

-Le framerate n'augmente pas. (Même si je fais qu'un seul appel à draw plutôt que plusieurs.)
-Les tiles ne s'affichent pas toujours dans l'ordre dans lequel elles devraient (erreur dans mon algorithme qui modifier le z de mes entités surement.), donc, je préfère les insérer au bonne endroit dans mon std::vector. (C'est plus simple.)
Mais bon je laisse quand même ma version personalisée de la SFML, ça pourra être utile dans certains cas.

Voici mon algorithme qui modifie le z de mes tiles, je l'ai mis en commentaire car il ne fonctionne pas mais quand j'insère simpelement les tiles au bonne endroit dans le vecteur et que je les dessines dans l'ordre sans passer par une tile map, pas de soucis.

void MyCanvas::addDynamicTile (Tile *tile, vector<Tile*> &visibleTiles) {
     //On insère la tile au bonne endroit dans le vecteur.
     vector<Tile*> oldVector = visibleTiles;
     vector<Tile*> behind, before;
     visibleTiles.clear();
     //On va rechercher toutes les tiles qui sont devant et derrière la tile.
     for (int i = 0; i < oldVector.size(); i++) {
         if (oldVector[i]->getZOrder() < Tile::MIN_ENTITY_Z_ORDER) {
            visibleTiles.push_back(oldVector[i]);
         } else {
             Vec2f centerDT = tile->getCenter();

             if (visibleTiles[i]->getType() == Entity::E_WALL) {

                 vector<Segment*> segments = lm->getTileSegWall(visibleTiles[i]);
                 int dist = segments[0]->getOrig().computeDist(centerDT);
                 Segment &seg = *segments[0];
                 for (unsigned int j = 1; j < segments.size(); j++) {
                     int tmpDist = segments[j]->getOrig().computeDist(centerDT);
                     if (tmpDist < dist) {
                         dist = tmpDist;
                         seg = *segments[j];
                     }
                 }

                 Segment seg2 (seg.getOrig(), centerDT);
                 int det = seg.getDir().x * seg2.getDir().y - seg.getDir().y * seg2.getDir().x;
                 (det >= 0) ? behind.push_back(oldVector[i]) : before.push_back(oldVector[i]);
             } else {
                 Vec2f center = oldVector[i]->getCenter();
                 Vec2f size = oldVector[i]->getSize();
                 Vec2f orig (center.x - size.x * 0.5f, center.y);
                 Vec2f ext (orig.x + size.x * 0.5f, center.y);
                 Segment seg (orig, ext);
                 Segment seg2 (orig, centerDT);
                 int det = seg.getDir().x * seg2.getDir().y - seg.getDir().y * seg2.getDir().x;
                 (det >= 0) ? behind.push_back(oldVector[i]) : before.push_back(oldVector[i]);
             }
         }
     }
     /*On ajoute toutes les tiles qui sont derrière, puis on ajoute la tile à insérer
      et enfin on ajoute toutes les tiles qui sont devant.*/

    for (unsigned int i = 0; i < behind.size(); i++) {
        visibleTiles.push_back(behind[i]);
    }

    //(behind.size() > 0) ? tile->setZOrder(behind[behind.size() - 1]->getZOrder() + 1) : tile->setZOrder(Tile::MIN_ENTITY_Z_ORDER);

    visibleTiles.push_back(tile);
    for (unsigned int i = 0; i < before.size(); i++) {
        /*if (!before[i]->isZOrderSaved())
            before[i]->saveZOrder();
        before[i]->setZOrder(tile->getZOrder() + 1);*/

        visibleTiles.push_back(before[i]);
    }
}
 

Au cas ou quelqu'un trouverait l'erreur.
« Modifié: Juillet 22, 2013, 11:33:26 am par Lolilolight »

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #47 le: Juillet 28, 2013, 12:36:12 pm »
Bon j'ai fais comme ça, par défaut si on ne le spécifie pas, le z du vertex vaut -1 et on désactive l'alpha testing et le depthtest, sinon, si le z est entre 0 et 1, on active l'alpha testing et le depthtest, et ça marche. :)

Je peux donc choisir ce que je veux faire, personnellement je trouve ça plus cool. ^^