Tom*_*m H 3 c++ opengl glut wavefront
我正在尝试在 OpenGL 中从 Starfox 64 绘制这个免费的机翼模型。我在 Blender 中将 .fbx 文件转换为 .obj,并使用tinyobjloader来加载它(我的大学科目的所有要求)。
我几乎将示例代码(使用现代 API)放入我的程序中,替换了文件名,并抓取了attrib.vertices和attrib.normals向量来绘制机翼。
我可以使用 GL_POINTS 查看顶点:
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, &vertices[0]);
glDrawArrays(GL_POINTS, 0, vertices.size() / 3);
glDisableClientState(GL_VERTEX_ARRAY);
Run Code Online (Sandbox Code Playgroud)
哪个看起来是正确的(我......认为?):
但我不确定如何渲染实体模型。简单地用 GL_TRIANGLES(如图所示)或 GL_QUADS 替换 GL_POINTS 是行不通的:
我正在使用 OpenGL 1.1 w/ GLUT(再次,大学)。我想我只是不知道自己在做什么,真的。帮助?
E:当我最初写这个答案时,我只使用了顶点和法线。我已经弄清楚如何让材质和纹理发挥作用,但目前没有时间写出来。当我有时间的时候我会添加这一点,但如果你想同时自己研究一下tinyobj头的话,这基本上是相同的逻辑。:-)
我在最后一天学到了很多关于 TinyOBJLoader 的知识,所以我希望这对将来的人有所帮助。归功于这个 GitHub 存储库,它在fileloader.cpp.
总结一下我在研究该代码时学到的东西:
形状是类型shape_t。对于单个模型 OBJ, 的大小shapes为 1。我假设 OBJ 文件可以包含多个对象,但我对文件格式的使用了解不多。
shape_t有一个mesh类型为 的成员mesh_t。该成员存储从 OBJ 的面部行解析的信息。您可以通过检查成员的大小来计算出对象的面数material_ids。
每个面的顶点、纹理坐标和法线索引存储在indices网格的成员中。这是类型std::vector<index_t>。这是指数的扁平向量。因此,对于具有三角面的模型 f1, f2 ... fi,它会存储v1, t1, n1, v2, t2, n2 ... vi, ti, ni. 请记住,这些索引对应于整个顶点、纹理坐标或法线。就我个人而言,我通过导入 Blender 并在打开三角测量的情况下导出模型来对模型进行三角测量。TinyOBJ 有自己的三角测量算法,您可以通过设置标志来打开reader_config.triangulate。
到目前为止我只处理过顶点和法线。以下是我如何访问和存储它们以便在 OpenGL 中使用:
for (size_t vec_start = 0; vec_start < attrib.vertices.size(); vec_start += 3) {
vertices.emplace_back(
attrib.vertices[vec_start],
attrib.vertices[vec_start + 1],
attrib.vertices[vec_start + 2]);
}
for (size_t norm_start = 0; norm_start < attrib.normals.size(); norm_start += 3) {
normals.emplace_back(
attrib.normals[norm_start],
attrib.normals[norm_start + 1],
attrib.normals[norm_start + 2]);
}
Run Code Online (Sandbox Code Playgroud)
这样,顶点和法线容器的索引将与面条目给出的索引相对应。
for (auto shape = shapes.begin(); shape < shapes.end(); ++shape) {
const std::vector<tinyobj::index_t>& indices = shape->mesh.indices;
const std::vector<int>& material_ids = shape->mesh.material_ids;
for (size_t index = 0; index < material_ids.size(); ++index) {
// offset by 3 because values are grouped as vertex/normal/texture
triangles.push_back(Triangle(
{ indices[3 * index].vertex_index, indices[3 * index + 1].vertex_index, indices[3 * index + 2].vertex_index },
{ indices[3 * index].normal_index, indices[3 * index + 1].normal_index, indices[3 * index + 2].normal_index })
);
}
}
Run Code Online (Sandbox Code Playgroud)
那么绘图就很容易了:
glBegin(GL_TRIANGLES);
for (auto triangle = triangles.begin(); triangle != triangles.end(); ++triangle) {
glNormal3f(normals[triangle->normals[0]].X, normals[triangle->normals[0]].Y, normals[triangle->normals[0]].Z);
glVertex3f(vertices[triangle->vertices[0]].X, vertices[triangle->vertices[0]].Y, vertices[triangle->vertices[0]].Z);
glNormal3f(normals[triangle->normals[1]].X, normals[triangle->normals[1]].Y, normals[triangle->normals[1]].Z);
glVertex3f(vertices[triangle->vertices[1]].X, vertices[triangle->vertices[1]].Y, vertices[triangle->vertices[1]].Z);
glNormal3f(normals[triangle->normals[2]].X, normals[triangle->normals[2]].Y, normals[triangle->normals[2]].Z);
glVertex3f(vertices[triangle->vertices[2]].X, vertices[triangle->vertices[2]].Y, vertices[triangle->vertices[2]].Z);
}
glEnd();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5348 次 |
| 最近记录: |