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

  • 相关阅读:
    BERT安装与使用
    32(2).层次聚类---BIRCH
    32(1).层次聚类---AGNES
    31(2).密度聚类---Mean-Shift算法
    31(1).密度聚类---DBSCAN算法
    linux环境变量
    Linux 中“一切都是文件”概念和相应的文件类型
    Linux 服务器如何禁止 ping 以及开启 ping
    如何用3个月零基础入门机器学习?
    28款GitHub最流行的开源机器学习项目
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/4187529.html
Copyright © 2020-2023  润新知