OpenGL---加载obj模型
2017-03-04 16:22
399 查看
obj文件格式介绍:http://www.cnblogs.com/youthlion/archive/2013/01/21/2870451.html
mesh.h
main.cpp
1.obj
不足:没有对纹理处理,比如没有纹理图片,缺乏相关操作等。
—————————–变一下样式———————————-
将drawMesh()修改一下(仍然没有对纹理进行处理)
mesh.h
#pragma once #include "vector" #include "iostream" #include "string" #include "fstream" #include "sstream" #include "algorithm" #include "assert.h" #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #pragma comment(lib, "glut.lib") using namespace std; struct vec3 { double x, y, z; }; struct vec2 { double x, y; }; class Vertex { public: int vertIndex; // 此顶点在顶点列表中的索引 int normIndex; // 顶点的法线索引 int textIndex; // 顶点的纹理索引 }; class Face { public: vector<Vertex> vertex; // 顶点和法线索引组成的列表 Face(){} ~Face(){} }; class Mesh { private: vector<vec3> vVertex; // 顶点数组 vector<vec2> vText; // 纹理数组 vector<vec3> vNorm; // 法线数组 vector<Face> vFace; // 面片数组 public: Mesh(){}; ~Mesh(){}; bool readFile(char* path); void drawMesh(); }; bool Mesh::readFile(char* path) { ifstream file(path); if (!file) { cerr << "Error::ObjLoader, could not open obj file:" << path << " for reading." << std::endl; return false; } string line; while (getline(file, line)) { if (line.substr(0, 2) == "vt") // 顶点纹理坐标数据 { istringstream s(line.substr(2)); vec2 v; s >> v.x; s >> v.y; //cout << "vt " << v.x << " " << v.y << endl; v.y = -v.y; // 注意这里加载的dds纹理 要对y进行反转 vText.push_back(v); } else if (line.substr(0, 2) == "vn") // 顶点法向量数据 { istringstream s(line.substr(2)); vec3 v; s >> v.x; s >> v.y; s >> v.z; //cout << "vn " << v.x << " " << v.y << " " << v.z << endl; vNorm.push_back(v); } else if (line.substr(0, 1) == "v") // 顶点位置数据 { istringstream s(line.substr(1)); vec3 v; s >> v.x; s >> v.y; s >> v.z; //cout << "v " << v.x << " " << v.y << " " << v.z << endl; vVertex.push_back(v); } else if (line.substr(0, 1) == "f") // 面数据 { Face face; //cout << "f "; istringstream vtns(line.substr(1)); string vtn; while (vtns >> vtn) // 处理一行中多个顶点属性 { Vertex vertex; replace(vtn.begin(), vtn.end(), '/', ' '); istringstream ivtn(vtn); if (vtn.find(" ") != string::npos) // 没有纹理数据,注意这里是2个空格 { ivtn >> vertex.vertIndex >> vertex.normIndex; vertex.vertIndex--; //使得下标从0开始 vertex.normIndex--; } else { ivtn >> vertex.vertIndex >> vertex.textIndex >> vertex.normIndex; //cout << vertex.vertIndex << "/" << vertex.textIndex << "/" << vertex.normIndex << " "; vertex.vertIndex--; vertex.textIndex--; vertex.normIndex--; } face.vertex.push_back(vertex); } vFace.push_back(face); //cout << endl; } else if (line[0] == '#') // 注释忽略 { } else { // 其余内容 暂时不处理 } } return true; } void Mesh::drawMesh() { if(vFace.empty()) return; // 有纹理 if(vText.size() > 0) { for(int f = 0; f < vFace.size(); f++) // 绘制每个面片 { int n = vFace[f].vertex.size(); // 面的顶点数 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_TRIANGLES); for(int v = 0; v < n; v++) { int it = vFace[f].vertex[v].textIndex; glTexCoord2f(vText[it].x, vText[it].y); int in = vFace[f].vertex[v].normIndex; glNormal3f(vNorm[in].x, vNorm[in].y, vNorm[in].z); int iv = vFace[f].vertex[v].vertIndex; glVertex3f(vVertex[iv].x, vVertex[iv].y, vVertex[iv].z); } glEnd(); } } // 没有纹理 else { for(int f = 0; f < vFace.size(); f++) // 绘制每个面片 { int n = vFace[f].vertex.size(); // 面的顶点数 glBegin(GL_TRIANGLES); for(int v = 0; v < n; v++) { int in = vFace[f].vertex[v].normIndex; glNormal3f(vNorm[in].x, vNorm[in].y, vNorm[in].z); int iv = vFace[f].vertex[v].vertIndex; glVertex3f(vVertex[iv].x, vVertex[iv].y, vVertex[iv].z); } glEnd(); } } //glFlush(); }
main.cpp
#include "mesh.h" const int windowWidth = 800; const int windowHeight = 600; Mesh mesh; void myDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_NORMALIZE); glColor3f(1, 1, 1); mesh.drawMesh(); glutSwapBuffers(); glutPostRedisplay(); } void myInit() { glClearColor(0, 0, 0, 0); glEnable(GL_NORMALIZE); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, windowWidth/ windowHeight, 1.0, 21.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(5, 6, 7, 0, 0, 0, 0, 1, 0); mesh.readFile("1.obj"); } int main() { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition(50, 50); glutInitWindowSize(windowWidth, windowHeight); glutCreateWindow("DEMO"); myInit(); glutDisplayFunc(myDisplay); glutMainLoop(); return 0; }
1.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
不足:没有对纹理处理,比如没有纹理图片,缺乏相关操作等。
—————————–变一下样式———————————-
将drawMesh()修改一下(仍然没有对纹理进行处理)
void Mesh::drawMesh() { if(vFace.empty()) return; // 有纹理 if(vText.size() > 0) { for(int f = 0; f < vFace.size(); f++) // 绘制每个面片 { int n = vFace[f].vertex.size(); // 面的顶点数 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBegin(GL_TRIANGLES); glColor3f(1, 1, 1); for(int v = 0; v < n; v++) { int it = vFace[f].vertex[v].textIndex; glTexCoord2f(vText[it].x, vText[it].y); int in = vFace[f].vertex[v].normIndex; glNormal3f(vNorm[in].x, vNorm[in].y, vNorm[in].z); int iv = vFace[f].vertex[v].vertIndex; glVertex3f(vVertex[iv].x, vVertex[iv].y, vVertex[iv].z); } glEnd(); glBegin(GL_LINE_LOOP); glColor3f(0, 0, 1); for (int v = 0; v < n; v++) { int it = vFace[f].vertex[v].textIndex; glTexCoord2f(vText[it].x, vText[it].y); int in = vFace[f].vertex[v].normIndex; glNormal3f(vNorm[in].x, vNorm[in].y, vNorm[in].z); int iv = vFace[f].vertex[v].vertIndex; glVertex3f(vVertex[iv].x, vVertex[iv].y, vVertex[iv].z); } glEnd(); } } // 没有纹理 else { for(int f = 0; f < vFace.size(); f++) // 绘制每个面片 { int n = vFace[f].vertex.size(); // 面的顶点数 glBegin(GL_TRIANGLES); for(int v = 0; v < n; v++) { int in = vFace[f].vertex[v].normIndex; glNormal3f(vNorm[in].x, vNorm[in].y, vNorm[in].z); int iv = vFace[f].vertex[v].vertIndex; glVertex3f(vVertex[iv].x, vVertex[iv].y, vVertex[iv].z); } glEnd(); } } }
相关文章推荐
- opengl加载obj模型
- 孙其功陪你学之——OpenGL加载OBJ模型文件并进行纹理修饰
- OpenGL OBJ模型加载.
- OpenGL -- OBJ 模型加载
- OpenGL学习脚印:模型加载初步-加载obj模型(load obj model)
- OpenGL 入门基础教程 —— 加载obj模型
- OpenGL学习:模型加载-obj模型和AssImp模型
- OpenGL学习--07--模型加载(obj)
- OPENGL 模型加载方法 ASSimp
- opengles加载obj格式3D模型含光照和纹理
- threejs 加载stl 或 obj 模型的代码模板
- 解决opengl加载3ds模型只有一张贴图的办法!!!!
- 使用opengl载入静态3d模型.obj的方法
- Java3D应用实例-加载Obj 三维模型
- 孙其功陪你学之——OpenGL加载OBJ文件库glm.c和glm.h
- threejs第五篇【一条龙测试之三 threejs加载 obj 格式模型】
- OpenGL系统设计-高级3D模型接口之OBJ模型(1)
- opengl读取OBJ模型文件
- three.js加载obj模型
- three.js学习笔记 obj模型加载问题 (转)