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

发布于 2024-09-03 23:55:18 字数 1796 浏览 5 评论 0原文

我的顶点缓冲区对象代码应该能够很好地渲染纹理,但是纹理却以一些三角形形状呈现得很奇怪。

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

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

该函数创建 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);

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

我问的是哪里出了问题,但我通常是否以正确的方式处理它?

谢谢。

My Vertex Buffer Object code is supposed to render textures nicely but instead the textures are being rendered oddly with some triangle shapes.

What happens - http://godofgod.co.uk/my_files/wrong.png

What is supposed to happen - http://godofgod.co.uk/my_files/right.png

This function creates the VBO and sets the vertex and texture coordinate data:

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

Here is some relavant code from another function which is supposed to draw the textures with the 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);

I would have hoped for the code to use the first three coordinates (top-left,bottom-left,top-right) and the last three (bottom-left,top-right,bottom-right) to draw the triangles with the texture data correctly in the most efficient way. I don't see why triangles should make it more efficient but apparently that's the way to go. It, of-course, fails for some reason.

I am asking what is broken but also am I going about it in the right way generally?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北陌 2024-09-10 23:55:18

如果您想对顶点和纹理坐标使用同一个 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);

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

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

并绘制。

编辑:按照巴巴尔的建议,使用 offsetof() 实现了偏移。

If you want to use the one VBO for both vertex and texture coordinates you need to group them using a struct.

Define your data:

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

Copy it into VBO:

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

Set pointers. Note that stride is your struct's size and pointer itself serves as offset:

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

And draw.

EDIT: Implemented offset with offsetof() as Bahbar suggested.

孤单情人 2024-09-10 23:55:18

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

You're loading data twice to the vbo. The second call to glBufferData is replacing the first one. Then both calls to gl*Pointer actually use the same data when calling draw.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文