开发者

Opengl VBO (with mixed index, tex coordinate array) does not work, help please

开发者 https://www.devze.com 2023-02-07 23:35 出处:网络
I am trying to improve the performance of my drawing. What I actually do is to draw a mesh in 2D with the height as the color. I have the mesh_xy matrix for the x-y coordinate and mesh_z for the heigh

I am trying to improve the performance of my drawing. What I actually do is to draw a mesh in 2D with the height as the color. I have the mesh_xy matrix for the x-y coordinate and mesh_z for the height matrix and construct a index matrix for the plotting elements. First I tried to use the client side array and it works fine. Then I made the minimal change by putting the mesh_xy to the server side as a VBO. Nothing is rendered. Anyone can help me?

The relating code is pasted below. draw_bmfm5() is the function using client side array which works perfect. draw_bmfm6() is the VBO (only the mesh_xy is in the server side). One thing I need to mention is: my graphics card supports the VBO which I have tested using other program.

    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(开发者_如何学Pythonfloat),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();

}


GL_INDEX_ARRAY does not mean what you think it means. It's meant to control a color selector from a color palette, which is used in GL when you render to palettized framebuffers. The simple fact that you call glDrawElements means that you're using vertex indices. There's no client-side array to Enable.

So... When you look at your VBO, you can see how that gets your calls confused:

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

The last call actually uses the buffer bound to ARRAY_BUFFER, i.e. vbo_tex. So, you're uploading your indices to vbo_tex and not putting anything into vbo_indx

Next, on your binding of the VBOs, you're not selecting the proper vbo for each Pointer call.

Indices and vertices are fundamentally different. You can put one or the other (preferably both) into vbos, but your index_xy structure is an array of arrays, so I'll write code that only puts the vertices in vbos (as I don't know the underlying data structure for the indices)

Putting this all together gives:

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: I have not tested this code, but I have fixed a number of issues. There might be other ones.

Last, pushing the index array data into VBOs would require binding and putting the data into ELEMENT_ARRAY_BUFFER, and pass offsets into the buffer from the glDrawElements call.

0

精彩评论

暂无评论...
验证码 换一张
取 消