我'm trying to port my fixed function pipeline openGL code to use GLSL, but I'与 glBufferData
发生了段错误 . 这对固定功能的东西都很好(即我可以渲染加载的网格没有问题) .
这是加载顶点的代码(来自AssImp导入器库):
在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...";
}
...
当我打电话给 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
有人有主意吗?
2 回答
在构造函数的顶部是什么?
看起来你的类包含大小为零的数组(除了作为最后一个数据成员之外,甚至不应该允许它,我不知道编译器如何允许你有两个这样的数组)并且你正在写超出这些数据的边界数组,覆盖下一个成员(
vertices_
向量的元数据) . 这会破坏vertices_
的大小或数据指针部分,然后将已删除的数据传递给glBufferData
,并带来可预测的不良后果 .线索是
glGenBuffers(4, &vboIds_[0]);
也破坏了你的程序 . 它's because you don'有任何名为vboIds
的空间用于OpenGL来存储结果 .更改
实际上有正确的尺寸 . 没有维度的数组需要额外的关注,只能在对象的末尾完成,并防止子类化 . 尽可能避免 . 如果大小可变,请指定尺寸或使用矢量 .
您需要在
glBufferData
之前调用glBindBuffer
.