调用glDrawArrays()触发访问违例异常,现代OpenGL模型类报错求助
这个错误(读取位置0x00000000的访问违例)几乎肯定是因为OpenGL尝试访问未正确绑定或配置的空资源,结合你是现代OpenGL新手的情况,咱们从最常见的几个点排查:
1. 绘制前是否绑定了对应的VAO?
现代OpenGL中,所有顶点属性配置都存在VAO里,如果你在调用glDrawArrays()前没有执行glBindVertexArray(yourVAOID),OpenGL会使用默认的0号VAO——而这个VAO根本没有配置任何顶点属性,自然会尝试读取空内存。
看你的RawModel类存储了vaoID,那绘制代码必须包含:
// 绘制时的正确流程 glBindVertexArray(rawModel.vaoID); // 关键:绑定你创建的VAO glDrawArrays(GL_TRIANGLES, 0, rawModel.vertexCount); glBindVertexArray(0); // 可选:解绑VAO避免后续误操作
如果漏掉了glBindVertexArray这一步,直接调用glDrawArrays,大概率会触发这个错误。
2. VAO的配置是否完整且正确?
创建VAO时,你需要确保完成以下步骤,缺一不可:
- 生成并绑定VAO:
glGenVertexArrays(1, &vaoID); glBindVertexArray(vaoID); - 生成、绑定VBO,并传入顶点数据:
unsigned int vboID; glGenBuffers(1, &vboID); glBindBuffer(GL_ARRAY_BUFFER, vboID); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - 设置顶点属性指针并启用:
// 假设是3维顶点坐标,属性位置0 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); glEnableVertexAttribArray(0); // 必须启用!不启用的话OpenGL会忽略这个属性
如果glEnableVertexAttribArray没调用,或者设置指针时VBO没绑定,VAO里的配置就是无效的,绘制时同样会读空地址。
3. 检查vertexCount是否匹配实际数据
你传入glDrawArrays的vertexCount必须和VBO里实际存储的顶点数量一致。比如你VBO里存了36个顶点(12个三角形),但vertexCount传了40,OpenGL会越界读取内存,也可能触发访问违例。
4. 确认GLEW初始化正确
虽然这个错误是在nvoglv32.dll里触发,但还是要确认你是在创建OpenGL上下文之后才调用glewInit(),并且检查了返回值:
GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "GLEW初始化失败: %s\n", glewGetErrorString(err)); // 处理错误 }
如果GLEW没正确初始化,部分OpenGL函数指针可能为空,但这个场景下概率较低,不过还是要排除。
快速验证方法
你可以先写一个极简的测试代码:创建一个VAO、VBO,填充几个三角形的顶点数据,绑定后调用glDrawArrays,如果这个测试能正常运行,说明问题出在你的RawModel类的创建或绘制流程里——大概率是VAO没绑定,或者VAO配置时漏了步骤。
内容的提问来源于stack exchange,提问作者joszko

