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 :

[FBOs, Renderbuffers et depth]


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Inscrit en
    Mai 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 3
    Par défaut [FBOs, Renderbuffers et depth]
    Bonjour,

    Je suis depuis un moment ce qui se passe dans ce board, mais n'ai jamasi vraiment posté. Pour mon premier, j'aurais besoin d'un conseil.

    Je cherche à utiliser les Renderbuffers pour générer un depth buffer et m'en servir comme masque sur fragments par la suite.

    Après la génération de mon FBO, je génère donc mon Renderbuffer de cette façon:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    GLuint depth;
    glGenRenderbuffersEXT(1, &depth);
    //initialize depth renderbuffer
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H);
    Ensuite,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //bind fbo
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
    //attach one texture
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_RECTANGLE_ARB, Tex.id, 0);
    //attach depth
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth);
    Le status du FBO est ici complet.

    Ensuite, je cherche à initialiser mon depth buffer à une certaine valeur, à activer le test de depth, désactiver l'écriture dans le depth buffer, ce que je fais par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    glClearDepth(1.0);	    // Set clearing value for depth
    glEnable(GL_DEPTH_TEST);	// Enable depth testing
    glDepthFunc(GL_LESS);	// Choose depth comparison function
    glDepthMask(GL_FALSE);		// Disable depth buffer writing
    glClear(GL_DEPTH_BUFFER_BIT);	// Clear depth buffer
    Les valeurs retournées par mon fragment program varient en augmentant de 0 à 1, je veux donc ne plus rien calculer sur les fragments donc le z est passé au dessus de 1.

    Mon problème est qu'ici, aucun fragment n'est calculé.
    En changeant la fonction de test de GL_LESS à GL_GREATER, les fragments sont tous calculés. Je pense donc que les valeurs dans le depth buffer ne sont pas les bonnes, mais je ne sais pas pourquoi.
    Par ailleurs, si je change la valeur que je veux mettre dans mon masque et que j'essaye de la demander (par gLGetFloatv() par exemple), j'obtiens toujours 1...

    Est-ce qu'il manque quelque chose pour initialiser correctement ces valeurs ? Par ailleurs, y a-t-il un moyen de tester les valeurs dudit depth buffer ?

    Merci d'avance !

  2. #2
    Membre éprouvé Avatar de razmott
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 133
    Par défaut
    Salut !

    La première chose à faire serait de nous passer le code complet, à commencer par le pixel shader !
    Les valeurs retournées par mon fragment program varient en augmentant de 0 à 1, je veux donc ne plus rien calculer sur les fragments donc le z est passé au dessus de 1.
    Je ne vois pas trop comment tu as fait .

    De plus nous n'avons pas le code d'intialisation du Framebuffer !
    Et je te signale que tu n'effectues aucun test de retour de fonction.

    Bon courage tout de même !

    @+

  3. #3
    Candidat au Club
    Inscrit en
    Mai 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 3
    Par défaut
    Merci de ta réponse !

    En effet, j'aurais pu commencer par proposer le code du pixel shader, le voici:
    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
    float3 main (
    	in float2 coords : TEXCOORD0,
    	uniform samplerRECT Tex,
    	uniform float a,
    	uniform float c, 
    	uniform float mu,
    	uniform float dt,
    	uniform float sigma,
    	uniform float theta,
    	uniform float pi,
    	uniform int m
    						)  : COLOR
    { 
    	float3 input = texRECT(Tex, coords);   // Getting data back
    	float3 output;
    
    	// Generating 2 pseudorandom uniform floating numbers in [0,1] from .z
    	//  the second one is stored in the .z and will be used in the next iteration
    	float x = (a*input.x+c);
    	x = x-m*floor(x/m);
    	float y = (a*x+c);
    	y = y-m*floor(y/m);
    	output.x = y;
    
    	// Generating a gaussian random number
    	float gaussian_random = sqrt(-2*log(x/m))*cos(2*pi*y/m);
    	output.z = input.z + mu*dt + sigma*sqrt(dt)*gaussian_random;
    
    	// Iteration counter
    	output.y = input.y+1;
    	return output;
    }
    La seule ligne importante est celle en gras: la valeur initiale est à 0, elle est incrémentée par ce shader d'une valeur aléatoire tirée sur une gaussienne centrée en mu*dt (le reste du code).
    Cela ne sert bien sûr absolument pas à de l'affichage, mais à du calcul pur paralléllisé (GPGPU).
    Une fois qu'un fragment a atteint la valeur 1 sur son canal 'z', je veux désactiver son rendu pour les passes suivantes, via un depth buffer.

    Ensuite, le code d'initialisation du FBO est simplement le suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    GLuint fbo;
    glGenFramebuffersEXT(1,&fbo);
    Les deux autres appels nécessaires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_RECTANGLE_ARB, Tex.id, 0);
    sont effectué en même temps que l'init du depth buffer (cf. le deuxième morceau de code de mon précédent message), je ne pense pas que ça gêne beaucoup.

    Le programme fonctionne en l'état, mais pour des raisons de performance, il me faut vraiment utiliser un depth buffer
    L'autre solution consiste à utiliser des Occlusion Queries: simples à mettre en place mais pas assez efficaces: le test se fait dans le shader, ce qui suppose qu'il a été lancé, d'où perte de temps...

    Ensuite, un simple rendu en boucle d'un rectangle de la taille de ma texture (méthode classique de GPGPU):
    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
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, w, 0.0, h);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glViewport(0, 0, w, h);
    glPolygonMode(GL_FRONT,GL_FILL);
    glBegin(GL_QUADS);
    	glTexCoord2f(0.0, 0.0); 
    	glVertex2f(0.0, 0.0);
    	glTexCoord2f(w, 0.0); 
    	glVertex2f(w, 0.0);
    	glTexCoord2f(w, h); 
    	glVertex2f(w, h);
    	glTexCoord2f(0.0, h); 
    	glVertex2f(0.0, h);
    glEnd();
    et je récupère à chaque itération mes données dans les textures par un appel à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
    glReadPixels(0,0,w,h,GL_RGB,GL_FLOAT,XDepth);	// XDepth = buffer tampon

    Avec ce code, je n'ai donc toujours pas de bonne valeur dans mon depth buffer, malgré, initialement, le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    glClearDepth(42.0);		// Set clearing value for depth			
    glClear(GL_DEPTH_BUFFER_BIT);	   // Clear depth buffer
    En testant par la suite la valeur avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    GLfloat res;
    glGetFloatv(GL_DEPTH_CLEAR_VALUE, &res);
    j'obtiens toujours 1 au lieu de la valeur spécifiée...

    Quelque chose est certainement oublié, mais quoi ? Mystère pour moi...

    PS: je n'avais pas indiqué les test sur les erreurs GL et FBO (glGetError() et glCheckFramebufferStatusEXT()), mais je les fais.

  4. #4
    Candidat au Club
    Inscrit en
    Mai 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 3
    Par défaut
    Les débuts en OpenGL sont bien difficiles...
    En fait j'oubliais que la "Depth Clear Value" est clampée entre 0 et 1...

    Néanmoins, cela ne fonctionne pas pour autant: après un réordonnancement bénéfique de 2 lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    glClear(GL_DEPTH_BUFFER_BIT);	// Clear depth buffer
    glDepthMask(GL_FALSE);			     // Disable depth buffer writing
    (autant écrire dans le depth buffer puis bloquer l'écriture...), voilà que l'application de ce masque ne fonctionne toujours pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    glClearDepth(0.6);	     // Set clearing value for depth
    glEnable(GL_DEPTH_TEST);	  // Enable depth testing
    glDepthFunc(GL_LEQUAL);		  // Choose depth comparison function
    glClear(GL_DEPTH_BUFFER_BIT);	// Clear depth buffer
    glDepthMask(GL_FALSE);		   // Disable depth buffer writing
    // Le reste est inchangé
    Mon incrémentation du 'z' de la texture se fait correctement, mais lorsqu'elle dépasse ici la valeur 0.6 (dans la texture de depth logiquement), le calcul se s'arrête pas, le fragment n'est toujours pas discardé.

    Est-ce que la valeur pourrait ne pas être bien passée au depth buffer ? L'écriture dans ce buffer mal interdite ?
    Ou est-ce qu'il manque autre chose, un lien entre le depth buffer et le point d'attache de la texture sur lequel on veut l'utiliser (je ne fais pas un rendu dans le framebuffer principal mais dans une texture), une autre instruction 'magique' ?

  5. #5
    Membre éprouvé Avatar de razmott
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 133
    Par défaut
    Salut !

    As-tu essayé sans le pixelshader ?
    Si ça marche on sait d'où ça vient.
    S'il y a un problème, c'est probablement le FBO. Mais comme ça fait longtemps que je n'y a pas touché...

    Essaie et moi je regarde mes anciens codes !

    Bon courage !
    @+

Discussions similaires

  1. [FBO] shader et depth buffer
    Par zenux dans le forum OpenGL
    Réponses: 3
    Dernier message: 04/04/2011, 21h23
  2. FBO: Depth Texture vide
    Par LastSpear dans le forum OpenGL
    Réponses: 5
    Dernier message: 14/10/2010, 22h17
  3. fbo et depth buffer
    Par casafa dans le forum OpenGL
    Réponses: 1
    Dernier message: 27/06/2007, 09h25
  4. [FLASH MX] attachMovie et depth
    Par meslaey dans le forum Flash
    Réponses: 6
    Dernier message: 02/07/2004, 15h43
  5. A propos depth buffer
    Par j.yves dans le forum DirectX
    Réponses: 1
    Dernier message: 03/12/2002, 00h41

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