2010-11-29 5 views
1

J'ai commencé à jouer avec un OpenGL ES 1.0 et je rencontre un problème (débutant): j'ai essayé de mapper une texture carrée au cube décrit par des triangles.Mappage d'une texture carrée à un triangle

// Turn necessary features on 
    glEnable(GL_TEXTURE_2D); 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_ONE, GL_SRC_COLOR); 
    glEnable(GL_CULL_FACE); 
    //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 

    // Bind the number of textures we need, in this case one. 
    glGenTextures(1, &texture[0]); 
    glBindTexture(GL_TEXTURE_2D, texture[0]); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

//Drawing code 
static GLfloat rot = 0.0; 

static const Vertex3D vertices[] = { 
    -1.0f,-1.0f,-1.0f, //0 00 
    1.0f,-1.0f,-1.0f, //1 10 
    1.0f, 1.0f,-1.0f, //2 11 
    -1.0f, 1.0f,-1.0f, //3 01  
}; 


static const int vertexCnt = 3 * 2; 

static const GLubyte cube[] = { 
    3,0,2, 
    1,2,0, 
}; 

static const GLfloat texCoords[] = { 
    0,1, 
    0,0, 
    1,1, 
    1,0, 
    1,1, 
    0,0, 
}; 


glClearColor(0.0, 0.0, 0.0, 1.0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

glLoadIdentity(); 

glTranslatef(0.0f, 0.0f, -3.0f); 

glBindTexture(GL_TEXTURE_2D, texture[0]); 

glEnableClientState(GL_VERTEX_ARRAY); 
//glEnableClientState(GL_COLOR_ARRAY); 
glEnableClientState(GL_NORMAL_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
glEnable(GL_COLOR_MATERIAL); 


glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 
glVertexPointer(3, GL_FLOAT, 0, vertices); 

//glColorPointer(4, GL_FLOAT, 0, colors); 
glNormalPointer(GL_FLOAT, 0, normals); 



glDrawElements(GL_TRIANGLES, vertexCnt, GL_UNSIGNED_BYTE, cube); 


glDisableClientState(GL_VERTEX_ARRAY); 
//glDisableClientState(GL_COLOR_ARRAY); 
glDisableClientState(GL_NORMAL_ARRAY); 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

Maintenant, après une tentative de zillion, je ne peux pas le faire fonctionner pour d'autres côtés ... Y at-il une règle de base pour le cas lors du mappage de texture carré triangles?

EDIT: Je pense que je devrais comprendre comment le mappage devrait être fait. Mais cela ne fonctionne pas pour cet exemple (un visage). Quelqu'un peut-il simplement vérifier si j'ai fait le mappage correctement (en supposant que le reste du code fonctionne)?

Un grand merci

+0

Je ne pense pas qu'il y ait un moyen de cartographier soigneusement un carré sur un cube tout en réutilisant les mêmes données de sommet. Je voudrais retravailler votre cube en 6 quads séparés = 24 sommets au lieu de 8. –

+0

Je soupçonne que votre tableau 'normals' est faux. Pourriez-vous nous montrer quel est le contenu de votre pointeur normal? Changez-vous la normale pour chaque visage? –

+0

Les normales sont un peu fausses mais je ne savais pas qu'elles ont un impact sur le mappage de texture. Je pensais qu'elles affectent seulement l'éclairage ... vont le vérifier.Merci – sinek

Répondre

1

Tout comme les autres, je ne pense pas qu'il y ait un truc pour mapper vos textures quad sur des triangles.

Le problème principal que vous rencontrez est dû aux discontinuités dans les coords de texture pour chaque coin. Si un coin comme coords UV {u, v} pour une face, cela ne signifie pas qu'il aura la même valeur pour les deux autres faces qui partagent le sommet. Il est possible de trouver une cartographie de sorte que UV soit unique à chaque coin du cube (partagé par 3 faces) et que les 4 valeurs UV ({0,0}, {1,0}, {1,1} et {0,1}) sont présents sur chaque face, mais certaines textures seraient complètement déformées. Essayez de vérifier ceci sur une feuille de papier: {1,1} n'est pas toujours à l'opposé de {0,0}. La manière la plus simple de commencer serait de déclarer explicitement 6 quadrilatères composés chacun de 2 triangles. Cela vous donne un total de 24 sommets (24 positions et 24 coeurs tex, entrelacés ou non) et 36 indices (6 quads composés de deux triangles, 6 * 2 * 3 = 36).

Voici votre code mis à jour pour afficher un cube (il pourrait y avoir un problème d'enroulement donc je visage désactivé culling pour être sûr):

glEnable(GL_TEXTURE_2D); 
glEnable(GL_BLEND); 
glEnable(GL_DEPTH_TEST); 
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
glDisable(GL_CULL_FACE); 

static const float vertices[] = { 
     0.0f, 1.0f, 0.0f, 
     1.0f, 1.0f, 0.0f, 
     0.0f, 0.0f, 0.0f, 
     1.0f, 0.0f, 0.0f, 

     0.0f, 1.0f, 1.0f, 
     0.0f, 0.0f, 1.0f, 
     1.0f, 1.0f, 1.0f, 
     1.0f, 0.0f, 1.0f, 

     0.0f, 1.0f, 1.0f, 
     1.0f, 1.0f, 1.0f, 
     0.0f, 1.0f, 0.0f, 
     1.0f, 1.0f, 0.0f, 

     0.0f, 0.0f, 1.0f, 
     0.0f, 0.0f, 0.0f, 
     1.0f, 0.0f, 1.0f, 
     1.0f, 0.0f, 0.0f, 

     1.0f, 1.0f, 0.0f, 
     1.0f, 1.0f, 1.0f, 
     1.0f, 0.0f, 0.0f, 
     1.0f, 0.0f, 1.0f, 

     0.0f, 1.0f, 0.0f, 
     0.0f, 0.0f, 0.0f, 
     0.0f, 1.0f, 1.0f, 
     0.0f, 0.0f, 1.0f 
     }; 


static const int vertexCnt = 6 * 4; 

static const GLubyte cube[] = { 
    0, 1, 2, 1, 2, 3, 
    4, 5, 6, 5, 6, 7, 
    8, 9, 10, 9, 10, 11, 
    12, 13, 14, 13, 14, 15, 
    16, 17, 18, 17, 18, 19, 
    20, 21, 22, 21, 22, 23 
}; 

static const GLfloat texCoords[] = { 
    0.0f, 0.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 1.0f, 

    1.0f, 0.0f, 
    1.0f, 1.0f, 
    0.0f, 0.0f, 
    0.0f, 1.0f, 

    0.0f, 0.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 1.0f, 

    0.0f, 1.0f, 
    0.0f, 0.0f, 
    1.0f, 1.0f, 
    1.0f, 0.0f, 

    0.0f, 0.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 1.0f, 

    1.0f, 0.0f, 
    1.0f, 1.0f, 
    0.0f, 0.0f, 
    0.0f, 1.0f 
    }; 

glClearColor(0.0, 0.0, 0.0, 1.0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

//glLoadIdentity(); 

//glTranslatef(0.0f, 0.0f, -3.0f); 
glRotatef(3.1415927f, 1.0f, 1.0f, 0.0f); 

glBindTexture(GL_TEXTURE_2D, spriteTexture); 

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 
glVertexPointer(3, GL_FLOAT, 0, vertices); 

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, cube); 
+0

Pouvez-vous s'il vous plaît vérifier que je cartographie correctement les coordonnées dans mon exemple ci-dessus. BTW. Merci pour l'info! – sinek

+0

Il essaie de dessiner un seul visage pour le moment. Les discontinuités ne sont pas le problème. –

+1

Oui, la question a été éditée (l'habitude d'être pour un cube) ;-) Le mappage semble correct maintenant, donc si rien n'apparaît à l'écran, je commencerais par désactiver la sélection de face et GL_COLOR_MATERIAL. – Ozirus

1

Je n'ai pas essayé de pièce à travers vos listes de sommets, mais ma conjecture est que vous avez vos coordonnées entièrement foiré et la cartographie de mal, vous avez indiqué votre format de mémoire tampon d'index de manière incorrecte, ou vous avez activé l'abattage du dos, et certains de vos sommets sont dans le mauvais ordre. En ce qui concerne les coordonnées de texture elles-mêmes, il ne devrait pas y avoir d'astuce avec le mappage aux triangles en comparaison avec les quadrilatères. Vous aurez juste besoin d'avoir 6 coordonnées de texture où précédemment vous auriez eu quatre, puisqu'il y a 6 sommets (deux duplicats par face). Vous pouvez éviter la duplication en utilisant un tampon d'index, comme vous l'avez fait pour votre cube. En ce qui concerne un éventuel problème de suppression de la face arrière, vous devez définir vos sommets dans le même ordre à chaque fois. Tous dans le sens des aiguilles d'une montre, par rapport à la direction de la texture, ou tous dans le sens inverse des aiguilles d'une montre.

Quelles commandes utilisez-vous pour configurer votre pipeline OpenGL et quelles commandes utilisez-vous pour dessiner ces sommets? Veuillez ajouter le code correspondant à la question.