Opengl VBO(带有混合索引,tex坐标数组)不起作用,请帮忙

时间:2011-02-02 18:38:51

标签: opengl

我正在努力提高绘图的性能。我实际上做的是在2D中绘制一个网格,高度为颜色。我有x-y坐标的mesh_xy矩阵和高度矩阵的mesh_z,并为绘图元素构建索引矩阵。首先,我尝试使用客户端阵列,它工作正常。然后我通过将mesh_xy作为VBO放到服务器端来进行最小的更改。什么都没有呈现。有人可以帮帮我吗?

相关代码粘贴在下面。 draw_bmfm5()是使用客户端数组的函数,它完美无缺。 draw_bmfm6()是VBO(只有mesh_xy在服务器端)。我需要提到的一件事是:我的显卡支持我使用其他程序测试的VBO。

    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();

}

1 个答案:

答案 0 :(得分:2)

GL_INDEX_ARRAY并不代表您认为的含义。它的意思是从调色板控制颜色选择器,当您渲染到调色板的帧缓冲区时,调色板中会使用该调色板。您调用glDrawElements这一简单事实意味着您正在使用顶点索引。启用没有客户端阵列。

所以...当你看VBO时,你可以看到这会让你的电话混乱:

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);

最后一次调用实际上使用绑定到ARRAY_BUFFER的缓冲区,即vbo_tex。 因此,您将索引上传到vbo_tex而不是将任何内容放入vbo_indx

接下来,在你对VBO进行绑定时,你没有为每个指针调用选择合适的vbo。

指数和顶点根本不同。你可以将一个或另一个(最好是两个)放入vbos,但你的index_xy结构是一个数组数组,所以我将编写只将顶点放在vbos中的代码(因为我不知道它的底层数据结构)索引)

把这些放在一起给出了:

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();

}

注意:我没有测试过这段代码,但我已经解决了很多问题。可能还有其他的。

最后,将索引数组数据推送到VBO中需要绑定并将数据放入ELEMENT_ARRAY_BUFFER,并将偏移量从glDrawElements调用传递到缓冲区。