【发布时间】:2013-05-12 18:25:55
【问题描述】:
我正在尝试将顶点缓冲区添加到 pixel city 程序城市生成程序的 Mesh.cpp 文件中。当前部分代码如下所示:
for (qsi = _quad_strip.begin(); qsi < _quad_strip.end(); ++qsi) {
glBegin (GL_QUAD_STRIP);
for (n = qsi->index_list.begin(); n < qsi->index_list.end(); ++n) {
glTexCoord2fv (&_vertex[*n].uv.x);
glVertex3fv (&_vertex[*n].position.x);
}
glEnd ();
}
这会将纹理绘制到某些建筑物的矩形边上。刚刚离开我在网上找到的 VBO 教程,我尝试将其转换为使用这样的顶点缓冲区(我将 vboId 存储在 Mesh.h 中):
for (qsi = _quad_strip.begin(); qsi < _quad_strip.end(); ++qsi) {
void * varray = (char *) malloc(sizeof(GLfloat)*5*qsi->index_list.size());
GLfloat *p = (GLfloat*)varray;
int counter = 0;
for (n = qsi->index_list.begin(); n < qsi->index_list.end(); ++n) {
memcpy(&p[counter+0],&_vertex[*n].uv.x, sizeof(GLfloat)*2);
memcpy(&p[counter+2],&_vertex[*n].position.x, sizeof(GLfloat)*3);
counter+=5;
}
glGenBuffersARB(1, &vboId);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(GLfloat)*5*qsi->index_list.size(), p, GL_STATIC_DRAW_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat)*5, (GLfloat*)0);
glVertexPointer(3, GL_FLOAT, sizeof(GLfloat)*5, (GLfloat*)2);
glDrawArrays(GL_QUAD_STRIP, 0, qsi->index_list.size());
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
free(varray);
}
但是,此代码根本不起作用。什么都没有渲染。有时,当我将参数弄乱到 glTexCoordPointer 或 glVertexPointer 中时,我真的会歪曲/垃圾数据绘制在屏幕上(或程序崩溃),但没有任何东西可以接近远程工作。
【问题讨论】:
-
对每个循环迭代都使用一个新的缓冲区有点达不到目的。
-
另外,这会在几帧后失败,因为你正在快速泄漏 VBO 内存。
-
我打算先让它工作,然后再把它移到循环之外。
-
问题是,您的数据已经完全按照单个 VBO 所需的方式进行布局。你可以只吃整个
_vertex数组。然后使用将n的索引列表传递给glDrawArrays。事实上,现在看起来您正在将顶点数据重新排列为连续的,然后传递一组不连续的索引 - 结果不会很好。 -
哎呀,对不起。您将把索引传递给
glDrawElements。glDrawArrays确实希望数据按顺序排列。