2010-06-01 35 views
1

Mon code d'objet tampon Vertex est supposé rendre les textures correctement, mais les textures sont rendues bizarrement avec des formes triangulaires.OpenGL Vertex Buffer Code d'objet donnant une mauvaise sortie

Qu'est-ce qui se passe - http://godofgod.co.uk/my_files/wrong.png

Ce qui est censé se produire - http://godofgod.co.uk/my_files/right.png

Cette fonction crée le VBO et définit le sommet et la texture de données de coordonnées:

extern "C" GLuint create_box_vbo(GLdouble size[2]){ 
    GLuint vbo; 
    glGenBuffers(1,&vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    GLsizeiptr data_size = 8*sizeof(GLdouble); 
    GLdouble vertices[] = {0,0, 0,size[1], size[0],0, size[0],size[1]}; 
    glBufferData(GL_ARRAY_BUFFER, data_size, vertices, GL_STATIC_DRAW); 
    data_size = 8*sizeof(GLint); 
    GLint textcoords[] = {0,0, 0,1, 1,0, 1,1}; 
    glBufferData(GL_ARRAY_BUFFER, data_size, textcoords, GL_STATIC_DRAW); 
    return vbo; 
} 

Voici un code relavant de une autre fonction qui est censée dessiner les textures avec le VBO.

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glColor4d(1,1,1,a/255); 
glBindTexture(GL_TEXTURE_2D, texture); 
glTranslated(offset[0],offset[1],0); 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glVertexPointer(2, GL_DOUBLE, 0, 0); 
glEnableClientState(GL_VERTEX_ARRAY); 
glTexCoordPointer (2, GL_INT, 0, 0); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
glDrawArrays(GL_TRIANGLES, 0, 3); 
glDrawArrays(GL_TRIANGLES, 1, 3); 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
glDisableClientState(GL_VERTEX_ARRAY); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 

je pu espérer le code à utiliser les trois premières coordonnées (en haut à gauche, inférieur gauche, supérieur droit) et les trois derniers (en bas à gauche, en haut à droite, en bas à droite) dessiner les triangles avec les données de texture correctement de la manière la plus efficace. Je ne vois pas pourquoi les triangles devraient le rendre plus efficace, mais apparemment, c'est la voie à suivre. Bien sûr, cela échoue pour une raison quelconque.

Je demande ce qui est cassé mais aussi suis-je en train de le faire dans le bon sens en général?

Merci.

Répondre

1

Si vous souhaitez utiliser le seul VBO pour les coordonnées de vertex et de texture, vous devez les regrouper à l'aide d'une structure.

Définir vos données:

typedef struct { 
    GLdouble x, y; 
    GLint s, t; 
} VertexData; 

VertexData data[] = { 
// x  y  s t 
    {0.0,  0.0,  0, 0}, 
    {0.0,  size[1], 0, 1}, 
    {size[0], 0.0,  1, 0}, 
    {size[0], size[1], 1, 1} 
}; 

copier dans VBO:

glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, sizeof(data), (GLvoid*)data, GL_STATIC_DRAW); 

pointeurs Set. Notez que stride est la taille de votre structure et que le pointeur lui-même sert de décalage:

glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glVertexPointer(2, GL_DOUBLE, sizeof(VertexData), (GLvoid*)offsetof(VertexData, x)); 
glTexCoordPointer(2, GL_INT, sizeof(VertexData), (GLvoid*)offsetof(VertexData, s)); 
glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

Et dessinez.

EDIT: décalage implémenté avec offsetof() comme suggéré par Bahbar.

+1

réel nitpicking, mais vous feriez mieux d'utiliser une forme de offsetof pour trouver le décalage pour les coordonnées de texture. Ici il n'y a probablement pas de remplissage entre y et s, mais disons que vous aviez 3 shorts pour la position, alors l'histoire serait très différente (3 * sizeof (GLshort) serait le mauvais décalage, car le décalage serait probablement de 8 octets plutôt que 6). – Bahbar

+0

Merci beaucoup pour cela. Je vais regarder maintenant. –

+0

En utilisant GLdouble pour les coordonnées de texture ainsi que les sommets, je peux certainement utiliser un tableau multidimensionnel? Je devrai utiliser des doubles pour les coordonnées de texture de mes textures arrondies. –

0

Vous chargez deux fois les données dans le vbo. Le deuxième appel à glBufferData remplace le premier. Ensuite, les deux appels à gl * Pointer utilisent les mêmes données lors de l'appel à draw.

+0

Merci pour votre réponse. J'ai lu quelque part que cela pourrait être fait de cette façon. C'était sur un sujet et la personne qui voulait une solution a dit que cela a fonctionné. Si je mets les coordonnées de texture après les sommets, que dois-je mettre à l'intérieur de "glTexCoordPointer"? Je ne comprends pas comment le faire pointer vers le 9ème élément du tableau où les coordonnées de texture commenceraient. Puis-je mettre ces fonctions ponctuelles dans la fonction create_box_vbo et les utiliser une seule fois? Merci encore. –

+0

Eh bien, j'ai juste essayé de déplacer les fonctions et ça a empiré, donc je suppose que je ne peux pas faire ça. –

+0

Je pensais juste que les coordonnées de texture seraient les mêmes pour chaque texture, alors pourquoi ne pas avoir un seul VBO pour les coordonnées de texture. C'est stupide de ne pas faire ça. –