1

我在搅拌机中生成模型(Suzie)并将其导出到带有法线的 .obj 文件。在我的应用程序加载模式期间,我注意到顶点和法线的数量不同(2012 年和 1967 年)。

型号详情

我尝试实现简单的单元格着色。问题在于将法线传递给着色器。为了存储顶点数据,我使用来自 glm 的向量。

std::vector<unsigned int> face_indices;
std::vector<unsigned int> normal_indices;
std::vector<glm::vec3> geometry;
std::vector<glm::vec3> normals;

结果我到目前为止

错误的法线

缓冲区布局

    glBindVertexArray(VAO);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
    glBufferData(GL_ARRAY_BUFFER, geometry.size() * sizeof(glm::vec3), &geometry[0], GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, NormalVBOID);
    glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_DYNAMIC_DRAW);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VIndexVBOID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, face_indices.size() * sizeof(unsigned int), &face_indices[0], GL_DYNAMIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

渲染片段

    glBindVertexArray(VAO);

    glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS);
    glDrawElements(GL_QUADS, face_indices.size(), GL_UNSIGNED_INT, (void*)0);

    glBindVertexArray(0);
4

2 回答 2

1

出现这种奇怪问题的原因是一些法线被多次使用以保留磁盘空间,所以我必须以正确的顺序重新排列它们。所以解决方案非常简单。

geometry.clear();
normals.clear();

geometry.resize(vv.size());
normals.resize(vv.size());

for (unsigned int i = 0; i < face_indices.size(); i++)
{
    int vi = face_indices[i];
    int ni = normal_indices[i];
    glm::vec3 v = vv [vi];
    glm::vec3 n = vn [ni];
    geometry[vi] = v ;
    normals[vi]  = n ;
    indices.push_back(vi);
}
于 2013-06-05T17:52:15.887 回答
1

您还应该记住,在导出之前在 Blender 中使用平滑修改器在某些情况下有助于确保每个顶点有 1 个法线(您可能需要也可能不需要设置每个顶点的法线视图而不是面法线视图。 ..can't rem 所以你必须测试)。这是因为默认情况下,blender 使用每个面的法线。平滑修改器(“w”热键菜单)会将其切换为每个顶点规范。然后在导出时,像往常一样导出顶点和规范,并且数字应该匹配。并非总是如此,但这在过去对我有用。这可能意味着在导入期间减少不必要的数据处理。

于 2014-02-25T01:27:29.047 回答