Reputation: 1778
I'm trying to port my fixed function pipeline openGL code to use GLSL, but I'm having a segfault happen with glBufferData
. This was all working very well with the fixed-function stuff (i.e. I could render the loaded mesh no problem).
Here's the code that loads the vertices (from the AssImp importer library):
Defined in the Mesh.h file:
...
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_;
...
implemented in 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...";
}
...
I can't seem to figure out why opengl gives a segfault when I call glBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(glm::vec3), &vertices_[0], GL_STATIC_DRAW);
.
full error is (using gdb in linux):
Program received signal SIGSEGV, Segmentation fault. 0x00007fffefb1ae70 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.304.64
Anyone have any ideas?
Upvotes: 1
Views: 1943
Reputation: 283921
What is this at the top of your constructor?
vaoId_[1];
vboIds_[4];
It looks like your class contains arrays of size zero (that shouldn't even be allowed except as the very last data member, I have no clue how the compiler allowed you to have two of them) and you are writing beyond the boundaries of these arrays, which overwrites the next member (the metadata of the vertices_
vector). This is trashing either the size or data pointer portion of vertices_
and then you pass the trashed data to glBufferData
with predictably bad consequences.
The clue was that glGenBuffers(4, &vboIds_[0]);
also crashed your program. It's because you don't have any space named vboIds
for OpenGL to store the results into.
Change
glm::detail::uint32 vaoId_[];
glm::detail::uint32 vboIds_[];
to actually have the correct dimensions. Arrays without dimensions require a lot of extra care, can only be done at the end of an object, and prevent subclassing. Avoid that if possible. Specify the dimensions or use a vector if the size is variable.
Upvotes: 2