使用OpenGL ES 2.0在glBufferData中加载顶点

3

我正在使用一个处理Wavefront OBJ 3D对象文件的解析器,但我不确定我是否正确地将其加载到OpenGL中。

基本上,我读取我的Wavefront OBJ文件并解析所有数据。

通常在加载数据时,我会按照以下步骤在OpenGL ES 1.1中进行:

glBegin(GL_TRIANGLES);
glNormal3f(normals[faces[i].normal[0]].v[0], normals[faces[i].normal[0]].v[1], normals[faces[i].normal[0]].v[2]);
glVertex3f(vertices[faces[i].vertex[0]].v[0], vertices[faces[i].vertex[0]].v[1], vertices[faces[i].vertex[0]].v[2]);
glNormal3f(normals[faces[i].normal[1]].v[0], normals[faces[i].normal[1]].v[1], normals[faces[i].normal[1]].v[2]);
glVertex3f(vertices[faces[i].vertex[1]].v[0], vertices[faces[i].vertex[1]].v[1], vertices[faces[i].vertex[1]].v[2]);
glNormal3f(normals[faces[i].normal[2]].v[0], normals[faces[i].normal[2]].v[1], normals[faces[i].normal[2]].v[2]);
glVertex3f(vertices[faces[i].vertex[2]].v[0], vertices[faces[i].vertex[2]].v[1], vertices[faces[i].vertex[2]].v[2]);
glEnd();

关于OpenGL ES 2.0,我尝试了以下内容来处理顶点,但没有成功:

glBufferData(GL_ARRAY_BUFFER, obj.vertices.size()*sizeof(float), &(obj.vertices[0].v), GL_STATIC_DRAW);

我的数据结构:

struct vertex {
    std::vector<float> v;
}

每个顶点都会创建一个名为v的向量,其包含{x,y,z}三个元素。

class waveObj {
    public:
        std::vector<vertex> vertices;
        std::vector<vertex> texcoords;
        std::vector<vertex> normals;
        std::vector<vertex> parameters;
        std::vector<face> faces;
}

struct face {
    std::vector<int> vertex;
    std::vector<int> texture;
    std::vector<int> normal;
};

我该如何像在OpenGL ES 1.1中那样加载我的数据到2.0中?

另外,是否可以加载矢量(v),而不是分别加载位置(float x,y,z)?

1个回答

2

有几个选项:

  • 为每个数据创建单独的VBO:一个用于位置,一个用于法线等
  • 创建包含交错数据的单个VBO-但这需要在您的代码中进行一些代码更改。

首先建议使用一个顶点属性+索引缓冲区:

关于索引缓冲区的一件事:

  • 您有单独的位置、法线、纹理索引(您直接从OBJ文件中获取这些值),但如果您想使用IBO(索引缓冲对象)绘制几何图形,则需要创建单个索引。

这是一些代码:

map<FaceIndex, GLushort, FaceIndexComparator>::iterator 
           cacheIndex = cache.find(fi);

if (cacheIndex != cache.end()) {
    node->mIndices.push_back(cacheIndex->second);   
}
else {
    node->mPositions.push_back(positions[fi.v]);
    node->mNormals.push_back(normals[fi.n]);
    node->mTexCoords.push_back(texCoords[fi.t]);
    node->mIndices.push_back((unsigned int)node->mPositions.size()-1);

    cache[fi] = ((unsigned int)node->mPositions.size()-1);
}

它的功能:

  • 对于每个pos、nomal和tex cood,它都有一个向量...但是当OBJ文件中有一个"f"标志时,我会检查我的缓存中是否有三元组。
  • 如果存在这样的三元组,则将该索引放入我的节点索引中。
  • 如果没有,我需要创建新的索引。

那段代码是开源的吗?它看起来比我为OpenGL ES 2.0目的创建的代码更优雅。此外,您提到的第一个选项,您有特定的示例吗?谢谢。 - JavaCake
关于VBO的更多信息:http://www.opengl.org/wiki/Vertex_Specification_Best_Practices,以及http://www.opengl.org/wiki/VBO,当然还有Songho的网站:http://www.songho.ca/opengl/gl_vbo.html。 - fen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接