2011-02-02 1 views
0

J'essaie d'améliorer les performances de mon dessin. Ce que je fais réellement est de dessiner un maillage en 2D avec la hauteur comme couleur. J'ai la matrice mesh_xy pour la coordonnée x-y et mesh_z pour la matrice de hauteur et construis une matrice d'index pour les éléments de traçage. J'ai d'abord essayé d'utiliser le tableau côté client et cela fonctionne très bien. Ensuite, j'ai fait le changement minimal en mettant le mesh_xy du côté du serveur comme un VBO. Rien n'est rendu. Est-ce que quelqu'un peut m'aider?OpenGL VBO (avec index mixte, tableau de coordonnées tex) ne fonctionne pas, aide s'il vous plaît

Le code associé est collé ci-dessous. draw_bmfm5() est la fonction utilisant un tableau côté client qui fonctionne parfaitement. draw_bmfm6() est le VBO (seul le mesh_xy est côté serveur). Une chose que je dois mentionner est: ma carte graphique supporte le VBO que j'ai testé en utilisant un autre programme.

void draw_bmfm5(float scale) 
{ 
    glPushMatrix(); 
    glScalef(scale,scale,1.0f); 

    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
    glShadeModel(GL_SMOOTH); 
    glEnable(GL_TEXTURE_1D); 
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//which is not default 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);//use texture coordinate 
    glEnableClientState(GL_INDEX_ARRAY); 
    glVertexPointer(2,GL_FLOAT,0,mesh_xy);//all 1d array, make it 2D and less data is transferred 
    glTexCoordPointer(1,GL_FLOAT,0,mesh_z); 
    for(i=0;i<n-1;i++) 
    { 
     glDrawElements(GL_TRIANGLE_STRIP,2*HEIGHT,GL_UNSIGNED_INT,index_xy[i]); 
    } 
    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    glDisableClientState(GL_INDEX_ARRAY); 

    glDisable(GL_TEXTURE_1D); 
    glPopMatrix(); 

} 

//the only difference between 5 and 6 is: 
//we are going to store the mesh_xy into the server side 
GLuint vbo_vertex,vbo_tex,vbo_indx; 
PFNGLGENBUFFERSARBPROC pglGenBuffersARB = 0;      // VBO Name Generation Procedure 
PFNGLBINDBUFFERARBPROC pglBindBufferARB = 0;      // VBO Bind Procedure 
PFNGLBUFFERDATAARBPROC pglBufferDataARB = 0;      // VBO Data Loading Procedure 
#define glGenBuffersARB   pglGenBuffersARB 
#define glBindBufferARB   pglBindBufferARB 
#define glBufferDataARB   pglBufferDataARB 

void create_vbo() 
{ 


    glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB"); 
    glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB"); 
    glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB"); 

    glGenBuffersARB(1,&vbo_vertex); 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex); 
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*2*sizeof(float),mesh_xy,GL_STATIC_DRAW); 

    glGenBuffersARB(1,&vbo_tex); 

    glGenBuffersARB(1,&vbo_indx); 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex); 
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*sizeof(float),mesh_z,GL_DYNAMIC_DRAW); 

    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER,vbo_indx); 
    glBufferDataARB(GL_ARRAY_BUFFER,HEIGHT*WIDTH*2*sizeof(int),index_xy,GL_DYNAMIC_DRAW); 


} 
void draw_bmfm6(float scale) 
{ 
    glPushMatrix(); 
    glScalef(scale,scale,1.0f); 

    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
    glShadeModel(GL_SMOOTH); 
    glEnable(GL_TEXTURE_1D); 
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//which is not default 
    glDisableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);//use texture coordinate 
    glEnableClientState(GL_INDEX_ARRAY); 
    //glVertexPointer(2,GL_FLOAT,0,mesh_xy);//all 1d array, make it 2D and less data is transferred 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex); 
    glVertexPointer(2,GL_FLOAT,0,0); 

    glTexCoordPointer(1,GL_FLOAT,0,mesh_z); 
    for(i=0;i<n-1;i++) 
    { 
     glDrawElements(GL_TRIANGLE_STRIP,2*HEIGHT,GL_UNSIGNED_INT,index_xy[i]); 
    } 
    glDisableClientState(GL_VERTEX_ARRAY); 

    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    glDisableClientState(GL_INDEX_ARRAY); 

    glDisable(GL_TEXTURE_1D); 
    glPopMatrix(); 

} 

Répondre

2

