2009-12-27 4 views
6

Je suis assez nouveau sur OpenGL, et il semble que je rencontre quelques difficultés. J'ai écrit un simple shader dans GLSL, qui est censé transformer des sommets par des matrices jointes données, permettant une animation squelettique simple. Chaque sommet a un maximum de deux influences de l'os (stockées comme les composantes x et y d'un Vec2), des indices et des poids correspondants associés à un tableau de matrices de transformation, et sont spécifiés comme variables d'attribut dans mon shader, puis en utilisant la fonction "glVertexAttribPointer".Cocoa et OpenGL, Comment définir un attribut de sommet GLSL en utilisant un tableau?

Voici où le problème se pose ... J'ai réussi à définir correctement le tableau de matrices "Uniform Variable", lorsque je vérifie ces valeurs dans le shader, elles sont toutes importées correctement et contiennent les données correctes. Cependant, lorsque je tente de définir la variable Indices conjointe, les sommets sont multipliés par des matrices de transformation arbitraires! Ils sautent à des positions apparemment aléatoires dans l'espace (qui sont différentes à chaque fois), je suppose que les indices sont mal définis et mon shader est en train de lire après la fin de mon tableau matriciel commun dans la mémoire suivante. Je ne sais pas exactement pourquoi, car en lisant toutes les informations que j'ai pu trouver sur le sujet, j'ai été surpris de voir le même code (sinon très similaire) dans leurs exemples, et cela semblait fonctionner pour eux.

J'ai essayé de résoudre ce problème depuis un certain temps maintenant et ça commence vraiment à m'énerver ... Je sais que les matrices sont correctes, et quand je change manuellement la valeur d'index dans le shader à un arbitraire Entier, il lit les valeurs correctes de la matrice et fonctionne comme il le devrait, en transformant tous les sommets de cette matrice, mais lorsque j'essaie d'utiliser le code que j'ai écrit pour définir les variables d'attribut, cela ne semble pas fonctionner.

Le code que je utilise pour définir les variables est la suivante ...

// this works properly... 
GLuint boneMatLoc = glGetUniformLocation([[[obj material] shader] programID], "boneMatrices"); 
glUniformMatrix4fv(boneMatLoc, matCount, GL_TRUE, currentBoneMatrices); 

GLfloat testBoneIndices[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; 

// this however, does not... 
GLuint boneIndexLoc = glGetAttribLocation([[[obj material] shader] programID], "boneIndices"); 
glEnableVertexAttribArray(boneIndexLoc); 
glVertexAttribPointer(boneIndexLoc, 2, GL_FLOAT, GL_FALSE, 0, testBoneIndices); 

Et mon vertex shader ressemble à ceci ...

// this shader is supposed to transform the bones by a skeleton, a maximum of two 
// bones per vertex with varying weights... 

uniform mat4 boneMatrices[32]; // matrices for the bones 
attribute vec2 boneIndices; // x for the first bone, y for the second 

//attribute vec2 boneWeight; // the blend weights between the two bones 

void main(void) 
{ 
gl_TexCoord[0] = gl_MultiTexCoord0; // just set up the texture coordinates... 


vec4 vertexPos1 = 1.0 * boneMatrices[ int(boneIndex.x) ] * gl_Vertex; 
//vec4 vertexPos2 = 0.5 * boneMatrices[ int(boneIndex.y) ] * gl_Vertex; 

gl_Position = gl_ModelViewProjectionMatrix * (vertexPos1); 
} 

Cela commence vraiment à me frustrer et toute aide sera appréciée,

-Andrew Gotow

Répondre

2

Ok, j'ai figu rougis. OpenGL dessine des triangles avec la fonction drawArrays en lisant toutes les 9 valeurs comme un triangle (3 vertices avec 3 composants chacun). Pour cette raison, les sommets sont répétés entre les triangles, donc si deux triangles adjacents partagent un sommet, il apparaît deux fois dans le tableau. Donc, mon cube que je pensais à l'origine avait 8 sommets, en fait 36!

six côtés, deux triangles sur un côté, trois sommets par triangle, tous se multiplient sur un total de 36 sommets indépendants au lieu de 8 partagés.

Le problème entier était un problème avec la spécification de trop peu de valeurs. Dès que j'ai étendu mon tableau de test pour inclure 36 valeurs, cela a fonctionné parfaitement.

Questions connexes