2013-01-10 42 views
0

我試圖移植我的固定功能管道openGL代碼來使用GLSL,但我有一個segfault與glBufferData發生。這一切都與固定功能的東西很好(即我可以渲染加載的網格沒有問題)。glBufferData上的段錯誤

下面是加載頂點(從AssImp進口商庫)的代碼:

... 
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..."; 
} 
... 
在Mesh.h文件中定義

我似乎無法弄清楚爲什麼在我打電話給glBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(glm::vec3), &vertices_[0], GL_STATIC_DRAW);時,opengl會給出段錯誤。

滿誤差(在linux用gdb):

計劃接收信號SIGSEGV,分割故障。 0x00007fffefb1ae70在?? ()從 /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.304.64

人有什麼想法?

+0

'vertices_.size()'和'&vertices_ [0]'的值是什麼? –

+0

values: vertices_.size():17964 (sizeof(glm :: vec3):12 (&vertices_ [0]):0x3f2a000 – Jarrett

+0

它可以用較小的緩衝區大小嗎?(比如'16 * sizeof(glm :: vec3)') –

回答

2

這是什麼在你的構造函數的頂部?

vaoId_[1]; 
vboIds_[4]; 

它看起來像你的類包含大小爲0陣列(即甚至不應該被允許,除非在最後的數據成員,我不知道編譯器如何讓你有兩個),你正在寫入這些數組的邊界之外,這會覆蓋下一個成員(vertices_矢量的元數據)。這會損壞vertices_的大小或數據指針部分,然後將已刪除的數據傳遞給glBufferData,從而產生可預料的不良後果。

線索是,glGenBuffers(4, &vboIds_[0]);也崩潰了你的程序。這是因爲你沒有任何用於OpenGL的空間vboIds來存儲結果。

變化

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

實際上有正確的尺寸。沒有維度的數組需要很多額外的關注,只能在對象的末尾完成,並防止子類化。如果可能,避免這種情況。如果尺寸是可變的,則指定尺寸或使用矢量。

+0

男人,這是一些聰明的偵探:)修正了它!非常感謝Ben!現在我只需要弄清楚爲什麼我的GLSL着色器是seg faulting哈哈:) – Jarrett

4

您需要在glBufferData之前致電glBindBuffer

+0

廢話,你說得對,我把它搬上了(並編輯了上面的問題)。得到相同的錯誤... – Jarrett