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

OpenGL Discussion :

[FBO+GLSL]rendu dans plus d'une texture à la fois


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Par défaut [FBO+GLSL]rendu dans plus d'une texture à la fois
    Salut, je suis en train de programmer un petit test de deferred shading (ou plutôt de post-processing généralisé) et je cherche à savoir comment on peut écrire dans plus d'une texture à la fois via FBO.
    Genre, je veux avoir une texture avec les couleurs, une avec les normales en tant que couleurs, et une avec la luminosité diffuse.

    Qu'est-ce que je dois mettre en place du côté GL-API et du côté shader GLSL ?
    (puis, idem avec Cg juste pour l'info).

  2. #2
    Membre éclairé
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Par défaut
    J'avais espéré au moins une réponse...

    enfin bon, un peu de Google et j'ai trouvé plus ou moins ce qu'il me fallait.
    http://www.gamedev.net/reference/pro...features/fbo2/
    http://www.opengl.org/discussion_boa...&Number=238733

    'fin bref, avant de marquer ce thread comme résolu, voici la réponse à mes questions:

    du côté API, il faut créer le FBO:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    GLuint fbo;
    glGenFramebuffersEXT(1, &fbo);
    et les textures: (considérons que nous avons défini un enum, dont les valeurs de 0 à N-1 représentent nos Render targets, et N est définie comme RenderTargetCount).
    (notez que RenderTargetCount doit être <= GLuint maxbuffers;
    glGetIntergeri(GL_MAX_COLOR_ATTACHMENTS, &maxbuffers)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    GLuint rendertargets[RenderTargetCount];
    glGenTextures(RenderTargetCount, rendertargets);
    for(u32 i = 0; i < RenderTargetCount; i++)
    {
      glBindTexture(GL_TEXTURE_2D, rendertargets[i]);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    }
    (nota: je laisse le format de texture en RGBA8 par défaut, mais en fait, il faudrait le définir en rapport au format optimal de ce target).

    ensuite, nous définissons nos textures comme
    RenderBuffer (eTargetColor) du FBO:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, rendertargets[eTargetColor], 0);
    Depthbuffer (eTargetDepth) du FBO:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, rendertargets[eTargetDepth], 0);
    puis d'autres buffers (genre les normales, la lumière ambiente, diffuse, speculaire, les ombres, etc)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENTn_EXT, GL_TEXTURE_2D, rendertargets[eBufferID], 0);

    puis tester si tout a foncmtionné:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

    ne pas oublier d'activer (lier) les objets ainsi créés avant leur utilisation
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

    avant de passer au rendu (tout à fait classique), il faudra faire comprendre à OpenGL dans quel ordre viennent nos targets.
    par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
    si nous ne voulons qu'utiliser par exemple notre eTargetNormal
    ou alors comme ceci pour plus d'un render target
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
    glDrawBuffers(2, buffers);
    dans notre cas, ca devrait donner ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    GLenum buffers[RenderTargetCount];
    buffers[eTargetColor] = GL_COLOR_ATTACHMENT0_EXT;
    //buffers[eTargetDepth] = GL_DEPTH_ATTACHMENT_EXT;
    for(u32 i = eTargetNormal; i < RenderTargetCount; i++)
    {
      buffers[i] = GL_COLOR_ATTACHMENT0_EXT + i;
    }
    glDrawBuffers(RenderTargetCount, buffers);

    pour reutiliser les textures, il faudra les activer et par exemple les rendre sur un simple quad la taille de votre fenêtre.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glBindTexture(GL_TEXTURE_2D, rendertarget[x]);


    (ne pas oublier aussi de détruire ce que vous créez)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    glDeleteFramebuffersEXT(1, &fbo);
    glDeleteTexture(RenderTargetCount, rendertarget);

    du côté GLSL, ou plus précisement dans le fragment shader, nous adressons les registres des différents targets comme avec gl_FragData[n], où n représente l'index dans les buffers définis ci-dessus et passés à l'API via glDrawBuffers(RenderTargetCount, buffers).
    donc par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    gl_FragData[0] = color;
    gl_FragData[1] = normal;
    gl_FragData[2] = litDiff;
    gl_FragData[3] = litAmb;
    gl_FragData[4] = litSpec;

    voilà, en fait, c'est assez simple comme procédure. Bien sûr, il faudra ajouter du post-processing aux textures ainsi obtenues, mais l'essentiel y est.
    (Ah oui, mon code est écrit comme ca, j'ai rien testé chez moi, donc ne comptez pas sur sa validité, il se peut qu'il y ait des erreurs. C'est une compilation de plusieurs autres tutoriaux sur ce sujet).

    Ce qui m'étonne tout de même après coup, ce qu'il semble y avoir peu de monde ici à utiliser les render targets. M'enfin, en espérant que ce petit tuto vous aide, vous ici.

  3. #3
    Membre très actif

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Par défaut


    tu as oublié les min et mag filter des textures où tu fais ton render

    si tu ne les set pas ça ne marchera pas quand tu voudras les utiliser en tant que vraies texture

  4. #4
    Membre éclairé
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Par défaut
    acx01b> merci de me le faire remarquer, mais tu auras certainement compris que l'essentiel de mon code ne réside pas dans la création de textures valides, mais dans l'utilisation de celles en tant que render target.

  5. #5
    Membre très actif

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Par défaut
    ben tu te pleignais de ne pas avoir beaucoup de participation à ton post sur les fbo !

    en fait j'ai regardé si tu ne mets pas les min et mag filter à tes texture ton fbo ne sera pas valide

    pour vérifier que le fbo est valide:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) 
    {
       // fbo non valide ...
       exit(1);
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/12/2014, 09h48
  2. Réponses: 2
    Dernier message: 21/09/2009, 20h44
  3. Réponses: 0
    Dernier message: 24/02/2009, 04h36
  4. FBO, et rendu 2D dans texture
    Par Rastacouéne dans le forum OpenGL
    Réponses: 1
    Dernier message: 10/12/2008, 11h44
  5. Directx 8 Probleme avec setrenderTarget pour un rendu du monde sur une texture
    Par zerailkiller dans le forum Développement 2D, 3D et Jeux
    Réponses: 7
    Dernier message: 14/01/2007, 13h50

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