[计算机图形学] 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 PIC

21 {

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/Normal3

28 };

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]].NX

24                 ,m_pic.V[m_pic.F[i].V[0]].Y/YU+m_pic.VN[m_pic.F[i].N[0]].NY

25                 , 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)