 读取三维网格模型(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[];
  17. int T[];
  18. int N[];
  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()<)continue;
  12. if(s[]=='v'){
  13. if(s[]=='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[]=='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[]=='f'){//f 2443//2656 2442//2656 2444//2656 面
  34. for(int k=s.size()-;k>=;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=;
  42. while(i<)
  43. {
  44. if(m_pic.V.size()!=)
  45. {
  46. in>>f->V[i];
  47. f->V[i]-=;
  48. }
  49. if(m_pic.VT.size()!=)
  50. {
  51. in>>f->T[i];
  52. f->T[i]-=;
  53. }
  54. if(m_pic.VN.size()!=)
  55. {
  56. in>>f->N[i];
  57. f->N[i]-=;
  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=;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()!=)glTexCoord2f(m_pic.VT[m_pic.F[i].T[]].TU,m_pic.VT[m_pic.F[i].T[]].TV); //纹理
  7. if(m_pic.VN.size()!=)glNormal3f(m_pic.VN[m_pic.F[i].N[]].NX,m_pic.VN[m_pic.F[i].N[]].NY,m_pic.VN[m_pic.F[i].N[]].NZ);//法向量
  8. glVertex3f(m_pic.V[m_pic.F[i].V[]].X/YU,m_pic.V[m_pic.F[i].V[]].Y/YU, m_pic.V[m_pic.F[i].V[]].Z/YU); // 上顶点
  9.  
  10. if(m_pic.VT.size()!=)glTexCoord2f(m_pic.VT[m_pic.F[i].T[]].TU,m_pic.VT[m_pic.F[i].T[]].TV); //纹理
  11. if(m_pic.VN.size()!=)glNormal3f(m_pic.VN[m_pic.F[i].N[]].NX,m_pic.VN[m_pic.F[i].N[]].NY,m_pic.VN[m_pic.F[i].N[]].NZ);//法向量
  12. glVertex3f(m_pic.V[m_pic.F[i].V[]].X/YU,m_pic.V[m_pic.F[i].V[]].Y/YU, m_pic.V[m_pic.F[i].V[]].Z/YU); // 左下
  13.  
  14. if(m_pic.VT.size()!=)glTexCoord2f(m_pic.VT[m_pic.F[i].T[]].TU,m_pic.VT[m_pic.F[i].T[]].TV); //纹理
  15. if(m_pic.VN.size()!=)glNormal3f(m_pic.VN[m_pic.F[i].N[]].NX,m_pic.VN[m_pic.F[i].N[]].NY,m_pic.VN[m_pic.F[i].N[]].NZ);//法向量
  16. glVertex3f(m_pic.V[m_pic.F[i].V[]].X/YU,m_pic.V[m_pic.F[i].V[]].Y/YU, m_pic.V[m_pic.F[i].V[]].Z/YU); // 右下
  17. glEnd();// 三角形绘制结束
  18.  
  19. /*if(m_pic.VN.size()!=0){
  20. glBegin(GL_LINES); // 绘制三角形
  21. 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); // 上顶点
  22. glVertex3f(m_pic.V[m_pic.F[i].V[0]].X/YU+m_pic.VN[m_pic.F[i].N[0]].NX
  23. ,m_pic.V[m_pic.F[i].V[0]].Y/YU+m_pic.VN[m_pic.F[i].N[0]].NY
  24. , m_pic.V[m_pic.F[i].V[0]].Z/YU+m_pic.VN[m_pic.F[i].N[0]].NZ); // 左下
  25. glEnd(); // 三角形绘制结束
  26. }*/
  27. }
  28. }

链接

本文链接: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效果的更多相关文章

  1. 读取obj文件用Mesh创建实例化

    using UnityEngine; using System.Collections; using System.IO; using System.Collections.Generic; usin ...

  2. 计算机图形学 opengl版本 第三版------胡事民 第四章 图形学中的向量工具

    计算机图形学 opengl版本 第三版------胡事民 第四章  图形学中的向量工具 一   基础 1:向量分析和变换   两个工具  可以设计出各种几何对象 点和向量基于坐标系定义 拇指指向z轴正 ...

  3. 计算机图形学 opengl版本 第三版------胡事民 第三章更多的绘图工具

    opengl  计算机图形学 第三版   第二部分   第三章更多的绘图工具 3.1   概述 第2章中  我们绘图使用的是屏幕窗口的基础坐标系    以像素为单位 屏幕坐标从左下角x从0延伸到scr ...

  4. [PHP] 读取大文件并显示

    使用PHP读取日志文件,当文件比较大的时候,会报内存不足,因此应该部分读取,读取指定的行数的数据 PHP代码: <?php class Test{ //日志路径 const LOG_PATH=& ...

  5. 图形学基础 | 实现OBJ文件的载入

    1. tiny_obj_loader.h 的使用include这个头文件需要先定义一个宏 #define TINYOBJLOADER_IMPLEMENTATION#include "tiny ...

  6. matlab读取csv文件并显示

    传统的方式可以通过读取文件,然后处理字符串的方式对csv文件进行解析,在matlab中可以通过csvread函数读取csv文件,然后通过plot对数据进行显示,也可以对里面的函数进行分析: csv文件 ...

  7. 计算机图形学——OpenGL开发库开发库

    vc++6.0 有 OpenGL 的东西.有头文件 GL.H, GLAUX.H, GLU.H 但没有 GLUT 软件包/工具包 如果想使用glut.h的话必须自己添加. 首先下载 OpenGL开发库, ...

  8. 计算机图形学OpenGL中的glLoadIdentity、glTranslatef、glRotatef原理,用法 .(转)

    单位矩阵 对角线上都是1,其余元素皆为0的矩阵. 在矩阵的乘法中,有一种矩阵起着特殊的作用,如同数的乘法中的1,我们称这种矩阵为单位矩阵. 它是个方阵,除左上角到右下角的对角线(称为主对角线)上的元素 ...

  9. GeoTools介绍、环境安装、读取shp文件并显示

    GeoTools是一个开放源代码(LGPL)Java代码库,它提供了符合标准的方法来处理地理空间数据,例如实现地理信息系统(GIS).GeoTools库实现了开放地理空间联盟(OGC)规范. Geot ...

随机推荐

  1. jquery remove/add css

    <input type="submit" class="btn btn-primary" id="submit" value=&quo ...

  2. 详解Oracle DELETE和TRUNCATE 的区别(摘)

    语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...

  3. setTimeout注意事项

    <script type="text/javascript">     function  show(v){        alert(v);    }    func ...

  4. (九) 一起学 Unix 环境高级编程 (APUE) 之 线程

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  5. html-5 --html5教程article、footer、header、nav、section使用

    header header元素是一种具有引导和导航作用的辅助元素.通常,header元素可以包含一个区块的标题(如h1至h6,或者hgroup元素标签),但也可以包含其他内容,例如数据表格.搜索表单或 ...

  6. LeetCode.4 两个有序数组的中位数问题

    这道题是那种典型的有显而易见的解法, 但是想要达到较优的时间复杂度的话就不是这么好做的题目. 我来说说我自己的思考过程 : 首先最先想到的是 O(m + n) 的解法, 也就是利用归并排序的归并将两个 ...

  7. C++中,指针数组和数组指针

    这俩兄弟长得实在太像,以至于经常让人混淆.然而细心领会和甄别就会发现它们大有不同. 前者是指针数组,后者是指向数组的指针.更详细地说. 前: 指针数组;是一个元素全为指针的数组. 后: 数组指针;可以 ...

  8. 磁盘配额quota应用

    1.文件系统支持 quota是针对整个文件系统来进行规划,所以我们得先查一下/home是否是个独立的文件系统. [root@Monitor home]# df -h /home Filesystem ...

  9. vb.net下载代码

    '后台 Partial Public Class Download2 Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender ...

  10. sublime text 也能矩形选择

    原来用editplus,但发现sublime text后便果断选择这个,她真的是很完美,但有一点就是不能像editplus一样矩形选择(Ctrl+鼠标左键这我知道,但感觉很麻烦)而感到小小的不爽... ...