Assimp装载机具有8个顶点的立方体

时间:2016-09-01 10:29:40

标签: opengl blender assimp

我正在加载当前使用这些标志的多维数据集的.obj模型:

const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenNormals | aiProcess_JoinIdenticalVertices);

模型只包含8个顶点(立方体的每个sommet),因此没有重复的顶点来指定assimp来绘制所需的所有三角形。 结果,我只得到了我的盒子的3个三角形。

我相信这是因为我使用:

glDrawArrays(GL_TRIANGLES, 0, vertices.size());

其中vertices.size()等于22(它是mesh-> mNumVertices的返回值)。

我不知道这22,对我来说它应该是8或6 * 2 * 3 = 36(6个面,每个有2个三角形)。任何人都可以解释它的来源吗?

我虽然使用GL_TRIANGLE_STRIP,但顶点的顺序不正确(我甚至不知道它们是否可以)。我得到更多的三角形而不是正确的三角形。

所以我的主要问题是:是否有一个我可以添加到ReadFile的标志 - 或其他东西 - 为要在.obj文件中绘制的每个三角形写一个顶点的副本。

PS:我从Blender导出Wavefront模型,也许是在Blender上我可以设置一些东西来导出redondant顶点。

我的.obj文件:       o 1

  # Vertex list

  v -0.5 -0.5 0.5
  v -0.5 -0.5 -0.5
  v -0.5 0.5 -0.5
  v -0.5 0.5 0.5
  v 0.5 -0.5 0.5
  v 0.5 -0.5 -0.5
  v 0.5 0.5 -0.5
  v 0.5 0.5 0.5

  usemtl Default
  f 4 3 2 1
  f 2 6 5 1
  f 3 7 6 2
  f 8 7 3 4
  f 5 8 4 1
  f 6 7 8 5

编辑:如何使用Qt OpenGL类型设置网格(现在使用EBO):

   void setupMesh(QOpenGLShaderProgram* program)
    {
    // Create Vertex Array Object
    if (!VAO->isCreated()) {
        VAO->create();
    }
    VAO->bind();

    VBO.create();
    VBO.bind();

    VBO.setUsagePattern(QOpenGLBuffer::StaticDraw);

    construct_sg_vertex();

    VBO.allocate(this->m_vec.constData(), this->m_vec.size() * sizeof(m_vec.at(0)));


    EBO.create();
    EBO.bind(); //glBindBuffer(GL_ARRAY_BUFFER, ebo);
    EBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
    EBO.allocate(indices.data(),indices.size()*sizeof(GLuint)); 

    // 0 : positions
    program->enableAttributeArray(0);
    program->setAttributeBuffer(0, GL_FLOAT, Vertex::positionOffset(), Vertex::PositionTupleSize, Vertex::stride());

    //1: colors
    program->enableAttributeArray(1);
    program->setAttributeBuffer(1, GL_FLOAT, Vertex::colorOffset(), Vertex::ColorTupleSize, Vertex::stride());

    VBO.release();
    EBO.release();
}

private:

QOpenGLBuffer VBO ;
QOpenGLVertexArrayObject* VAO = new QOpenGLVertexArrayObject();
QOpenGLBuffer EBO ; //New Element Buffer
};

使用这个添加的索引缓冲区我改变了绘制方式:        VAO-> bind();        glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_INT,0);

因此,根本没有任何内容......

1 个答案:

答案 0 :(得分:1)

从你提供的标志我希望生成24个顶点:一个立方体由6个面组成,每个面由2个三角形组成。当现在生成法线时(根据aiProcess_GenNormals的请求),立方体的每一侧都有4个唯一的顶点。注意,顶点在这里指的是位置和法线的组合。 4个唯一顶点和6个边总共24个顶点。

现在到绘图问题:由于aiProcess_JoinIdenticalVertices是请求,assimp会将所有相同的顶点连接在一起,只留下aiMesh->mVertices数组中的这些唯一顶点。单独,这些信息不足以绘制任何东西。另外需要的是关于如何以三角形组装这些顶点的信息,由aiMesh->mFaces给出。从这些面中,要么必须生成索引缓冲区,要么通过以正确的顺序复制它们将顶点组装成新的数组。下一个代码显示了如何构造索引缓冲区的数据:

std::vector<unsigned int> indices;
indices.reserve(aimesh->mNumFaces * 3);
for (unsigned int fid = 0; fid < aimesh->mNumFaces; fid++)
{
    auto& face = aimesh->mFaces[fid];
    for (size_t iid = 0; iid < 3; iid++)
        indices.push_back(face.mIndices[iid]);
}

指数数据可供OpenGL使用。