C++结合OpenGL新增顶点布局、VAO类后无法渲染,报错1281无效值
错误1:IndexBuffer类绑定逻辑错误
IndexBuffer的bind()和unbind()方法错误绑定到了GL_ARRAY_BUFFER,索引缓冲必须绑定到GL_ELEMENT_ARRAY_BUFFER,否则VAO无法正确关联索引数据,绘制时会触发无效值错误。
修复代码:
void IndexBuffer::bind() const { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferId); } void IndexBuffer::unbind() const { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
错误2:VertexArray的addBuffer逻辑错误
当前实现存在三个问题:
- 所有顶点属性都固定绑定到位置0,多属性场景会覆盖配置
- 步长参数传入了单个属性的大小,正确应该是单个完整顶点的总字节大小
- 偏移量
offset计算后没有传入glVertexAttribPointer,固定传了0 - ElementLayout结构体不需要单独存stride,stride是所有属性大小的总和
修复方案:
首先修改VertexLayout相关代码,增加总步长计算:
// VertexLayout.h struct ElementLayout { unsigned int size; // 单个属性的分量数 unsigned int type; // 数据类型 unsigned int normalized; // 是否归一化 }; class VertexLayout { private: std::vector<ElementLayout> elements; unsigned int m_stride = 0; // 单个顶点总步长 public: VertexLayout() = default; ~VertexLayout() = default; void layoutPush(unsigned int size) { elements.push_back({size, GL_FLOAT, GL_FALSE}); m_stride += size * sizeof(float); } std::vector<ElementLayout> getElements() const { return elements; } unsigned int getStride() const { return m_stride; } };
然后修改addBuffer实现:
void VertexArray::addBuffer(VertexBuffer& vb, VertexLayout& layout) { bind(); vb.bind(); const auto& elements = layout.getElements(); unsigned int offset = 0; for (unsigned int i = 0; i < elements.size(); i++) { glEnableVertexAttribArray(i); glVertexAttribPointer(i, elements[i].size, elements[i].type, elements[i].normalized, layout.getStride(), (void*)offset); offset += elements[i].size * sizeof(float); } }
错误3:主函数调用逻辑错误
- 你手动创建了
testVAO并绑定,后续va.addBuffer是配置的另一个VAO对象,渲染时没有绑定你自己封装的va对象 - 开启
va.addBuffer后,手动写的glVertexAttribPointer和glEnableVertexAttribArray属于testVAO的配置,和你封装的va无关
修复主函数逻辑:
// 删掉手动创建test VAO的相关代码,全部用你封装的类 VertexBuffer vb(vertices, 5 * 3 * sizeof(float)); IndexBuffer ib(indices, 6 * sizeof(unsigned int)); VertexLayout layout; layout.layoutPush(3); VertexArray va; va.addBuffer(vb, layout); // 渲染循环里绘制前绑定VAO和IBO va.bind(); ib.bind(); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
内容的提问来源于stack exchange,提问作者Razielruss
相关产品推荐
相关产品推荐

