现代OpenGL教程(五):obj文件和obj模型加载(imgui+OpenGL3.3)

您所在的位置:网站首页 彩色立方体图片 现代OpenGL教程(五):obj文件和obj模型加载(imgui+OpenGL3.3)

现代OpenGL教程(五):obj文件和obj模型加载(imgui+OpenGL3.3)

2023-09-12 11:14| 来源: 网络整理| 查看: 265

前言:该系列教程主要参考自网站www.opengl-tutorial.org,基于开源GUI框架imgui v1.61实现,imgui自带的例子里面直接集成了glfw+gl3w环境,本系列教程将gl3w换成了glew,glew具体环境配置可参考:OpenGL环境配置教程:VS2012 + GLEW + GLFW + GLM。

教程目录(持续更新中): 现代OpenGL教程(一):绘制三角形(ImGui+OpenGL3.3) 现代OpenGL教程(二):矩阵变换(ImGui+OpenGL3.3) 现代OpenGL教程(三):绘制彩色立方体(ImGui+OpenGL3.3) 现代OpenGL教程(四):立方体纹理贴图(ImGui+OpenGL3.3) 现代OpenGL教程(五):obj模型加载(ImGui+OpenGL3.3) 现代OpenGL教程(六):鼠标和键盘(ImGui+OpenGL3.3) 现代OpenGL教程(七):基础光照——颜色(ImGui+OpenGL3.3) 现代OpenGL教程(八):基础光照——Phong光照模型(ImGui+OpenGL3.3) 现代OpenGL教程(九):基础光照——材质(ImGui+OpenGL3.3)

本节教程在上一节( 现代OpenGL教程(四):立方体纹理贴图(imgui+OpenGL3.3))的基础上,实现了obj文件的读取和在OpenGL中的显示。完整代码下载地址:https://github.com/maijiaquan/blog-code/tree/master/opengl-loadObj

运行效果 obj文件示例 # Blender3D v249 OBJ File: untitled.blend # www.blender3d.org mtllib cube.mtl v 1.000000 -1.000000 -1.000000 v 1.000000 -1.000000 1.000000 v -1.000000 -1.000000 1.000000 v -1.000000 -1.000000 -1.000000 v 1.000000 1.000000 -1.000000 v 0.999999 1.000000 1.000001 v -1.000000 1.000000 1.000000 v -1.000000 1.000000 -1.000000 vt 0.748573 0.750412 vt 0.749279 0.501284 vt 0.999110 0.501077 vt 0.999455 0.750380 vt 0.250471 0.500702 vt 0.249682 0.749677 vt 0.001085 0.750380 vt 0.001517 0.499994 vt 0.499422 0.500239 vt 0.500149 0.750166 vt 0.748355 0.998230 vt 0.500193 0.998728 vt 0.498993 0.250415 vt 0.748953 0.250920 vn 0.000000 0.000000 -1.000000 vn -1.000000 -0.000000 -0.000000 vn -0.000000 -0.000000 1.000000 vn -0.000001 0.000000 1.000000 vn 1.000000 -0.000000 0.000000 vn 1.000000 0.000000 0.000001 vn 0.000000 1.000000 -0.000000 vn -0.000000 -1.000000 0.000000 usemtl Material_ray.png s off f 5/1/1 1/2/1 4/3/1 f 5/1/1 4/3/1 8/4/1 f 3/5/2 7/6/2 8/7/2 f 3/5/2 8/7/2 4/8/2 f 2/9/3 6/10/3 3/5/3 f 6/10/4 7/6/4 3/5/4 f 1/2/5 5/1/5 2/9/5 f 5/1/6 6/10/6 2/9/6 f 5/1/7 8/11/7 6/10/7 f 8/11/7 7/12/7 6/10/7 f 1/2/8 2/9/8 3/13/8 f 1/2/8 3/13/8 4/14/8

其中:

v代表顶点vt代表顶点的纹理坐标vn代表顶点的法线f代表面

v vt vn都很好理解。f比较复杂,例如f 8/11/7 7/12/7 6/10/7: 假设有三角形△ABC,则

6/10/7描述了三角形的第一个顶点A7/12/7描述了三角形的第二个顶点B8/11/7描述了三角形的第三个顶点C

对于第三个顶点C:

8指向顶点C的坐标的索引。此例中是(-1.000000 1.000000 -1.000000)(索引从1开始,和C++中从0开始不同)11指向顶点C要用的纹理坐标。此例中是(0.748355 0.998230)。7指向要用的法线。此例中是(0.000000 1.000000 -0.000000)。 第一步:实现obj文件加载函数 bool loadOBJ( const char *path, std::vector &out_vertices, std::vector &out_uvs, std::vector &out_normals) { printf("Loading OBJ file %s...\n", path); std::vector vertexIndices, uvIndices, normalIndices; std::vector temp_vertices; std::vector temp_uvs; std::vector temp_normals; FILE *file = fopen(path, "r"); if (file == NULL) { printf("Impossible to open the file ! Are you in the right path ? See Tutorial 1 for details\n"); getchar(); return false; } while (1) { char lineHeader[128]; // read the first word of the line int res = fscanf(file, "%s", lineHeader); if (res == EOF) break; // EOF = End Of File. Quit the loop. // else : parse lineHeader if (strcmp(lineHeader, "v") == 0) { glm::vec3 vertex; fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z); temp_vertices.push_back(vertex); } else if (strcmp(lineHeader, "vt") == 0) { glm::vec2 uv; fscanf(file, "%f %f\n", &uv.x, &uv.y); uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders. temp_uvs.push_back(uv); } else if (strcmp(lineHeader, "vn") == 0) { glm::vec3 normal; fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z); temp_normals.push_back(normal); } else if (strcmp(lineHeader, "f") == 0) { std::string vertex1, vertex2, vertex3; unsigned int vertexIndex[3], uvIndex[3], normalIndex[3]; int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2]); if (matches != 9) { printf("File can't be read by our simple parser :-( Try exporting with other options\n"); fclose(file); return false; } vertexIndices.push_back(vertexIndex[0]); vertexIndices.push_back(vertexIndex[1]); vertexIndices.push_back(vertexIndex[2]); uvIndices.push_back(uvIndex[0]); uvIndices.push_back(uvIndex[1]); uvIndices.push_back(uvIndex[2]); normalIndices.push_back(normalIndex[0]); normalIndices.push_back(normalIndex[1]); normalIndices.push_back(normalIndex[2]); } else { // Probably a comment, eat up the rest of the line char stupidBuffer[1000]; fgets(stupidBuffer, 1000, file); } } // For each vertex of each triangle for (unsigned int i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3