0

固定関数パイプラインの openGL コードを移植して GLSL を使用しようとしていますが、glBufferData. これはすべて、固定機能のもので非常にうまく機能していました (つまり、ロードされたメッシュを問題なくレンダリングできました)。

頂点をロードするコードは次のとおりです (AsImp インポーター ライブラリから)。

Mesh.h ファイルで次のように定義されています。

...
glm::detail::uint32 vaoId_[];
    glm::detail::uint32 vboIds_[];

    std::vector< glm::vec3 > vertices_;
    std::vector< glm::vec3 > normals_;
    std::vector< glm::vec2 > textureCoordinates_;
    std::vector< glm::vec4 > colors_;
...

Mesh.cpp で実装:

...
Mesh::Mesh(const aiMesh* mesh) {
    vaoId_[1];
    vboIds_[4];

    BOOST_LOG_TRIVIAL(debug) << "loading mesh...";

    glm::detail::uint32 currentIndex = 0;

    for (glm::detail::uint32 t = 0; t < mesh->mNumFaces; ++t) {
        const aiFace* face = &mesh->mFaces[t];
        GLenum face_mode;

        switch(face->mNumIndices) {
            case 1: face_mode = GL_POINTS; break;
            case 2: face_mode = GL_LINES; break;
            case 3: face_mode = GL_TRIANGLES; break;
            default: face_mode = GL_POLYGON; break;
        }

        glm::detail::uint32 numIndices = face->mNumIndices;

        vertices_.resize( currentIndex + numIndices );
        normals_.resize( currentIndex + numIndices );
        textureCoordinates_.resize( currentIndex + numIndices );
        colors_.resize( currentIndex + numIndices );

        //BOOST_LOG_TRIVIAL(debug) << "loading face: " << face->mNumIndices;
        // go through all vertices in face
        for(glm::detail::uint32 i = 0; i < numIndices; i++) {
            // get group index for current index i
            int vertexIndex = face->mIndices[i];

            if (mesh->mNormals != 0) {
                vertices_[currentIndex + i]     = glm::vec3( mesh->mVertices[vertexIndex].x, mesh->mVertices[vertexIndex].y, mesh->mVertices[vertexIndex].z );
                normals_[currentIndex + i]      = glm::vec3( mesh->mNormals[vertexIndex].x, mesh->mNormals[vertexIndex].y, mesh->mNormals[vertexIndex].z );
            }

            if (mesh->HasTextureCoords(0)) {
                textureCoordinates_[currentIndex + i] = glm::vec2( mesh->mTextureCoords[0][vertexIndex].x, mesh->mTextureCoords[0][vertexIndex].y );
            }

            //utilities::AssImpUtilities::color4_to_vec4(&mesh->mColors[0][vertexIndex], colors_[colors_.size() + i]);
            if (mesh->mColors[0] != 0) {
                colors_[currentIndex + i]           = glm::vec4(
                                                        (float)mesh->mColors[0][vertexIndex].a,
                                                        (float)mesh->mColors[0][vertexIndex].b,
                                                        (float)mesh->mColors[0][vertexIndex].g,
                                                        (float)mesh->mColors[0][vertexIndex].r
                                                    );
            }           
        }

        currentIndex += 3;
    }

    BOOST_LOG_TRIVIAL(debug) << "loading mesh into video memory...";

    BOOST_LOG_TRIVIAL(debug) << "blah: " << vertices_.size();
    BOOST_LOG_TRIVIAL(debug) << "blah: " << ( sizeof(glm::vec3) );
    BOOST_LOG_TRIVIAL(debug) << "blah: " << ( &vertices_[0] );

    // create our vao
    glGenVertexArrays(1, &vaoId_[0]);
    glBindVertexArray(vaoId_[0]);

    // create our vbos
    //glGenBuffers(4, &vboIds_[0]);
    glGenBuffers(1, &vboIds_[0]); // Using only '1' for now (otherwise causes seg fault)
    glBindBuffer(GL_ARRAY_BUFFER, vboIds_[0]);
    glBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(glm::vec3), &vertices_[0], GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    // Disable our Vertex Buffer Object
    glBindVertexArray(0);

    BOOST_LOG_TRIVIAL(debug) << "done loading mesh...";
}
...

を呼び出したときに opengl が segfault を返す理由がわかりませんglBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(glm::vec3), &vertices_[0], GL_STATIC_DRAW);

完全なエラーは次のとおりです(Linuxでgdbを使用):

プログラム受信信号 SIGSEGV、セグメンテーション違反。0x00007fffefb1ae70 in ?? () /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.304.64 から

誰にもアイデアはありますか?

4

2 に答える 2

4

glBindBufferの前に電話する必要がありますglBufferData

于 2013-01-10T19:46:54.117 に答える
2

コンストラクターの上部にあるこれは何ですか?

vaoId_[1];
vboIds_[4];

あなたのクラスにはサイズ 0 の配列が含まれているようです (最後のデータ メンバー以外は許可されるべきではありません。コンパイラが 2 つの配列を持つことをどのように許可したかはわかりません)。これらの境界を超えて書いています。次のメンバー (vertices_ベクターのメタデータ) を上書きします。これは、のサイズまたはデータ ポインター部分のいずれかをvertices_破棄し、破棄されたデータを に渡し、glBufferData予想どおり悪い結果をもたらします。

手がかりはglGenBuffers(4, &vboIds_[0]);、プログラムもクラッシュしたことでした。vboIds結果を格納するための OpenGL 用の名前のスペースがないためです。

変化する

glm::detail::uint32 vaoId_[];
glm::detail::uint32 vboIds_[];

実際に正しい寸法を持っています。次元のない配列は特別な注意が必要で、オブジェクトの最後でしか実行できず、サブクラス化を妨げます。可能であればそれを避けてください。次元を指定するか、サイズが可変の場合はベクトルを使用します。

于 2013-01-10T21:22:46.373 に答える