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. #81
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 393
    Points : 685
    Points
    685
    Par défaut
    Tu n'as jamais envisagé que le problème venait de ton code et pas des drivers ? (même si cela peut arriver, c'est généralement assez bien documenté)

    Tu espères quelles performances si tu fais de la 3D sans GPU ? Et même pour de la 2D un peu sérieuse ? (particules, effets graphiques...)

    Comment espères vendre un moteur conçu par quelqu'un qui ne maîtrise visiblement pas le sujet ?

    (@skeud: je crois que la lib NVIDIA VXGI utilise un système de voxel et ray tracing pour les calculs d'illumination globale - c'est basé sur GigaVoxel de mémoire. Mais cela reste assez expérimental, je ne sais pas si c'est utilisé dans des jeux commerciaux)

  2. #82
    Invité
    Invité(e)
    Par défaut
    Tu n'as jamais envisagé que le problème venait de ton code et pas des drivers ? (même si cela peut arriver, c'est généralement assez bien documenté)
    Pas pour les drivers opensource, et je pense pas que les projets commerciaux utilisent des drivers opensources, mais je ne vise pas des projets commerciaux, mais plutôt des projets non commerciaux. (Genre des amateurs tel que moi qui recherchent un moteur à la fois flexible et simple)

    Et maintenant tu viens demander des conseils, après la manière dont tu t'es comporté, n'espère clairement pas avoir de l'aide de ma part.
    Ok, aucun problème.

    Comment espères vendre un moteur conçu par quelqu'un qui ne maîtrise visiblement pas le sujet ?
    Le moteur aura un énorme avantage, il permettra de faire des rendus tels que ceux utilisés par des projets commerciaux, mais sur des plateformes gratuites, plateformes utilisées par des gens qui ont peu de moyens financiers.
    Bref ça suffit de dire que je ne maîtrises pas le sujet je suis capable de trouver pleins de solutions en peu de temps donc je ne pense pas que je ne maîtrise pas le sujet au contraire pour les jeux 2D => aucun problème, c'est plutôt pour la 3D ou là, ça se complexifie et ou il n'y a pas encore vraiment de bonnes technos à ma connaissance à se sujet là à part des technologies ultra-complexes.

    (@skeud: je crois que la lib NVIDIA VXGI utilise un système de voxel et ray tracing pour les calculs d'illumination globale - c'est basé sur GigaVoxel de mémoire. Mais cela reste assez expérimental, je ne sais pas si c'est utilisé dans des jeux commerciaux)
    En effet tout ceci est encore, expérimental, mais je compte suivre la même voie que directX, de toute façon je ne vois pas l'intérêt de refaire un moteur comme ogre, unity ou autre.

    De toute façon il va falloir utiliser une autre technologie que opengl car, opengl ne permet pas de faire ça de manière optimale avec le CPU. :/

  3. #83
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 393
    Points : 685
    Points
    685
    Par défaut
    Citation Envoyé par Lolilolight Voir le message
    Pas pour les drivers opensource, et je pense pas que les projets commerciaux utilisent des drivers opensources, mais je ne vise pas des projets commerciaux, mais plutôt des projets non commerciaux. (Genre des amateurs tel que moi qui recherchent un moteur à la fois flexible et simple)
    Quoi ?
    Les projets (commerciaux ou non) ne fournissent pas les drivers, c'est les fabricants de GPU et les développeurs des systèmes d'exploitation qui les fournissent.
    Ceux qui développent des jeux/moteurs doivent se débrouiller pour que leur moteur tourne chez un maximum de client, quelque soit les drivers, la version d'OpenGL supportées, les capacités du GPU et du CPU...

    Citation Envoyé par Lolilolight Voir le message
    Le moteur aura un énorme avantage, il permettra de faire des rendus tels que ceux utilisés par des projets commerciaux, mais sur des plateformes gratuites, plateformes utilisées par des gens qui ont peu de moyens financiers.
    Euh... prouve le ! Pour le moment, tu n'as rien montré qui permet de penser que tu obtiens la même qualité de rendu (tu le dis toi même que tu as pleins de problèmes d'affichage, alors que tu es encore dans les choses simples)

    Citation Envoyé par Lolilolight Voir le message
    Bref ça suffit de dire que je ne maîtrises pas le sujet je suis capable de trouver pleins de solutions en peu de temps donc je ne pense pas que je ne maîtrise pas le sujet au contraire pour les jeux 2D => aucun problème, c'est plutôt pour la 3D ou là, ça se complexifie et ou il n'y a pas encore vraiment de bonnes technos à ma connaissance à se sujet là à part des technologies ultra-complexes.
    Pour la 2D, je n'ai rien vu qui me laisserais penser que ton moteur soit capable de gérer une rendu correct.

    Tu as parlé de pas mal de problématiques que tu as rencontré (multi-threads, OpenGL, etc) et pour le moment, ta solution a été de travailler sur un seul thread et uniquement sur CPU.
    En dehors du fait qu'il est fort probable que ton moteur soit peu performant, tu as surtout montré ton incapacité à surmonter les problèmes (et à utiliser 100% du potentiel du hardware).

    En gros, tu as éviter les problèmes techniques et tu as implémenté les algos de rendu 2D qui sont connus depuis 30 ans ? Difficile de vendre un moteur avec un tel argument.

    Sinon, beaucoup d'étudiants s'amusent à faire des projets 3D pendant leur études, voire des lycéens passionnés. C'est des techniques trop complexes pour toi, mais pas pour eux ?
    Tu veux devenir professionnel indépendant alors que l'on peut trouver des milliers d'étudiants plus compétents que toi ? (et je ne parle même pas quand ils auront 4-5 d'expérience pro derrière eux, ce seront de dieux face à toi...)

    Citation Envoyé par Lolilolight Voir le message
    De toute façon il va falloir utiliser une autre technologie que opengl car, opengl ne permet pas de faire ça de manière optimale avec le CPU. :/
    Là, on est d'accord : OpenGL n'est pas optimal pour travailler avec le CPU... C'est une erreur de frappe (tu parlais en fait du GPU) ou tu parles effectivement du CPU ?
    Parce que OpenGL, c'est pour bosser avec le GPU, alors qu'il ne soit pas optimal pour le CPU, on s'en moque un peu.

    Sinon, tu crois que NVIDIA s'amuserait à présenter des techniques qui n'ont pas besoin du GPU ? Leur but est quand même au final de vendre des GPU, donc ça serait un peu étrange qu'ils présentent des techniques non-GPU
    - Le commercial de NVIDIA : Oh, regardez, on arrive à avoir un meilleur rendu et on n'a même pas besoin de GPU pour faire cela.
    - Le boss de NVIDIA : T'es viré !

  4. #84
    Invité
    Invité(e)
    Par défaut
    Autant passé par des techniques non GPU, les GPU sont souvent sources de problèmes et comme tu le dis ont doit se débrouiller pour faire tourner sa sur un max de GPU, d'OS et de drivers qui sont, tous différents. :/

    Ce qui signifie, je suppose, différent également au niveau du code.

    En tout cas jusqu'à présent je n'ai pas été très satisfait des drivers, OS, et librairies développées, je trouve que c'était pas au point et beaucoup de code, de résultats inattendus, etc...

    DirectX a sûrement été fait pour le GPU, oui, mais le problème ne vient pas de opengl ou bien de directX mais de ce que j'ai cité plus haut.

    On doit se démerder pour faire tourner ça sur un max de drivers et d'os différents, et pour les rendus plus complexes c'est la galère.

    Les étudiants voient sûrement des techniques plus complexe comme par exemple, la triangulations pour découper les polygones en triangles et faire des tests de collisions. (Chose que je suis actuellement entrain de faire)
    En tout cas il y en a qui devaient faire un moteur de raytracing un moment.

    Bref en tant qu'étudiant je peux te dire que on n'apprend rien au niveau de la programmation GPU!

    Je l'ai seulement découverte après les études, et je peux te dire que c'est beaucoup plus galère et que je comprend maintenant pourquoi on ne l'apprend pas.

    Le CPU, supporte les même techniques, peu importe la carte graphique, le driver et l'os utilisée, ce qui le rend beaucoup plus facilement programmable.

    Un étudiant je ne suis pas sûr qu'il aie une maîtrise totale des mathématiques, de la physique, et de la programmation comme moi.

    Et dans 4-5 ans j'aurai en plus des notions d'électroniques et d'infographistes et aussi peu être bien en son, donc, non, ils ne me surpasserons sûrement pas.

  5. #85
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 393
    Points : 685
    Points
    685
    Par défaut
    Citation Envoyé par Lolilolight Voir le message
    une maîtrise totale des mathématiques, de la physique, et de la programmation comme moi.


    Le gars, il a abandonné la programmation GPU et multithreads parce que c'était trop compliqué pour lui, mais il affirme qu'il maîtrise la programmation. Et quand tu parles de maîtrise des maths et de la physique, tu t'es arrêté aux équations à 2 inconnues et au mouvement d'un pendule, le reste était trop compliqué ?

    On va dire que j'ai mal lu et mal compris et que tu ne viens pas de te ridiculiser encore une fois...

    (En tout cas, je comprends mieux d'où vient ton incompétence : tu es trop arrogent pour voir ton incompétence et donc y remédier. Tout s'explique)

  6. #86
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Lolilolight t'as l'air d'un gros cave sur ton avatar, tu devrais le changer

  7. #87
    Membre éprouvé Avatar de maeiky
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2013
    Messages
    201
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2013
    Messages : 201
    Points : 976
    Points
    976
    Par défaut
    Si oui je pense que je vais faire comme toi, c'est à dire, tout au niveau du CPU. (Mais ça risque d'être complexe surtout pour la 3D. :/)
    Tout en CPU signifie faire de la rasterization. Mais, je fais tout CPU en option, entre autre pour la portabilité. Tu dois comprendre la différence entre les 2, le CPU on perd en performance pour calculer les pixels un à un, sur GPU on perd en performance pour faire de la synchronisation.
    Le GPU est excellent pour pour travailler sur de petites choses en parallèle contrairement au CPU.

    J'ai commencer mon moteur tout en CPU, ensuite ajouté l’option GPU me semble aisé, pour moi c'est comme traduire un langage vers un autre. Quand l'affichage GPU est activé, je l'utilise au maximum, je mets le plus de calcul dans le vertex shader.

    Je pense entouré chaque objets d'un polygone (ou bien d'une sphere ou bien une boîte englobante, peu importe) et chercher l'intersection avec le rayon et enfin, calculer la couleur du pixel, cependant, j'aurai besoin de quelques conseils surtout pour recalculer la couleur d'un pixel avec le CPU là ou le rayon touche l'objet.

    Dois je faire un screen de la scène, la sauver dans une image et changer sa couleur ?
    Il faut donc une technologie capable de capturer une image et de récupérer ainsi les pixels de l’image.
    Je ne comprend pas ce que tu tente de faire? J'ai l'impression que tu tente de capturer un rendu GPU? Sinon, j’appelle ça un buffer.
    Linx, un nouveau langage intuitif
    Simacode IDE, auto-complétion & compilation instantané
    GZE, moteur 2d/3d multi-langage/multi-plateforme

  8. #88
    Invité
    Invité(e)
    Par défaut
    Oui je vais proposer les deux, rendus CPU et GPU, ainsi, si j'ai un problème avec le driver au niveau du GPU, je peux toujours désactivé cette option et activer l'option CPU.

    Bon j'ai pas abandonné la programmation GPU parce que c'était trop compliqué, mais simplement parce que la techno que j'utilise ne fonctionne pas alors quand c'est ça je l'abandonne.

    Et dieu seul sait combien il est difficile dans le monde libre de trouvé un bon driver pour le GPU. :/ (Surtout pour les scènes plus complexe. )

  9. #89
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Lolilolight Voir le message
    Bon j'ai pas abandonné la programmation GPU parce que c'était trop compliqué, mais simplement parce que la techno que j'utilise ne fonctionne pas alors quand c'est ça je l'abandonne.

    Et dieu seul sait combien il est difficile dans le monde libre de trouvé un bon driver pour le GPU. :/ (Surtout pour les scènes plus complexe. )
    Tu abandonnes car la techno que tu utilises ne fonctionne pas? J'aurais plutot tendance à dire que tu l'utilises mal ><.

    Difficile de trouver de bon driver? Alors pourquoi on arrive à faire tourner des jeu 3D sous linux facilement? Ils utilisent bien le driver eux pourtant. Donc on en revient au même point, avant de mettre en cause le driver, remet plutôt en cause ton code.

    Quand il y a un segfault, tu regardes bien ton code non? Avant de dire que c'est de la faute de l'OS....
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  10. #90
    Invité
    Invité(e)
    Par défaut
    Je préfère faire un moteur ou aucune connaissance de opengl, de la SDL ou encore de SFML n'est requise, le développeur pourra faire la même chose qu'avec opengl mais, tout les calculs de la lumière, des ombres, de la réfraction, de la disfraction, etc.., vont se faire au niveau du CPU, sans connaissance requise d'openGL.

    La création de contextes avec opengl est souvent buguée dans les environements multi-thread et en plus l'implémentation varie fort d'une plateforme à l'autre.

    Je ne parle même pas des shaders ou là c'est encore pire au niveau performances surtout pour les anciennes version d'opengl!

    Je sais qu'il y a des jeux en 3D qui tourne avec des GPU, mais, pour les scènes plus complexes, on est souvent bloqué, et au niveau des shaders il faut savoir comment fonctionne opengl qui comporte quand même,un bon paquets de fonctions et d'extensions qui en plus, ne sont pas toutes portable.

    Au niveaux des performances aussi c'est galère.

    Et puis la plupart des gros jeux en 3D que je connais ne tournent que sur PC ou bien sur playstation 4 pour les jeux de type AAA.

    Et ce n'est pas très compliqué d'affiché des scènes toute simple en 3D, mais pour des scènes plus complexe sur des plateformes variée avec des performances médiocre, ça devient vite galère.

  11. #91
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Lolilolight Voir le message
    Je préfère faire un moteur ou aucune connaissance de opengl, de la SDL ou encore de SFML n'est requise, le développeur pourra faire la même chose qu'avec opengl mais, tout les calculs de la lumière, des ombres, de la réfraction, de la disfraction, etc.., vont se faire au niveau du CPU, sans connaissance requise d'openGL.

    La création de contextes avec opengl est souvent buguée dans les environements multi-thread et en plus l'implémentation varie fort d'une plateforme à l'autre.

    Je ne parle même pas des shaders ou là c'est encore pire au niveau performances surtout pour les anciennes version d'opengl!

    Je sais qu'il y a des jeux en 3D qui tourne avec des GPU, mais, pour les scènes plus complexes, on est souvent bloqué, et au niveau des shaders il faut savoir comment fonctionne opengl qui comporte quand même,un bon paquets de fonctions et d'extensions qui en plus, ne sont pas toutes portable.

    Au niveaux des performances aussi c'est galère.

    Et puis la plupart des gros jeux en 3D que je connais ne tournent que sur PC ou bien sur playstation 4 pour les jeux de type AAA.

    Et ce n'est pas très compliqué d'affiché des scènes toute simple en 3D, mais pour des scènes plus complexe sur des plateformes variée avec des performances médiocre, ça devient vite galère.
    T'es quand meme au courant que 99,999999999999% des jeux tournent sur le GPU? et que 99,999999% des jeux n'étant pas sous windows sont fait avec opengl? Et que directX11 embarque une partie d'opengl par soucis de performance?

    Et puis la plupart des gros jeux en 3D que je connais ne tournent que sur PC ou bien sur playstation 4 pour les jeux de type AAA.
    oui et?

    le développeur pourra faire la même chose qu'avec opengl
    T'as de l'espoir toi .
    Création d'openGL: 1992. Et ils sortent toujours des versions à l'heure actuelle. Donc non, ton moteur ne permettra pas de faire la même chose qu'openGL.

    Plus je te lis, plus j'ai vraiment l'impression que tu te prends pour le dieu de la création de jeu (ou moteur graphique, comme tu veux). Il faut sincèrement que tu redescende sur terre, car là tu te ridiculise complètement. Autant je trouvais qu'avoir des discussion avec toi pouvait etre enrichissant il y a pas longtemps, mais après ce message..... Je me rends compte qu'en fait, tu n'as aucune connaissance dans ce domaine.
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  12. #92
    Invité
    Invité(e)
    Par défaut
    T'es quand meme au courant que 99,999999999999% des jeux tournent sur le GPU? et que 99,999999% des jeux n'étant pas sous windows sont fait avec opengl? Et que directX11 embarque une partie d'opengl par soucis de performance?
    Opengl ne sera utilisé que pour l'affichage de la framebuffer, mais rien de plus, tout les calculs se feront au niveau du CPU et plus dans des shaders qui bouffent max performances. (surtout avec des ifs)
    En plus il faut faire du découpage de polygones convexes pour la gestion de la semi-transparence et du tri ce qui bouffe aussi les perfs.

    Le seul soucis c'est de pouvoir récupérer la couleur et la profondeurs des fragments, sans utiliser de shaders, mais pour ça, j'ai une idée ou j'implémente mon propre système de rasterizer.

    T'as de l'espoir toi .
    Création d'openGL: 1992. Et ils sortent toujours des versions à l'heure actuelle. Donc non, ton moteur ne permettra pas de faire la même chose qu'openGL.

    Plus je te lis, plus j'ai vraiment l'impression que tu te prends pour le dieu de la création de jeu (ou moteur graphique, comme tu veux). Il faut sincèrement que tu redescende sur terre, car là tu te ridiculise complètement. Autant je trouvais qu'avoir des discussion avec toi pouvait etre enrichissant il y a pas longtemps, mais après ce message..... Je me rends compte qu'en fait, tu n'as aucune connaissance dans ce domaine.
    Hum, je pense que je me suis mal exprimé, le moteur utilisera encore opengl, mais, plus pour les calculs (blending, calcul pour la lumière, calcul pour les ombres, etc...)

    Donc tout mes if qui sont actuellement exécuté dans mes shaders vont être exécuté par le CPU.

    Même chose pour les textures, qui vont être, calculée avec le CPU, puis passée au GPU, car sampler2D c'est assez lent également.

    Mais oui tu as raison à ce niveau là, je n'ai pas beaucoup de connaissances. (Au niveau de l'OS)

  13. #93
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Ah bah voilà, on va y arriver à ce que tu entendes ce que j'essaye de t'expliquer depuis plusieurs jours.

    Effectivement, tes shaders n'étaient pas correct (tu viens seulement de l'avouer, et encore, à demi-mot). Donc tu revois ta manière de fonctionner.

    Tu utilises toujours openGL, mais tu devrais l'utiliser complètement, openGL sera toujours meilleur que toi pour faire ce pour quoi cette lib a été programmer, à savoir:
    _ Affichage de polygone
    _ Gestion des lumière
    ....

    Donc n'essaye pas de le faire de ton coté, tu n'y arriveras pas aussi bien qu'eux. Essaye plutot de reprendre ton code actuel, et le modifier afin de prendre en compte les remarques qu'on te fait depuis plusieurs jour, de cette manière tu auras un moteur beaucoup plus puissant et qui s'orientera vers ce que tu veux .

    Il ne faut surtout pas que tu supprimes les shader, c'est la manière la plus optimisé pour modifier une surface de base en surface complexe.
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  14. #94
    Invité
    Invité(e)
    Par défaut
    Ok mais comment faire alors pour gérer, la semi-transparence. (surtout en 3D)

    Si je ne fais pas ça dans un shader je dois reconstruire mes polygones côté CPU et ça va me bouffer pas mal de perfs car l'algorithme est complexe. :/

    Et en plus mon code qui tente de gérer al semi-transparence avec les shaders ne fonctionne pas. :/

    Et puis dès que j'utilise un shader j'ai mon FPS qui baisse de moitié hors que quand j'en utilise pas tout va bien.

    Ce n'est pas que le FPS est tellement bas que ça devient injouable mais comme tu me l'as si bien dis 15 FPS c'est très juste, et si je peux passer a 30, voir même à 60 FPS ça serait bien, bref, je pense que je vais essayer de faire des tests en modifiant mon code existant et ensuite, je prendrais ce qui est le plus performant.

    Mais la gestion du z avec la transparence dans le fragment shader c'est la galère surtout avec le blending. :/ (Et en plus ce n'est pas portable)

    Avec les nouvelles formules de blending de SFML, c'est encore pire et je n'arrive pas du tout à avoir la bonne couleur pour mes pixels. :/

    J'ai essayé d'appliqué un blendNone pour les composantes rgb et un blendalpha pour la composante a mais ça ne fonctionne pas.

    Bref, j'ai essayé pleins de choses avec les shaders, mais on dirait que pour le z des fragments, je n'ai tout simplement pas les bonnes valeurs, et pour le blending également. :/

    Et bon comme je ne sais pas les calculs que opengl fait derrière ça m'embête vraiment.

  15. #95
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    La transparence n'est pas géré dans le shader.

    voici un exemple sur l'utilisation de la transparence pour un cube.

    Je le redis encore, les shader ne sont là que pour modifier l'apparence de la surface de ton objet, et non pas effectué des calculs et autres trucs du genre.

    En gros, le principe du shader c'est de dire:
    Pour chaque pixel de la surface de mon polygone, effectué des action afin de modifier:
    _ l'emplacement du pixel
    _ la normal de la surface à cet endroit.
    _ La variable de reflection (entre 1 et 0)
    _ La variable de refraction (pour refléchir la lumière, entre 1 Et 0 aussi)
    _ La variable de transparence (entre 1 et 0).

    Et point barre, il ne doit rien faire d'autre. Si tu utilises comme il faut les shader, tu n'auras pas de perte de perf significatives car il utilise des opérations simple type:
    pour le pixel en coordonnée X/Y prendre les valeurs dans la map X/Y pour chaque composante via les différentes map (bumpmap, ....).

    Il faut bien comprendre comment fonctionne un moteur graphique et je t'invite clairement à aller regarder sur internet le fonctionnement concernant les couleurs, car c'est la dessus que tu sembles avoir le plus de mal:
    _ Un moteur de rendu utilise une liste d'objet.
    Ces objets ont différentes propriété:
    _ La position des sommet (afin de calculer les intersection et l'affichage sur la fenêtre) -> c'est géré par openGL.
    _ La couleur de la matière -> c'est géré par openGL
    _ Les primitive de ton objet -> c'est géré par openGL
    _ La modification de la surface de l'objet -> C'est géré par les shader
    _ La transparence/reflexion -> C'est géré par openGL.

    Donc tu vois bien que dans ton code, tu ne dois avoir que la déclaration des objet, et des shader, le reste tu ne dois pas faire de calcul la dessus.
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  16. #96
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 393
    Points : 685
    Points
    685
    Par défaut
    Prendre un tuto a jour plutot qu'OpenGL 1 sans shader. Par exemple http://www.opengl-tutorial.org/inter...-transparency/ (ils sont traduit sur Dvp)

    Je suis pas forcement fan de la distinction OpenGL/Shader. Dans tous les cas, le driver OpenGL ne fait que balancer des donnees au GPU et il fait tous les calculs. (pour le blend, tu definies la fonction dans le code hote, mais l'execution est faite cote GPU)

  17. #97
    Invité
    Invité(e)
    Par défaut
    Mais il faut trier les triangles du plus opaques au moins opaque et puis que fais tu si les polygones de tes objets ne sont pas convexe, donc, si les triangles se croisent, lesquels afficher en 1er ?

    tu dois décomposer les triangles de tout tes objets en plusieurs polygone convexes, ce qui est vraiment coûteux!

    Pour optimiser, j'ai tenter de faire des ifs dans les shaders sur la composante alpha de chaque fragments, mais ce n'est pas optimal non plus. :/

    Alors la seule solution que j'ai trouvée c'est de créer les buffers et faire les tests pour chaque fragment avec le CPU, et charger tout dans une grande image que j'affiche à chaque frame.

    Et si je les trie avec le z pareil, en plus le z de chaque triangles change en fonction de l'orientation de la caméra. :/
    Dernière modification par Invité ; 20/01/2015 à 18h53.

  18. #98
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 393
    Points : 685
    Points
    685
    Par défaut
    L'ordre des éléments pour la transparence est un problème classique, tu trouves pas mal de doc sur le sujet> Et il existe techniques de transparence sans avoir besoin de réordonner (cf order-independent transparency).

    Pour les if, oui c'est pas optimal sur GPU (branch divergence), mais :
    1. est-ce que ca sera plus rapide sur CPU => non, a moins de cumuler les erreurs de code sur GPU
    2. est-ce qu'il existe des techniques evitant les if sur GPU => oui


    Mais, c'est en faisant des erreurs que l'on apprend...

  19. #99
    Invité
    Invité(e)
    Par défaut
    L'order independant transparency t'oblige quand même à dessiner les objets opaques d'abord. :/

    Pour l'instant la seule solution que j'ai pu trouvé, c'est avec un if. :/

    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
     
    math::Vec3f srcColor = math::Vec3f(r.x * u + r.y * v + r.z * w,
                                                         g.x * u + g.y * v + g.z * w,
                                                         b.x * u + b.y * v + b.z * w,
                                                         a.x * u + a.y * v + a.z * w) * texColor;
    float srcAlpha = srcColor.w;
    math::Vec3f dstColor = math::Vec3f(frameBuffer[(y * size.x + x)*4] / 255.f,
                                                         frameBuffer[(y * size.x + x)*4+1] / 255.f,
                                                         frameBuffer[(y * size.x + x)*4+2] / 255.f,
                                                         frameBuffer[(y * size.x + x)*4+3] / 255.f);
    float dstAlpha = depthBuffer[y * size.x + x].w;
    math::Vec3f finalColor;
    if (bz >= actualZ) {
           finalColor = srcColor * srcAlpha + dstColor * (1 - srcAlpha);
    } else {
           finalColor = dstColor * dstAlpha + srcColor * (1 - dstAlpha);
    }
    depthBuffer[y * size.x + x] = math::Vec3f(0, 0, bz, srcAlpha);
    frameBuffer[(y * size.x + x) * 4] = finalColor.x * 255;
    frameBuffer[(y * size.x + x) * 4 + 1] = finalColor.y * 255;
    frameBuffer[(y * size.x + x) * 4 + 2] = finalColor.z * 255;
    frameBuffer[(y * size.x + x) * 4 + 3] = finalColor.w * 255;
    Là je peux dessiner les objets opaques dans n'importe quel ordre :

    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
     
        Entity* entity = new Tile(&tex, Vec3f(0, 0, 30), Vec3f(120, 60, 0), sf::IntRect(0, 0, 100, 50));
        Entity* entity2 = new Tile(&tex, Vec3f(50, 25, 55), Vec3f(120, 60, 0), sf::IntRect(0, 0, 100, 50));
        Entity* entity3 = new Tile(nullptr, Vec3f(100, 50, 80), Vec3f(120, 60, 0), sf::IntRect(0, 0, 100, 50), sf::Color::Red);
        Entity* entity4 = new Tile(nullptr, Vec3f(150, 75, 105), Vec3f(120, 60, 0), sf::IntRect(0, 0, 100, 50), sf::Color::Yellow);
        Entity* entity5 = new Tile(&tex, Vec3f(200, 100, 130), Vec3f(120, 60, 0), sf::IntRect(0, 0, 100, 50));
        std::vector<Entity*> entities = {entity5, entity4, entity3, entity2, entity};
        sf::Clock clock;
        unsigned int fps = 0;
        while (window.isOpen())
        {
             sf::Event event;
             while(window.pollEvent(event)) {
                   if (event.type == sf::Event::Closed)
                        window.close();
             }
             window.clear();
             CPURenderComponent cpu(Vec3f(0, 0, 0), Vec3f(800, 600, 0),Vec3f(400, 300, 0), false, window);
             cpu.clear();
             cpu.loadEntitiesOnComponent(entities);
             cpu.drawNextFrame();
             window.draw(cpu);
             window.display();
         }
    Ce qui me donne le bon résultat, à part que il y a une ligne entre les 2 triangles mais ça c'est normal : je n'ai pas encore effectuer de multisampling.

    Pièce jointe 166884

    Mais le soucis est que, avec le cpu ce n'est pas très optimisé, je tombe a 30 FPS juste pour afficher 10 triangles avec ce bout de code.

    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
    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
     
    void CPURenderComponent::drawNextFrame() {
                for (unsigned int i = 0; i < m_instances.size(); i++) {
                    for (unsigned int j = 0; j < m_instances[i]->getVertexArrays().size(); j++) {
                        TransformMatrix& tm = m_instances[i]->getTransforms()[j].get();
                        for (unsigned int k = 0; k < m_instances[i]->getVertexArrays()[j]->getVertexCount(); k++) {
                            math::Matrix4f texM;
                            math::Matrix4f invTexM;
                            if (m_instances[i]->getMaterial().getTexture() != nullptr) {
                                texM = m_instances[i]->getMaterial().getTexture()->getTextureMatrix();
                                invTexM = texM.inverse();
                            }
                            if (m_instances[i]->getVertexArrays()[j]->getPrimitiveType() == sf::TrianglesFan
                                && m_instances[i]->getVertexArrays()[j]->getVertexCount() >= 3
                                && k < m_instances[i]->getVertexArrays()[j]->getVertexCount() - 2) {
                                math::Vec3f p1 = math::Vec3f((*m_instances[i]->getVertexArrays()[j])[0].position.x,(*m_instances[i]->getVertexArrays()[j])[0].position.y,(*m_instances[i]->getVertexArrays()[j])[0].position.z);
                                math::Vec3f p2 = math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+1].position.x,(*m_instances[i]->getVertexArrays()[j])[k+1].position.y,(*m_instances[i]->getVertexArrays()[j])[k+1].position.z);
                                math::Vec3f p3 = math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+2].position.x,(*m_instances[i]->getVertexArrays()[j])[k+2].position.y,(*m_instances[i]->getVertexArrays()[j])[k+2].position.z);
                                p1 = tm.transform(p1);
                                p2 = tm.transform(p2);
                                p3 = tm.transform(p3);
                                p1 = window.mapCoordsToPixel(p1, view);
                                p2 = window.mapCoordsToPixel(p2, view);
                                p3 = window.mapCoordsToPixel(p3, view);
                                sf::Color c1 = (*m_instances[i]->getVertexArrays()[j])[0].color;
                                sf::Color c2 = (*m_instances[i]->getVertexArrays()[j])[k+1].color;
                                sf::Color c3 = (*m_instances[i]->getVertexArrays()[j])[k+2].color;
                                math::Vec3f ct1 = texM * math::Vec3f((*m_instances[i]->getVertexArrays()[j])[0].texCoords.x,(*m_instances[i]->getVertexArrays()[j])[0].texCoords.y, 1.f);
                                math::Vec3f ct2 = texM * math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+1].texCoords.x,(*m_instances[i]->getVertexArrays()[j])[k+1].texCoords.y, 1.f);
                                math::Vec3f ct3 = texM * math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+2].texCoords.x,(*m_instances[i]->getVertexArrays()[j])[k+2].texCoords.y, 1.f);
                                std::array<math::Vec3f, 3> vertices = {math::Vec3f(p1.x, p1.y, 0),math::Vec3f(p2.x, p2.y, 0), math::Vec3f(p3.x, p3.y, 0)};
                                std::array<std::array<float, 2>, 3> extends = math::Computer::getExtends(vertices);
                                float minX = (extends[0][0] < 0) ? 0 : extends[0][0];
                                float minY = (extends[1][0] < 0) ? 0 : extends[1][0];
                                float maxX = (extends[0][1] >= size.x) ? size.x-1 : extends[0][1];
                                float maxY = (extends[1][0] >= size.y) ? size.y-1 : extends[1][1];
                                for (unsigned int x = minX; x < maxX; x++) {
                                    for (unsigned int y = minY; y < maxY; y++) {
                                        math::Vec2f p(x, y);
                                        float det1 = (x - p1.x) * (p2.y - p1.y) - (y - p1.y) * (p2.x - p1.x);
                                        float det2 = (x - p2.x) * (p3.y - p2.y) - (y - p2.y) * (p3.x - p2.x);
                                        float det3 = (x - p3.x) * (p3.y - p1.y) - (y - p3.y) * (p3.x - p1.x);
                                        bool isInside = ((det1 <= 0 && det2 <= 0 && det3 >= 0)
                                                         || det1 >= 0 && det2 >= 0 && det3 <= 0) ? true : false;
     
                                        if (isInside) {
     
                                            math::Matrix2f m1(p1.x - p3.x, p2.x - p3.x,
                                                              p1.y - p3.y, p2.y - p3.y);
                                            float u = ((p2.y - p3.y) * (p.x - p3.x) + (p3.x - p2.x) * (p.y - p3.y)) / m1.getDet();
                                            float v = ((p3.y - p1.y) * (p.x - p3.x) + (p1.x - p3.x) * (y - p3.y)) / m1.getDet();
                                            float w = math::Math::abs(1 - u - v);
                                            math::Vec3f z (p1.z, p2.z, p3.z);
                                            float bz = z.x * u + z.y * v + z.z * w;
                                            float actualZ = depthBuffer[y * size.x + x].z;
                                            if (bz >= view.getViewport().getPosition().z && bz <= view.getViewport().getSize().z) {
                                                math::Vec3f tcx = math::Vec3f(ct1.x, ct2.x, ct3.x);
                                                math::Vec3f tcy = math::Vec3f(ct1.y, ct2.y, ct3.y);
                                                math::Vec3f tc = invTexM * math::Vec3f(tcx.x * u + tcx.y * v + tcx.z * w,
                                                                             tcy.x * u + tcy.y * v + tcy.z* w, 1.f);
                                                math::Vec3f texColor(1.f, 1.f, 1.f, 1.f);
                                                if (m_instances[i]->getMaterial().getTexture() != nullptr) {
                                                    const sf::Image& texImg = m_instances[i]->getMaterial().getTexture()->getImage();
                                                    sf::Color color = texImg.getPixel(tc.x, tc.y);
                                                    texColor = math::Vec3f (color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f);
                                                }
                                                math::Vec3f r = math::Vec3f (c1.r / 255.f, c2.r / 255.f, c3.r / 255.f);
                                                math::Vec3f g = math::Vec3f (c1.g / 255.f, c2.g / 255.f, c3.g / 255.f);
                                                math::Vec3f b = math::Vec3f (c1.b / 255.f, c2.b / 255.f, c3.b / 255.f);
                                                math::Vec3f a = math::Vec3f (c1.a / 255.f, c2.a / 255.f, c3.a / 255.f);
                                                math::Vec3f srcColor = math::Vec3f(r.x * u + r.y * v + r.z * w,
                                                                                    g.x * u + g.y * v + g.z * w,
                                                                                    b.x * u + b.y * v + b.z * w,
                                                                                    a.x * u + a.y * v + a.z * w) * texColor;
                                                float srcAlpha = srcColor.w;
                                                math::Vec3f dstColor = math::Vec3f(frameBuffer[(y * size.x + x)*4] / 255.f,
                                                                                   frameBuffer[(y * size.x + x)*4+1] / 255.f,
                                                                                   frameBuffer[(y * size.x + x)*4+2] / 255.f,
                                                                                   frameBuffer[(y * size.x + x)*4+3] / 255.f);
                                                float dstAlpha = depthBuffer[y * size.x + x].w;
                                                math::Vec3f finalColor;
                                                if (bz >= actualZ) {
                                                    finalColor = srcColor * srcAlpha + dstColor * (1 - srcAlpha);
                                                } else {
                                                    finalColor = dstColor * dstAlpha + srcColor * (1 - dstAlpha);
                                                }
                                                depthBuffer[y * size.x + x] = math::Vec3f(0, 0, bz, srcAlpha);
                                                frameBuffer[(y * size.x + x) * 4] = finalColor.x * 255;
                                                frameBuffer[(y * size.x + x) * 4 + 1] = finalColor.y * 255;
                                                frameBuffer[(y * size.x + x) * 4 + 2] = finalColor.z * 255;
                                                frameBuffer[(y * size.x + x) * 4 + 3] = finalColor.w * 255;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                winFrameBuffer.create(size.x, size.y, &frameBuffer[0]);
                fbTexture.loadFromImage(winFrameBuffer);
            }
    J'ai essayé aussi d'afficher le tout avec le GPU et un shader mais là ça ne fonctionne pas, j'ai des lignes noires entre mes textures. :/

    Par contre le FPS est bien sûr plus élevé.

    Voici les 2 rendus que j'obtiens (et pourtant, le code est le même, voici le code de mes shaders : )
    Et j'ai bien désactivé le blending.

    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    std::cout<<"version 130"<<std::endl;
                       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 depthGenFragShader =
                            "#version 130 \n"
                            "uniform sampler2D depthBuffer;"
                            "uniform sampler2D texture;"
                            "uniform vec3 resolution;"
                            "uniform float haveTexture;"
                            "uniform float maxM;"
                            "uniform float maxP;"
                            "uniform float m;"
                            "uniform float p;"
                            "in mat4 projMat;"
                            "void main () {"
                                  "vec2 position = ( gl_FragCoord.xy / resolution.xy );"
                                  "vec4 color = texture2D(depthBuffer, position);"
                                  "vec4 pixel = (haveTexture==1) ? gl_Color * texture2D(texture, gl_TexCoord[0].xy) : gl_Color;"
                                  "float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;"
                                  "float intensity = (maxM != 0) ? m / maxM : 0.f;"
                                  "float power = (maxP != 0) ? p / maxP : 0.f;"
                                  "/*if (z >= color.z) {*/"
                                      "gl_FragColor = vec4(intensity, power, z, pixel.a);"
                                  "/*} else {"
                                      "gl_FragColor = color;"
                                  "}*/"
                            "}";
                        const std::string frameBufferGenFragShader =
                            "#version 130 \n"
                            "uniform sampler2D depthBuffer;"
                            "uniform sampler2D frameBuffer;"
                            "uniform sampler2D texture;"
                            "uniform vec3 resolution;"
                            "uniform float haveTexture;"
                            "in mat4 projMat;"
                            "void main () {"
                                "vec2 position = ( gl_FragCoord.xy / resolution.xy );"
                                "vec4 depth = texture2D(depthBuffer, position);"
                                "vec4 color = texture2D(frameBuffer, position);"
                                "vec4 pixel = (haveTexture==1) ? gl_Color * texture2D(texture, gl_TexCoord[0].xy) : gl_Color;"
                                "float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;"
                                "float srcAlpha = pixel.a;"
                                "float dstAlpha = depth.a;"
                                "if (z >= depth.z) {"
                                    "gl_FragColor = pixel * srcAlpha + color * (1 - srcAlpha);"
                                "} else {"
                                    "gl_FragColor = color * dstAlpha + pixel * (1 - dstAlpha);"
                                "}"
                            "}";
    Et voici ce que j'obtiens :

    Nom : Capture du 2015-01-21 15:39:34.png
Affichages : 204
Taille : 170,9 Ko

    Pourquoi n'ai je pas le même résultat avec un rendu CPU et un rendu GPU ?

    Les 2 codes sont pourtant les même il me semble!

  20. #100
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 211
    Points
    23 211
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (bz >= actualZ) {
           finalColor = srcColor * srcAlpha + dstColor * (1 - srcAlpha);
    } else {
           finalColor = dstColor * dstAlpha + srcColor * (1 - dstAlpha);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    bool src=(bz >= actualZ);
    
    finalColor = color[src] * alpha[src] + color[!src] * (1 - alpha[src]);


    Que tu peux encore réécrire en somme de produits.

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