IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Projets Discussion :

Moteur de jeux (ODFAEG) et jeux.


Sujet :

Projets

  1. #581
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 045
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 045
    Points : 11 368
    Points
    11 368
    Billets dans le blog
    10
    Par défaut
    Il vaut mieux essayer de comprendre pourquoi glScissor ne fonctionne pas, plutôt que faire ça dans ton fragment shader.
    En effet glScissor permet de ne pas rasteriser tout ce qui sort du scissor défini, ce qui est une optimisation non négligeable.

    Tu n'as toujours pas répondu à cette question : as-tu activé les extensions de débogage OpenGL (KHR_debug, ou ARB_debug_output).
    Elles sont très utiles, et permettent de réparer beaucoup de soucis.

    Un autre outil extrêmement utile est RenderDoc, qui permet de voir les différentes étapes de ton rendu, et de déboguer les appels OpenGL.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  2. #582
    Invité
    Invité(e)
    Par défaut Implémentation de glScissor.
    Salut j'ai compris pourquoi mon glScissor ne fonctionnait pas mais j'ai un autre soucis, lorsque j'utilise glScissor dans une sous fenêtre ça me cache aussi le panneau de gauche dans la fenêtre principale. (Celui ou j'affiche les fichiers du projet)

    Le code est sur git.

    Sinon non je n'utilise pas les extensions de déboguage, j'utilise seulement glGetError.

  3. #583
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 045
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 045
    Points : 11 368
    Points
    11 368
    Billets dans le blog
    10
    Par défaut
    Si je ne me trompe pas, si tu utilises glScissor quelque part, il faut ensuite que tu le remettes à la valeur par défaut, pour qu'il ne reste pas actif là où ce n'est pas nécessaire.

    Droppe glGetError, et utilise les extensions de debug.

    Par rapport à ton repo, tu as pris en compte les derniers commentaires que j'y ai fait ? (sur GitHub)

    EDIT:

    Apparemment non, tu n'as pas pris en compte mon dernier commentaire sur la suppression des doublons, ils sont toujours là.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  4. #584
    Invité
    Invité(e)
    Par défaut
    Ha bah ça va lorsque je remet la sous fenêtre en invisible ça me redessine bien le panneau comme avant.
    Et comme je n'ai pas besoin d'aller sur le panneau de la fenêtre principal pendant que je sélectionne la texture (de tout façon je ne peux pas avoir deux fenêtres active à la fois) ça n'est pas vraiment un soucis.
    (Ha merde il y a encore des doublons)

  5. #585
    Invité
    Invité(e)
    Par défaut
    J'ai remarqué un bug avec glScissor. Pourtant je le remet bien comme il était avant après le dessin du panneau et de tous ses enfants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    void Panel::onDraw(RenderTarget& target, RenderStates states) {
                    rect.setPosition(getPosition());
                    rect.setSize(getSize());
                    glCheck(glEnable(GL_SCISSOR_TEST));
                    glCheck(glScissor(getPosition().x, getWindow().getSize().y - (getPosition().y + getSize().y), getSize().x, getSize().y));
                    target.draw(rect, states);
                    for (unsigned int i = 0; i < sprites.size(); i++) {
                        target.draw(sprites[i], states);
                    }
                    for (unsigned int i = 0; i < shapes.size(); i++) {
                        target.draw(*shapes[i], states);
                    }
                }
                void Panel::drawOn(RenderTarget& target, RenderStates states) {
                    if (scrollX || scrollY) {
                        target.draw(corner, states);
                    }
                    if (scrollX) {
                        target.draw(vertScrollBar, states);
                    }
                    if (scrollY) {
                        target.draw(horScrollBar, states);
                    }
                    glCheck(glDisable(GL_SCISSOR_TEST));
                }
    onDraw est appelé au début et drawOn à la fin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    void draw(RenderTarget& target, RenderStates states) {
                    //states.transform = getTransform();
                    onDraw(target, states);
                    std::multimap<int, LightComponent*, std::greater<int>> sortedChildren;
                    for (unsigned int i = 0; i < children.size(); i++) {
                        sortedChildren.insert(std::make_pair(children[i]->getPriority(), children[i].get()));
                    }
                    std::multimap<int, LightComponent*, std::greater<int>>::iterator it;
                    for (it = sortedChildren.begin(); it != sortedChildren.end(); it++) {
                        if (it->second->isVisible()
                            && it->second->getPosition().x + it->second->getSize().x >= getPosition().x
                            && it->second->getPosition().y + it->second->getSize().y >= getPosition().y
                            && it->second->getPosition().x <= getPosition().x + getSize().x
                            && it->second->getPosition().y <= getPosition().y + getSize().y) {
                            /*if(name == "PFILES" && it == sortedChildren.begin()) {
                                std::cout<<"child pos : "<<it->second->getPosition()<<" child size : "<<it->second->getSize()<<std::endl;
                            }*/
                            it->second->draw(target, states);
                        }
                    }
                    drawOn(target, states);
                }
    Cependant ça fait buger la fenêtre de création d'un nouveau projet, la drop down list ne s'affiche plus, le text du label "height" est trop grand, et le texte dans les textArea "name" et "width" ne s'affichent pas.

    PS : il reste activé car lorsque je dessine dans un panneau d'une autre fenêtre le panneau vient caché ce qui est dessiné dans le fenêtre principale.
    Dernière modification par Invité ; 15/01/2019 à 19h45.

  6. #586
    Invité
    Invité(e)
    Par défaut Correction d'un bug.
    glScissor ne se désactivait pas bien lors du dessin de guis dans plusieurs fenêtres.
    Maintenant c'est réglé j'ai trouvé pourquoi.

  7. #587
    Invité
    Invité(e)
    Par défaut Nouvel article sur mon devblog : order independant transparency.
    https://laurentdur.wordpress.com/ord...-transparency/

    Et pour prouvé que ça marche j'ai même mis les calculs pour les équations pour trois sprites semi-transparents!

  8. #588
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 045
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 045
    Points : 11 368
    Points
    11 368
    Billets dans le blog
    10
    Par défaut
    Alors, il manque des images, dans ton article, pour illustrer tes propos.
    Ensuite, je ne vois pas pourquoi le fait de dessiner la première passe te permet de dessiner tous tes autres sprites avec la seconde équation.
    Ou plutôt, cette façon de faire ne fonctionne qu'avec deux layers de sprites, et pas plus, c'est tout.
    Si ton moteur n'a que deux layers, alors effectivement, elle fonctionne, sinon elle ne fonctionne pas.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  9. #589
    Invité
    Invité(e)
    Par défaut
    Alors, il manque des images, dans ton article, pour illustrer tes propos.
    Oui je viens d'en rajouter, à la fin de l'article.

    Ensuite, je ne vois pas pourquoi le fait de dessiner la première passe te permet de dessiner tous tes autres sprites avec la seconde équation.
    Je l'ai expliqué c'est plus performant de faire comme cela car sinon il faut testé indépendamment pour chaque sprite si il est plus proche que ce qui est déjà dessiné et donc faire un draw par sprite ce qui est contreperformant. Si la composante z de ce qui est déjà dessiné est maximale alors tous les autres sprites sont forcément derrière celui qui a été dessiné en premier car c'est le z de celui là qui compte lors du test et donc dans ce cas on peut appliquer la seconde équation pour tout les autres et donc dessiner tout en une seule fois.

    Ou plutôt, cette façon de faire ne fonctionne qu'avec deux layers de sprites, et pas plus, c'est tout.
    Si ton moteur n'a que deux layers, alors effectivement, elle fonctionne, sinon elle ne fonctionne pas.
    Pourtant il arrive à un moment, si tu regarde bien le dernier screen que j'ai mis, que je dessine trois sprites l'un sur l'autre (le feu, le héro et le mur), le mur est devant le héro et le héro est devant le feu, et à l'intersection on voit bien : le mur, le personnage et puis le feu donc, ça marche.

  10. #590
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 045
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 045
    Points : 11 368
    Points
    11 368
    Billets dans le blog
    10
    Par défaut
    Ton exemple est biaisé par le fait que tous tes sprites ne sont pas semi transparents (les flammes, le personnage et le mur ne sont pas semi transparents, et une simple alpha rejection suffirait pour eux).
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  11. #591
    Invité
    Invité(e)
    Par défaut
    Ton exemple est biaisé par le fait que tous tes sprites ne sont pas semi transparents (les flammes, le personnage et le mur ne sont pas semi transparents, et une simple alpha rejection suffirait pour eux).
    Excuse moi mauvais exemple, la valeur alpha est en effet rejetée pour le mur, le héro et le feu et le reste n'est pas semi-transparent.

    Prenons plutôt le sol qui lui contient des pixels semi-transparent sur les bords j'ai du faire cela pour gérer les transitions de sprites.

    On pourrait pensé que je n'utilise que deux couches pour le sol, je superpose un sprite d'herbe sur un autre, mais il n'est pas impossible qu'un troisième sprite d'herbe vienne se superposé sur les deux autres.
    Et pourtant l'herbe est bien dessinée.

    PS ; si ma solution ne marcherait pas on devrait voir les bords de mes sprites d'herbes.
    Dernière modification par Invité ; 16/01/2019 à 15h47.

  12. #592
    Invité
    Invité(e)
    Par défaut
    Je viens de testé avec 3 sprites de couleurs semi-transparentes et en effet, ça ne fonctionne que avec 2 sprites. (La couleur du milieu change si je change l'ordre de dessin)
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
        RenderWindow window(sf::VideoMode(1200, 700), "Scissor test",sf::Style::Default,sf::ContextSettings(0, 0, 4, 3, 0));
        Texture tex;
        tex.loadFromFile("tilesets/herbe.png");
        Tile* t1 = new Tile(nullptr,Vec3f(0, 0, 0), Vec3f(100, 50, 0),sf::IntRect(0, 0, 100, 50),sf::Color(255, 0, 0, 50));
        Tile* t2 = new Tile(nullptr,Vec3f(50, 0, 10),Vec3f(100, 50, 0),sf::IntRect(0, 0, 100, 50),sf::Color(0,255,0,200));
        Tile* t3 = new Tile(nullptr,Vec3f(25, 25, 20),Vec3f(100, 50, 0),sf::IntRect(0, 0, 100, 50),sf::Color(0, 0, 255, 128));
        OITRenderComponent orc (window,0,"E_TILE");
        const int NB_TILES = 3;
        std::vector<Entity*> entities;
        entities.resize(NB_TILES);
        while (window.isOpen()) {
            sf::Event event;
            while (window.pollEvent(event)) {
                if (event.type == sf::Event::Closed)
                    window.close();
            }
            std::vector<int> tileIndexes;
            while (tileIndexes.size() < NB_TILES) {
                unsigned int tileIndex;
                do {
                    tileIndex = Math::random(0, NB_TILES);
                } while (std::find(tileIndexes.begin(), tileIndexes.end(),tileIndex) != tileIndexes.end());
                tileIndexes.push_back(tileIndex);
            }
            entities[tileIndexes[0]] = t1;
            entities[tileIndexes[1]] = t2;
            entities[tileIndexes[2]] = t3;
            orc.clear();
            orc.loadEntitiesOnComponent(entities);
            orc.drawNextFrame();
            window.clear();
            /*for (unsigned int i = 0; i < NB_TILES; i++) {
                window.draw(*entities[tileIndexes[i]]);
            }*/
            Tile tile = orc.getFrameBufferTile();
            tile.setCenter(window.getView().getPosition());
            window.draw(tile);
            window.display();
        }
        return 0;
    Cependant pour le moment ça répond à mes besoins je n'ai pas besoin de faire plus de deux couches pour dessiner le sol.
    Et je ne connais pas de formule miracle qui permet de le faire avec plus de deux tiles et je ne pense pas qu'il en existe une, tout ce que j'ai trouvé sur le net, ce sont des approximations (mais ça ne rendait pas bien avec mes sprites d'herbes) ou bien des techniques utilisant l'opengl moderne comme par exemple, les per pixel lists.

  13. #593
    Invité
    Invité(e)
    Par défaut
    Enfin si il y a moyen de le faire mais ça serait contre performant car ça nécessite une lecture dans le framebuffer en cours de dessin et donc un draw par sprite, la solution c'est d'isoler les deux partie de l'équation, faire la moyenne (en ignorant la valeur (0, 0, 0)) pour les deux parties de l'équation et faire l'addition à la fin.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    sprite 1 (DSTCOLOR) avec sprite 3 (SRCCOLOR) :
    SRCCOLOR (0,1,0)*0.75=(0,0.75,0)
    DSTCOLOR (1,0,0)*(1-0.75)=(0.25,0,0)
    sprite 2 (SRCCOLOR) avec sprite 3 (DSTCOLOR) :
    SRCCOLOR (0,1,0)*0.75=(0,0.75,0)
    DSTCOLOR (0,0,1)*(1-0.75)=(0,0,0.25)
     
    Texture1 : 
    ((0,0.75,0)+(0,0.75,0))*0.5=(0,1.5,0)*0.5=(0,0.75,0)
    (DSTCOLOR*ONE+SRCCOLOR*SRCALPHA)*0.5
     
    Texture2 : 
    (0.25,0,0)+(0,0,0.25)=(0.25,0,0.25)*0.5=(0.125,0,0.125)
    (DSTCOLOR*ONE+SRCCOLOR*ONEMINUSSRCALPHA)*0.5
     
    Texture : 
    (0,0.75,0)+(0.125,0,0.125)=(0.125,0.75,0.125)
    Ca donne bien le même résultat que si je fais un blending back to front en dessinant le sprite1, le sprite2 et ensuite le sprite3.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
        (1,0,0,0.25) Z = 0.
        (0,0,1,0.5) Z = 1.
        (0,1,0,0.75) Z = 2.
     
    Essayons d’appliqué notre procédé vu précédemment, on va dessiner le sprite1 ensuite le sprite2 et enfin le sprite3.
     
    On a déjà la couleur résultant au dessus pour le sprite1 avec le sprite2 c’est (0.5,0,0.5,0.625)
     
    Avec le sprite 3 ça donne :
     
    (0.1,0)*0.75+(0.5,0,0.5)*(1-0.75)=(0,0.75,0)+(0.125,0,0.125) = (0.125,0.75,0.125) et la nouvelle valeur de alpha est : 0.75+0.625*(1-0.75)=0.90625
    Mais pour l'instant je ne vois pas de moyen de le faire de manière optimisée. (avec un seul draw pour tout les sprites) si quelqu'un à une solution je suis preneur. ^^

    PS : je pensais faire que l'addition et faire la moyenne à la fin mais on ne peut pas dépassé un pour les valeurs de la texture.

  14. #594
    Invité
    Invité(e)
    Par défaut Mise à jour de l'article OIT sur mon devblog avec la nouvelle solution.
    Maintenant que j'ai compris pourquoi ça ne fonctionnait pas pour plus que deux layers, j'ai mis à jour le devblog mais tant que je n'ai pas trouvé de moyen de le faire de manière optimisée, je ne met pas de code ni d'images.

  15. #595
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 045
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 045
    Points : 11 368
    Points
    11 368
    Billets dans le blog
    10
    Par défaut
    Déjà, les objets qui n'ont besoin que de l'alpha rejection peuvent être rendus comme des objets opaques.
    Ensuite, essaie d'implémenter correctement le Blended Weighted OIT ?
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  16. #596
    Membre éclairé
    Avatar de Gregouar
    Profil pro
    Chercheur en mathématiques
    Inscrit en
    Décembre 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chercheur en mathématiques

    Informations forums :
    Inscription : Décembre 2007
    Messages : 246
    Points : 899
    Points
    899
    Par défaut
    PS : je pensais faire que l'addition et faire la moyenne à la fin mais on ne peut pas dépassé un pour les valeurs de la texture.
    Il doit y avoir moyen si tu utilises le bon format de framebuffer, du même gout que ce qu'on fait pour le HDR. Pas sûr que ça soit la meilleure solution pour ce que tu veux faire ceci-dit.
    Holyspirit : Hack'n'Slash amateur gratuit !

    www.holyspirit.fr

  17. #597
    Invité
    Invité(e)
    Par défaut
    J'ai un début de solution, j'ai essayé avec des couleurs ça marche, mais quand je lance le jeux, c'est trop sombre.

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
     
    #include "../../../include/odfaeg/Graphics/oitRenderComponent.h"
    #include "glCheck.h"
    #include <memory.h>
    using namespace sf;
    using namespace std;
    namespace odfaeg {
        namespace graphic {
            OITRenderComponent::OITRenderComponent (RenderWindow& window, int layer, std::string expression, sf::ContextSettings settings) :
                HeavyComponent(window, math::Vec3f(window.getView().getPosition().x, window.getView().getPosition().y, layer),
                              math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0),
                              math::Vec3f(window.getView().getSize().x + window.getView().getSize().x * 0.5f, window.getView().getPosition().y + window.getView().getSize().y * 0.5f, layer)),
                view(window.getView()),
                expression(expression) {
                update = false;
                sf::Vector3i resolution ((int) window.getSize().x, (int) window.getSize().y, window.getView().getSize().z);
                settings.depthBits = 32;
                depthBuffer.create(resolution.x, resolution.y,settings);
                frontBuffer.create(resolution.x, resolution.y,settings);
                settings.depthBits = 0;
                averageBlendEqPart1.create(resolution.x, resolution.y,settings);
                averageBlendEqPart2.create(resolution.x, resolution.y,settings);
                alpha.create(resolution.x, resolution.y,settings);
                frameBuffer.create(resolution.x, resolution.y,settings);
     
                frontBuffer.setView(window.getView());
                depthBuffer.setView(window.getView());
                frameBuffer.setView(window.getView());
                averageBlendEqPart1.setView(window.getView());
                averageBlendEqPart2.setView(window.getView());
                frontBufferSprite = Sprite (frontBuffer.getTexture(), math::Vec3f(0, 0, 0), math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0), IntRect(0, 0, window.getView().getSize().x, window.getView().getSize().y));
                depthBufferSprite = Sprite (depthBuffer.getTexture(), math::Vec3f(0, 0, 0), math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0), IntRect(0, 0, window.getView().getSize().x, window.getView().getSize().y));
                frameBufferSprite = Sprite(frameBuffer.getTexture(), math::Vec3f(0, 0, 0), math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0), IntRect(0, 0, window.getView().getSize().x, window.getView().getSize().y));
                blendEqPart1 = Sprite (averageBlendEqPart1.getTexture(), math::Vec3f(0, 0, 0), math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0), IntRect(0, 0, window.getView().getSize().x, window.getView().getSize().y));
                blendEqPart2 = Sprite (averageBlendEqPart2.getTexture(), math::Vec3f(0, 0, 0), math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0), IntRect(0, 0, window.getView().getSize().x, window.getView().getSize().y));
                alphaSprite = Sprite (alpha.getTexture(), math::Vec3f(0, 0, 0), math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0), IntRect(0, 0, window.getView().getSize().x, window.getView().getSize().y));
                core::FastDelegate<bool> signal (&OITRenderComponent::needToUpdate, this);
                core::FastDelegate<void> slot (&OITRenderComponent::drawNextFrame, this);
                core::Command cmd(signal, slot);
                getListener().connect("UPDATE", cmd);
                if (Shader::isAvailable()) {
                    const std::string  vertexShader =
                    "#version 130 \n"
                    "out mat4 projMat;"
                    "void main () {"
                        "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
                        "gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;"
                        "gl_FrontColor = gl_Color;"
                        "projMat = gl_ProjectionMatrix;"
                    "}";
                    const std::string  simpleVertexShader =
                    "#version 130 \n"
                    "void main () {"
                        "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
                        "gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;"
                        "gl_FrontColor = gl_Color;"
                    "}";
                    const std::string addSrcColorFragShader =
                    "#version 130 \n"
                    "in mat4 projMat;"
                    "uniform vec3 resolution;"
                    "uniform sampler2D frontBuffer;"
                    "uniform sampler2D depthBuffer;"
                    "uniform sampler2D texture;"
                    "uniform float haveTexture;"
                    "void main() {"
                        "vec2 position = (gl_FragCoord.xy / resolution.xy);"
                        "vec4 front_color = texture2D(frontBuffer, position);"
                        "vec4 texel = texture2D(texture, gl_TexCoord[0].xy);"
                        "vec4 colors[2];"
                        "colors[1] = texel * gl_Color;"
                        "colors[0] = gl_Color;"
                        "bool b = (haveTexture > 0.9);"
                        "vec4 color = colors[int(b)];"
                        "gl_FragColor = vec4(color.rgb * (1 - front_color.a), color.a);"
                    "}";
                    const std::string addDstColorFragShader =
                    "#version 130 \n"
                    "in mat4 projMat;"
                    "uniform vec3 resolution;"
                    "uniform sampler2D frontBuffer;"
                    "uniform sampler2D depthBuffer;"
                    "uniform sampler2D texture;"
                    "uniform float haveTexture;"
                    "void main() {"
                        "vec2 position = (gl_FragCoord.xy / resolution.xy);"
                        "vec4 front_color = texture2D(frontBuffer, position);"
                        "vec4 texel = texture2D(texture, gl_TexCoord[0].xy);"
                        "vec4 colors[2];"
                        "colors[1] = texel * gl_Color;"
                        "colors[0] = gl_Color;"
                        "bool b = (haveTexture > 0.9);"
                        "vec4 color = colors[int(b)];"
                        "gl_FragColor = vec4(front_color.rgb * front_color.a, front_color.a);"
                    "}";
                    const std::string avgFragShader =
                    "#version 130 \n"
                    "uniform sampler2D texture;"
                    "uniform float nb;"
                    "void main() {"
                        "vec4 color = texture2D(texture, gl_TexCoord[0].xy);"
                        "gl_FragColor = vec4(color.r / nb, color.g / nb, color.b / nb, color.a);"
                    "}";
                    const std::string setAlphaFragShader =
                    "#version 130 \n"
                    "uniform vec3 resolution;"
                    "uniform sampler2D texture;"
                    "uniform sampler2D frameBuffer;"
                    "void main() {"
                        "position = (gl_FragCoord.xy / resolution.xy);"
                        "vec4 alpha = texture2D(texture, gl_TexCoords[0].xy).a;"
                        "vec4 color = texture2D(frameBuffer, position);"
                        "gl_FragColor = vec4(color.rgb, alpha);"
                    "}";
                    const std::string depthGenFragShader =
                    "#version 130 \n"
                    "in mat4 projMat;"
                    "uniform sampler2D texture;"
                    "uniform float haveTexture;"
                    "void main () {"
                        "vec4 texel = texture2D(texture, gl_TexCoord[0].xy);"
                        "vec4 colors[2];"
                        "colors[1] = texel * gl_Color;"
                        "colors[0] = gl_Color;"
                        "bool b = (haveTexture > 0.9);"
                        "vec4 color = colors[int(b)];"
                        "float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;"
                        "gl_FragColor = vec4(0, 0, z, color.a);"
                    "}";
                    const std::string frameBufferGenFragShader =
                    "#version 130 \n"
                    "uniform sampler2D depthBuffer;"
                    "uniform sampler2D texture;"
                    "uniform vec3 resolution;"
                    "uniform float haveTexture;"
                    "in mat4 projMat;"
                    "void main () {"
                        "vec2 position = ( gl_FragCoord.xy / resolution.xy );"
                        "vec4 max = texture2D(depthBuffer, position);"
                        "vec4 texel = texture2D(texture, gl_TexCoord[0].xy);"
                        "vec4 colors[2];"
                        "colors[1] = texel * gl_Color;"
                        "colors[0] = gl_Color;"
                        "bool b = (haveTexture > 0.9);"
                        "vec4 color = colors[int(b)];"
                        "float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;"
                        "colors[1] = color;"
                        "colors[0] = vec4(0, 0, 0, 0);"
                        "b = (z < max.z);"
                        "gl_FragColor = colors[int(b)];"
                    "}";
                    if (!depthBufferGenerator.loadFromMemory(vertexShader, depthGenFragShader))
                        throw core::Erreur(50, "Failed to load depth buffer generator shader", 0);
                    if (!frameBufferGenerator.loadFromMemory(vertexShader, frameBufferGenFragShader))
                        throw core::Erreur(51, "Failed to load frame buffer generator shader", 0);
                    if (!computeAvgShader.loadFromMemory(simpleVertexShader, avgFragShader)) {
                        throw core::Erreur(51, "Failed to load compute avg shader", 0);
                    }
                    if (setAlphaShader.loadFromMemory(simpleVertexShader, setAlphaFragShader)) {
                        throw core::Erreur(51, "Failed to load set alpha shader", 0);
                    }
                    if (!addSrcColorShader.loadFromMemory(vertexShader,addSrcColorFragShader)) {
                        throw core::Erreur(51, "Failed to load add src color shader", 0);
                    }
                    if (!addDstColorShader.loadFromMemory(vertexShader,addDstColorFragShader)) {
                        throw core::Erreur(51, "Failed to load add dst color shader", 0);
                    }
                    addSrcColorShader.setParameter("resolution",resolution.x, resolution.y, resolution.z);
                    addSrcColorShader.setParameter("frontBuffer", frontBuffer.getTexture());
                    addDstColorShader.setParameter("depthBuffer", depthBuffer.getTexture());
                    addSrcColorShader.setParameter("texture", Shader::CurrentTexture);
                    addDstColorShader.setParameter("resolution",resolution.x, resolution.y, resolution.z);
                    addDstColorShader.setParameter("frontBuffer", frontBuffer.getTexture());
                    addDstColorShader.setParameter("depthBuffer", depthBuffer.getTexture());
                    addDstColorShader.setParameter("texture", Shader::CurrentTexture);
                    setAlphaShader.setParameter("resolution", resolution.x, resolution.y, resolution.z);
                    setAlphaShader.setParameter("frameBuffer", frameBuffer.getTexture());
                    setAlphaShader.setParameter("texture", Shader::CurrentTexture);
                        //throw core::Erreur(52, "Failed to load specular texture generator shader", 0);
                    /*if (!bumpTextureGenerator->loadFromMemory(vertexShader, bumpGenFragShader))
                        throw core::Erreur(53, "Failed to load bump texture generator shader", 0);
                    if (!refractionTextureGenerator->loadFromMemory(vertexShader, refractionGenFragShader))
                        throw core::Erreur(54, "Failed to load refraction texture generator shader", 0);*/
                    frameBufferGenerator.setParameter("resolution",resolution.x, resolution.y, resolution.z);
                    frameBufferGenerator.setParameter("depthBuffer", depthBuffer.getTexture());
                    frameBufferGenerator.setParameter("texture", Shader::CurrentTexture);
                    depthBufferGenerator.setParameter("texture", Shader::CurrentTexture);
                    computeAvgShader.setParameter("texture", Shader::CurrentTexture);
                    //specularTextureGenerator->setParameter("specularTexture",specularTexture->getTexture());
                    backgroundColor = sf::Color::Transparent;
                } else {
                    throw core::Erreur(55, "Shader not supported!", 0);
                }
            }
            void OITRenderComponent::pushEvent(sf::Event event, RenderWindow& rw) {
                if (event.type == sf::Event::Resized && &getWindow() == &rw && isAutoResized()) {
                    std::cout<<"recompute size"<<std::endl;
                    recomputeSize();
                    getListener().pushEvent(event);
                    getView().reset(physic::BoundingBox(getView().getViewport().getPosition().x, getView().getViewport().getPosition().y, getView().getViewport().getPosition().z, event.size.width, event.size.height, getView().getViewport().getDepth()));
                }
            }
            bool OITRenderComponent::needToUpdate() {
                return update;
            }
            void OITRenderComponent::changeVisibleEntities(Entity* toRemove, Entity* toAdd, EntityManager* em) {
                bool removed;
                em->removeAnimatedVisibleEntity(toRemove, visibleEntities, view, removed);
                if (removed) {
                    em->insertAnimatedVisibleEntity(toAdd, visibleEntities, view);
                    loadEntitiesOnComponent(visibleEntities);
                    update = true;
                }
            }
            std::string OITRenderComponent::getExpression() {
                return expression;
            }
            void OITRenderComponent::setBackgroundColor(sf::Color color) {
                this->backgroundColor = color;
            }
            void OITRenderComponent::clear() {
                 frameBuffer.clear(backgroundColor);
                 depthBuffer.clear(sf::Color::Transparent);
                 frontBuffer.clear(sf::Color::Transparent);
                 averageBlendEqPart1.clear(sf::Color::Transparent);
                 averageBlendEqPart2.clear(sf::Color::Transparent);
                 alpha.clear(sf::Color::Transparent);
            }
            Sprite& OITRenderComponent::getAvgBlendEqPart1() {
                return blendEqPart1;
            }
            Sprite& OITRenderComponent::getAvgBlendEqPart2() {
                return blendEqPart2;
            }
            Sprite& OITRenderComponent::getFrameBufferSprite () {
                return frameBufferSprite;
            }
            Sprite& OITRenderComponent::getDepthBufferSprite() {
                return depthBufferSprite;
            }
            Sprite& OITRenderComponent::getFrontBufferSprite() {
                return frontBufferSprite;
            }
            Sprite& OITRenderComponent::getAlphaSprite() {
                return alphaSprite;
            }
            const Texture& OITRenderComponent::getDepthBufferTexture() {
                return depthBuffer.getTexture();
            }
            const Texture& OITRenderComponent::getFrameBufferTexture() {
                return frameBuffer.getTexture();
            }
            const Texture& OITRenderComponent::getFrontBufferTexture() {
                return frontBuffer.getTexture();
            }
            bool OITRenderComponent::loadEntitiesOnComponent(std::vector<Entity*> vEntities)
            {
     
                batcher.clear();
                for (unsigned int i = 0; i < vEntities.size(); i++) {
                    if ( vEntities[i]->isLeaf()) {
                        for (unsigned int j = 0; j <  vEntities[i]->getFaces().size(); j++) {
                             batcher.addFace( vEntities[i]->getFaces()[j]);
                        }
                    }
                }
                m_instances = batcher.getInstances();
                visibleEntities = vEntities;
                update = true;
                return true;
            }
            void OITRenderComponent::setView(View view) {
                this->view = view;
                frameBuffer.setView(view);
                depthBuffer.setView(view);
                frontBuffer.setView(view);
                averageBlendEqPart1.setView(view);
                averageBlendEqPart2.setView(view);
                alpha.setView(view);
            }
            void OITRenderComponent::setExpression(std::string expression) {
                update = true;
                this->expression = expression;
            }
            void OITRenderComponent::drawNextFrame() {
                update = false;
                currentStates.blendMode = sf::BlendNone;
                for (unsigned int i = 0; i < m_instances.size(); i++) {
                     if (m_instances[i].getMaterial().getTexture() == nullptr)
                        depthBufferGenerator.setParameter("haveTexture", 0);
                     else
                        depthBufferGenerator.setParameter("haveTexture", 1);
     
                     currentStates.shader=&depthBufferGenerator;
                     currentStates.texture=m_instances[i].getMaterial().getTexture();
                     depthBuffer.draw(m_instances[i].getAllVertices(),currentStates);
                     currentStates.shader=nullptr;
                     frontBuffer.draw(m_instances[i].getAllVertices(), currentStates);
                }
                /*frontBuffer.display();
                frontBufferSprite.setCenter(view.getPosition());
                frameBuffer->draw(*frontBufferSprite, currentStates);
                currentStates.shader=frameBufferGenerator.get();
                currentStates.blendMode=sf::BlendMode(sf::BlendMode::Factor::OneMinusDstAlpha, sf::BlendMode::Factor::DstAlpha, sf::BlendMode::Equation::Add, sf::BlendMode::Factor::OneMinusDstAlpha, sf::BlendMode::Factor::One, sf::BlendMode::Equation::Add);
                for (unsigned int i = 0; i < m_instances.size(); i++) {
                    if (m_instances[i].getMaterial().getTexture() == nullptr)
                        frameBufferGenerator->setParameter("haveTexture", 0);
                     else
                        frameBufferGenerator->setParameter("haveTexture", 1);
                    currentStates.texture = m_instances[i].getMaterial().getTexture();
                    frameBuffer->draw(m_instances[i].getAllVertices(), currentStates);
                }*/
                /*averageBlendEqPart1.draw(frontBufferSprite, currentStates);
                averageBlendEqPart2.draw(frontBufferSprite, currentStates);*/
                currentStates.shader=&addSrcColorShader;
                currentStates.blendMode=sf::BlendMode(sf::BlendMode::Factor::One, sf::BlendMode::Factor::One, sf::BlendMode::Equation::Add, sf::BlendMode::Factor::OneMinusDstAlpha, sf::BlendMode::Factor::One, sf::BlendMode::Equation::Add);
                for (unsigned int i = 0; i < m_instances.size(); i++) {
                    if (m_instances[i].getMaterial().getTexture() == nullptr)
                        addSrcColorShader.setParameter("haveTexture", 0);
                    else
                        addSrcColorShader.setParameter("haveTexture", 1);
                    currentStates.texture = m_instances[i].getMaterial().getTexture();
                    averageBlendEqPart1.draw(m_instances[i].getAllVertices(), currentStates);
                }
                currentStates.shader=&addDstColorShader;
                unsigned int nb = 0;
                for (unsigned int i = 0; i < m_instances.size(); i++) {
                    if (m_instances[i].getMaterial().getTexture() == nullptr)
                        addDstColorShader.setParameter("haveTexture", 0);
                    else
                        addDstColorShader.setParameter("haveTexture", 1);
                    currentStates.texture = m_instances[i].getMaterial().getTexture();
                    averageBlendEqPart2.draw(m_instances[i].getAllVertices(), currentStates);
                    nb += m_instances[i].getVertexArrays().size();
                }
     
                /*currentStates.blendMode = sf::BlendMode(sf::BlendMode::Factor::Zero,sf::BlendMode::Factor::Zero,sf::BlendMode::Equation::Add, sf::BlendMode::Factor::OneMinusDstAlpha, sf::BlendMode::Factor::One, sf::BlendMode::Equation::Add);
                currentStates.shader = nullptr;
                alpha.draw(frontBufferSprite, currentStates);
                currentStates.shader=&frameBufferGenerator;
                for (unsigned int i = 0; i < m_instances.size(); i++) {
                    if (m_instances[i].getMaterial().getTexture() == nullptr)
                        frameBufferGenerator.setParameter("haveTexture", 0);
                    else
                        frameBufferGenerator.setParameter("haveTexture", 1);
                    currentStates.texture = m_instances[i].getMaterial().getTexture();
                    alpha.draw(m_instances[i].getAllVertices(), currentStates);
                }
                alpha.display();
                alphaSprite.setCenter(view.getPosition());*/
                currentStates.blendMode=sf::BlendNone;
                computeAvgShader.setParameter("nb", nb-1);
                currentStates.shader = &computeAvgShader;
                averageBlendEqPart1.display();
                blendEqPart1.setCenter(view.getPosition());
                averageBlendEqPart1.draw(blendEqPart1, currentStates);
                averageBlendEqPart2.display();
                blendEqPart2.setCenter(view.getPosition());
                averageBlendEqPart2.draw(blendEqPart2, currentStates);
                /*currentStates.shader = &simpleShader;
                currentStates.blendMode = sf::BlendNone;
                averageBlendEqPart2.draw(blendEqPart2, currentStates);*/
                currentStates.shader = nullptr;
                currentStates.blendMode=sf::BlendMode(sf::BlendMode::Factor::One, sf::BlendMode::Factor::One, sf::BlendMode::Equation::Add, sf::BlendMode::Factor::OneMinusDstAlpha, sf::BlendMode::Factor::One, sf::BlendMode::Equation::Add);;
                frameBuffer.draw(blendEqPart1, currentStates);
                frameBuffer.draw(blendEqPart2, currentStates);
                /*currentStates.blendMode = sf::BlendNone;
                currentStates.shader = &setAlphaShader;
                frameBuffer.draw(alphaSprite, currentStates);*/
                for (unsigned int i = 0; i < drawables.size(); i++) {
                    frameBuffer.draw(drawables[i].first.get(), drawables[i].second);
                }
                averageBlendEqPart1.display();
                averageBlendEqPart2.display();
                frontBuffer.display();
                depthBuffer.display();
                frameBuffer.display();
            }
            std::vector<Entity*> OITRenderComponent::getEntities() {
                return visibleEntities;
            }
            void OITRenderComponent::draw(Drawable& drawable, RenderStates states) {
                update = true;
                drawables.push_back(std::make_pair(std::ref(drawable), states));
            }
            void OITRenderComponent::draw(RenderTarget& target, RenderStates states) {
                frameBufferSprite.setCenter(target.getView().getPosition());
                target.draw(frameBufferSprite, states);
                drawables.clear();
            }
     
            View& OITRenderComponent::getView() {
                return view;
            }
            int OITRenderComponent::getLayer() {
                return getPosition().z;
            }
            void OITRenderComponent::updateParticleSystems() {
                for (unsigned int i = 0; i < visibleEntities.size(); i++) {
                    if (dynamic_cast<physic::ParticleSystem*>(visibleEntities[i]) != nullptr) {
                        static_cast<physic::ParticleSystem*>(visibleEntities[i])->update();
                    }
                }
                loadEntitiesOnComponent(visibleEntities);
                update = true;
            }
        }
    }

    Pourquoi est ce que c'est si sombre ? Et je trouve que ça ne rend pas très bien avec les textures, il doit y avoir une erreur...

    Ce que je veux faire c'est ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    sprite 1 (1, 0, 0, 0.25)
    sprite 2 (0, 0, 1, 0.5)
    sprite 3 (0, 1, 0, 0.75)
    sprite 1 (SRCCOLOR) with sprite 3 (DSTCOLOR) :
    SRCCOLOR (1,0,0) * (1-0.75) =(0.25,0,0)
    DSTCOLOR (0,1,0) * 0.75 = (0,0.75,0)
    sprite 2 (SRCCOLOR) with sprite 3 (DSTCOLOR) :
    SRCCOLOR (0,0,1)*(1-0.75)=(0,0,0.25)
    DSTCOLOR (0,1,0)*0.75=(0,0.75,0)
     
    Texture1 : 
    ((0.25,0,0)+(0,0,0.25))*0.5=(0.25,0,0.25)*0.5=(0.125,0,0.125)
    (DSTCOLOR*ONE+SRCCOLOR*ONEMINUSDSTALPHA)*0.5
     
    Texture2 : 
    (0,0.75,0)+(0,0.75,0)=(0,1.5,0)*0.5=(0,0.75,0)
    (DSTCOLOR*ONE+SRCCOLOR*DSTALPHA)*0.5
     
    Texture : 
    (0.125,0,0.125)+(0.125,0.75,0.125)=(0.125,0.75,0.125)
     
    sprite 1 (1, 0, 0, 0.25)
    sprite 2 (0, 0, 1, 0.5)
    sprite 3 (0, 1, 0, 0.75)
    sprite 2 (SRCCOLOR) with sprite 3 (DSTCOLOR) :
    SRCCOLOR (0,0,1) * (1-0.75) = (0,0,0.25)
    DSTCOLOR (0,1,0) * 0.75 = (0,0.75,0)
    sprite 1 (SRCCOLOR) with sprite 3 (DSTCOLOR) :
    SRCCOLOR (1,0,0)*(1-0.75)=(0.25,0,0)
    DSTCOLOR (0,1,0)*0.75=(0,0.75,0)
     
    Texture1 : 
    ((0.25,0,0)+(0,0,0.25))*0.5=(0.25,0,0.25)*0.5=(0.125,0,0.125)
    (DSTCOLOR*ONE+SRCCOLOR)*0.5
     
    Texture2 : 
    (0,0.75,0)+(0,0.75,0)=(0,1.5,0)*0.5=(0,0.75,0)
    (DSTCOLOR*ONE+SRCCOLOR*ONE)*0.5
     
    Texture : 
    (0.125,0,0.125)+(0.125,0.75,0.125)=(0.125,0.75,0.125)
    Je recherche tout ce qui est le plus proche de la caméra et je le stocke dans une texture. Et puis je rend tout mes sprite avec l'équation : SRCCOLOR * (1-DST_ALPHA) + DSTCOLOR * DSTALPHA.

    Pour que ça marche, il faut diviser l'équation en deux parties, faire l'addition des couleurs pour les deux parties, ensuite faire la moyenne et enfin faire l'addition finale bref c'est assez compliqué à mettre en place mais ça fonctionne, pas encore très bien car le jeux est trop sombre mais j'ai testé avec trois couleur, mélanger aléatoirement les sprites et ça fonctionne à l'intersection des trois tiles la couleurs ne change pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    RenderWindow window(sf::VideoMode(1200, 700), "Scissor test",sf::Style::Default,sf::ContextSettings(0, 0, 4, 3, 0));
        Texture tex;
        tex.loadFromFile("tilesets/herbe.png");
        Tile* t1 = new Tile(&tex,Vec3f(0, 0, 0), Vec3f(100, 50, 0),sf::IntRect(0, 0, 100, 50)/*,sf::Color(255, 0, 0,255)*/);
        Tile* t2 = new Tile(&tex,Vec3f(50, 0, 10),Vec3f(100, 50, 0),sf::IntRect(0, 0, 100, 50)/*,sf::Color(0,255,0,255)*/);
        Tile* t3 = new Tile(&tex,Vec3f(25, 25, 20),Vec3f(100, 50, 0),sf::IntRect(0, 0, 100, 50)/*,sf::Color(0, 0, 255, 200)*/);
        OITRenderComponent orc (window,0,"E_TILE");
        const int NB_TILES = 3;
        std::vector<Entity*> entities;
        entities.resize(NB_TILES);
        while (window.isOpen()) {
            sf::Event event;
            while (window.pollEvent(event)) {
                if (event.type == sf::Event::Closed)
                    window.close();
            }
            std::vector<int> tileIndexes;
            while (tileIndexes.size() < NB_TILES) {
                unsigned int tileIndex;
                do {
                    tileIndex = Math::random(0, NB_TILES);
                } while (std::find(tileIndexes.begin(), tileIndexes.end(),tileIndex) != tileIndexes.end());
                tileIndexes.push_back(tileIndex);
            }
            entities[tileIndexes[0]] = t1;
            entities[tileIndexes[1]] = t2;
            entities[tileIndexes[2]] = t3;
            orc.clear();
            orc.loadEntitiesOnComponent(entities);
            orc.drawNextFrame();
            window.clear();
            /*for (unsigned int i = 0; i < NB_TILES; i++) {
                window.draw(*entities[tileIndexes[i]]);
            }*/
            Sprite tile = orc.getFrameBufferSprite();
            tile.setCenter(window.getView().getPosition());
            window.draw(tile);
            window.display();
        }
    Bon plus qu'à régler de problème de sombreté et ça devrait être bon..., mais là je sèche, je ne sais pas pourquoi c'est si sombre pourtout quand je dessine les textures comme ça ça marche mais une fois que je dessine toute la map là mes textures sont beaucoup plus sombre. -_-
    Bizarre.

    PS : Tiens c'est bizarre ça marche avec toute les couleurs sauf le blanc, quand je veux rendre du blanc ça me met du gris.
    Dernière modification par Invité ; 18/01/2019 à 01h21.

  18. #598
    Invité
    Invité(e)
    Par défaut
    Ha j'ai trouvé ce n'est pas par le nombre de sprites qu'il faut diviser mais par le nombre de couches!

    Comment pourrais je faire pour calculer ce nombre dans le fragment shader ...

    Il y a les atomic counter mais il faut vraiment un driver récent pour faire cela.

    N'y a t'il pas moyen de le faire autrement ?
    Dernière modification par Invité ; 18/01/2019 à 02h48.

  19. #599
    Invité
    Invité(e)
    Par défaut
    Apparemment je dois utiliser un stencil buffer pour calculer le nombre de couches : https://open.gl/depthstencils

    Il faut incrémenter la valeur de un à chaque fois que le depthtest passe.

    Mais je n'ai jamais implémenté ce genre de chose. Et après je devrais lire la valeur dans le stencil buffer et diviser par le nombre de couches pour faire la moyenne et je pense que ça marchera mieux comme ça parce que là. *_*

  20. #600
    Membre éclairé
    Avatar de Gregouar
    Profil pro
    Chercheur en mathématiques
    Inscrit en
    Décembre 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chercheur en mathématiques

    Informations forums :
    Inscription : Décembre 2007
    Messages : 246
    Points : 899
    Points
    899
    Par défaut
    Plutôt que de tourner en rond et produire des solutions contre-performantes, pourquoi est-ce que tu ne ferais pas quelque chose de simple comme:
    -Un système de couches de rendus te permettant de choisir l'ordre dans lequel tu veux faire tes rendus (par exemple une couche pour les tiles de sol, une couche pour des modèles 3D, une couche pour des effets de sort, une couche pour la GUI)
    -Quand tu affiches tout ce qui touche à la 2D, tu le fais dans l'ordre dans lequel tu demandes de dessiner (ainsi, c'est à l'utilisateur du moteur de décider par exemple d'afficher les tiles d'herbe, etc de haut en bas => très facile à faire si ils sont déjà mis sur une grille par exemple).
    -Quand tu affiches la 3D, tu sépares en deux cas : transparent et non transparent => tu tries par distance d'affichage pour afficher d'abord tout ce qui est opaque du plus proche au plus loin (pour profiter du early z-testing), ensuite tu dessines tes objets transparents du plus loin au plus proche (pour avoir le bon alpha blending directement en fixed function et tu t'ennuies même pas à devoir écrire un shader). A priori, ça devrait arriver à peu près jamais que tu aies deux triangles transparents qui s'intersectent de toute façon. Parfois (souvent ?) ça ne vaut pas la peine de chercher à envoir une solution exacte quand tu fais du temps réel... il suffit de regarder un peu et tu verras que même dans les triples A tu peux facilement trouver des artefacts graphiques.
    Holyspirit : Hack'n'Slash amateur gratuit !

    www.holyspirit.fr

Discussions similaires

  1. [jeux video] Souvenir, jeux de baston
    Par Faith's Fall dans le forum Jeux
    Réponses: 80
    Dernier message: 25/01/2013, 11h18
  2. Moteur de regles pour un jeux web
    Par lastico21000 dans le forum Jeux web
    Réponses: 0
    Dernier message: 03/03/2012, 20h17
  3. Moteur 3D pour mon petit jeux.
    Par Invité dans le forum Moteurs 3D
    Réponses: 1
    Dernier message: 17/01/2010, 10h13
  4. [X360] jeux xbox et jeux PC
    Par Biosox dans le forum Consoles
    Réponses: 1
    Dernier message: 06/01/2009, 15h34
  5. creer des jeux intelligent comme jeux d'echec
    Par hkader dans le forum Développement 2D, 3D et Jeux
    Réponses: 4
    Dernier message: 14/09/2007, 08h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo