You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用正则加载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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 20:45:29