GL_INDEX_ARRAY ne signifie pas ce que vous pensez que cela signifie. Il est destiné à contrôler un sélecteur de couleur à partir d'une palette de couleurs, qui est utilisée dans GL lorsque vous effectuez un rendu sur des framebuffers palettisés. Le simple fait d'appeler glDrawElements signifie que vous utilisez des indices de vertex. Il n'y a pas de tableau côté client à Activer.

Alors ... Quand vous regardez votre VBO, vous pouvez voir comment cela obtient vos appels confus:

glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex); 
glBufferDataARB(GL_ARRAY_BUFFER,3000*141*sizeof(float),mesh_z,GL_DYNAMIC_DRAW); 

glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER,vbo_indx); 
glBufferDataARB(GL_ARRAY_BUFFER,HEIGHT*WIDTH*2*sizeof(int),index_xy,GL_DYNAMIC_DRAW); 

Le dernier appel utilise en fait le tampon lié à ARRAY_BUFFER, à savoir vbo_tex. Ainsi, vous téléchargez vos index sur vbo_tex et ne mettez rien dans vbo_indx

Ensuite, sur votre liaison des VBO, vous ne sélectionnez pas le vbo approprié pour chaque appel de Pointer.

Les indices et les sommets sont fondamentalement différents. Vous pouvez mettre l'un ou l'autre (de préférence les deux) dans vbos, mais votre structure index_xy est un tableau de tableaux, donc je vais écrire du code qui met seulement les sommets dans vbos (car je ne connais pas la structure de données sous-jacente indices)

Mettre tout cela ensemble donne:

void create_vbo() 
{ 
    glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB"); 
    glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB"); 
    glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB"); 

    glGenBuffersARB(1,&vbo_vertex); 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex); 
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*2*sizeof(float),mesh_xy,GL_STATIC_DRAW); 

    glGenBuffersARB(1,&vbo_tex); 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex); 
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*sizeof(float),mesh_z,GL_DYNAMIC_DRAW); 

} 
void draw_bmfm6(float scale) 
{ 
    glPushMatrix(); 
    glScalef(scale,scale,1.0f); 

    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
    glShadeModel(GL_SMOOTH); 
    glEnable(GL_TEXTURE_1D); 
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//which is not default 
    glEnableClientState(GL_VERTEX_ARRAY); // Why was this Disable ? 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);//use texture coordinate 
    //glEnableClientState(GL_INDEX_ARRAY); // removed 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex); 
    glVertexPointer(2,GL_FLOAT,0,0); 

    glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex); // Binding the texcoord buffer 
    glTexCoordPointer(1,GL_FLOAT,0,0); // 0 as offset 
    for(i=0;i<n-1;i++) 
    { 
     glDrawElements(GL_TRIANGLE_STRIP,2*HEIGHT,GL_UNSIGNED_INT,index_xy[i]); 
    } 
    glDisableClientState(GL_VERTEX_ARRAY); 

    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    // glDisableClientState(GL_INDEX_ARRAY); // not needed 

    glDisable(GL_TEXTURE_1D); 
    glPopMatrix(); 

} 

note: Je ne l'ai pas testé ce code, mais je l'ai fixé un certain nombre de questions. Il pourrait y en avoir d'autres. Enfin, pousser les données du tableau d'index dans les VBO nécessiterait de lier et de placer les données dans ELEMENT_ARRAY_BUFFER, et de faire des décalages dans le tampon à partir de l'appel glDrawElements.

+0

Bonjour Bahbar, Merci pour la réponse détaillée. J'ai appliqué votre modification et cela fonctionne !! La performance s'est beaucoup améliorée. Une question est: si je mets seulement la matrice vertex mesh_xy du côté serveur comme VBO, mais laisse le mesh_z côté client (puisque cette matrice change à chaque fois), la couleur est la même et ne reflète pas la map height mesh_z. Est-il possible de faire ça? Merci agin. Votre aide est grandement appréciée. – shangping

+0

@shangping: Oui c'est possible. Utilisez simplement glBindBuffer (GL_ARRAY_BUFFER, 0) avant d'appeler votre glTexCoordPointer avec le tampon côté client. – Bahbar

+0

Bonjour Bahbar, Merci pour la réponse rapide. Cela a encore fonctionné. Mais le problème est: tout le gain de performance est perdu et c'est le même que mon tableau côté client. Le code est comme suit: \t glBindBufferARB (GL_ARRAY_BUFFER, vbo_vertex); \t glVertexPointer (2, GL_FLOAT, 0,0); \t \t glBindBufferARB (GL_ARRAY_BUFFER, 0); \t glTexCoordPointer (1, GL_FLOAT, 0, maillage_z); Savez-vous quelle est la raison? – shangping