使用正则加载OBJ模型后渲染异常,疑顶点索引有误
OBJ立方体模型加载渲染异常问题排查
问题背景
正在开发一个OBJ模型加载类,通过正则表达式提取顶点数据与顶点索引,使用OpenGL渲染Autodesk Inventor导出的立方体模型时出现异常,怀疑是顶点索引相关问题导致。
使用的正则表达式
- 提取顶点(
v前缀)的正则:
v ([-+]?([0]\.[0-9]*|[1-9]*[0-9]*\.[0-9]*)) ([-+]? ([0]\.[0-9]*|[1-9]*[0-9]*\.[0-9]*)) ([-+]?([0]\.[0-9]*|[1-9]*[0-9]*\.[0-9]*))
- 提取面(
f前缀)的正则:
f ([0-9]|[1-9][0-9]+)\/.*\/.* ([0-9]|[1-9][0-9]+)\ /.*\/.* ([0-9]|[1-9][0-9]+)\/.*\/.*
数据存储结构
提取的数据存储到以下向量中:
std::vector<glm::fvec3> vertices_postion; std::vector<GLint> vertices_postion_indicies;
OpenGL数据上传代码
glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, vertices_postion.size() * sizeof(glm::fvec3), &vertices_postion[0], GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertices_postion_indicies.size() * sizeof(GLint), &vertices_postion_indicies[0], GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0);
渲染代码
glUseProgram(shader->getProgram()); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, vertices_postion_indicies.size(), GL_UNSIGNED_INT, (void*)0);
模型数据
顶点数据
v1: -5 v2: 0 v3: -5 v1: -5 v2: 0 v3: 5 v1: -5 v2: 10 v3: 5 v1: -5 v2: 10 v3: -5 v1: 5 v2: 0 v3: -5 v1: 5 v2: 10 v3: -5 v1: 5 v2: 0 v3: 5 v1: 5 v2: 10 v3: 5
顶点索引数据
1,2,4,4,2,3,5,1,6,6,1,4,7,5,8,8,5,6,2,7,3,3,7,8,2,1,7,7,1,5,8,6,3,3,6,4
异常渲染效果

问题分析与修复方案
1. 索引类型不匹配
OpenGL渲染时指定了GL_UNSIGNED_INT作为索引类型,但存储索引的向量用的是GLint(有符号整数),类型不匹配会导致索引解析错误。
- 修复:将索引向量类型改为
GLuint:
std::vector<GLuint> vertices_postion_indicies;
- 同步修改EBO上传代码的
sizeof参数:
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertices_postion_indicies.size() * sizeof(GLuint), &vertices_postion_indicies[0], GL_STATIC_DRAW);
2. OBJ索引与OpenGL索引计数规则不兼容
OBJ文件中顶点索引从1开始计数,而OpenGL的顶点数组是0-based(从0开始),直接使用提取的索引会访问错误的顶点甚至越界。
- 修复:提取索引后,每个值减1再存入向量。例如提取到索引
1,存入时改为0,以此类推。
3. 正则表达式语法错误
提取f前缀的正则中有多余空格(\ /.*\/.*部分的空格),会导致匹配失败,无法正确提取索引。
- 修复:删除多余空格,修正后的正则:
f ([0-9]|[1-9][0-9]+)\/.*\/.* ([0-9]|[1-9][0-9]+)\/.*\/.* ([0-9]|[1-9][0-9]+)\/.*\/.*
内容的提问来源于stack exchange,提问作者lostsky25
相关产品推荐
相关产品推荐

