首页 > 代码库 > [计算机图形学] OpenGL读取obj文件并显示其3D效果
[计算机图形学] OpenGL读取obj文件并显示其3D效果
? 读取三维网格模型(Wavefront OBJ文件)
无法向立方体:cube.obj
有法向兔子模型:bunny.obj
有法向有纹理八字模型:Eight.obj
OBJ文件的格式可参考:http://www.cnblogs.com/youthlion/archive/2013/01/21/2870451.html
? 利用OpenGL显示该模型的绘制效果(全部)
顶点显示
线条显示
面片显示
? 核心代码说说
1、下面的点、纹理、法向量、面用于构成一个PIC的类,PIC用于存储从OBJ文件中读取的3D图形的信息:
1 struct POINT3{ 2 double X; 3 double Y; 4 double Z; 5 }; 6 struct WenLi{ 7 double TU; 8 double TV; 9 };10 struct FaXiangLiang{11 double NX;12 double NY;13 double NZ;14 };15 struct Mian{16 int V[3];17 int T[3];18 int N[3]; 19 };20 class PIC21 {22 public: 23 vector<POINT3> V;//V:代表顶点。格式为V X Y Z,V后面的X Y Z表示三个顶点坐标。浮点型24 vector<WenLi> VT;//表示纹理坐标。格式为VT TU TV。浮点型25 vector<FaXiangLiang> VN;//VN:法向量。每个三角形的三个顶点都要指定一个法向量。格式为VN NX NY NZ。浮点型26 vector<Mian> F;//F:面。面后面跟着的整型值分别是属于这个面的顶点、纹理坐标、法向量的索引。27 //面的格式为:f Vertex1/Texture1/Normal1 Vertex2/Texture2/Normal2 Vertex3/Texture3/Normal328 };
2、下面函数用于读取obj文件并将信息保存在PIC实例的对象中:
1 void CMainWnd::ReadPIC() 2 { 3 ifstream ifs(name);//cube bunny Eight 4 string s; 5 Mian *f; 6 POINT3 *v; 7 FaXiangLiang *vn; 8 WenLi *vt; 9 while(getline(ifs,s))10 {11 if(s.length()<2)continue;12 if(s[0]==‘v‘){13 if(s[1]==‘t‘){//vt 0.581151 0.979929 纹理14 istringstream in(s);15 vt=new WenLi();16 string head;17 in>>head>>vt->TU>>vt->TV;18 m_pic.VT.push_back(*vt);19 }else if(s[1]==‘n‘){//vn 0.637005 -0.0421857 0.769705 法向量20 istringstream in(s);21 vn=new FaXiangLiang();22 string head;23 in>>head>>vn->NX>>vn->NY>>vn->NZ;24 m_pic.VN.push_back(*vn);25 }else{//v -53.0413 158.84 -135.806 点26 istringstream in(s);27 v=new POINT3();28 string head;29 in>>head>>v->X>>v->Y>>v->Z;30 m_pic.V.push_back(*v);31 }32 }33 else if(s[0]==‘f‘){//f 2443//2656 2442//2656 2444//2656 面34 for(int k=s.size()-1;k>=0;k--){35 if(s[k]==‘/‘)s[k]=‘ ‘;36 }37 istringstream in(s);38 f=new Mian();39 string head;40 in>>head;41 int i=0;42 while(i<3)43 {44 if(m_pic.V.size()!=0)45 {46 in>>f->V[i];47 f->V[i]-=1;48 }49 if(m_pic.VT.size()!=0)50 {51 in>>f->T[i];52 f->T[i]-=1;53 }54 if(m_pic.VN.size()!=0)55 {56 in>>f->N[i];57 f->N[i]-=1;58 }59 i++;60 }61 m_pic.F.push_back(*f);62 }63 }64 }
3、下面函数用于根据保存在obj中图形利用openGL中的函数绘制出来:
1 void CMainWnd::GLCube() 2 { 3 for(int i=0;i<m_pic.F.size();i++) 4 { 5 glBegin(GL_POINTS); // 绘制三角形GL_TRIANGLES;GL_LINE_LOOP;GL_LINES;GL_POINTS 6 if(m_pic.VT.size()!=0)glTexCoord2f(m_pic.VT[m_pic.F[i].T[0]].TU,m_pic.VT[m_pic.F[i].T[0]].TV); //纹理 7 if(m_pic.VN.size()!=0)glNormal3f(m_pic.VN[m_pic.F[i].N[0]].NX,m_pic.VN[m_pic.F[i].N[0]].NY,m_pic.VN[m_pic.F[i].N[0]].NZ);//法向量 8 glVertex3f(m_pic.V[m_pic.F[i].V[0]].X/YU,m_pic.V[m_pic.F[i].V[0]].Y/YU, m_pic.V[m_pic.F[i].V[0]].Z/YU); // 上顶点 9 10 if(m_pic.VT.size()!=0)glTexCoord2f(m_pic.VT[m_pic.F[i].T[1]].TU,m_pic.VT[m_pic.F[i].T[1]].TV); //纹理11 if(m_pic.VN.size()!=0)glNormal3f(m_pic.VN[m_pic.F[i].N[1]].NX,m_pic.VN[m_pic.F[i].N[1]].NY,m_pic.VN[m_pic.F[i].N[1]].NZ);//法向量12 glVertex3f(m_pic.V[m_pic.F[i].V[1]].X/YU,m_pic.V[m_pic.F[i].V[1]].Y/YU, m_pic.V[m_pic.F[i].V[1]].Z/YU); // 左下13 14 if(m_pic.VT.size()!=0)glTexCoord2f(m_pic.VT[m_pic.F[i].T[2]].TU,m_pic.VT[m_pic.F[i].T[2]].TV); //纹理15 if(m_pic.VN.size()!=0)glNormal3f(m_pic.VN[m_pic.F[i].N[2]].NX,m_pic.VN[m_pic.F[i].N[2]].NY,m_pic.VN[m_pic.F[i].N[2]].NZ);//法向量16 glVertex3f(m_pic.V[m_pic.F[i].V[2]].X/YU,m_pic.V[m_pic.F[i].V[2]].Y/YU, m_pic.V[m_pic.F[i].V[2]].Z/YU); // 右下17 glEnd();// 三角形绘制结束 18 19 20 /*if(m_pic.VN.size()!=0){21 glBegin(GL_LINES); // 绘制三角形22 glVertex3f(m_pic.V[m_pic.F[i].V[0]].X/YU,m_pic.V[m_pic.F[i].V[0]].Y/YU, m_pic.V[m_pic.F[i].V[0]].Z/YU); // 上顶点23 glVertex3f(m_pic.V[m_pic.F[i].V[0]].X/YU+m_pic.VN[m_pic.F[i].N[0]].NX24 ,m_pic.V[m_pic.F[i].V[0]].Y/YU+m_pic.VN[m_pic.F[i].N[0]].NY25 , m_pic.V[m_pic.F[i].V[0]].Z/YU+m_pic.VN[m_pic.F[i].N[0]].NZ); // 左下26 glEnd(); // 三角形绘制结束27 }*/28 } 29 }
链接
本文链接:http://www.cnblogs.com/zjutlitao/p/4187529.html
本文github: https://github.com/beautifulzzzz/OpenGL/tree/master/TuXing
更多精彩:http://www.cnblogs.com/zjutlitao/p/4125085.html
[计算机图形学] OpenGL读取obj文件并显示其3D效果
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。