我创建了一个.obj加载器,它从在blender 2.66中创建的网格文件中读取,并将数据加载到作为VBO传递给Opengl的std :: vector中。网格文件中的所有顶点都没有(0,0,0)的位置。 那么,网格在中心获得额外顶点的可能原因是什么?由于原始网格只是一个只有四个顶点的三角形平面。
struct Vertex
{
//Position
GLfloat m_X;
GLfloat m_Y;
GLfloat m_Z;
//Normal
GLfloat m_NX;
GLfloat m_NY;
GLfloat m_NZ;
//TexCoords
GLfloat m_U;
GLfloat m_V;
};
void Mesh::loadMesh(std::string Filename)
{
...
const unsigned int PositionAttribute = 0;
const unsigned int NormalAttribute = 1;
const unsigned int TexCoordAttribute = 2;
//Create a new VBO and use the variable id to store the VBO id
glGenBuffers(1, &MeshVBO);
//make the new VBO active
glBindBuffer(GL_ARRAY_BUFFER, MeshVBO);
//Pass the Mesh's vertex data into the VBO to be transferred to super fast Video RAM
glBufferData(GL_ARRAY_BUFFER, m_Vertices.size() * sizeof(Vertex), &m_Vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(PositionAttribute);
glEnableVertexAttribArray(NormalAttribute);
glEnableVertexAttribArray(TexCoordAttribute);
//specifies the location and data of an array of vertex
glVertexAttribPointer(PositionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
glVertexAttribPointer(NormalAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(GLfloat) * 3)); //12 byte offset
glVertexAttribPointer(TexCoordAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(GLfloat) * 6)); //24 byte offset
//make the new VBO active
glBindBuffer(GL_ARRAY_BUFFER, MeshVBO);
glGenBuffers(1, &MeshIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, MeshIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (sizeof(GLushort) * m_IndexList.size()), &m_IndexList[0], GL_STATIC_DRAW);
//Cleanup
delete[] m_VertexArray;
delete[] m_Indices;
m_VertexArray = NULL;
m_Indices = NULL;
return Success;
}
void Mesh::drawMesh()
{
glDrawElements(GL_POINTS, (GLsizei)m_IndexList.size() + 1, GL_UNSIGNED_SHORT, 0);
}
Plane.obj
# Blender v2.66 (sub 1) OBJ File: ''
# www.blender.org
mtllib plane.mtl
o Plane
v 0.622129 -0.622129 0.000000
v -0.622129 -0.622129 0.000000
v 0.622129 0.622129 -0.000000
v -0.622129 0.622129 -0.000000
vn 1.000000 0.000000 0.000000
usemtl None
s off
f 2//1 1//1 3//1
f 4//1 2//1 3//1
答案 0 :(得分:4)
您的主要问题是OBJ文件中的索引是基于1的,而OpenGL使用基于0的索引。这意味着您必须从OBJ文件中读取的索引中减去1。在您阅读解析代码中的索引之后,这是最方便的,因为大多数编程语言和API使用基于0的索引。
如果您希望能够读取更多选择的OBJ文件,则还必须在输入文件中处理负索引值。这似乎并不常用,如果文件来自一个控制良好的源(例如,您总是使用相同的软件自己生成它们),您可以跳过此步骤。如果存在,则负指数相对于到目前为止读取的顶点的末尾。例如。 index -1是最新的顶点读取,-2是最新的顶点读取等。
在发布的代码中,您在绘图调用中添加了1到可用索引的数量:
glDrawElements(GL_POINTS, (GLsizei)m_IndexList.size() + 1, GL_UNSIGNED_SHORT, 0);
我怀疑您可能已经这样做以弥补错误的索引值。获得正确的索引值后,应删除+ 1
。
有关OBJ格式的更详细文档,维基百科页面(http://en.wikipedia.org/wiki/Wavefront_.obj_file)包含一个很好的概述。我发现的最详细和最全面的定义是:http://www.martinreddy.net/gfx/3d/OBJ.spec。 OBJ格式可以包含相当高级的功能,如NURBS。如果您编写自己的解析器和渲染器,您可能希望找到一个子集。否则你会忙一段时间。
如果您想了解更多有关如何有效地从OBJ文件渲染网格的深入信息,以下是我对早期问题的一些相关答案: