OpenGL:尝试使用 VBO(顶点缓冲区对象)绘制线条,它不显示

Posted

技术标签:

【中文标题】OpenGL:尝试使用 VBO(顶点缓冲区对象)绘制线条,它不显示【英文标题】:OpenGL: try to draw lines using VBO(vertex buffer object), it doesn't display 【发布时间】:2015-06-12 13:48:39 【问题描述】:

我尝试将我的 openGL 代码从使用显示列表切换到使用 VBO。 在代码中,我尝试绘制一个绿色网格地板,它由与 x 轴平行的绿线和与 z 轴平行的绿线组成。 但是当程序运行时,地板不显示。而且我找不到哪里出了问题。

这是我初始化楼层 VBO 的代码:

//**********************************
//defined in head of my source code
struct BufferVBO1

    GLfloat x;
    GLfloat y;
    GLfloat z;
    GLfloat r;
    GLfloat g;
    GLfloat b;
;
struct IdVBO

    GLuint id;
    size_t bufsiz;
;
IdVBO vboGround;
//**************************************
glGenBuffers(1, &vboGround.id);
int groundSiz1 = ( (floorEdge_x_max-floorEdge_x_min)/(5*LENGTH_UNIT)+1 )*2 ;
int groundSiz2 = ( (floorEdge_z_max-floorEdge_z_min)/(5*LENGTH_UNIT)+1 )*2 ;
vboGround.bufsiz = groundSiz1+groundSiz2 ;
BufferVBO1 *groundBuf = new BufferVBO1 [vboGround.bufsiz];
for(int i=0, idx=0; idx<groundSiz1; ++i)

    groundBuf[idx].x = floorEdge_x_min+i*5*LENGTH_UNIT;
    groundBuf[idx].y = 0;
    groundBuf[idx].z = floorEdge_z_min;
    groundBuf[idx].r = 75/255.0;
    groundBuf[idx].g = 1.0;
    groundBuf[idx].b = 63/255.0;
    ++idx;

    groundBuf[idx].x = floorEdge_x_min+i*5*LENGTH_UNIT;
    groundBuf[idx].y = 0;
    groundBuf[idx].z = floorEdge_z_max;
    groundBuf[idx].r = 75/255.0;
    groundBuf[idx].g = 1.0;
    groundBuf[idx].b = 63/255.0;
    ++idx;

for(int i=0, idx=groundSiz1; idx<vboGround.bufsiz; ++i)

    groundBuf[idx].x = floorEdge_x_min;
    groundBuf[idx].y = 0;
    groundBuf[idx].z = floorEdge_z_min+i*5*LENGTH_UNIT;
    groundBuf[idx].r = 75/255.0;
    groundBuf[idx].g = 1.0;
    groundBuf[idx].b = 63/255.0;
    ++idx;

    groundBuf[idx].x = floorEdge_x_max;
    groundBuf[idx].y = 0;
    groundBuf[idx].z = floorEdge_z_min+i*5*LENGTH_UNIT;
    groundBuf[idx].r = 75/255.0;
    groundBuf[idx].g = 1.0;
    groundBuf[idx].b = 63/255.0;
    ++idx;


glBindBuffer(GL_ARRAY_BUFFER, vboGround.id);
glBufferData(GL_ARRAY_BUFFER, sizeof(BufferVBO1)*vboGround.bufsiz, groundBuf, GL_STATIC_DRAW);
delete [] groundBuf ;
glBindBuffer(GL_ARRAY_BUFFER, 0);

这是要显示的代码:

 glDisable(GL_LIGHTING);
 glBindBuffer(GL_ARRAY_BUFFER, vboGround.id);
 glEnableClientState(GL_VERTEX_ARRAY);
 glVertexPointer(3, GL_FLOAT, sizeof(BufferVBO1), (void*)0);
 glEnableClientState(GL_COLOR_ARRAY);
 glColorPointer( 3, GL_FLOAT, sizeof(BufferVBO1), (void*)(sizeof(GLfloat)*3) );
 for(int i=0; i<vboGround.bufsiz; i+=2)
    glDrawArrays(GL_LINE, i, 2);
 glDisableClientState(GL_VERTEX_ARRAY);
 glDisableClientState(GL_COLOR_ARRAY);
 glBindBuffer(GL_ARRAY_BUFFER, 0);
 glEnable(GL_LIGHTING);

我尝试使用 VBO 绘制一个简单的 GL_QUADS 地板,它可以工作!但是当我尝试绘制绿色网格地板时,它不显示。

告诉我问题出在哪里。

【问题讨论】:

不确定这是否是您唯一的问题,但传递给glBufferData() 的大小以字节为单位。看起来您正在传递顶点数。 感谢您的回复。这是个错误。我把glBufferData(GL_ARRAY_BUFFER, vboGround.bufsiz, groundBuf, GL_STATIC_DRAW);改成glBufferData(GL_ARRAY_BUFFER, sizeof(BufferVBO1)*vboGround.bufsiz, groundBuf, GL_STATIC_DRAW);还是不行!! 【参考方案1】:

这里glDrawArrays()的第一个参数是无效的:

glDrawArrays(GL_LINE, i, 2);

GL_LINE 不是有效的原始类型。你需要使用GL_LINES:

glDrawArrays(GL_LINES, i, 2);

GL_LINE 可能看起来非常相似,但它是glPolygonMode() 的可能参数之一。

当您的 OpenGL 调用未按预期运行时,您应该始终调用 glGetError()。在这种情况下,它应该返回GL_INVALID_ENUM

顺便说一句,您可以在单个 glDrawArrays() 调用中绘制所有线条,而不是使用循环:

glDrawArrays(GL_LINES, 0, vboGround.bufsize);

【讨论】:

以上是关于OpenGL:尝试使用 VBO(顶点缓冲区对象)绘制线条,它不显示的主要内容,如果未能解决你的问题,请参考以下文章

初识OpenGL VBO顶点缓冲对象

OpenGL顶点数组对象不记录VBO和IBO绑定

iPhone Cheetah 3D OpenGL ES 顶点缓冲对象 (VBO) 示例

我的OpenGL学习进阶之旅介绍 顶点数组对象VAO并实战一下

顶点缓冲区对象(删除进程)opengl

使用 VBO 在 OpenGL 中渲染人群