我使用Vertex Array快速绘制了很多三角形:
void initializeGL() {
...
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(3, GL_FLOAT, 0, colors);
}
void paintGL() {
...
glDrawElements(GL_TRIANGLES, 3*numTriangles, GL_UNSIGNED_INT, indices);
}
但是我想通过使用顶点缓冲对象(VBO)来使渲染速度更快。
我是否理解glVertexPointer()告诉GPU它在CPU中哪里可以获取顶点数据然后GPU从每个paintGL()的CPU中的这个位置复制它?
使用VBO可以通过将顶点数据仅写入GPU一次来改善这一点吗?
我正在使用Qt我尝试使用QGLBuffer类:
void GLWidget::initializeGL() {
...
vertexBuffer = new QGLBuffer(QGLBuffer::VertexBuffer);
vertexBuffer->create();
vertexBuffer->bind();
vertexBuffer->setUsagePattern(QGLBuffer::StaticDraw);
vertexBuffer->allocate(vertices, 3*numVertices*sizeof(float)); // copies vertices to GPU?
vertexBuffer->release();
#define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glColorPointer(3, GL_FLOAT, 0, colors);
}
当我运行它时,它会在崩溃之前挂起很长时间:-(。 如果我注释掉vertexBuffer-> release();它根本不显示任何内容,但不会崩溃。
我在这里做错了什么?
另外:我怎么能同样只将我的颜色发送到GPU一次? 没有QGLBuffer :: ColorBuffer类型!?
编辑: 我在我的项目中包含了GLee。[h / c]并通过以下方式替换了QGLBuffer调用:
unsigned int vbufferid;
glGenBuffers(1, &vbufferid);
glBindBuffer(GL_ARRAY_BUFFER, vbufferid);
int size = 3*numVertices*sizeof(float);
glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW);
但代码仍然没有绘制任何东西!?
通过glGenBuffers调用为vbufferid分配值1,所以我不认为问题是我的显卡。
编辑2: 我发现如果我注释掉glEnableClientState(GL_COLOR_ARRAY);用VBO(但没有颜色)显示三角形的线!
那么在将VBO用于顶点时,如何将颜色传输到GPU?
没有GL_COLOR_BUFFER类型!?
答案 0 :(得分:1)
我是否正确地理解glVertexPointer()告诉GPU它在CPU中哪里可以获取顶点数据然后GPU从每个paintGL()的CPU中的这个位置复制它?
使用VBO可以通过将顶点数据仅写入GPU一次来改善这一点吗?
这是关于一般的想法,虽然实际的执行(你不必关心)有点琐碎。
一个常见的误解是:OpenGL没有“初始化”。当然,您可以在初始阶段将某些资源上传到OpenGL,但是作为状态机,OpenGL需要在您需要之前进入所需状态。
然后就是你真正的问题:你的顶点位置在缓冲对象中。但是你的颜色不是。但是你给OpenGL一个指针,它误解为顶点缓冲区的偏移量。
所以我建议你在glDrawElements
电话之前移动以下几行:
#define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vbufferid);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glBindBuffer(GL_ARRAY_BUFFER, 0); // or put the colors into a VBO as well
glColorPointer(3, GL_FLOAT, 0, colors);
glDrawElements(…
请注意,缓冲区在执行glVertexPointer调用之前显式绑定,并在颜色指针之前解除绑定。
但是,拥有VBO中的一些属性,而有些属性并未达到目的。因此我建议你将所有的顶点属性移动到VBO中,最好是一个VBO,一个接着一个数组(步长0和它们之间的偏移)或交错(stride =整个属性向量的大小,偏移量是偏移量)第一个属性向量)。
上传到VBO
unsigned int vbufferid;
glGenBuffers(1, &vbufferid);
glBindBuffer(GL_ARRAY_BUFFER, vbufferid);
int vertexbufsize = (3)*numVertices*sizeof(float);
int colorbufsize = (3)*numVertices*sizeof(float);
glBufferData(GL_ARRAY_BUFFER, vertexbufsize + colorbufsize, NULL, GL_STATIC_DRAW); // data=NULL : initialize, but don't copy
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexbufsize, vertices);
glBufferSubData(GL_ARRAY_BUFFER, vertexbufsize, colorbufsize, vertices);
使用VBO组合绘图
#define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vbufferid);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(vertexbufsize));
glDrawElements(…