OpenGL顶点缓冲区对象代码输出错误

时间:2010-06-01 19:34:21

标签: c++ opengl rendering textures vbo

我的顶点缓冲区对象代码应该很好地渲染纹理,但是使用某些三角形形状渲染纹理时奇怪。

会发生什么 - http://godofgod.co.uk/my_files/wrong.png

应该发生什么 - http://godofgod.co.uk/my_files/right.png

此函数创建VBO并设置顶点和纹理坐标数据:

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

这是来自另一个函数的一些相关代码,它应该用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);

我希望代码能够使用前三个坐标(左上角,左下角,右上角)和最后三个(左下角,右上角,右下角)绘制三角形以最有效的方式正确地使用纹理数据。我不明白为什么三角形应该使它更有效,但显然这是要走的路。当然,它出于某种原因失败了。

我在问什么是破碎的,但我是否也会以正确的方式解决这个问题?

谢谢。

2 个答案:

答案 0 :(得分:1)

如果要对顶点和纹理坐标使用一个VBO,则需要使用结构对它们进行分组。

定义您的数据:

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

将其复制到VBO:

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

设置指针。请注意,stride是结构的大小,指针本身用作偏移量:

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

画画。

编辑:正如Bahbar建议的那样,用offsetof()实现了偏移量。

答案 1 :(得分:0)

您正在将数据加载到vbo两次。第二次调用glBufferData正在替换第一个。然后在调用draw时,两次调用gl * Pointer实际上都使用相同的数据。