不能混合 OpenGL 缓冲区和 CPU 缓冲区

Can't mix OpenGL buffers and CPU buffers

我有一些体素引擎代码,可以将块的外表面计算成一系列顶点、法线和纹理坐标数组,并将它们存储在 CPU 内存中,这样我就可以绘制它们.

画完之后,我把选中的脸画成半透明的红脸,放在一切之上。

它有效,但随着世界的发展,它变得缓慢;所以我开始做正确的事情,用 glGenBuffers 生成缓冲区。这也有效,但之后我画的单张脸消失了。我也可能将其移至 GPU 缓冲区,但我想知道为什么会这样。

这大致是我用来从 CPU 内存中绘制的代码(有效,它以红色显示选定的面孔):

// Drawing the world, this is repeated for each chunk
glVertexPointer(3, GL_FLOAT, 0, &mVertex[0]);
glNormalPointer(GL_FLOAT, 0, &mNormal[0]);
glTexCoordPointer(2, GL_FLOAT, 0, &mTexture[0]);
glDrawArrays(GL_QUADS, 0, cVertex.size()/3);

// Drawing the selected face, face*12 or face*8 gives the correct index
glColor4f(1,0,0,0.2);
glVertexPointer(3, GL_FLOAT, 0, &boxVertex[face*12]);
glNormalPointer(GL_FLOAT, 0, &boxNormal[face*12]);
glTexCoordPointer(2, GL_FLOAT, 0, &boxTextureCord[face*8]);
glDrawArrays(GL_QUADS, 0, 4);

结果(无纹理):

这里我展示了从 GPU 内存中绘制的变化(选定的面停止渲染):

// Drawing the world, this is repeated for each chunk
// Buffers have been previously filled with mVertex, mNormal and mTexture
glBindBuffer(GL_ARRAY_BUFFER , mBuffers[0]);
glVertexPointer(3, GL_FLOAT, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER , mBuffers[1]);
glNormalPointer(GL_FLOAT, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[2]);
glTexCoordPointer(2, GL_FLOAT, 0, nullptr);
glDrawArrays(GL_QUADS, 0, cVertex.size()/3);

// Drawing the selected face, face*12 or face*8 gives the correct index
glColor4f(1,0,0,0.2);
glVertexPointer(3, GL_FLOAT, 0, &boxVertex[face*12]);
glNormalPointer(GL_FLOAT, 0, &boxNormal[face*12]);
glTexCoordPointer(2, GL_FLOAT, 0, &boxTextureCord[face*8]);
glDrawArrays(GL_QUADS, 0, 4);

结果(无纹理):

所做的唯一更改是此处显示的更改以及调用 glGenBuffers 然后将缓冲区复制到 GPU 的代码。

OpenGL 是一个状态引擎。状态一旦设置,就会一直保留,直到再次更改。

当您调用 glBindBuffer(GL_ARRAY_BUFFER, mBuffers[2]) 时,命名缓冲区对象 mBuffers[2] 将绑定到目标 GL_ARRAY_BUFFER
以下对 glVertexPointer, glNormalPointer and glTexCoordPointer 的所有调用都使用此缓冲区,并且此函数的最后一个参数被视为缓冲区对象数据存储中的字节偏移量。

如果你想再次使用 "CPU" 缓冲区并直接将内存地址传递给那些函数,那么你必须通过绑定值零来解除绑定当前缓冲区。从目标 GL_ARRAY_BUFFER 解除绑定缓冲区后,最后一个参数指定指向数据数组的指针:

glColor4f(1,0,0,0.2);

glBindBuffer(GL_ARRAY_BUFFER, 0); // zero effectively unbinds any buffer object

glVertexPointer(3, GL_FLOAT, 0, &boxVertex[face*12]);
glNormalPointer(GL_FLOAT, 0, &boxNormal[face*12]);
glTexCoordPointer(2, GL_FLOAT, 0, &boxTextureCord[face*8]);

glDrawArrays(GL_QUADS, 0, 4);