6

我正在尝试在 OOP 中为 VBO 编写一个包装器,它由 addVertex、addNormal..addX、flush() 和 render() 函数组成。起初,我将顶点、法线、索引保存在单独的向量中,例如:

std::vector<glm::vec4> vertexBuffer;
std::vector<glm::vec4> colorBuffer;
std::vector<glm::vec3> normalBuffer;
std::vector<glm::vec2> texCoordBuffer;
std::vector<unsigned int> indexBuffer;

但是当我在某处读到时,为每个人保存不同的 VBO ID 是完全低效的,因此最好将它们按 VertexNormalTexCoordColor - VNTC - VNTC ... 的顺序打包,并在单个 VBO ID 中表示它们。因此,缓冲区在上传到 GPU 时可以有效地使用。所以这次我仍然将它们保存在向量中,但是当我调用 flush() 时,我想用结构体打包它们,然后将该结构体向量上传到 GPU:

struct VBOData {
    glm::vec4 vert;
    glm::vec3 normal;
    glm::vec4 color;
    glm::vec2 texcoord;
};
std::vector<VBOData> vboBuffer;

然后我在 flush() 中上传所有内容:

vboBuffer.reserve(vertexBuffer.size());

for (int i = 0; i < vertexBuffer.size(); ++i) {
    VBOData data;
    data.vert = vertexBuffer[i];
    data.color = colorBuffer[i];
    data.normal = normalBuffer[i];
    data.texcoord = texCoordBuffer[i];
    vboBuffer.push_back(data);
}

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vboBuffer.size() * sizeof(VBOData), (GLchar*) &vboBuffer[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

现在出现了这个问题,如果我的对象不包含颜色、法线或 tex 坐标并且只包含顶点怎么办?还是仅关于顶点和法线?或者总是有顶点的不同数据组合?我可以按 V(N)(T)(C) 顺序动态打包它们以提高效率吗?

4

1 回答 1

1

Now there is this problem, what if my object doesn't contain colors, normals, or tex coords and only consists of vertices ? Or only about vertices and normals ?

Then you are going to set the offset to components you got with glVertexAttribPointer, and not set of components you are not using.

BTW you have a nice tutorial on opengl.org about VBOs.

于 2013-10-16T06:23:50.910 回答