openGL三维网格坐标,旋转,缩放,灯光设置,纹理读取,模型读取(MFC单文档)
- 格式:doc
- 大小:1.25 MB
- 文档页数:30
OpenGL(Open Graphics Library)是一种用于渲染2D和3D图形的跨平台图形API。
OpenGL提供了一系列的函数,可以用来配置图形环境、绘制几何图形、处理纹理、执行变换等。
以下是一个简要的OpenGL使用手册的概述:1. 初始化OpenGL环境:-创建OpenGL上下文,配置窗口和视口,初始化OpenGL的各种参数。
2. 设置投影和视图矩阵:-使用OpenGL的矩阵操作函数,设置投影矩阵和视图矩阵,定义场景中物体的可见范围和视图。
3. 创建和加载着色器:-编写顶点着色器和片元着色器,将它们编译成着色器程序,并链接到OpenGL上下文。
4. 创建和绑定缓冲区对象:-创建顶点缓冲对象(VBO)和索引缓冲对象(IBO)来存储顶点数据和索引数据。
5. 定义顶点数据和绘制图形:-定义顶点数据,将数据传递到缓冲区对象中,使用OpenGL函数绘制图形。
6. 处理纹理:-加载纹理图像,创建纹理对象,将纹理数据传递到GPU,使用纹理进行图形渲染。
7. 执行变换:-使用OpenGL的矩阵操作函数,对物体进行平移、旋转、缩放等变换。
8. 设置光照和材质:-配置光源和材质属性,实现光照效果。
9. 深度测试和遮挡剔除:-启用深度测试和遮挡剔除,以处理物体的深度关系和遮挡关系。
10. 处理用户输入:-处理用户输入,例如键盘和鼠标事件,以交互式地改变场景。
11. 错误处理:-添加错误检查,确保OpenGL函数的调用没有错误,方便调试。
12. 清理和释放资源:-在程序结束时清理和释放分配的OpenGL资源,防止内存泄漏。
13. OpenGL扩展:-了解和使用OpenGL的扩展,以获取更先进的图形特性。
14. 学习资源:-利用OpenGL的学习资源,包括在线教程、书籍和社区,以深入了解图形编程。
请注意,上述步骤是一个简要的概述。
OpenGL是一个庞大而灵活的库,涵盖了广泛的图形编程概念。
深入学习OpenGL需要时间和实践。
实验OpenGL几何变换1.实验目的:理解掌握一个OpenGL程序平移、旋转、缩放变换的方法。
2.实验内容:(1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移、旋转、缩放变换的方法;(2)根据示范代码,尝试完成实验作业;3.实验原理:(1)OpenGL下的几何变换在OpenGL的核心库中,每一种几何变换都有一个独立的函数,所有变换都在三维空间中定义。
平移矩阵构造函数为glTranslate<f,d>(tx, ty, tz),作用是把当前矩阵和一个表示移动物体的矩阵相乘。
tx, ty,tz指定这个移动物体的矩阵,它们可以是任意的实数值,后缀为f(单精度浮点float)或d(双精度浮点double),对于二维应用来说,tz=0.0。
旋转矩阵构造函数为glRotate<f,d>(theta, vx, vy, vz),作用是把当前矩阵和一个表示旋转物体的矩阵相乘。
theta, vx, vy, vz指定这个旋转物体的矩阵,物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数theta表示旋转的角度。
向量v=(vx, vy,vz)的分量可以是任意的实数值,该向量用于定义通过坐标原点的旋转轴的方向,后缀为f(单精度浮点float)或d(双精度浮点double),对于二维旋转来说,vx=0.0,vy=0.0,vz=1.0。
缩放矩阵构造函数为glScale<f,d>(sx, sy, sz),作用是把当前矩阵和一个表示缩放物体的矩阵相乘。
sx, sy,sz指定这个缩放物体的矩阵,分别表示在x,y,z方向上的缩放比例,它们可以是任意的实数值,当缩放参数为负值时,该函数为反射矩阵,缩放相对于原点进行,后缀为f(单精度浮点float)或d(双精度浮点double)。
注意这里都是说“把当前矩阵和一个表示移动<旋转, 缩放>物体的矩阵相乘”,而不是直接说“这个函数就是旋转”或者“这个函数就是移动”,这是有原因的,马上就会讲到。
MFC空间几何变换之图像平移、镜像、旋转、缩放详解一. 图像平移前一篇文章讲述了图像点运算(基于像素的图像变换),这篇文章讲述的是图像几何变换:在不改变图像容的情况下对图像像素进行空间几何变换的处理方式。
点运算对单幅图像做处理,不改变像素的空间位置;代数运算对多幅图像做处理,也不改变像素的空间位置;几何运算对单幅图像做处理,改变像素的空间位置,几何运算包括两个独立的算法:空间变换算法和灰度级插值算法。
空间变换操作包括简单空间变换、多项式卷绕和几何校正、控制栅格插值和图像卷绕,这里主要讲述简单的空间变换,如图像平移、镜像、缩放和旋转。
主要是通过线性代数中的齐次坐标变换。
图像平移坐标变换如下:运行效果如下图所示,其中BMP图片(0,0)像素点为左下角。
其代码核心算法:1.在对话框中输入平移坐标(x,y) m_xPY=x,m_yPY=y2.定义Place=dlg.m_yPY*m_nWidth*3 表示当前m_yPY行需要填充为黑色3.新建一个像素矩阵ImageSize=new unsigned char[m_nImage]4.循环整个像素矩阵处理for(int i=0 ; i<m_nImage ; i++ ){if(i<Place) {ImageSize[i]=black;continue;}//黑色填充底部从小往上绘图else if(i>=Place && countWidth<dlg.m_xPY*3) {//黑色填充左部分ImageSize[i]=black;countWidth++; continue;}else if(i>=Place && countWidth>=dlg.m_xPY*3) {//图像像素平移区域ImageSize[i]=m_pImage[m_pImagePlace];//原(0,0)像素赋值过去m_pImagePlace++;countWidth++;if(countWidth==m_nWidth*3) {//一行填满m_pImagePlace走到(0,1)number++;m_pImagePlace=number*m_nWidth*3;}}}5.写文件绘图fwrite(ImageSize,m_nImage,1,fpw)第一步:在ResourceView资源视图中,添加Menu子菜单如下:(注意ID号)第二步:设置平移对话框。
OpenGL函数使用手册(一)OpenGL函数库格式:<库前缀><根命令><可选的参数个数><可选的参数类型> 库前缀有 gl、glu、aux、glut、wgl、glx、agl 等等,1,核心函数库主要可以分为以下几类函数:(1) 绘制基本的几何图元函数。
如:glBegain().(2) 矩阵操作、几何变换和投影变换的函数。
如:矩阵入栈glPushMatrix(),还有矩阵的出栈、转载、相乘,此外还有几何变换函数glTranslate*(),投影变换函数glOrtho()和视口变换函数glViewport()等等。
(3) 颜色、光照和材质函数。
(4) 显示列表函数,主要有创建、结束、生成、删除和调用显示列表的函数glNewList()、glEndList()、glGenLists()、glDeleteLists()和glCallList()。
(5) 纹理映射函数,主要有一维和二维纹理函数,设置纹理参数、纹理环境和纹理坐标的函数glTexParameter*()、glTexEnv*()和glTetCoord*()等。
(6) 特殊效果函数。
(7) 选着和反馈函数。
(8) 曲线与曲面的绘制函数。
(9) 状态设置与查询函数。
(10) 光栅化、像素函数。
2,OpenGL实用库(The OpenGL Utility Library)(GLU)包含有43个函数,函数名的前缀名为glu.(1) 辅助纹理贴图函数。
(2) 坐标转换和投影变换函数。
(3) 多边形镶嵌工具。
(4) 二次曲面绘制工具。
(5) 非均匀有理B样条绘制工具。
(6) 错误反馈工具,获取出错信息的字符串gluErrorString() 3,OpenGL辅助库包含有31个函数,函数名前缀名为aux这部分函数提供窗口管理、输入输出处理以及绘制一些简单的三维物体。
4,OpenGL工具库(OpenGL Utility Toolkit)包含大约30多个函数,函数前缀名为glut,此函数由glut.dll来负责解释执行。
openGL+VS2010的例程--旋转⽴⽅体(三维)效果图如上:步骤:⾸先,设置模型视⾓往后退,再旋转视⾓;然后,⽤默认绘制⽴⽅体函数绘制;最后,利⽤空闲对模型做⾓度微调。
实现代码如下:1 #include <GL\glut.h>23 GLfloat xRotated, yRotated, zRotated;45void Display(void)6 {7 glClear(GL_COLOR_BUFFER_BIT);8 glLoadIdentity();9 glTranslatef(0.0,0.0,-4.0);10 glRotatef(xRotated,1.0,0.0,0.0);11 glRotatef(yRotated,0.0,1.0,0.0);12 glRotatef(zRotated,0.0,0.0,1.0);13//glScalef(2.0,1.0,1.0);14 glutWireCube(1.5);15 glFlush(); //Finish rendering16 glutSwapBuffers();17 }1819void Reshape(int x, int y)20 {21if (y == 0 || x == 0) return; //Nothing is visible then, so return22//Set a new projection matrix23 glMatrixMode(GL_PROJECTION);24 glLoadIdentity();25//Angle of view:40 degrees26//Near clipping plane distance: 0.527//Far clipping plane distance: 20.028 gluPerspective(40.0,(GLdouble)x/(GLdouble)y,0.5,20.0);29 glMatrixMode(GL_MODELVIEW);30 glViewport(0,0,x,y); //Use the whole window for rendering31 }32static int times = 0;33void Idle(void)34 {35 times++;36if(times >30000)37 times = 0;3839if(times %30000 == 0)40 {41 xRotated += 0.3;42 yRotated += 0.1;43 zRotated += -0.4;44 Display();45 }46 }474849int main (int argc, char **argv)50 {51//Initialize GLUT52 glutInit(&argc, argv);53 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //For animations you should use double buffering54 glutInitWindowSize(300,300);55//Create a window with rendering context and everything else we need56 glutCreateWindow("Cube example");57 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);58 xRotated = yRotated = zRotated = 0.0;59 glClearColor(0.0,0.0,0.0,0.0);60//Assign the two used Msg-routines61 glutDisplayFunc(Display);62 glutReshapeFunc(Reshape);63 glutIdleFunc(Idle);64//Let GLUT get the msgs65 glutMainLoop();66return0;67 }。
第四章 OpenGL 图形变换OpenGL 图形变换是OpenGL 技术体系的核心内容之一,它的最主要功能是让虚拟世界里的物体动起来,是虚拟世界的动力驱动系统,也可以称之三维图形系统的引擎!OpenGL 图形变换的主要内容包括几何变换、投影变换、裁剪变换、视口变换等,本章尽量以通俗易懂的方式来讲解各技术要点。
4. 1 图形变换浅说OpenGL 图形变换和照相是非常相似的,它们之间的关系大致描述如下。
1、视点变换(View Transformation ) 视点变换相当于把相机放到一定的位置上,镜头对准场景。
如图4-1所示。
图4-1 视点变换与相机定位在OpenGL中,默认情况下,视点变换相当于把相机放到世界坐标系的原点(0,0,0),镜头指向Z轴的负方向,相当于从世界坐标系的原点向屏幕内部的虚拟场景观察。
2、模型变换(Model Transformation)模型变换相当于场景中人物或对象位置的变化、角度的改变和大小的改变。
图4-2 虚拟照相场景中的人物YXZ观察方向X照相时场景中的人物或对象需要作调整,以便他们位于场景中合适的位置上。
有此时候人物不在视野范围内时,还要走动一下,进入镜头场景内,方向不对时,还要转动一下,眼睛转向镜头。
比如图4-2所示,照相时,警察不在镜头场景内,他需要向后向移动。
中间的企鹅背对镜头,他需要转过向来面向镜头。
企鹅向左边的气球中吹气,气球变大。
调整后的场景如图4-3所示。
图4-3 虚拟照相场景中的调整后人物或对象上述调整过程中的人员移动 和企鹅的转身动作 和气球充气变大 都属于模型变换。
3、投影变换(Projection Transformation ) 投影变换相当于调整相机镜头焦距,放大或缩小景物(如图4-4所示)。
图4-4 投影变换与相机焦距调整OpenGL 中投影变换的本质功能是定义一个视景体,使视景体外的多余部分被裁剪掉,再把景物变换到一个规则投影体(高、宽、深均为2个单位的立方体)。
C语言实现OpenGL渲染OpenGL是一种强大的图形渲染API(应用程序接口),它可用于创建高性能的2D和3D图形应用程序。
在本文中,我们将探讨如何使用C语言实现OpenGL渲染。
1. 初始化OpenGL环境在开始之前,我们需要初始化OpenGL环境。
这可以通过以下步骤完成:1.1. 创建窗口使用C语言中的窗口创建库(如GLUT或GLFW)创建一个可见的窗口。
这个窗口将充当我们OpenGL渲染的目标。
1.2. 设置视口使用glViewport函数将窗口的尺寸设置为需要进行渲染的大小。
视口定义了OpenGL将渲染的区域。
1.3. 创建正交投影或透视投影矩阵使用glOrtho或gluPerspective函数创建透视或正交投影矩阵。
投影矩阵将定义OpenGL渲染的视图。
2. 渲染基本图形一旦我们初始化了OpenGL环境,我们可以开始渲染基本图形。
以下是一些常见的基本图形渲染函数:2.1. 绘制点使用glBegin和glEnd函数,以及glVertex函数,可以绘制一个或多个点。
2.2. 绘制线段使用glBegin和glEnd函数,以及glVertex函数,可以绘制一条或多条线段。
2.3. 绘制三角形使用glBegin和glEnd函数,以及glVertex函数,可以绘制一个或多个三角形。
2.4. 绘制多边形使用glBegin和glEnd函数,以及glVertex函数,可以绘制一个或多个多边形。
3. 设置光照效果为了给渲染的图形添加逼真感,可以设置光照效果。
以下是一些常见的光照函数:3.1. 设置光源使用glLight函数,可以设置光源的位置、光照颜色等参数。
3.2. 设置材质属性使用glMaterial函数,可以设置渲染对象的表面材质属性,如漫反射、镜面反射等。
3.3. 使用光照模型使用glShadeModel函数,可以选择光照模型,如平滑光照模型或平面光照模型。
4. 纹理映射纹理映射能够使渲染的图形更逼真。
华中科技大学电子科学与技术系课程设计报告( 2010-- 2011年度第2 学期)名称:软件课程设计题目:基于OpenGL的3D旋转魔方实现院系:班级:学号:学生姓名:指导教师:设计周数:成绩:日期:年月日目录1.课程设计介绍............................................................................................ (2)1.1目的.............................................................................................................. (2)1.2内容.............................................................................................................. (2)1.3取得的成果 (2)2.程序分析..................................................................................................... (3)2.1 程序原理 (3)2.2 程序流程 (4)2.3 数据结构 (13)2.4 重要函数 (13)3.程序分析与结果演示 (16)3.1 成果演示 (16)3.2 程序分析 (17)4.出现过的问题 (18)5.心得和小节 (19)1.课程设计介绍1.1目的21世纪是高科技时代,是信息技术时代,而计算机技术无疑会引领各行各业,为我们带来一个全新的时代。
作为新世纪的接班人,我们必须拥有良好的计算机应用能力,才能跟上世界发展的大流,不至于在激烈的竞争中被淘汰。
而程序作为计算机的灵魂,因此编程能力对当代大学生来说至关重要。
opengles 缩放效果实现原理OpenGLES是一种用于嵌入式设备的图形库,可以实现高性能的2D 和3D图形渲染。
缩放是OpenGLES中常用的图形效果之一,它可以将图像按比例放大或缩小。
本文将介绍OpenGLES缩放效果的实现原理。
在OpenGLES中,缩放效果的实现基于变换矩阵。
变换矩阵是一个3x3的矩阵,用于对图像进行平移、旋转和缩放等操作。
在缩放效果中,只需修改变换矩阵中的缩放部分即可实现图像的缩放。
图像的缩放是通过修改顶点坐标来实现的。
顶点坐标是描述图形形状的一组点的坐标,通过将顶点坐标乘以变换矩阵,可以实现图像的缩放。
具体来说,对于一个点的坐标(x, y),通过变换矩阵的缩放部分,可以将该点的坐标变为(x * sx, y * sy),其中sx和sy 分别表示在x和y方向上的缩放比例。
在OpenGLES中,可以使用以下代码来进行缩放的变换矩阵的设置:```Matrix.setIdentityM(matrix, 0); // 初始化变换矩阵Matrix.scaleM(matrix, 0, sx, sy, 1.0f); // 设置缩放比例```其中,matrix是一个float类型的数组,用于存储变换矩阵;sx和sy分别表示在x和y方向上的缩放比例。
在进行图像绘制时,需要将顶点坐标与变换矩阵相乘,得到经过缩放效果处理后的顶点坐标。
具体来说,对于一个顶点的坐标(x, y),通过变换矩阵的乘法运算,可以得到新的顶点坐标(x', y'),即:```x' = x * sxy' = y * sy```然后,使用新的顶点坐标进行图像绘制,就可以实现缩放效果。
需要注意的是,缩放比例sx和sy的取值范围通常为0到1之间,表示缩小;大于1表示放大。
如果sx和sy的值相同,则图像在x 和y方向上的缩放比例相同,保持图像的宽高比不变;如果sx和sy的值不同,则图像在x和y方向上的缩放比例不同,会改变图像的宽高比。
openGL三维网格坐标,旋转,缩放,灯光设置,纹理读取,模型读取(MFC单文档)在我的MFC单文档项目中enableview.h和enableview.cpp负责上面的窗口建立,myopenglview.h和myopenglView.cpp主要是功能的实现1.三维网格建立:void GLGrid(float pt1x, float pt1y, float pt1z, float pt2x, float pt2y, float pt2z, int num){const float _xLen = (pt2x - pt1x) / num;const float _yLen = (pt2y - pt1y) / num;const float _zLen = (pt2z - pt1z) / num; glLineWidth(2.f);glLineStipple(1, 0x0303);//线条样式glBegin(GL_LINES);glEnable(GL_LINE_SMOOTH);int xi = 0;int yi = 0;int zi = 0;//绘制平行于X的直线for (zi = 0; zi <= num; zi++){float z = _zLen * zi + pt1z;for (yi = 0; yi <= num; yi++){float y = _yLen * yi + pt1y;glVertex3f(pt1x, y, z);glVertex3f(pt2x, y, z);}}//绘制平行于Y的直线for (zi = 0; zi <= num; zi++){float z = _zLen * zi + pt1z;for (xi = 0; xi <= num; xi++){float x = _xLen * xi + pt1x;glVertex3f(x, pt1y, z);glVertex3f(x, pt2y, z);}}//绘制平行于Z的直线for (yi = 0; yi <= num; yi++){float y = _yLen * yi + pt1y;for (xi = 0; xi <= num; xi++){float x = _xLen * xi + pt1x;glVertex3f(x, y, pt1z);glVertex3f(x, y, pt2z);}}glEnd();}void CmyopenglView::ordination() {glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glEnable(GL_BLEND);glEnable(GL_POINT_SMOOTH); //设置反走样glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); //设置反走样glEnable(GL_LINE_SMOOTH);glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);glEnable(GL_POL YGON_SMOOTH);glHint(GL_POL YGON_SMOOTH_HINT, GL_NICEST);glRotatef(-45, 0.0, 1.0, 0.0);//网格glPushMatrix();glColor3f(0.9f, 0.9f, 0.9f);glTranslatef(-4, -4, -4);GLGrid(0,0,0,8,0,8,20);glPopMatrix();glPushMatrix();glTranslated(-4,4, -4);glRotatef(90, 1.0, 0.0, 0.0);glColor3f(0.9f, 0.9f, 0.0f);GLGrid(0, 0, 0, 8, 0, 8, 20);glPopMatrix();glPushMatrix();glTranslatef(-4, -4, -4);glRotatef(90, 0.0, 0.0, 1.0);glColor3f(0.0f, 0.9f, 0.0f);GLGrid(0, 0, 0, 8, 0, 8, 20);glPopMatrix();glDisable(GL_BLEND);glDisable(GL_LINE_SMOOTH);glDisable(GL_POINT_SMOOTH);glDisable(GL_POL YGON_SMOOTH);}我们在ordination()函数中增加绘制x,y,z坐标的代码void CmyopenglView::ordination() {glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glEnable(GL_BLEND);glEnable(GL_POINT_SMOOTH); //设置反走样glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); //设置反走样glEnable(GL_LINE_SMOOTH);glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);glEnable(GL_POL YGON_SMOOTH);glHint(GL_POL YGON_SMOOTH_HINT, GL_NICEST);glRotatef(-45, 0.0, 1.0, 0.0);//网格glPushMatrix();glColor3f(0.9f, 0.9f, 0.9f);glTranslatef(-4, -4, -4);GLGrid(0,0,0,8,0,8,20);glPopMatrix();glPushMatrix();glTranslated(-4,4, -4);glRotatef(90, 1.0, 0.0, 0.0);glColor3f(0.9f, 0.9f, 0.0f);GLGrid(0, 0, 0, 8, 0, 8, 20);glPopMatrix();glPushMatrix();glTranslatef(-4, -4, -4);glRotatef(90, 0.0, 0.0, 1.0);glColor3f(0.0f, 0.9f, 0.0f);GLGrid(0, 0, 0, 8, 0, 8, 20);glPopMatrix();//x//glTranslatef(-2, -2, -2);glColor3f(1.0f, 0.0f, 0.0f);glBegin(GL_LINES);glVertex3f(0.0f, 0.0f, 0.0f);glVertex3f(3.5, 0.0f, 0.0f);glEnd();glPushMatrix();glTranslatef(3.5, 0.0f, 0.0f);glRotatef(90.0f, 0.0f, 1.0f, 0.0f);glutWireCone(0.027, 0.09, 10, 10);glPopMatrix();//yglColor3f(0.0f, 1.0f, 0.0f);glBegin(GL_LINES);glVertex3f(0.0f, 0.0f, 0.0f);glVertex3f(0.0, 3.5, 0.0f);glEnd();glPushMatrix();glTranslatef(0.0, 3.5, 0.0f);glRotatef(90.0f, -1.0f, 0.0f, 0.0f);glutWireCone(0.027, 0.09, 10, 10);glPopMatrix();//zglColor3f(0.0f, 0.0f, 1.0f);glBegin(GL_LINES);glVertex3f(0.0f, 0.0f, 0.0f);glVertex3f(0.0, 0.0f, 3.5);glEnd();glPushMatrix();glTranslatef(0.0, 0.0f, 3.5);glRotatef(90.0f, 0.0f, 0.0f, 1.0f);glutWireCone(0.027, 0.09, 10, 10);glPopMatrix();glDisable(GL_BLEND);glDisable(GL_LINE_SMOOTH);glDisable(GL_POINT_SMOOTH);glDisable(GL_POL YGON_SMOOTH); }、2.基本三维图形创建点模型/线模型/面模型glColor3f(1.0f, 1.0f, 1.0f);if (model == 1){if (type == 1)glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);if (type == 2)glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);if (type == 3)glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);auxSolidCube(4);}if (model == 2){if (type == 1)glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);if (type == 2)glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);if(type == 3)glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);auxSolidSphere(3.0);}if (model == 3){glPushMatrix();glRotatef(90, -1.0, 0.0, 0.0);if (type == 1)glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);if (type == 2)glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);if (type == 3)glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);glutSolidCone(3, 3, 100, 100);glPopMatrix();}if (model == 4){if (type == 1)glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);if (type == 2)glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);if (type == 3)glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);glutSolidTeapot(2.5);}3.鼠标相应旋转缩放BOOL enableview::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt){// TODO: 在此添加消息处理程序代码和/或调用默认值double a = zDelta / 120;if ((scale + a * 0.1) < 10)scale += a * 0.1;this->InvalidateRect(NULL, FALSE);return CView::OnMouseWheel(nFlags, zDelta, pt);}void enableview::OnMouseMove(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值if (nFlags & MK_LBUTTON == TRUE) {//MessageBox("mouse move function triggered!", "attentino", MB_OK);du += point.x - oldmx; //鼠标在窗口x轴方向上的增量加到视点绕y轴的角度上,这样就左右转了h += 0.03f*(point.y - oldmy); //鼠标在窗口y轴方向上的改变加到视点的y坐标上,就上下转了if (h>15.0f) h = 15.0f; //视点y坐标作一些限制,不会使视点太奇怪else if (h<-5.0f) h = -5.0f;oldmx = point.x, oldmy = point.y; //把此时的鼠标坐标作为旧值,为下一次计算增量做准备/*CString debug;debug.Format(_T("h,du= %0.3f %3d\n"), h, du);OutputDebugString(debug);*///OnPaint();this->OnDraw(this->GetDC()); //重绘界面}else if (nFlags & MK_RBUTTON == TRUE){oldmx += point.x - oldmx;oldmy += point.y - oldmy;glTranslatef(oldmx, oldmy, -0.1f);this->OnDraw(this->GetDC());oldmx = point.x, oldmy = point.y;}else {oldmx = point.x, oldmy = point.y;//OutputDebugString(_T("mouse up\n"));}//CView::OnMouseMove(nFlags, point);}4.键盘相应旋转缩放BOOL CmyopenglView::PreTranslateMessage(MSG* pMsg){if (pMsg->message == WM_KEYDOWN) // If a keydown message{if (pMsg->wParam == _T('W')){this->rotate_x += 6.0;if (this->rotate_x > 360)this->rotate_x = -360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('X')){this->rotate_x += 6.0;if (this->rotate_x < -360)this->rotate_x = 360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('A')){this->rotate_y -= 6.0;if (this->rotate_y < -360)this->rotate_y = 360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('D')){this->rotate_y += 6.0;if (this->rotate_y > 360)this->rotate_y = -360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('Z')){this->rotate_z -= 6.0;if (this->rotate_z < -360)this->rotate_z = 360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('E')){this->rotate_z += 6.0;if (this->rotate_z > 360)this->rotate_z = -360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('Q')){if ((scale + 2) < 10)scale += 2;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('R')){scale -= 2;this->InvalidateRect(NULL, FALSE);}}return CView::PreTranslateMessage(pMsg);}5.灯光设置:单方位灯光/多方位光/多种类型光效果// 设置材质颜色GLfloat mat_ambient[] = { 0.6f, 0.6f, 0.6f, 1.0f }; // 蓝色的材质环境光GLfloat mat_diffuse[] = { 0.6f, 0.6f, 0.9f, 1.0f }; // 蓝色的材质漫反射光GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // 全白色的材质镜面反射光GLfloat mat_emission[] = { 0.5f, 0.5f, 0.5f, 1.0f }; // 淡白色的材质辐射光GLfloat no_mat[] = { 0.0f, 0.0f, 0.0f, 1.0f }; // 无光(黑色光),用于关闭某种属性光时应用GLfloat no_shininess[] = { 0.0f }; // 无镜面反射GLfloat low_shininess[] = { 5.0f }; // 低镜面反射指数GLfloat high_shininess[] = { 70.0f }; // 高镜面反射指数void CmyopenglView::InitalLigt(){GLfloat light_position1[4] = { -52, -16, -50, 0 };GLfloat light_position2[4] = { -26, -48, -50, 0 };GLfloat light_position3[4] = { 16, -52, -50, 0 };GLfloat direction1[3] = { 52, 16, 50 };GLfloat direction2[3] = { 26, 48, 50 };GLfloat direction3[3] = { -16, 52, 50 };GLfloat light_position4[4] = { 52, 16, 50, 0 };GLfloat light_position5[4] = { 26, 48, 50, 0 };GLfloat light_position6[4] = { -16, 52, 50, 0 };GLfloat direction4[3] = { -52, -16, -50 };GLfloat direction5[3] = { -26, -48, -50 };GLfloat direction6[3] = { 16, -52, -50 };GLfloat color1[4], color2[4], color3[4], color4[4], color5[4], color6[4];glClearColor(1, 1, 1, 0);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);if (color_type == 0) { //彩色灯光color1[0] = 1; color1[1] = 0; color1[2] = 0; color1[3] = 1;color2[0] = 0.5; color2[1] = 1; color2[2] = 0; color2[3] = 1;color3[0] = 0; color3[1] = 0; color3[2] = 1; color3[3] = 1;color4[0] = 1; color4[1] = 0; color4[2] = 0; color4[3] = 1;color5[0] = 0.5; color5[1] = 1; color5[2] = 0; color5[3] = 1;color6[0] = 0; color6[1] = 0; color6[2] = 1; color6[3] = 1;GLfloat ambient[4] = { 0.3f, 0.3f, 0.3f, 1.0f };GLfloat material_color[4] = { 1, 1, 1, 0.5f };GLfloat material_specular[4] = { 0.5f, 0.5f, 0.5f, 0.5f };GLfloat material_ambient[4] = { 0.0, 0.0, 0.0, 0.0 };glLightfv(GL_LIGHT3, GL_POSITION, light_position4);glLightfv(GL_LIGHT3, GL_SPOT_DIRECTION, direction4);glLightfv(GL_LIGHT3, GL_DIFFUSE, color4);glLightfv(GL_LIGHT3, GL_SPECULAR, color4);glLightfv(GL_LIGHT4, GL_POSITION, light_position5);glLightfv(GL_LIGHT4, GL_SPOT_DIRECTION, direction5);glLightfv(GL_LIGHT4, GL_DIFFUSE, color5);glLightfv(GL_LIGHT4, GL_SPECULAR, color5);glLightfv(GL_LIGHT5, GL_POSITION, light_position6);glLightfv(GL_LIGHT5, GL_SPOT_DIRECTION, direction6);glLightfv(GL_LIGHT5, GL_DIFFUSE, color6);glLightfv(GL_LIGHT5, GL_SPECULAR, color6);glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular);glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material_color);glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material_ambient);glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128);glDisable(GL_LIGHT0);glDisable(GL_LIGHTING);glEnable(GL_LIGHTING);glEnable(GL_LIGHT3);glEnable(GL_LIGHT4);glEnable(GL_LIGHT5);glDisable(GL_COLOR_MATERIAL);return;}if (color_type == 1){//白色灯光glDisable(GL_LIGHT3);glDisable(GL_LIGHT4);glDisable(GL_LIGHT5);glDisable(GL_LIGHTING);GLfloat m_LightPostion[4] = { 0.0f, 10.0f, 10.0f, 1.0f };GLfloat ambientLight[] = { 0.25f, 0.25f, 0.25f, 1.0f };GLfloat diffuseLight[] = { 0.5, 0.5f, 0.5f, 1.0f };GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };glEnable(GL_LIGHTING);glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);glLightfv(GL_LIGHT0, GL_POSITION, m_LightPostion);glEnable(GL_LIGHT0);glEnable(GL_COLOR_MATERIAL);glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);}else {glDisable(GL_LIGHT3);glDisable(GL_LIGHT4);glDisable(GL_LIGHT5);glDisable(GL_LIGHTING);glDisable(GL_COLOR_MATERIAL);glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);//glDisable(GL_LIGHTING);GLfloat no_ambientLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; // 用于关掉默认的全局环境光// 设置光源的颜色GLfloat ambientLight[] = { 0.8f, 0.8f, 0.8f, 1.0f }; // 白色环境光GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f }; // 白色漫射光GLfloat specularLight[] = { 0.8f, 0.8f, 0.8f, 1.0f }; // 白色镜面反射光GLfloat m_LightPostion[] = { 0.0f, 0.0f, 1.0f, 0.0f }; // 光源起始位置// 1.仅漫射光if (color_type == 12) {glEnable(GL_LIGHTING);//glLightModelfv(GL_LIGHT_MODEL_AMBIENT, no_ambientLight); // 关掉默认的全局环境光glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);glLightfv(GL_LIGHT0, GL_POSITION, m_LightPostion);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat); // 关闭材质的环境反射光颜色glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); // 设置mat_diffuse的材质漫反射光glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat); //关闭材质的镜面反射光颜色glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess); // 设置材质的镜面反射指数为0glMaterialfv(GL_FRONT, GL_EMISSION, no_mat); // 关闭材质的辐射光glEnable(GL_LIGHT0);}// 2.仅镜面光if (color_type == 13) {glEnable(GL_LIGHTING);//glLightModelfv(GL_LIGHT_MODEL_AMBIENT, no_ambientLight); // 关掉默认的全局环境光glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);glLightfv(GL_LIGHT0, GL_POSITION, m_LightPostion);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);glMaterialfv(GL_FRONT, GL_DIFFUSE, no_mat);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);glEnable(GL_LIGHT0);}// 3.漫射光与低镜面光if (color_type == 16) {glEnable(GL_LIGHTING);glLightModelfv(GL_LIGHT_MODEL_AMBIENT, no_ambientLight); // 关掉默认的全局环境光glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);glLightfv(GL_LIGHT0, GL_POSITION, m_LightPostion);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);glEnable(GL_LIGHT0);}// 4.辐射光与低镜面光if (color_type == 18) {glEnable(GL_LIGHTING);glLightModelfv(GL_LIGHT_MODEL_AMBIENT, no_ambientLight); // 关掉默认的全局环境光glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);glLightfv(GL_LIGHT0, GL_POSITION, m_LightPostion);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);glMaterialfv(GL_FRONT, GL_DIFFUSE, no_mat);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);glEnable(GL_LIGHT0);}}}6.纹理载入映射BOOL CmyopenglView::LoadImageResources() {FILE *File = NULL;AUX_RGBImageRec* textrue_Resource[6];if (model == 5 && type == 51)resource_path[0] = "shuijing.bmp";if(model == 5 && type == 52 )resource_path[0] = "earth.bmp";if (model == 5 && type == 53)resource_path[0] = "painting1.bmp";if (model == 5 && type == 54)resource_path[0] = "5.bmp";/*resource_path[1] = "image/2.bmp";resource_path[2] = "image/3.bmp";resource_path[3] = "image/4.bmp";resource_path[4] = "image/5.bmp";resource_path[5] = "image/6.bmp";*///装载图像文件资源for (int i = 0; i < 6; i++)//如果只需要一张贴图其实resource_path数组只需要一个元素就可以了{File = fopen(resource_path[0], "r");if (!File){//MessageBox(NULL, "加载图像资源文件失败!", "Fail", MB_OK);return FALSE;}fclose(File);CString str = CString(resource_path[0]);USES_CONVERSION;LPCWSTR wszClassName = A2CW(W2A(str));textrue_Resource[i] = auxDIBImageLoad(wszClassName);File = NULL;}//生成纹理glGenTextures(6, texture);for (int i = 0; i < 6; i++){glBindTexture(GL_TEXTURE_2D, texture[i]);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//Use the mipmap textureglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, \textrue_Resource[i]->sizeX, textrue_Resource[i]->sizeY, \GL_RGB, GL_UNSIGNED_BYTE, textrue_Resource[i]->data);//删除堆上的临时图像delete textrue_Resource[i]->data;delete textrue_Resource[i];}return TRUE;}void CmyopenglView::Draw_textrue() {GLUquadricObj* qobj;glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_FLAT);glEnable(GL_DEPTH_TEST);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);InitalLigt(); ///初始化光照信息glEnable(GL_TEXTURE_2D);glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);glPushMatrix();glTranslatef(0.0f, 0.0f, scale); //滚轮缩放gluLookAt(r*cos(c*du), h, r*sin(c*du), 0, 0, 0, 0, 1, 0); //从视点看远点,y轴方向(0,1,0)是上方向,鼠标拖动glRotatef(this->rotate_x, 1.0, 0.0, 0.0);glRotatef(this->rotate_y, 0.0, 1.0, 0.0);glRotatef(this->rotate_z, 0.0, 0.0, 1.0);if (iao)ordination();glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);qobj = gluNewQuadric();//画球体glBindTexture(GL_TEXTURE_2D, texture[0]);glEnable(GL_TEXTURE_2D);gluQuadricTexture(qobj, GL_TRUE);//纹理函数if (type == 51){glBegin(GL_QUADS);// Front FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-3.0f, -3.0f, 3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(3.0f, -3.0f, 3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(3.0f, 3.0f, 3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-3.0f, 3.0f, 3.0f);// Back FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-3.0f, -3.0f, -3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-3.0f, 3.0f, -3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(3.0f, 3.0f, -3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(3.0f, -3.0f, -3.0f);// Top FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-3.0f, 3.0f, -3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-3.0f, 3.0f, 3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(3.0f, 3.0f, 3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(3.0f, 3.0f, -3.0f);// Bottom FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-3.0f, -3.0f, -3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(3.0f, -3.0f, -3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(3.0f, -3.0f, 3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-3.0f, -3.0f, 3.0f);// Right faceglTexCoord2f(0.0f, 0.0f); glVertex3f(3.0f, -3.0f, -3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(3.0f, 3.0f, -3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(3.0f, 3.0f, 3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(3.0f, -3.0f, 3.0f);// Left FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-3.0f, -3.0f, -3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-3.0f, -3.0f, 3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(-3.0f, 3.0f, 3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-3.0f, 3.0f, -3.0f);glEnd();}if( type == 52 )gluSphere(qobj, 4, 60, 60);//二次曲面qobjif( type == 53 )gluCylinder(qobj, 3.5, 3.5, 6, 26, 23);if( type == 54 )gluCylinder(qobj, 3.5, 0.0, 6, 26, 23);glPopMatrix();glDisable(GL_TEXTURE_2D);}6.读取obj模型我只是简单的读取vt,vn,f等基本参数void CmyopenglView::ReadObj(char* Filename) {VN.clear();V.clear();VT.clear();F.clear();FQ.clear();ifstream in(Filename);string aline; //逐行读入string erase;while (getline(in, aline)){if (aline[0] == 'v'){if (aline[1] == 'n') //vn{istringstream sin(aline);V ertex v;sin >> erase >> v.x >> v.y >> v.z;VN.push_back(v);}else if (aline[1] == 't')//vt{istringstream sin(aline);Texture v;sin >> erase >> v.s >> v.t;VT.push_back(v);}else //v{istringstream sin(aline);V ertex v;sin >> erase >> v.x >> v.y >> v.z;V.push_back(v);}}else if (aline[0] == 'f'){istringstream sin(aline);sin >> erase;vector<string> strvector;string temp;while (sin >> temp) {strvector.push_back(temp);}if (strvector.size() == 3) {//三角面片Face fff;for (int count = 0; count < 3; count++) {string kkk = strvector[count];int i = 0;int num = 0;//顶点索引for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.v[count] = num;i++;num = 0;//vtnum = 0;for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.vt[0] = num;i++;num = 0;//法向量索引for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.vn[count] = num;}F.push_back(fff);}else if (strvector.size() == 4){FaceQ fff;for (int count = 0; count < strvector.size(); count++) { string kkk = strvector[count];int i = 0;int num = 0;//顶点索引for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.v[count] = num;i++;num = 0;//vtnum = 0;for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.vt[0] = num;i++;num = 0;//法向量索引for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.vn[count] = num;}FQ.push_back(fff);}}}}绘制obj模型:void CmyopenglView::OnReadobj(){model = 6;wchar_t filters[] =L"3D模型文件(*.obj)\|*.obj|所有文件(*.*)|*.*||";CFileDialog fileDlg(TRUE, NULL, NULL,OFN_HIDEREADONL Y, filters);if (fileDlg.DoModal() == IDOK){CString strBuf = fileDlg.GetPathName();USES_CONVERSION;char *Filename = T2A(strBuf.GetBuffer(0));ReadObj(Filename);}stringstream ss;ss <<"OK!";string str;ss >> str;CString s;s = str.c_str();MessageBox(s);float min_x, min_y, min_z, max_x, max_y, max_z;min_x = min_y = min_z = 10000000;max_x = max_y = max_z = -1000000;for (int i = 0; i < V.size(); i++){min_x = min(min_x, V[i].x);min_y = min(min_y, V[i].y);min_z = min(min_z, V[i].z);max_x = max(max_x, V[i].x);max_y = max(max_y, V[i].y);max_z = max(max_z, V[i].z);}worldx = (min_x + max_x) / 2;worldy = (min_y + max_y) / 2;worldz = (min_z + max_z) / 2;type = 1;Invalidate();CDC* ppDC = GetWindowDC();OnDrawGL(ppDC);// TODO: 在此添加命令处理程序代码}void CmyopenglView::Draw_obj(){if (type == 1) {if (!VN.empty()) {for (int i = 0; i < F.size(); i++) {glBegin(GL_LINE_LOOP);for (int j = 0; j < 3; j++) {glV ertex3f(V[F[i].v[j] - 1].x, V[F[i].v[j] - 1].y, V[F[i].v[j] - 1].z);}glEnd();}for (int i = 0; i < FQ.size(); i++) {glBegin(GL_LINE_LOOP);for (int j = 0; j < 4; j++) {glV ertex3f(V[FQ[i].v[j] - 1].x, V[FQ[i].v[j] - 1].y, V[FQ[i].v[j] - 1].z);}glEnd();}}else {for (int i = 0; i < F.size(); i++) {glBegin(GL_LINE_LOOP);for (int j = 0; j < 3; j++) {glV ertex3f(V[F[i].v[j] - 1].x, V[F[i].v[j] - 1].y, V[F[i].v[j] - 1].z);}glEnd();}for (int i = 0; i < FQ.size(); i++) {glBegin(GL_LINE_LOOP);for (int j = 0; j < 4; j++) {glV ertex3f(V[FQ[i].v[j] - 1].x, V[FQ[i].v[j] - 1].y, V[FQ[i].v[j] - 1].z);}glEnd();}}}else if (type == 3) {glBegin(GL_POINTS);for (int i = 0; i < V.size(); i++)glV ertex3f(V[i].x, V[i].y, V[i].z);glEnd();}else{if (!VN.empty()) {for (int i = 0; i < F.size(); i++) {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glBegin(GL_TRIANGLES);for (int j = 0; j < 3; j++) {glNormal3f(VN[F[i].vn[j] - 1].x, VN[F[i].vn[j] - 1].y, VN[F[i].vn[j] - 1].z);glV ertex3f(V[F[i].v[j] - 1].x, V[F[i].v[j] - 1].y, V[F[i].v[j] - 1].z);}glEnd();}for (int i = 0; i < FQ.size(); i++) {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glBegin(GL_QUADS);for (int j = 0; j < 4; j++) {glNormal3f(VN[FQ[i].vn[j] - 1].x, VN[FQ[i].vn[j] - 1].y, VN[FQ[i].vn[j] - 1].z);glV ertex3f(V[FQ[i].v[j] - 1].x, V[FQ[i].v[j] - 1].y, V[FQ[i].v[j] - 1].z);}glEnd();}}else{for (int i = 0; i < F.size(); i++) {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glBegin(GL_TRIANGLES);for (int j = 0; j < 3; j++) {glV ertex3f(V[F[i].v[j] - 1].x, V[F[i].v[j] - 1].y, V[F[i].v[j] - 1].z);}glEnd();}for (int i = 0; i < FQ.size(); i++) {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glBegin(GL_QUADS);for (int j = 0; j < 4; j++) {glV ertex3f(V[FQ[i].v[j] - 1].x, V[FQ[i].v[j] - 1].y, V[FQ[i].v[j] - 1].z);}glEnd();}}}}。