1

我的顶点缓冲区对象代码应该可以很好地渲染纹理,但纹理却被奇怪地渲染为一些三角形。

会发生什么 - 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);

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

我在问什么坏了,但我通常是否以正确的方式处理它?

谢谢你。

4

2 回答 2

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() 实现偏移。

于 2010-06-02T00:03:21.407 回答
0

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

于 2010-06-01T19:45:17.020 回答