我正在尝试通过复制赋值运算符将两个顶点缓冲区对象从一个Mesh
对象复制到另一个对象。最初,我的顶点数组对象和缓冲区初始化如下:
void Mesh::construct(Vertex* vertices, unsigned int nVerts) {
vertexCount = nVerts;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
std::vector<glm::vec3> positions;
std::vector<glm::vec2> texCoords;
positions.reserve(nVerts);
texCoords.reserve(nVerts);
for (unsigned int i = 0; i < nVerts; i++) {
positions.push_back(vertices[i].getPosition());
texCoords.push_back(vertices[i].getTexCoord());
}
for (int i = 0; i < NUM_BUFFERS; i++) {
glGenBuffers(1, &vab[i]);
}
glBindBuffer(GL_ARRAY_BUFFER, vab[POSITION_VB]);
glBufferData(GL_ARRAY_BUFFER, nVerts * sizeof (positions[0]), &positions[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vab[TEXCOORD_VB]);
glBufferData(GL_ARRAY_BUFFER, nVerts * sizeof (texCoords[0]), &texCoords[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
这在实例化Mesh
对象并调用:
void Mesh::render() {
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glBindVertexArray(0);
}
但是,当我尝试将网格复制到另一个网格并进行渲染时,我在glDrawArrays(GL_TRIANGLES, 0, vertexCount);
行上出现了分段错误。这是我的复制赋值运算符:
Mesh& Mesh::operator=(const Mesh& param) {
if (this == ¶m) {
return *this;
} else {
GLint size = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
for (int i = 0; i < NUM_BUFFERS; i++) {
glGenBuffers(1, &vab[i]);
}
// Vertices
// Bind Buffers
glBindBuffer(GL_COPY_READ_BUFFER, param.vab[POSITION_VB]);
glGetBufferParameteriv(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &size);
glBindBuffer(GL_COPY_WRITE_BUFFER, vab[POSITION_VB]);
glBufferData(GL_COPY_WRITE_BUFFER, size, nullptr, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Copy Data
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, size);
// Texture Coords
// Bind Buffers
glBindBuffer(GL_COPY_READ_BUFFER, param.vab[TEXCOORD_VB]);
glGetBufferParameteriv(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &size);
glBindBuffer(GL_COPY_WRITE_BUFFER, vab[TEXCOORD_VB]);
glBufferData(GL_COPY_WRITE_BUFFER, size, nullptr, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
// Copy Data
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, size);
// Unbind buffers
glBindVertexArray(0);
this->vertexCount = param.vertexCount;
return *this;
}
}
有人能看到任何问题吗?我已经检查过glGetBufferParameteriv(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &size);
返回的大小在两种情况下都是正确的(对于位置和纹理坐标缓冲区)。在调用glGetError()
后,我也检查了glCopyBufferSubData
,这两个都返回0.不确定接下来要尝试什么?我的错误可能在其他地方,但这是我第一次尝试复制缓冲区,所以想要检查我正在做那个部分。如果有帮助,我的Mesh
析构函数是:
Mesh::~Mesh() {
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(NUM_BUFFERS, vab);
}
通过调试器,我可以看到,这当然是在行之后调用一次:
this->mesh = Mesh(*texture);
这只是构建一个网格,然后分配它(纹理只是将四边形的大小调整为纹理的大小,并调用在开头显示的构造函数和正确的顶点位置)。
答案 0 :(得分:4)
您复制数组,但永远不会将复制的版本绑定到GL_ARRAY_BUFFER
,这意味着您的glVertexAttribPointer
调用指向任何内容。
我也对这段代码保持警惕:
glBindBuffer(GL_ARRAY_BUFFER, vab[POSITION_VB]);
glBufferData(GL_ARRAY_BUFFER, nVerts * sizeof (positions[0]), &positions[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vab[TEXCOORD_VB]);
glBufferData(GL_ARRAY_BUFFER, nVerts * sizeof (texCoords[0]), &texCoords[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
似乎位置顶点指针将引用纹理数据,因为当您调用glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
我认为您希望订单如此:
glBindBuffer(GL_ARRAY_BUFFER, vab[POSITION_VB]);
glBufferData(GL_ARRAY_BUFFER, nVerts * sizeof (positions[0]), &positions[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vab[TEXCOORD_VB]);
glBufferData(GL_ARRAY_BUFFER, nVerts * sizeof (texCoords[0]), &texCoords[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
但我不确定。我通常将所有顶点属性交织到一个顶点缓冲区中。