Multitexturing, shader mécontent
Bonsoir à tous ! Sauriez-vous comment gérer le multitexturing à travers les shaders ?? En fait j'ai codé une mini lib qui charge les fichiers .obj et effectue le rendu. Durant celui-ci, les différentes textures sont envoyées au fragment shader qui les réceptionne dans un tableau mais encore faut-il que ce dernier sache quelle texture sélectionner dans le tableau. Pour cela j'utilise des attributs de vertex indiquant le rang (Valeur initalisée à 0 et incrémentée à chaque fois que la fonction de chargement tombe sur un "usemtl" dans le fichier .obj). Seulement ça ne fonctionne pas comme prévu, voici les codes pour commencer :
Fonction de chargement :
Code:
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
| bool OBJ2_LoadOBJ(string path,OBJ2_VBO *vbo,const bool mipmap,const float X,const float Y,const float Z)
{
ifstream fichierOBJ(path.c_str(),ios::binary);
if(fichierOBJ==NULL)
return false;
//...
while(1) //Lecture de l'ensemble des faces
{
retour=getline(fichierOBJ,ligneLue);
if(!retour) //Fin de fichier
{
vbo->nbVertices=vbo->coordVertices.size()/3;
glGenVertexArrays(1,&vbo->VAO);
glGenBuffers(1,&vbo->bufferVRAM);
glBindVertexArray(vbo->VAO);
glBindBuffer(GL_ARRAY_BUFFER,vbo->bufferVRAM);
glBufferData(GL_ARRAY_BUFFER,...+vbo->attribNumtex.size()*sizeof(unsigned int),NULL,GL_STREAM_DRAW); //"attribNumtex" contient les rangs du tableau de texture
//...
glVertexAttribPointer(4,1,GL_UNSIGNED_INT,GL_FALSE,sizeof(unsigned int),(void*)(...));
glEnableVertexAttribArray(4); //Attributs contenant le rang de la texture
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
/////////////////////////////////////////////
break;
}
//...
}
fichierOBJ.close();
cout << path << " loaded" << endl << endl;
return true;
} |
Fonction de rendu :
Code:
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
| void OBJ2_DrawVBO(OBJ2_VBO *vbo,const GLuint shader)
{
glBindVertexArray(vbo->VAO);
if(vbo->textures.size()!=0)
{
int texShader[vbo->textures.size()];
int compteurTex=0;
while(1)
{
glActiveTexture(GL_TEXTURE0+compteurTex);
glBindTexture(GL_TEXTURE_2D,vbo->textures[compteurTex]);
texShader[compteurTex]=compteurTex;
//cout << vbo->textures[compteurTex] << endl;
compteurTex++;
if(compteurTex==vbo->textures.size())
break;
}
//cout << endl;
glUniform1iv(glGetUniformLocation(shader,"tex"),vbo->textures.size(),texShader); //Envoi textures au fragment shader
}
glDrawArrays(GL_TRIANGLES,0,vbo->nbVertices);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(0);
} |
Vertex shader :
Code:
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
| #version 330 core
layout (location=0) in vec3 vertex;
layout (location=1) in vec2 coordTex;
layout (location=2) in vec3 normale;
layout (location=3) in vec4 color;
layout (location=4) in uint numtex;
uniform mat4 projection;
uniform mat4 modele;
uniform mat4 vue;
out vec2 coordTexFrag;
out vec4 couleurFrag;
out uint numtexFrag;
void main(void)
{
vec4 vertex2=vec4(vertex,1.0);
gl_Position=projection*vue*modele*vertex2;
coordTexFrag=coordTex;
couleurFrag=color;
numtexFrag=numtex;
} |
Fragment shader :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #version 330 core
uniform sampler2D tex[32]; //Les textures
in vec2 coordTexFrag;
in vec4 couleurFrag;
in uint numtexFrag;
out vec4 FragColor;
void main(void)
{
FragColor=texture(tex[numtexFrag],coordTexFrag.xy);
} |
Si j'exécute ce code le compilateur GLSL me lance un "int/uint varying in is not flat interpolated" à la figure ! Je suis allé me renseigner ici et j'ai ajouté le mot "flat" avant "uint numtexFrag" dans le vertex shader et le fragment shader après quoi la compilation GLSL se fait mais j'ai une image complètement blanche à l'écran ..., le problème ne se pose pas si je rentre une valeur fixe telle que 0 ou 1 à la place de "numtexFrag" à la ligne 12 du fragment shader. J'ai déjà essayé en utilisant des float au lieu de int mais ça crée des imprécisions qui peuvent avoir pour effet de me retrouver avec la mauvaise texture affichée.
Un grand merci à la personne qui pourra m'aider à résoudre cela.