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 :

Passer plusieurs textures à un shader : PROBLEME


Sujet :

OpenGL

  1. #1
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut Passer plusieurs textures à un shader : PROBLEME
    Bonjour ,

    J'ai un problème avec un fragment shader, et je n'ai trouvé aucune réponse satisfaisante sur Internet. En gros, je dois passer trois textures à un shader (les trois textures sont valides car je peux les afficher sans problème). Toutefois, lorsque je les passe au shader, seule la première fonctionne seulement si je supprime les deux autres. Dès que j'en met 2, aucune ne fonctionne. Idem pour 3. Voici un code minimal reproduisant l'erreur :

    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
    glUseProgram (lightPyramidsTraversalProg);
     
    // Première texture sur l'unité 0
    glActiveTexture (GL_TEXTURE0);
    glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationPosition);
    GLuint texLoc1 = glGetUniformLocation(lightPyramidsTraversalProg, "lightPyramidsPosition");
    glUniform1i(texLoc1, 0);
     
    // Seconde texture sur l'unité 1
    glActiveTexture (GL_TEXTURE1);
    glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationNormal);
    GLuint texLoc2 = glGetUniformLocation(lightPyramidsTraversalProg, "lightPyramidsNormal");
    glUniform1i(texLoc2, 1);
     
    glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, lightPyramidsTraversalFBO);
     
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
    glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
     
    DrawQuad (512.0, 512.0);	
     
    glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
     
    glUseProgram (0);
    Le vertex shader :

    // Vertex shader
    void main ()
    {
    gl_Position = ftransform();

    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_TexCoord[1] = gl_MultiTexCoord1;
    //gl_TexCoord[2] = gl_MultiTexCoord2;
    //gl_TexCoord[3] = gl_MultiTexCoord3;
    }
    Pour le fragment shader :

    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
    // Fragment shader
    uniform sampler2D lightPyramidsPosition;
    uniform sampler2D lightPyramidsNormal;
    /*uniform sampler2D lightPyramidsIntensity;
     
    uniform sampler2D validityTexture;
     
    uniform float currentLevel; // Niveau actuel du mipmap
    uniform int currentResolution; // Resolution du niveau actuel du mipmap
    uniform int previousResolution; // Resolution du niveau précédent du mipmap*/
     
    void main ()
    {
    //	float offset = 1.0 / currentResolution;
    	vec3 finalColor = vec3 (0.0, 0.0, 0.0);
     
    	// On récupère dans un premier temps la position, la normale et la couleur du pixel
    	vec3 positionPixel = texture2D (lightPyramidsPosition, gl_TexCoord[0].st, 0.0).xyz;
    	vec3 normalPixel = normalize (texture2D (lightPyramidsNormal, gl_TexCoord[1].st, 0.0).xyz);
    	//vec3 colorPixel = texture2D (lightPyramidsIntensity, gl_TexCoord[2].st, 0.0).xyz;
     
    	finalColor = positionPixel;
    	gl_FragData[0] = vec4 (finalColor, 0.0);
    }
    Concrètement, la seule façon pour que ça fonctionne c'est : de ne binder qu'une seule texture (donc appel à glActiveTexture (GL_TEXTURE0)). Si je bind même qu'une seule texture sur l'unité 1, ça ne fonctionne plus. Si j'en bind 2, une sur l'unité 0 et l'autre sur l'unité 1, plus aucune ne fonctionne.

    J'ai pourtant l'impression que le code est correct...

  2. #2
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Bon, après de multiples essais, j'ai trouvé, par contre je ne me l'explique pas. Alors ça, qui est logique, ça ne fonctionne 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
    glActiveTexture (GL_TEXTURE0);
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationPosition);
    	GLuint texLoc1 = glGetUniformLocation(lightPyramidsTraversalProg, "lightPyramidsPosition");
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationPosition);
       glUniform1i(texLoc1, 0);
     
    	glActiveTexture (GL_TEXTURE1);
    	//glEnable (GL_TEXTURE_2D);
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationNormal);
    	GLuint texLoc2 = glGetUniformLocation(lightPyramidsTraversalProg, "lightPyramidsNormal");
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationNormal);
    	glUniform1i(texLoc2, 1);
     
    	glActiveTexture (GL_TEXTURE2);
    	//glEnable (GL_TEXTURE_2D);
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationIntensity);
    	GLuint texLoc3 = glGetUniformLocation(lightPyramidsTraversalProg, "lightPyramidsIntensity");
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationIntensity);
       glUniform1i(texLoc3, 2);
    Par contre ça, ça fonctionne parfaitement :

    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
    glActiveTexture (GL_TEXTURE2);
    	//glEnable (GL_TEXTURE_2D);
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationIntensity);
    	GLuint texLoc3 = glGetUniformLocation(lightPyramidsTraversalProg, "lightPyramidsIntensity");
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationIntensity);
       glUniform1i(texLoc3, 2);
     
    	glActiveTexture (GL_TEXTURE1);
    	//glEnable (GL_TEXTURE_2D);
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationNormal);
    	GLuint texLoc2 = glGetUniformLocation(lightPyramidsTraversalProg, "lightPyramidsNormal");
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationNormal);
    	glUniform1i(texLoc2, 1);
     
    	glActiveTexture (GL_TEXTURE0);
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationPosition);
    	GLuint texLoc1 = glGetUniformLocation(lightPyramidsTraversalProg, "lightPyramidsPosition");
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationPosition);
       glUniform1i(texLoc1, 0);
    Si je spécifie dans l'ordre inverse (2-1-0), ça fonctionne, mais dans l'autre sens, ça ne fonctionne pas... De plus, il faut que j'utilise gl_TexCoords[0] pour les trois textures. Si j'utilise gl_TexCoords[1] pour la deuxième et gl_TexCoords[2] pour la troisième, fonctionne plus. Bon, ça fera l'affaire en attendant de comprendre :/.

  3. #3
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Points : 486
    Points
    486
    Par défaut
    Salut,

    De plus, il faut que j'utilise gl_TexCoords[0] pour les trois textures. Si j'utilise gl_TexCoords[1] pour la deuxième et gl_TexCoords[2] pour la troisième, fonctionne plus.
    Es-tu sûr d'utiliser, par exemple,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    glMultiTexCoord2d(GL_TEXTURE0, u, v)
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    glTexCoord2d(u, v)
    J'ai déjà eu des problèmes en oubliant de préciser à quelle unité de textures s'appliquent mes coordonnées, c'est peut être ton soucis aussi...

  4. #4
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Je n'ai pas besoin d'appeler gl_MultiTexCoord, je ne texture rien. Mes textures servent juste à faire des lookups dans le shader.

  5. #5
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Points : 486
    Points
    486
    Par défaut
    euh...dans ce cas les lignes de ton pixel shader:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_TexCoord[1] = gl_MultiTexCoord1;
    et celles de ton fragment shader
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    vec3 positionPixel = texture2D (lightPyramidsPosition, gl_TexCoord[0].st, 0.0).xyz;
    	vec3 normalPixel = normalize (texture2D (lightPyramidsNormal, gl_TexCoord[1].st, 0.0).xyz);
    ne vont pas avec ce que tu dis:
    1. soit tu assignes des coordonnées de textures et tu les récupère / utilise comme tu le fais là.
    2. soit tu n'utilises pas de coordonées de textures, et dans ce cas il n'y aura jamais rien dans gl_multitexcoord0, 1 et les suivants...

  6. #6
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Ah... Bah en fait quand je dessine le carré j'utilise glTexCoord2i... Mais ce que tu dis n'est pas bête, je crois que je commence à comprendre :p.

  7. #7
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Hop hop,

    Vous m'excuserez de ne pas créer un autre topic supplémentaire même si ma question n'est pas exactement en rapport avec l'autre question.

    Après avoir résolu ce soucis, je viens de m'apercevoir d'un autre problème. Mes trois textures ont été générées par un shader dans un FBO (via gl_FragData). Je peux afficher mes textures sans soucis. Totuefois, j'ai besoin de générer des mipmaps, avec le pixel d'un niveau suivant étant la valeur moyenne des quatre sous pixels (donc si je ne me trompes pas : GL_LINEAR pour MAG_FILTER, et GL_LINEAR_MIPMAP_NEAREST pour MIN_FILTER).

    Le soucis, c'est que seul le premier niveau semble être correctement initialisé. Pour générer les mipmaps, j'utilise GL_GENERATE_MIPMAP, car glGenerateMipmapEXT ne semble pas fonctionner sur les cartes ATi d'après ce que j'ai pu trouver sur le Net :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    glGenTextures (1, &lightPyramidsCreationNormal);
    	glBindTexture (GL_TEXTURE_2D, lightPyramidsCreationNormal);
    	glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, 512, 512, 0, GL_RGBA, GL_FLOAT, NULL);
    	glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    	glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    	glTexParameteri (GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    Pour autant, si je vérifie la taille des textures :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    GLfloat data1, data2;
    	glGetTexLevelParameterfv (GL_TEXTURE_2D, 1, GL_TEXTURE_WIDTH, &data1);
    	glGetTexLevelParameterfv (GL_TEXTURE_2D, 1, GL_TEXTURE_HEIGHT, &data2);
    J'obtiens bien 256*256, 128*128... En fait, la texture de base est bien affichée, toutes les autres sont noires :/.

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/02/2009, 04h36
  2. Réponses: 8
    Dernier message: 19/03/2008, 19h08
  3. Réponses: 13
    Dernier message: 25/01/2005, 10h05
  4. Combiner plusieurs textures avec couches alpha
    Par TibobiT dans le forum OpenGL
    Réponses: 2
    Dernier message: 01/05/2004, 15h20
  5. [STRUTS] comment passer plusieur param GET aves <html:lin
    Par lfournial dans le forum Struts 1
    Réponses: 3
    Dernier message: 20/01/2004, 08h57

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