【问题标题】:OpenGL triangle adjacency calculationOpenGL三角形邻接计算
【发布时间】:2016-09-09 20:46:07
【问题描述】:

我正在尝试编写一个程序,该程序使用 OpenGL 的三角形邻接特性 (GL_TRIANGLES_ADJACENCY) 来确定来自本地光源的网格的轮廓。我正在使用 ASSIMP 加载我的网格,就加载和显示网格而言,一切似乎都正常工作。不幸的是,我为存储相邻三角形的索引而编写的代码似乎无法正常工作。

index[0] = mesh.mFaces[i].mIndices[0];
index[2] = mesh.mFaces[i].mIndices[1];
index[4] = mesh.mFaces[i].mIndices[2];
index[1] = findAdjacentIndex( mesh, index[0], index[2], index[4] );
index[3] = findAdjacentIndex( mesh, index[0], index[2], index[4] );
index[5] = findAdjacentIndex( mesh, index[0], index[2], index[4] );

我的算法背后的基本思想是,给定一个网格和来自该网格的三个索引,找到共享第一个和第二个顶点之间的边。然后,返回不使用我们原始传递的三角形的第三个索引的三角形的第三个索引。这样,相同的算法可以按顺序用于三角形的所有索引。

unsigned int Mesh::findAdjacentIndex(const aiMesh& mesh, const unsigned int index1, const unsigned int index2, const unsigned int index3) {
    std::vector<unsigned int> indexMap[2];

    // first pass: find all faces that use the first index
    for( unsigned int i=0; i<mesh.mNumFaces; ++i ) {
        unsigned int*& indices = mesh.mFaces[i].mIndices;
        if( indices[0] == index1 || indices[1] == index1 || indices[2] == index1 ) {
            indexMap[0].push_back(i);
        }
    }

    // second pass: find the two faces that share the second index
    for( unsigned int i=0; i<indexMap[0].size(); ++i ) {
        unsigned int*& indices = mesh.mFaces[indexMap[0][i]].mIndices;
        if( indices[0] == index2 || indices[1] == index2 || indices[2] == index2 ) {
            indexMap[1].push_back(i);
        }
    }

    // third pass: find the face that does NOT use the third index and return its third index
    for( unsigned int i=0; i<indexMap[1].size(); ++i ) {
        unsigned int*& indices = mesh.mFaces[indexMap[1][i]].mIndices;
        if( indices[0] != index3 && indices[1] != index3 && indices[2] != index3 ) {
            if( indices[0] != index1 && indices[0] != index2 ) {
                return indices[0];
            }
            if( indices[1] != index1 && indices[1] != index2 ) {
                return indices[1];
            }
            if( indices[2] != index1 && indices[2] != index2 ) {
                return indices[2];
            }
        }
    }

    // no third index was found, this means there is no face adjacent to this one.
    // return primitive restart index
    return restartIndex;
}

根据我对所写内容的理解,上面的函数应该可以在这个取自 OpenGL 规范的示例图像上完美运行:

Triangle Adjacency Example

不幸的是,我的函数不适用于我的任何现实世界网格,我不知道为什么。例如,通过函数传递一个简单的盒子网格似乎通常返回 0 作为每个顶点的相邻索引,这对我来说没有什么意义。结果是邻接没有正确上传,我的对象的轮廓不正确......

如果这里的任何人都可以因此而阐明出了什么问题以及我可以做些什么来解决它,我将非常感激。如果需要,我也很乐意提供更多信息。

【问题讨论】:

    标签: c++ algorithm opengl 3d adjacency-matrix


    【解决方案1】:

    你让它变得比它需要的复杂得多。您想要搜索共享特定边的三角形并返回第三个顶点。然后就这样做。

    for(unsigned int i=0; i<mesh.mNumFaces; ++i ) {
        unsigned int*& indices = mesh.mFaces[i].mIndices;
        for(int edge = 0; edge < 3; ++edge) { //iterate all edges of the face
            unsigned int v1 = indices[edge]; //first edge index
            unsigned int v2 = indices[(edge + 1) % 3]; //second edge index
            unsigned int vOpp = indices[(edge + 2) % 3]; //index of opposite vertex
            //if the edge matches the search edge and the opposite vertex does not match
            if(((v1 == index1 && v2 == index2) || (v2 == index1 && v1 == index2)) && vOpp != index3)
                return vOpp; //we have found the adjacent vertex
        }
    }
    return -1;
    

    此外,您需要更改通话。如果使用相同的参数调用该函数 3 次,当然会得到相同的结果:

    index[1] = findAdjacentIndex( mesh, index[0], index[2], index[4] );
    index[3] = findAdjacentIndex( mesh, index[2], index[4], index[0] );
    index[5] = findAdjacentIndex( mesh, index[4], index[0], index[2] );
    

    【讨论】:

    • 非常感谢您的帮助,我将尝试您的简化功能。我的示例代码确实有一个错误。在我的实际代码中,我不会连续三次调用相同的函数。我会给你的功能试一试,然后报告它是否有效。
    • 刚刚试了一下。稍作修改,您的解决方案就完美运行了!无论出于何种原因, glPrimitiveRestartIndex() 根本无法正常工作,但在失败情况下返回 index3 解决了剩余的工件。非常感谢您的帮助,非常感谢!
    猜你喜欢
    • 2018-02-11
    • 2014-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    相关资源
    最近更新 更多