Opengl实验报告及源代码实验七 模型加载
OpenGL曲线曲面的绘制与3D模型的装载与显示
实验7 OpenGL曲线、曲面的绘制与3D模型的装载与显示实验目的:1)理解Bezier曲线、曲面绘制的基本原理;理解OpenGL中一维、二维插值求值器的用法。
2)掌握OpenGL中曲线、曲面绘图的方法,对比不同参数下的绘图效果差异;实验要求:1)教师领读代码;2)学生上机实验;3)针对代码1,分别或同时去掉开关1和开关2的代码注释,查看并记录实验效果;用公式说明Bezier曲线、曲面的绘制计算过程;4)针对代码2,分别或同时去掉各开关,观察并记录显示效果差异;用公式说明Bezier曲面插值点的计算过程;说明线框模型与曲面模型的区别;5)针对代码3:实验和观察材质参数、光照参数、坐标参数对实验效果的影响;6)理解均匀与非均匀样条有理曲线或曲面的差异;7)针对代码4:掌握非均匀有理B样条曲面(NURBS曲面)的曲面绘制方法;8)阅读https:///sweetdark/blog/184313代码,编写曲面裁剪和细分曲面的效果。
9)OpenGL如何装载并显示3D MAX导出的3D模型实验及代码,课外自行完成。
代码1:用四个控制点绘制一条三次Bezier曲线://Demo: 用四个控制顶点来画一条三次Bezier曲线#include <stdlib.h>#include <time.h>#include <GL/glut.h>//4个控制点的3D坐标——z坐标全为0GLfloat ctrlpoints[4][3] = {{-4, -4, 0}, {-2, 4, 0}, {2, -4, 0}, {4, 4, 0}};void init(void){//背景色glClearColor(0.0, 0.0, 0.0, 1.0);//将控制点坐标映射为曲线坐标//参数:GL_MAP1_VERTEX_3,3维点坐标//参数2和3:控制参数t或u的取值范围[0, 1]维坐标3——3:曲线内插值点间的步长4参数////参数5:曲线间的补偿为顶点数4个——总步长为12//参数6:控制点二维数组首元素地址//note: 若是在这里设置了相关参数,后续对ctrlpoints内容更改曲线不变glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);//打开开关——允许3维坐标控制点到参数点转换开关glEnable(GL_MAP1_VERTEX_3);glShadeModel(GL_FLAT);//代码开关2:去掉本注释,可启用反走样/*glEnable(GL_BLEND);glEnable(GL_LINE_SMOOTH); //允许直线反走样glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); // Antialias the lines glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);*/}void display(void){int i;glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 1.0, 1.0);//代码开关1:去掉本注释,查看动态的曲线绘图效果:动态更新控制点坐标/*for(int t = 0; t < 4; t++) {for(int j = 0; j < 3; j++)ctrlpoints[t][j] = (rand() % 1024 / 1024.0 - 0.5) * 10;}//动态映射glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);*/glLoadIdentity();glColor3f(1.0, 0.0, 0.0);//绘制连续线段glBegin(GL_LINE_STRIP);//参数t或u取值为i/30,共计31个点for (i = 0; i <= 30; i++)glEvalCoord1f((GLfloat) i/30.0); //根据4个控制点坐标的参数化插值glEnd();/* 显示控制点*/glPointSize(5.0);glBegin(GL_POINTS);for (i = 0; i < 4; i++)glVertex3fv(&ctrlpoints[i][0]);glEnd();glTranslatef(-0.1f,0.1f,0.0f);glColor3f(0.0, 1.0, 0.0);//glLineWidth(2.0);//绘制连续线段——线段数越多,曲线越光滑glBegin(GL_LINE_STRIP);//设置参数t或u取值为i/60,共计61个点//实验:若让t从-2变化到+2,可看到什么效果for (i = 0; i <= 60; i++)glEvalCoord1f((GLfloat) i/60.0); //根据4个控制点坐标的参数化插值glEnd();glTranslatef(-0.1f,0.1f,0.0f);glColor3f(1.0, 1.0, 1.0);//绘制连续线段glBegin(GL_LINE_STRIP);//设置参数t或u取值为i/60,共计61个点//实验:若让t从-2变化到+2,可看到什么效果for (i = 0; i <= 100; i++)glEvalCoord1f((GLfloat) i/100.0);glEnd();glutSwapBuffers();}//3D空间中绘制2D效果,采用正交投影void reshape(GLsizei w, GLsizei h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h)glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0); elseglOrtho(-5.0*(GLfloat)w/(GLfloat)h, 5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void keyboard(unsigned char key, int x, int y).{//请参考"变换示例参考"一文,考虑添加键盘命令,交互式来控制金字塔的旋转switch (key){case 'x':case 'X':case 27: //ESC键exit(0);break;default:break;}}int main(int argc, char** argv){srand( (unsigned int)time(0) );glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);//使用双缓存模式和深度缓存glutInitWindowSize(800, 800);glutInitWindowPosition(0, 0);glutCreateWindow(D Bezier曲线);init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutKeyboardFunc(keyboard);glutIdleFunc(display);//设置空闲时调用的函数glutMainLoop();return 0;}效果图:动态曲线绘制效果图:,查看直线反走样效果:2,打开代码开关1关闭代码开关.对比分析反走样前后曲线绘制效果差异。
opengl实验报告
opengl实验报告OpenGL实验报告引言:OpenGL(Open Graphics Library)是一种跨平台的图形编程接口,被广泛应用于计算机图形学、游戏开发和科学可视化等领域。
本实验报告将介绍我对OpenGL的实验研究和学习成果。
一、实验目的本次实验的主要目的是掌握OpenGL的基本概念和使用方法,了解图形渲染的原理和过程,以及学习如何在OpenGL中创建和操作图形对象。
二、实验环境本次实验使用的是OpenGL的最新版本,并在Windows操作系统下进行开发。
使用的开发工具是Visual Studio和OpenGL的开发库。
三、实验过程1. 熟悉OpenGL的基本概念在开始实验之前,我先学习了OpenGL的基本概念,包括OpenGL的坐标系统、图形渲染管线、着色器等。
了解这些概念对于后续的实验非常重要。
2. 创建窗口和上下文在OpenGL中,我们需要先创建一个窗口和一个OpenGL上下文,以便进行图形渲染。
通过调用相关的OpenGL函数,我成功创建了一个窗口,并初始化了OpenGL的上下文。
3. 绘制基本图形接下来,我开始尝试绘制一些基本的图形,比如点、线和三角形。
通过设置顶点坐标和颜色,我成功绘制出了这些基本图形,并在窗口中显示出来。
4. 添加纹理为了使图形更加逼真和丰富,我学习了如何在OpenGL中添加纹理。
通过加载图片并设置纹理坐标,我成功将纹理贴在了绘制的图形上,使其具有了更加真实的效果。
5. 光照和阴影效果为了增加图形的立体感和真实感,我学习了如何在OpenGL中添加光照和阴影效果。
通过设置光源的位置和属性,以及材质的属性,我成功实现了光照和阴影的效果,使图形看起来更加逼真。
6. 动画效果为了使图形具有动态效果,我学习了如何在OpenGL中实现简单的动画效果。
通过每帧更新顶点的位置和纹理坐标,我成功实现了图形的旋转和平移动画,使其具有了动态的效果。
四、实验结果和分析通过以上的实验过程,我成功掌握了OpenGL的基本概念和使用方法,并实现了一些基本的图形渲染效果。
OpenGL第七章源代码
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Psuedo window coordinates
gluOrtho2D(0.0, (GLfloat) w, 0.0f, (GLfloat) h);
0x03, 0xf0, 0xff, 0x80,
0x03, 0xf5, 0xff, 0xe0,
0x07, 0xfd, 0xff, 0xf8,
0x1f, 0xfc, 0xff, 0xe8,
0xff, 0xe3, 0xbf, 0x70,
for(x = 0; x < 16; x++)
// Draw the "fire" bitmap, advance raster position
glBitmap(32, 32, 0.0, 0.0, 32.0, 0.0, fire);
}
// Do the buffer Swap
}
-----------------------------------------------------------
bitmap2.c 绘制模式
#include <gl/glut.h>
GLfloat hh;
GLubyte wb[2]={0x00,0xff};
GLint i,j;
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
OpenGL上机报告
目录实验一中点算法 (2)一、实验目的和要求 (2)二、主要算法描述 (2)三、代码实现 (4)四、实验结果 (7)实验二Bezier曲线画茶壶 (11)一、实验目的和要求 (11)二、主要算法描述 (11)三、代码实现 (12)四、实验结果 (15)心得体会: (16)实验一 中点算法一、实验目的和要求学习使用OpenGL ,初步了解基本的OpenGL 编程方法。
熟练掌握中点算法,知道如何运用中点算法编程绘制直线、椭圆和圆。
编制中点画圆程序,上机实现在给定条件下下用中点算法画出圆形。
二、主要算法描述试验设计思路:圆是一个八分对称的图形,因此在计算圆上像素点的坐标时,可以只计算八分之一个圆,再依照对称原理算出其他七段的像素点(如下图)。
设圆方程的隐函数表示为 类似于中点法绘制直线的原理,我们将平面点划分为圆内和圆外(如下图):圆弧外的点:F(X ,Y)>0;圆弧内的点:F(X ,Y)<0;),(222=-+=R y x y x F假设在),(i i y x 绘制了一个像素,则下一步必须确定像素位置是),1(i i y x +还是)1,1(-+i i y x 更接近圆。
一次由两个点的中点决定,若中点)21,1(-+i i y x 在圆内,则说明)1,1(-+i i y x 更接近圆,否则说明),1(i i y x +更接近圆(如下图)。
为了在计算中避开计算圆的方程时会遇到的平方与开方,故运用迭代方法由式1211++=++i i i x p p 与111212+++-++=i i i i y x p p 计算决定参数。
试验编程思路:1. 输入圆半径r 和圆心),(c c y x ,并得到圆周(圆心在原点)上的第一个点:),0(),(00r y x =2. 计算决策参数的初值:r p -=103. 在每个k x 位置,从0=k 开始,完成下列测试:加入0<k p ,圆心在原点的下一个点位),(1k k y x +,并且1211++=++k k k x p p否则,圆的下一个点是)1,1(-+k k y x ,并且111212+++-++=k k k k y x p p其中11+=+k k x x 且11-=+k k y y4.确定其他七个八分圆中的对称点。
实验1,opengl的基本语法实验报告心得体会
实验1,opengl的基本语法实验报告心得体会实验1,opengl的基本语法实验报告心得体会篇一:图形学实验报告openGL的基本语法《计算机图形学基础》实验1 OpenGL的基本语法一、实验目的及要求1. 了解OpenGL的主要功能2. 了解OpenGL的绘制流程3. 掌握OpenGL的基本语法4. 通过以上内容,掌握 OpenGL的编程框架,实现简单的图形绘制二、实验环境主要是软件开发环境:VC三、实验内容OpenGL绘制矩形的简单例子。
四、实验结果五、程序代码#includevoid Initial(void){}void Display(void){glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口glColor3f(, , );//设置当前的绘图颜色为红色glRectf(, , , ); //绘制一个矩形glFlush();//处理所有的OpenGL程序}int main(int argc, char* argv[]){glutInit(&argc, argv); glutInitDisplayMo(转载于: 小龙文档网:实验1,opengl的基本语法实验报告心得体会)de(GLUT_SINGLE | GLUT_RGB); //初始化glClearColor(, , , ); //设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);//设置投影参数gluOrtho2D(,,,); 窗口的显示模式glutInitWindowSize(400,300); //设置窗口的尺寸glutInitWindowPosition(100,120); //设置窗口的位置}glutCreateWindow("矩形"); //创建一个名为矩形的窗口glutDisplayFunc(Display); //设置当前窗口的显示回调函数Initial(); //完成窗口初始化glutMainLoop(); //启动主GLUT事件处理循环return 0;六、心得体会。
图形学实验报告 OpenGL中的实体模型与层次模型
《计算机图形学基础》实验3OpenGL中的实体模型与层次模型一、实验目的及要求1.掌握GLUT库中的多面体函数的绘制方法;2.掌握GLUT库中的二、三次曲面的绘制方法;3.掌握绘制实体或线框模型的绘制方法;4.掌握显示列表的用法;二、实验环境主要是软件开发环境:VC 6.0三、实验内容1.利用OpenGL绘制简单多面体、二次及三次曲线的例子。
2.利用OpenGL绘制奥运五环标志。
四、实验结果1、利用OpenGL绘制简单多面体、二次及三次曲线的例子。
2、利用OpenGL绘制奥运五环标志五、程序代码1、利用OpenGL绘制简单多面体、二次及三次曲线#include <gl/glut.h>static GLsizei iMode = 1;static GLfloat xRot = 0.0f; //x方向旋转参数static GLfloat yRot = 0.0f; //y方向旋转参数GLUquadricObj *obj; //二次曲面对象void Initial(void){glClearColor(1.0f, 1.0f, 1.0f, 1.0f);glColor3f(0.0f, 0.0f, 0.0f);obj = gluNewQuadric( );gluQuadricDrawStyle(obj, GLU_LINE); //以线框方式绘制二次曲面对象}void ChangeSize(int w, int h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D (-1.5f, 1.5f, -1.5f, 1.5f);}void Display(void){glClear(GL_COLOR_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glRotatef(xRot, 1.0f, 0.0f, 0.0f); //旋转图形glRotatef(yRot, 0.0f, 1.0f, 0.0f); //旋转图形//指定需要绘制的图元switch(iMode) {case 1:glutWireTetrahedron(); break;case 2:glutSolidTetrahedron(); break;case 3:glutWireOctahedron(); break;case 4:glutSolidOctahedron(); break;case 5:glutWireSphere(1.0f,15,15); break;case 6:glutSolidSphere(1.0f,15,15); break;case 7:glutWireTeapot(1.0f); break;case 8:glutSolidTeapot(1.0f); break;case 9:gluSphere(obj, 1.0f, 15, 15); break;case 10:gluCylinder(obj,1.0f,0.0f,1.0f,15,15);break;case 11:gluPartialDisk(obj,0.3f,0.8f,15,15,30.0f,260.0f); break;default: break;}glFlush();}void ProcessMenu(int value){iMode = value;glutPostRedisplay();}void SpecialKeys(int key, int x, int y){if(key == GLUT_KEY_UP) xRot-= 5.0f;if(key == GLUT_KEY_DOWN) xRot += 5.0f;if(key == GLUT_KEY_LEFT) yRot -= 5.0f;if(key == GLUT_KEY_RIGHT) yRot += 5.0f;if(xRot > 356.0f) xRot = 0.0f;if(xRot < -1.0f) xRot = 355.0f;if(yRot > 356.0f) yRot = 0.0f;if(yRot < -1.0f) yRot = 355.0f;glutPostRedisplay();}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(400,400);glutInitWindowPosition(100,100);glutCreateWindow("OpenGL模型绘制函数示例");//创建菜单并定义菜单回调函数int nGlutPolyMenu = glutCreateMenu(ProcessMenu);glutAddMenuEntry("线框正四面体",1); //创建GLUT多面体绘制菜单glutAddMenuEntry("实体正四面体",2);glutAddMenuEntry("线框正八面体",3);glutAddMenuEntry("实体正八面体",4);int nGlutCurveMenu = glutCreateMenu(ProcessMenu); //创建GLUT曲面绘制菜单glutAddMenuEntry("线框球面",5);glutAddMenuEntry("实体球面",6);glutAddMenuEntry("线框茶壶",7);glutAddMenuEntry("实体茶壶",8);int nGluCurveMenu = glutCreateMenu(ProcessMenu); //创建GLU曲面绘制菜单glutAddMenuEntry("线框球面",9);glutAddMenuEntry("线框圆锥面",10);glutAddMenuEntry("线框圆环面",11);int nMainMenu = glutCreateMenu(ProcessMenu); //创建主菜单glutAddSubMenu("GLUT多面体", nGlutPolyMenu);glutAddSubMenu("GLUT曲面", nGlutCurveMenu);glutAddSubMenu("GLU曲面", nGluCurveMenu);glutAttachMenu(GLUT_RIGHT_BUTTON);glutDisplayFunc(Display);glutReshapeFunc(ChangeSize);glutSpecialFunc(SpecialKeys);Initial();glutMainLoop();return 0;}2、利用OpenGL绘制奥运五环标志#include <gl/glut.h>GLuint OlympicRings;void Initial(void){glClearColor(1.0f, 1.0f, 1.0f, 1.0f);OlympicRings = glGenLists(1);glNewList(OlympicRings, GL_COMPILE);glColor3f(1.0, 1.0, 0.0);glTranslatef(-22.0, 0.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); //绘制黄色环glColor3f(0.0, 1.0, 0.0);glTranslatef(44.0, 0.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); //绘制绿色环glColor3f(0.0, 0.0, 0.0);glTranslatef(-22.0, 30.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); //绘制黑色环glColor3f(0.0, 0.0, 1.0);glTranslatef(-42.0, 0.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); //绘制蓝色环glColor3f(1.0, 0.0, 0.0);glTranslatef(84.0, 0.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); //绘制红色环glEndList();}void ChangeSize(int w, int h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D (-70.0f, 70.0f, -70.0f, 70.0f);}void Display(void){glClear(GL_COLOR_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glCallList(OlympicRings); //调用显示列表glFlush();}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(400,400);glutInitWindowPosition(100,100);glutCreateWindow("OpenGL模型绘制函数示例");glutDisplayFunc(Display);glutReshapeFunc(ChangeSize);Initial();glutMainLoop();return 0;}六、心得体会多面体画出来,如果函数引用缺少一部分,那么会很小。
OpenGL实验预习报告
OpenGL绘图实验预习报告一.实验OpenGL的英文全称是“Open Graphics Library”即“开放的图形程序接口”,它是计算机工业标准应用程序接口,主要用于开发二维和三维图形应用程序。
OpenGL是一套底层三维图形API,之所以称之为底层API,是因为它没有提供几何实体图元,不能直接用以描述场景。
但通过一些转换程序,可以很方便的将AutoCAD、3DS等图形设计软件制作的DFX和3DS模型文件转换成OpenGL的顶点数据。
OpenGL是与硬件无关的软件接口,使用它图形软件生产厂商再不用为各种不同的机型开发设计不同的软件,只要操作系统使用了OpenGL适配器就可以达到相同的效果,它是一个开放图形库,目前在Windows、MacOS、OS/2、Unix/X-Windows 等系统下均可使用,且仅在窗口相关部分(系统相关)略有差异,因此具有良好的可移植性,同时调用方法简洁明了,深受好评,应用广泛。
OpenGL能在网络环境下以客户机/服务器模式工作,充分发挥集群运算的威力,是专业图形处理、科学计算等高端应用领域的标准图形库。
(一)OpenGL基础知识OpenGL是一种开放式的图形软件开发包,它采用C语言风格,提供大量的函数来进行图形方面的处理,一般编程使用的函数库包括:OpenGL图形库-----函数以gl开头,可以实现比较简单的绘制功能,核心函数共115个。
这些函数可以运行在现在任何主流操作系统中。
绘制基本几何图元的函数如绘制图元的函数glBegain()、glEnd()、glNormal*()、glVertex*()。
矩阵操作、几何变换和投影变换的函数如矩阵入栈函数glPushMatrix()、矩阵出栈函数glPopMatrix()、装载矩阵函数glLoadMatrix()、矩阵相乘函数glMultMatrix(),当前矩阵函数glMatrixMode()和矩阵标准化函数glLoadIdentity(),几何变换函数glTranslate*()、glRotate*()和glScale*(),投影变换函数glOrtho()、glFrustum()和视口变换函数glViewport()等等。
计算机图形学 OpenGL 外部图形的的加载、旋转和平移
外部图形的加载、旋转和平移1、实验目的和要求外部图形的的加载、旋转和平移2、实验内容用MFC方法和OpengL知识来实现位图和.cur格式图形文件的的加载、旋转和平移。
3、实验步骤1)程序设计Camera.cpp 实现照相机模型与变换。
CoordinateAxis.cpp 实现图中的向量绘制和标注。
MFCGL.cpp 实现的功能相当于主函数调用的功能。
MFCGLView.cpp 主干文件,对图形的编辑的具体实现。
2)程序调试、测试与运行结果分析(1)X视图Y视图Z视图旋转功能平移共能功能选择键,依次为选择、旋转、平移和三种视图。
(2)功能上实现的感觉还可以,基本上已经达到要求,但由于图形文件是从网上下来的,不是自己编辑设计的,而且也不是cad文件,是没有达到题目要求,Win7不能安装CAD软件,这是我自己考虑不周,实验结果还是比较满意的。
4、实验总结此次课程设计,对我的很有挑战。
在课上对文件加载这部分知识没有过多的领会,导致我在网上找了很长时间的加载函数。
后来网上有了个用MFC 加载图形的例子,根据它的截图和关键算法的代码实现,再加上以前对MFC 稍微有点了解,知道函数该添加在什么位置,花了将近一个下午的时间将在RES文件夹中的文件进行了加载、旋转和平移,代码看的不是特别懂,有点糊里糊涂,而且可能对MFC了解的也不是特别深,致使我在编译时错误不断,有时甚至达到了115个错误。
后来原因只是因为一个符号错了,看来还得再细节上多多注意,还有头一次用MFC实现OpengL方法的编程,感觉还好,最起码有结果出来了。
MFC的优点就是框架已经搭建好了,不用在费事去做过多与需求功能无关的事,很多文件都是直接生成的,只需加几个头文件就行了,还有就是添加功能函数。
总体讲收获很大,对自己的编程能力又多了一点自信。
5、附录res/rc2:包含项目使用的附加资源的脚本文件。
1)MFCGLView.cpp文件代码:// MFCGLView.cpp : implementation of the CMFCGLView class//#include "stdafx.h"#include "MFCGL.h"#include "MainFrm.h"#include "MFCGLDoc.h"#include "MFCGLView.h"#include "CoordinateAxis.h"#include <math.h>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifGLfloat ambientLight[] = { 0.3f, 0.3f,0.3f, 1.0f };GLfloat diffuseLight[] = { 0.7f, 0.7f,0.7f, 1.0f };GLfloat lightPos[] = {-50.0f, 50.0f,100.0f, 1.0f };/////////////////////////////////////////////////////////////////////////////// CMFCGLViewIMPLEMENT_DYNCREATE(CMFCGLView, CView)BEGIN_MESSAGE_MAP(CMFCGLView, CView)//{{AFX_MSG_MAP(CMFCGLView)ON_WM_CREATE()ON_WM_DESTROY()ON_WM_SIZE()ON_WM_TIMER()ON_WM_ERASEBKGND()ON_COMMAND(C_PAN, OnCameraPan)ON_UPDATE_COMMAND_UI(C_PAN, OnUpdateCameraPan)ON_COMMAND(SELECTMODE, OnSELECTMODE)ON_UPDATE_COMMAND_UI(SELECTMODE, OnUpdateSELECTMODE) ON_WM_MOUSEMOVE()ON_WM_KEYDOWN()ON_WM_LBUTTONDOWN()ON_WM_RBUTTONDOWN()ON_COMMAND(C_ROTATE, OnSceneRotate)ON_UPDATE_COMMAND_UI(C_ROTATE, OnUpdateSceneRotate)ON_WM_PAINT()ON_COMMAND(ID_ORTHO, OnOrtho)ON_UPDATE_COMMAND_UI(ID_ORTHO, OnUpdateOrtho)ON_COMMAND(ID_PERSPECTIVE, OnPerspective)ON_UPDATE_COMMAND_UI(ID_PERSPECTIVE, OnUpdatePerspective)ON_COMMAND(ID_X_VIEW, OnXView)ON_COMMAND(ID_Y_VIEW, OnYView)ON_COMMAND(ID_Z_VIEW, OnZView)ON_COMMAND(ID_FREE_VIEW, OnFreeView)ON_UPDATE_COMMAND_UI(ID_X_VIEW, OnUpdateXView)ON_UPDATE_COMMAND_UI(ID_Y_VIEW, OnUpdateYView)ON_UPDATE_COMMAND_UI(ID_Z_VIEW, OnUpdateZView)ON_UPDATE_COMMAND_UI(ID_FREE_VIEW, OnUpdateFreeView)ON_COMMAND(ID_SHOW_COORDINATE_AXIS, OnShowCoordinateAxis) ON_UPDATE_COMMAND_UI(ID_SHOW_COORDINATE_AXIS, OnUpdateShowCoordinateAxis)ON_COMMAND(ID_DRAWMODE_SOLID, OnDrawmodeSolid)ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SOLID, OnUpdateDrawmodeSolid)ON_COMMAND(ID_DRAWMODE_WIRE, OnDrawmodeWire)ON_UPDATE_COMMAND_UI(ID_DRAWMODE_WIRE, OnUpdateDrawmodeWire)ON_WM_SETCURSOR()ON_COMMAND(ID_DRAWMODE_POINTS, OnDrawmodePoints)ON_UPDATE_COMMAND_UI(ID_DRAWMODE_POINTS, OnUpdateDrawmodePoints)ON_COMMAND(ID_DRAWMODE_SILHOUETTE, OnDrawmodeSilhouette) ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SILHOUETTE,OnUpdateDrawmodeSilhouette)ON_COMMAND(ID_DRAWMODE_ORIENTATION_INSIDE, OnDrawmodeOrientationInside)ON_UPDATE_COMMAND_UI(ID_DRAWMODE_ORIENTATION_INSIDE, OnUpdateDrawmodeOrientationInside)ON_COMMAND(ID_DRAWMODE_ORIENTATION_OUTSIDE, OnDrawmodeOrientationOutside)O N_UPDATE_COMMAND_UI(ID_DRAWMODE_ORIENTATION_OUTSIDE, OnUpdateDrawmodeOrientationOutside)ON_COMMAND(ID_DRAWMODE_SHADING_FLAT, OnDrawmodeShadingFlat)ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SHADING_FLAT, OnUpdateDrawmodeShadingFlat)ON_COMMAND(ID_DRAWMODE_SHADING_NONE, OnDrawmodeShadingNone)ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SHADING_NONE, OnUpdateDrawmodeShadingNone)ON_COMMAND(ID_DRAWMODE_SHADING_SMOOTH, OnDrawmodeShadingSmooth)ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SHADING_SMOOTH, OnUpdateDrawmodeShadingSmooth)//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CMFCGLView construction/destructionCMFCGLView::CMFCGLView(){// TODO: add construction code herem_pShape = gluNewQuadric();m_fLineWidth = 0.05;m_hGLContext = NULL;m_GLPixelIndex = 0;m_Action = SELECT;m_RotateAxis = AXIS_Z;m_bBuildList = FALSE;m_bOrtho = FALSE;m_ViewMode = FREE_VIEW;m_bShowAxis = TRUE;m_bSelection = FALSE;m_nDrawMode = SOLID;m_nDrawOrient = OUTSIDE;m_nShading = SMOOTH;}CMFCGLView::~CMFCGLView(){gluDeleteQuadric(m_pShape);}BOOL CMFCGLView::PreCreateWindow(CREATESTRUCT& cs) {// TODO: Modify the Window class or styles here by modifyingcs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);return CView::PreCreateWindow(cs);}/////////////////////////////////////////////////////////////////////////////// CMFCGLView drawingvoid CMFCGLView::OnDraw(CDC* pDC){CMFCGLDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data here}/////////////////////////////////////////////////////////////////////////////// CMFCGLView printingBOOL CMFCGLView::OnPreparePrinting(CPrintInfo* pInfo) {// default preparationreturn DoPreparePrinting(pInfo);}void CMFCGLView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {// TODO: add extra initialization before printing}void CMFCGLView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {// TODO: add cleanup after printing}/////////////////////////////////////////////////////////////////////////////// CMFCGLView diagnostics#ifdef _DEBUGvoid CMFCGLView::AssertValid() const{CView::AssertValid();}void CMFCGLView::Dump(CDumpContext& dc) const{CView::Dump(dc);}CMFCGLDoc* CMFCGLView::GetDocument() // non-debug version is inline {ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCGLDoc))); return (CMFCGLDoc*)m_pDocument;}#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////// CMFCGLView message handlersBOOL CMFCGLView::SetWindowPixelFormat(HDC hDC) {PIXELFORMATDESCRIPTOR pixelDesc;pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR); pixelDesc.nVersion = 1;pixelDesc.dwFlags =PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL |PFD_STEREO_DONTCARE|PFD_DOUBLEBUFFER;pixelDesc.iPixelType = PFD_TYPE_RGBA;olorBits = 32;pixelDesc.cRedBits = 8;pixelDesc.cRedShift = 16;pixelDesc.cGreenBits =8;pixelDesc.cGreenShift =8;pixelDesc.cBlueBits = 8;pixelDesc.cBlueShift = 0;pixelDesc.cAlphaBits = 0;pixelDesc.cAlphaShift = 0;pixelDesc.cAccumBits = 64;pixelDesc.cAccumRedBits = 16;pixelDesc.cAccumGreenBits = 16;pixelDesc.cAccumBlueBits = 16;pixelDesc.cAccumAlphaBits = 0;pixelDesc.cDepthBits = 32;pixelDesc.cStencilBits = 8;pixelDesc.cAuxBuffers = 0;pixelDesc.iLayerType = PFD_MAIN_PLANE;pixelDesc.bReserved = 0;pixelDesc.dwLayerMask = 0;pixelDesc.dwVisibleMask = 0;pixelDesc.dwDamageMask = 0;m_GLPixelIndex = ChoosePixelFormat( hDC, &pixelDesc); if (m_GLPixelIndex==0){m_GLPixelIndex = 1;if (DescribePixelFormat(hDC,m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0){return FALSE;}}if (SetPixelFormat( hDC,m_GLPixelIndex,&pixelDesc)==FALSE){return FALSE;}return TRUE;}int CMFCGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) {if (CView::OnCreate(lpCreateStruct) == -1)return -1;HWND hWnd = GetSafeHwnd();HDC hDC = ::GetDC(hWnd);if (SetWindowPixelFormat(hDC)==FALSE)return 0;if (CreateViewGLContext(hDC)==FALSE)return 0;SetTimer(0,100,NULL);return 0;}BOOL CMFCGLView::CreateViewGLContext(HDC hDC){m_hGLContext = wglCreateContext(hDC);if (m_hGLContext == NULL){return FALSE;}if (wglMakeCurrent(hDC, m_hGLContext)==FALSE) {return FALSE;}return TRUE;}void CMFCGLView::OnDestroy(){if(wglGetCurrentContext()!=NULL){wglMakeCurrent(NULL, NULL) ;}if (m_hGLContext!=NULL){wglDeleteContext(m_hGLContext);m_hGLContext = NULL;}CView::OnDestroy();}void CMFCGLView::OnSize(UINT nType, int cx, int cy) {CView::OnSize(nType, cx, cy);GLsizei width, height;GLdouble aspect;width = cx;height = cy;if (cy==0)aspect = (GLdouble)width;elseaspect = (GLdouble)width/(GLdouble)height; m_WHRatio=aspect;glViewport(0, 0, width, height);InitOpenGL();}void CMFCGLView::OnTimer(UINT nIDEvent) {CView::OnTimer(nIDEvent);}//override the virtual function to prevent the window redraw the window client BOOL CMFCGLView::OnEraseBkgnd(CDC* pDC){return FALSE;}void CMFCGLView::OnCameraPan(){m_Action = CAMERA_PAN;m_bSelection = FALSE;}void CMFCGLView::OnUpdateCameraPan(CCmdUI* pCmdUI){pCmdUI->SetCheck(m_Action==CAMERA_PAN);pCmdUI->Enable(m_ViewMode==FREE_VIEW);}void CMFCGLView::OnSELECTMODE(){m_Action = SELECT;m_bSelection = TRUE;}void CMFCGLView::OnUpdateSELECTMODE(CCmdUI* pCmdUI){pCmdUI->SetCheck(m_Action==SELECT);pCmdUI->Enable(m_ViewMode==FREE_VIEW);}void CMFCGLView::OnMouseMove(UINT nFlags, CPoint point) {DisplayWorldCoord(point);if(nFlags==MK_LBUTTON){int rx = point.x-m_OldPoint.x;int ry = point.y-m_OldPoint.y;switch(m_Action){case CAMERA_PAN:m_Camera.Offset(rx/100.0,-ry/100.0,0);break;case SCENE_ROTATE:m_Scene.RotateRoundAxis(rx/10,m_RotateAxis);break;}m_OldPoint=point;Invalidate();}if(nFlags==MK_RBUTTON){int rx=point.x-m_OldPoint.x;switch(m_Action){case CAMERA_PAN:m_Camera.Offset(0,0,rx/100.0);HCURSOR hCursor = NULL;CWinApp *cWinApp = AfxGetApp ();hCursor = cWinApp->LoadCursor (IDC_CUR_ZOOM);::SetCursor(hCursor);break;}m_OldPoint=point;Invalidate();}//DisplayWorldCoord(point);CView::OnMouseMove(nFlags, point);}void CMFCGLView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {if(nChar == VK_TAB && m_Action == SCENE_ROTATE)m_RotateAxis = (m_RotateAxis+1) %3;CView::OnKeyDown(nChar, nRepCnt, nFlags);}void CMFCGLView::OnLButtonDown(UINT nFlags, CPoint point) {m_OldPoint = point;UINT xPos = point.x;WORD yPos = point.y;if(m_bSelection == TRUE){ProcessSelection(xPos, yPos);}CView::OnLButtonDown(nFlags, point);}void CMFCGLView::OnRButtonDown(UINT nFlags, CPoint point) {m_OldPoint = point;HCURSOR hCursor = NULL;CWinApp *cWinApp = AfxGetApp ();if(m_Action == CAMERA_PAN){hCursor = cWinApp->LoadCursor (IDC_CUR_ZOOM);::SetCursor(hCursor);}CView::OnRButtonDown(nFlags, point);}void CMFCGLView::OnSceneRotate(){m_Action = SCENE_ROTATE;m_bSelection = FALSE;}void CMFCGLView::OnUpdateSceneRotate(CCmdUI* pCmdUI) {pCmdUI->SetCheck(m_Action == SCENE_ROTATE);pCmdUI->Enable(m_ViewMode==FREE_VIEW);}void CMFCGLView::OnPaint(){CPaintDC dc(this);glLoadIdentity();glClearColor(0.0,0.0,0.0,1);glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);CheckOrtho();SetViewMode();if(m_bShowAxis){glDisable(GL_DEPTH_TEST);CCoordinateAxis(2,2,2).Display();glEnable(GL_DEPTH_TEST);}RenderScene();SwapBuffers(dc.m_ps.hdc);}void CMFCGLView::OnOrtho(){if(m_bOrtho)return;else{m_bOrtho=TRUE;Invalidate();}}void CMFCGLView::OnUpdateOrtho(CCmdUI* pCmdUI){pCmdUI->SetCheck(m_bOrtho);}void CMFCGLView::OnPerspective(){if(!m_bOrtho)return;else{m_bOrtho=FALSE;Invalidate();}}void CMFCGLView::OnUpdatePerspective(CCmdUI* pCmdUI) {pCmdUI->SetCheck(!m_bOrtho);}void CMFCGLView::InitOpenGL(){glLineWidth(m_fLineWidth);glEnable(GL_LINE_SMOOTH);glFrontFace(GL_CW);glEnable(GL_CULL_FACE);glCullFace(GL_FRONT);glEnable(GL_LIGHTING);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_POSITION, lightPos);glEnable(GL_LIGHT0);glEnable(GL_COLOR_MATERIAL);glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);glEnable(GL_NORMALIZE);}void CMFCGLView::OnXView(){m_ViewMode = X_VIEW;m_bOrtho = TRUE;Invalidate();}void CMFCGLView::OnYView(){m_ViewMode = Y_VIEW;m_bOrtho = TRUE;Invalidate();}void CMFCGLView::OnZView(){m_ViewMode = Z_VIEW;m_bOrtho = TRUE;Invalidate();}void CMFCGLView::OnFreeView(){m_ViewMode = FREE_VIEW;m_bOrtho = FALSE;Invalidate();}void CMFCGLView::OnUpdateXView(CCmdUI* pCmdUI) {pCmdUI->SetCheck(m_ViewMode == X_VIEW);}void CMFCGLView::OnUpdateYView(CCmdUI* pCmdUI) {pCmdUI->SetCheck(m_ViewMode == Y_VIEW);}void CMFCGLView::OnUpdateZView(CCmdUI* pCmdUI) {pCmdUI->SetCheck(m_ViewMode == Z_VIEW);}void CMFCGLView::OnUpdateFreeView(CCmdUI* pCmdUI) {pCmdUI->SetCheck(m_ViewMode == FREE_VIEW);}void CMFCGLView::SetViewMode(){glMatrixMode(GL_MODELVIEW);switch(m_ViewMode){case X_VIEW:gluLookAt(100,0,0,0,0,0,0,0,1);break;case Y_VIEW:gluLookAt(0,100,0,0,0,0,0,0,1);break;case Z_VIEW:gluLookAt(0,0,100,0,0,0,0,1,0);break;case FREE_VIEW:m_Camera.Apply();gluLookAt(5,5,2,0,0,0,0,0,1);m_Scene.Apply();break;}}void CMFCGLView::CheckOrtho() {if(!m_bOrtho){glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(35,m_WHRatio,1,1000); glMatrixMode(GL_MODELVIEW); }else{glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-3*m_WHRatio,3*m_WHRatio,-3,3,-1000,1000);glMatrixMode(GL_MODELVIEW);}}void CMFCGLView::OnShowCoordinateAxis(){m_bShowAxis =! m_bShowAxis;Invalidate();}void CMFCGLView::OnUpdateShowCoordinateAxis(CCmdUI* pCmdUI) {pCmdUI->SetCheck(m_bShowAxis);}void CMFCGLView::OnDrawmodeSolid(){// TODO: Add your command handler code herem_nDrawMode = SOLID;InvalidateRect(NULL);}void CMFCGLView::OnUpdateDrawmodeSolid(CCmdUI* pCmdUI) {// TODO: Add your command update UI handler code herepCmdUI->SetCheck (m_nDrawMode == SOLID);}void CMFCGLView::OnDrawmodeWire(){// TODO: Add your command handler code herem_nDrawMode = WIRE;Invalidate();}void CMFCGLView::OnUpdateDrawmodeWire(CCmdUI* pCmdUI) {// TODO: Add your command update UI handler code herepCmdUI->SetCheck (m_nDrawMode == WIRE);}// Parse the selection buffer to see which planet/moon was selected void CMFCGLView::ProcessPlanet(GLuint *pSelectBuff){int id,count;char cMessage[64];count = pSelectBuff[0];id = pSelectBuff[3];if(m_Action == SELECT && m_bSelection){switch(id){case DISK:strcpy(cMessage,"Success: Selected Disk.");break;case SPHERE:strcpy(cMessage,"Success: Selected Sphere.");break;case CONE:strcpy(cMessage,"Success: Selected Cone.");break;case CYLINDER:strcpy(cMessage,"Success: Selected Cylinder.");break;case TEAPOT:strcpy(cMessage,"Success: Selected Teapot.");break;case TORUS:strcpy(cMessage,"Success: Selected Torus.");break;case CUBE:strcpy(cMessage,"Success: Selected Cube.");break;default:strcpy(cMessage,"Error - Nothing was clicked on!");break;}}AfxMessageBox(cMessage,0,0);}#define BUFFER_LENGTH 64void CMFCGLView::ProcessSelection(int xPos, int yPos) {GLuint selectBuff[BUFFER_LENGTH];GLint hits, viewport[4];glSelectBuffer(BUFFER_LENGTH, selectBuff);glGetIntegerv(GL_VIEWPORT, viewport);glMatrixMode(GL_PROJECTION);glPushMatrix();glRenderMode(GL_SELECT);glLoadIdentity();gluPickMatrix(xPos, viewport[3] - yPos, 2,2, viewport); gluPerspective(45.0f, m_WHRatio, 1.0, 425.0);RenderScene();hits = glRenderMode(GL_RENDER);if(hits == 1)ProcessPlanet(selectBuff);glMatrixMode(GL_PROJECTION);glPopMatrix();glMatrixMode(GL_MODELVIEW);}void CMFCGLView::RenderScene(){switch(m_nDrawMode){case SOLID:gluQuadricDrawStyle(m_pShape, GLU_FILL);break;case WIRE:gluQuadricDrawStyle(m_pShape, GLU_LINE);break;case POINTS:gluQuadricDrawStyle(m_pShape, GLU_POINT);break;case SILHOUETTE:gluQuadricDrawStyle(m_pShape, GLU_SILHOUETTE);break;}switch(m_nDrawOrient){case INSIDE:gluQuadricOrientation(m_pShape, GLU_INSIDE);break;case OUTSIDE:gluQuadricOrientation(m_pShape, GLU_OUTSIDE);break;}switch(m_nShading){case NONE:gluQuadricNormals(m_pShape, GLU_NONE);break;case FLAT:gluQuadricNormals(m_pShape, GLU_FLAT);break;case SMOOTH:gluQuadricNormals(m_pShape, GLU_SMOOTH);break;}glMatrixMode(GL_MODELVIEW);glPushMatrix();glInitNames();glPushName(0);glColor3ub(255,255,255);glLoadName(SPHERE);gluSphere( m_pShape, 1, 50, 50 );glPushMatrix();glColor3ub(255,255,255);glTranslatef(-3.0,0.0,0.0);glLoadName(CONE);gluCylinder( m_pShape, 1, 0, 2, 50, 50 );CCoordinateAxis(2,2,2).Display();glPopMatrix();glPushMatrix();glColor3ub(255,255,255);glTranslatef(0.0,2.0,0.0);glLoadName(CYLINDER);gluCylinder( m_pShape, 0.5, 0.5, 2, 50, 50 ); CCoordinateAxis(2,2,2).Display();glPopMatrix();glPushMatrix();glColor3ub(255,255,255);glTranslatef(-2.0,-2.0,0.0);glLoadName(DISK);gluDisk( m_pShape, 0.5, 1, 15, 25 );CCoordinateAxis(2,2,2).Display();glPopMatrix();switch(m_nDrawMode){case WIRE:glPushMatrix();glColor3ub(255,255,255);glTranslatef(2.0,2.0,0.0);glLoadName(TEAPOT);auxWireTeapot(0.5);CCoordinateAxis(2,2,2).Display();glPopMatrix();glPushMatrix();glColor3ub(255,255,255);glTranslatef(-2.0,-2.0,0.0);glLoadName(TORUS);auxWireTorus(0.3, 0.09);CCoordinateAxis(2,2,2).Display(); glPopMatrix();glPushMatrix();glColor3ub(255,255,255);glTranslatef(2.5,0.0,0.0);glLoadName(CUBE);auxWireCube(1.0);CCoordinateAxis(2,2,2).Display(); glPopMatrix();break;case SOLID:glPushMatrix();glColor3ub(255,255,255);glTranslatef(2.5,0.0,0.0);glLoadName(CUBE);auxSolidCube(1.0);CCoordinateAxis(2,2,2).Display(); glPopMatrix();glPushMatrix();glColor3ub(255,255,255);glTranslatef(-2.0,-2.0,0.0);glLoadName(TORUS);auxSolidTorus(0.3,0.09);CCoordinateAxis(2,2,2).Display();glPopMatrix();glPushMatrix();glColor3ub(255,255,255);glTranslatef(2.0,2.0,0.0);glLoadName(TEAPOT);auxSolidTeapot(0.5);CCoordinateAxis(2,2,2).Display();glPopMatrix();break;}glFlush();}BOOL CMFCGLView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message){// TODO: Add your message handler code here and/or call defaultif (nHitTest != HTCLIENT){return CView::OnSetCursor(pWnd, nHitTest, message);}HCURSOR hCursor = NULL;CWinApp *cWinApp = AfxGetApp ();switch (m_Action) {case SCENE_ROTATE:hCursor = cWinApp->LoadCursor (IDC_CUR_ROTATE);break;case CAMERA_PAN:hCursor = cWinApp->LoadCursor (IDC_CUR_MOVE);break;case SELECT:hCursor = cWinApp->LoadCursor (IDC_CUR_SELECT);break;default:hCursor = LoadCursor (NULL, IDC_ARROW);break;}if (hCursor) SetCursor (hCursor);return TRUE;}void CMFCGLView::OnDrawmodePoints(){// TODO: Add your command handler code herem_nDrawMode = POINTS;Invalidate();}void CMFCGLView::OnUpdateDrawmodePoints(CCmdUI* pCmdUI) {// TODO: Add your command update UI handler code herepCmdUI->SetCheck (m_nDrawMode == POINTS);}void CMFCGLView::OnDrawmodeSilhouette(){// TODO: Add your command handler code herem_nDrawMode = SILHOUETTE;Invalidate();}void CMFCGLView::OnUpdateDrawmodeSilhouette(CCmdUI* pCmdUI) {// TODO: Add your command update UI handler code herepCmdUI->SetCheck (m_nDrawMode == SILHOUETTE);}void CMFCGLView::OnDrawmodeOrientationInside(){// TODO: Add your command handler code herem_nDrawOrient = INSIDE;Invalidate();}void CMFCGLView::OnUpdateDrawmodeOrientationInside(CCmdUI* pCmdUI) {// TODO: Add your command update UI handler code herepCmdUI->SetCheck(m_nDrawOrient == INSIDE);}void CMFCGLView::OnDrawmodeOrientationOutside(){// TODO: Add your command handler code herem_nDrawOrient = OUTSIDE;Invalidate();}void CMFCGLView::OnUpdateDrawmodeOrientationOutside(CCmdUI* pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->SetCheck(m_nDrawOrient == OUTSIDE);}void CMFCGLView::OnDrawmodeShadingFlat(){// TODO: Add your command handler code herem_nShading = FLAT;Invalidate();}void CMFCGLView::OnUpdateDrawmodeShadingFlat(CCmdUI* pCmdUI) {// TODO: Add your command update UI handler code herepCmdUI->SetCheck(m_nShading == FLAT);}void CMFCGLView::OnDrawmodeShadingNone(){// TODO: Add your command handler code herem_nShading = NONE;Invalidate();}void CMFCGLView::OnUpdateDrawmodeShadingNone(CCmdUI* pCmdUI) {// TODO: Add your command update UI handler code herepCmdUI->SetCheck(m_nShading == NONE);}void CMFCGLView::OnDrawmodeShadingSmooth(){// TODO: Add your command handler code herem_nShading = SMOOTH;Invalidate();}void CMFCGLView::OnUpdateDrawmodeShadingSmooth(CCmdUI* pCmdUI) {// TODO: Add your command update UI handler code herepCmdUI->SetCheck(m_nShading == SMOOTH);}void CMFCGLView::DisplayWorldCoord(CPoint point){// Display the world coordinates on the status barchar buf[80];CPoint x = point.x;CPoint y = point.y;CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;ASSERT(pFrame);CStatusBar* pStatus = &pFrame->m_wndStatusBar;ASSERT(pStatus);sprintf(buf, "X = %5.2f , Y= %5.2f \n", x, y);pStatus->SetPaneText(1, buf, TRUE);pStatus->Invalidate();}2)Camera.cpp代码#include "stdafx.h"#include "Camera.h"void MyMatrixMult(float* V1,float* V2,float* V3) {glPushMatrix();glLoadMatrixf(V1);glMultMatrixf(V2);glGetFloatv(GL_MODELVIEW_MATRIX,V3); glPopMatrix();}CTransferMatrix::CTransferMatrix(){MyIdentity();}void CTransferMatrix::MyIdentity(){int i;for(i=0;i<16;i++)Matrix[i]=0.0;for(i=0;i<16;i+=5)Matrix[i]=1.0;}void CTransferMatrix::Load(float* M){for(int i=0;i<16;i++)Matrix[i]=M[i];}CScene::CScene(){}void CScene::RotateRoundAxis(float r,int axis){ glPushMatrix();glLoadMatrixf(m_TransferMatrix.Matrix);if(axis==AXIS_X)glRotatef(r,1,0,0);if(axis==AXIS_Y)glRotatef(r,0,1,0);if(axis==AXIS_Z)glRotatef(r,0,0,1);float m_newMatrix[16];glGetFloatv(GL_MODELVIEW_MATRIX,m_newMatrix); m_TransferMatrix.Load(m_newMatrix);glPopMatrix();}void CScene::Apply(){glMultMatrixf(m_TransferMatrix.Matrix);}void CCamera::RotateRoundAxis(float r,int axis){glPushMatrix();glLoadMatrixf(m_TransferMatrix.Matrix);if(axis==AXIS_X)glRotatef(r,1,0,0);if(axis==AXIS_Y)glRotatef(r,0,1,0);if(axis==AXIS_Z)glRotatef(r,0,0,1);float m_newMatrix[16];glGetFloatv(GL_MODELVIEW_MATRIX,m_newMatrix); m_TransferMatrix.Load(m_newMatrix);glPopMatrix();}CCamera::CCamera(){}void CCamera::Offset(float x,float y,float z){glPushMatrix();glLoadIdentity();glTranslatef(x,y,z);float m_tempMatrix[16];float m_newMatrix[16];glGetFloatv(GL_MODELVIEW_MATRIX,m_newMatrix);MyMatrixMult(m_newMatrix,m_TransferMatrix.Matrix,m_newMatrix); m_TransferMatrix.Load(m_newMatrix);glPopMatrix();}void CCamera::Apply(){glMultMatrixf(m_TransferMatrix.Matrix);}。
关于opengl实验报告
关于opengl实验报告OpenGL实验报告一、实验目的本实验旨在通过使用OpenGL图形库,掌握基本的3D图形编程技术,以及了解OpenGL的基本操作和常用函数。
二、实验环境1. 操作系统:Windows 102. 开发环境:Visual Studio 20193. 编程语言:C++4. 图形库:OpenGL三、实验内容1. 创建一个窗口并初始化OpenGL环境2. 绘制一个简单的三维立方体3. 添加光照效果和材质4. 实现简单的相机控制5. 添加纹理贴图四、实验过程1. 创建窗口并初始化OpenGL环境首先,我们使用OpenGL提供的函数来创建一个窗口,并初始化OpenGL环境。
这一步是整个实验的基础,也是我们能够进行后续操作的前提。
2. 绘制一个简单的三维立方体利用OpenGL提供的函数,我们可以很容易地绘制一个简单的三维立方体。
通过设置顶点坐标和法向量,我们可以使用OpenGL提供的函数来绘制出一个立方体。
3. 添加光照效果和材质在绘制立方体的基础上,我们可以通过设置光源的位置和颜色,以及物体的材质属性,来实现光照效果和材质的渲染。
这一步可以让我们的立方体看起来更加真实。
4. 实现简单的相机控制通过控制相机的位置和方向,我们可以实现简单的相机控制。
这样可以让我们在3D场景中自由地移动和观察物体。
5. 添加纹理贴图最后,我们可以通过加载纹理图片,并将其贴到立方体的表面上,来实现纹理贴图。
这样可以让我们的立方体看起来更加生动和具有真实感。
五、实验总结通过本次实验,我们学习了如何使用OpenGL图形库进行3D图形编程,掌握了基本的操作和常用函数。
同时,我们也实现了一个简单的3D场景,包括绘制立方体、添加光照效果和材质、实现相机控制以及添加纹理贴图。
这些技术和知识对于今后的图形编程工作将会有很大的帮助。
OpenGL实验指导
计算机图形学实验指导书课程名称: 计算机图形学基础英文名称: Computer Graphics 课程性质: 限选编写人: 孔繁茹2010年9月1日计算机学院阅读说明● 未加标注的为参考实验 ● 标有☆的为必做实验 ● 标有★的为选做实验实验要求● 每个小组 ≤ 4人,需要完成以下任务⏹ 所有必做实验 (40%) 8 * 5分 ⏹ 2项选做实验 (20%) 2 * 10分 ⏹ 1项综合实验 (40%) 1 * 40分Part 1 预备知识实验1.1 环境设置[参考程序] demo.c 图 1.1.1 一、实验目的熟悉VC 编程环境, 配置OpenGL 图形环境 二、实验内容1.OpenGL 环境设置将OpenGL 所需函数库和头文件复制到指定目录.也可以通过批处理文件的方式, 将下面四行存入一文本文件, 改名为set.bat , 然后双击set.bat 运行. copy glut.h "C:\Program Files\Microsoft Visual Studio\VC98\Include\GL" copy glut32.lib "C:\Program Files\Microsoft Visual Studio\VC98\Lib" copy glut32.dll "C:\WINDOWS\system32" pause注意: 如果VC 安装在D 盘或其他盘, 应修改相应路径 2.编译运行demo.c, 查看环境是否配置成功Part 2 OpenGL 编程基础图 1.1.1实验2.1 OpenGL 编程基础[参考程序]hello.c 图2.1.1 chap2-1.cpp 图2.1.2一、实验目的熟悉OpenGL 编程框架、基本函数、几何原语 二、实验内容1. 运行hello.c, 查看运行结果, 并完成以下练习1) 改变背景颜色 2) 改变图形颜色 3) 改变窗口大小 4) 改变窗口位置2. 用OpenGL 几何原语绘制点, 直线, 多边形, 三角形带等基本图形. OpenGL 编程基础可参考附录。
OpenGL实验一实验报告
计算机学院09计算机科学与技术专业 04 班学号:3109006029 姓名:冯沐强协作者:________ 教师评定: _________一、实验目的1 掌握OpenGL的三维图形绘制方法2 掌握Visual C++环境下的OpenGL图形开发二、实验要求在Windows平台上用VC++结合GLUT做实验,要求掌握结合VC++和OpenGL的基本图形(四面体、六面体、圆柱、圆锥等)建模及编程技能,以及图形学的基本原理,实验完成后要求根据自己的成果撰写一份实验报告。
1 基本三维几何图形(四面体、六面体、圆柱、球等)的建模及基本的交互2 人机交互(图形的基本变换,如旋转、平移、尺度缩放及橡皮筋技术等)三、实验环境操作系统:Windows xp开发环境:VC以及GLUT图形交互设备:鼠标和键盘四、实验内容1 GLUT在VC环境下的正确配置下载GLUT包,解压后,文件夹中有dll,lib,h文件,将,复制到C:\WINDOWS\system32下,将glut32.lib, 放到C:\Program Files\Microsoft Visual Studio\VC98\Lib(即安装的目录),将复制到C:\ProgramFiles\Microsoft Visual Studio\VC98\Include\GL2对基本图形(四面体,六面体,圆柱,球等)的建模及基本交互。
a 在上述四种图形的中选择两种及两种以上进行建模或者组合他们产生新的对象。
b 基本的交互包括:利用鼠标、键盘实现图像的交互(主要实现物体的浏览)void RenderScene(void)五、存在的问题和感想话说我配置OPENGL占用了大量时间。
第一次使用Opengl,对其函数没底,是一边看opengl函数查询.CHM ,一边做的。
发现只要按其函数名找函数,查找使用方法和里面的参数的运用,很容易上手。
通过本实验,使我掌握了Opengl在VC上的配置和Opengl部分函数的使用。
OpenGL编程实习报告
OpenGL编程实习报告班级:学号:姓名:专业:摄影测量与遥感指导老师:实习目的:1、了解OPENGL绘图原理;熟悉OPENGL的编程步骤;掌握在OPENGL中绘图。
2、实现在VC++6.0环境下在OPENGL中绘图,绘制一个圆形或正方形;实现这个三维物体的变换。
实习原理:OpenGL的基本工作流程为:OpenGL程序的基本结构为定义窗口、清理窗口、绘制物体、结束运行。
其基本操作有:描述图元、绘制图元、OpenGL变换。
在Windows下用GDI作图必须通过设备上下文(DeviceContext简写DC)调用相应的函数;用OpenGL作图也是类似,OpenGL函数是通过"渲染上下文"(RenderingContext简写RC)完成三维图形的绘制。
Windows下的窗口和设备上下文支持"位图格式"(PIXELFORMAT)属性,和RC有着位图结构上的一致。
只要在创建RC时与一个DC建立联系(RC也只能通过已经建立了位图格式的DC来创建),OpenGL的函数就可以通过RC对应的DC画到相应的显示设备上。
实习步骤:1、首先创建工程。
用AppWizard产生一个MFC单文档(SDI)的EXE文件。
选中三维控制(3D Controls),其余保持默认值即可。
2、将此工程所需的OpenGL文件和库加入到工程中。
在工程菜单中,选择"Build"下的"Settings"项。
单击"Link"标签,选择"General"目录,在Object/Library Modules的编辑框中输入"OpenGL32.lib glu32.lib glaux.lib",选择"OK"结束。
然后打开文件"stdafx.h",将语句#include <gl\gl.h>和#include <gl\glu.h>插入到文件中。
参考资料--opengl实验报告
贵州大学实验报告学院:计算计科学与信息学院专业:班级:
这次试验的主要任务是学会配置opengl的运行环境,并通过编写程序来测试能否正确的生成相应的图案,所以还算比较简单的,做实验时只要看一下老师发给我们的ppt,然后按照上面的步骤一步一步的操作就行,先是把下载好的压缩包解压然后找到安装目录,然后将相应的文件放到相
贵州大学实验报告
学院:计算计科学与信息学院专业:数字媒体技术班级:数媒091
贵州大学实验报告
学院:计算计科学与信息学院专业:数字媒体技术班级:数媒091。
实验七 OpenGL显示加速技术
实验报告Array课程名称:____计算机图形学___ 指导老师:______ _______成绩:_______ __
实验名称:OpenGL显示加速技术实验类型:_____基础实验_____同组学生姓名:______________
一、实验目的和要求
通过实现实验内容,掌握OpenGL中顶点数组和显示列表的使用,并验证课程中关于OpenGL显示加速技术的内容。
二、实验内容和原理
使用Visual Studio C++编译已有项目工程。
要求修改代码达到以下要求:
1.补充完成函数drawVA(),实现使用顶点数组绘制场景:
void drawVA()
{
…
}
2.补充完成函数Gen3DObjectList (),实现显示列表的生成:
GLint Gen3DObjectList()
{
…
};
3.分析对比使用三种方法得到的fps。
4.添加拾取功能,对于鼠标点中的Bunny或桌子,改变显示颜色。
三、主要仪器设备
Microsoft Visual Studio 2010
Windows 7 Ultimate
Glut压缩包
Ex7 工程
四、操作方法和实验步骤
五、实验结果与分析
六、讨论、心得
这次实验是本学期的最后一次实验,难度颇大,学会了如何在OpenGL中实现除了显示列表外的另一种显示方式,即顶点数组。
鼠标操作的实现也让OPENGL的学习有了进一步的提高。
opengl开发环境配置实验总结
opengl开发环境配置实验总结OpenGL是一种跨平台的图形编程接口,可以用于开发各种图形应用程序。
在进行OpenGL开发之前,我们需要配置好开发环境,以便能够顺利进行开发工作。
本文将总结一下关于OpenGL开发环境配置的实验过程和相关经验。
为了进行OpenGL开发,我们需要准备好以下几个工具和库:1. 编程语言:OpenGL可以使用多种编程语言进行开发,例如C++、Java等。
在本次实验中,我们选择使用C++语言进行开发。
2. 集成开发环境(IDE):IDE是进行软件开发的集成工具,可以提供代码编辑、编译、调试等功能。
在本次实验中,我们选择使用Visual Studio作为IDE。
3. OpenGL库:OpenGL库是进行OpenGL开发必备的库文件,包含了各种OpenGL函数和常量的定义。
在本次实验中,我们选择使用GLEW和GLFW这两个常用的OpenGL库。
接下来,我们将一步步进行OpenGL开发环境的配置。
第一步是安装Visual Studio。
我们可以从官方网站上下载Visual Studio的安装包,并按照提示进行安装。
安装完成后,我们打开Visual Studio,新建一个C++项目,选择空项目作为项目类型。
第二步是下载和配置OpenGL库。
我们可以从GLEW和GLFW的官方网站上下载它们的最新版本。
下载完成后,我们将它们的头文件和库文件拷贝到Visual Studio的安装目录下的相应文件夹中。
具体来说,将GLEW的头文件拷贝到include文件夹中,将GLEW 和GLFW的库文件拷贝到lib文件夹中。
第三步是配置Visual Studio项目。
我们需要告诉Visual Studio去哪里找到OpenGL的头文件和库文件。
打开Visual Studio,右击项目名称,选择属性,然后在属性窗口中找到“VC++目录”和“链接器”选项,分别添加头文件和库文件的路径。
在“VC++目录”选项中的“包含目录”中添加GLEW和GLFW的头文件路径,在“链接器”选项中的“附加库目录”中添加GLEW和GLFW的库文件路径。
OpenGl实验报告
glMatrixMode(GL_PROJECTION);
//指定当前操作投影矩阵堆栈
glLoadIdentity();
//重置投影矩阵
GLfloat fAspect;
fAspect = (float)w/(float)h;
gluPerspective(45, fAspect, 1.0, 600.0);//设置透视投影矩阵
1
人生有几件绝对不能失去的东西:自制的力量,冷静的头脑,希望和信心
2
一、 实验目的与要求
1、学习和掌握 OpenGL 的使用 2、掌握矩阵堆栈的实现方法 3、根据自己的创意实现实验内容,进一步掌握和理解 OpenGL 的使用
二、 实验内容
1、请编写地球围绕太阳自动旋转的方式 2、请再加上一个月亮, 并围绕地球旋转,并添加轨道 3、实现用户通过键盘或鼠标加入或减少行星和卫星
if (a[5]>0)
a[5]--;
break;
case 'd':
if (a[6]<4)
a[6]++;
break;
case 'D':
if (a[6]>0)
a[6]--;
break;
case 'f':
if (a[7]<3)
a[7]++;
break;
case 'F':
if (a[7]>0)
a[7]--;
void Initial() {
glEnable(GL_DEPTH_TEST); //启用深度测试 glClearColor(0.0, 0.0, 0.0, 0.0);//设置背景颜色 }
opengl--实验指导书
物理与电子信息工程学院《计算机图形学基础》实验指导书(师范类计本专业)任课教师:赵汉理2009/2010学年第2学期目录实验一熟悉OpenGL开发环境 (1)实验二 OpenGL中基本几何元素的绘制 (3)实验三贴纹理 (7)实验四创建不同光源 (15)实验五单面材质与双面材质 (17)实验六纹理滤波 (21)实验七 Alpha混合 (24)实验八彩色气球 (26)实验九创建动态场景 (28)参考用书 (29)课程考核方式及成绩评定办法 (29)实验一熟悉OpenGL开发环境[实验目的和要求]1、熟悉OpenGL编程环境。
2、掌握OpenGl编程的框架。
[实验内容]1、打开VC然后创建一个新工程2、创建一个空的OpenGL窗口包含glut头文件:#include<GL/glut.h>绘制函数基本流程:void renderScene(void) {glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_TRIANGLES);glVertex3f(-0.5,-0.5,0.0);glVertex3f(0.5,0.0,0.0);glVertex3f(0.0,0.5,0.0);glEnd();glFlush();}主函数中的基本结构:void main(int argc, char **argv) {glutInit(&argc, argv);glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);glutInitWindowPosition(100,100);glutInitWindowSize(320,320);glutCreateWindow("OpenGL Tutorial");glutDisplayFunc(renderScene);glutMainLoop();}glut库相关文件的复制路径:C:\Program Files\Microsoft Visual Studio\VC98\include\GL\glut.h C:\Program Files\Microsoft Visual Studio\VC98\lib\glut32.libC:\Windows\System32\glut32.dllVC中Win32控制台项目的属性:链接器->输入->附加依赖项:glut32.lib glu32.lib opengl32.lib思考OpenGL项目设置和Win32的基本设置有什么不同之处。
计算机图形学实验报告模板
算法步骤如下:
.输入直线两端点P0(X0,Y0)和P1(X1,Y1)。
.计算初始值△x, △y,e=-△x,x=X0,y=Y0。
.绘制点(x,y)。
.e更新为e+2△y。判断e的符号,若e>0,则(x,y)更新为(x+1,y+1),同样将e更新为e-2△x;否则(x,y)更新为(x+1,y)。
OpenGL的绘制流程分为两个方面:一个完整的窗口系统的OpenGL图形处理系统的结构为:最底层为图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,最上面的层为应用软件;OpenGL命令将被放在一个命令缓冲区中,这样命令缓冲区中包含了大量的命令、顶点数据和纹理数据。当缓冲区被清空时,缓冲区中的命令和数据都将传递给流水线的下一个阶段。
// glRectf(50.0f,100.0f,150.0f,50.0f); //绘制一个矩形
glBegin(GL_LINE_LOOP); //五角星
glVertex2i(10,10);
glVertex2i(30,35);
glVertex2i(50,10);
glVertex2i(5,25);
glVertex2i(55,25);
了解了上述基础知识后,配置好OpenGL环境,然后在该环境中编程练习图形的绘制,本次实验主要是对点的绘制、直线的绘制和多边形面的绘制。
3.实验代码及结果
3.1点的绘制:
#include<gl/glut.h>
void Initial(void)
{
glClearColor(1.0f,1.0f,1.0f,1.0f); //设置窗口背景颜色为白色
为了进一步熟悉OpenGL编程,了解基本图形生成算法中的直线绘制,学会直线绘制算法中最常用的三种算法:数值微分法、中点画线算法和Bresenham算法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告学生姓名:学号:专业班级:实验类型:□验证□综合□设计□创新实验日期:2018.11 实验成绩:一、实验名称实验七模型加载二、实验内容1.设计并实现Mesh类,利用该类实现模型网格的解析、加载、管理与渲染。
2.设计并实现Model类,利用该类实现几何模型的解析、加载、管理与渲染。
3.基于Mesh类和Model类,利用Assimp模型加载库,加载并渲染三维几何模型。
三、实验目的1.掌握3D模型网格数据的组织与渲染方法。
2.掌握3D模型数据的结构与组织,以及模型数据的解析与渲染方法。
3.了解Assimp库中管理3D模型的数据结构,掌握Assimp库的使用方法。
四、实验步骤1.定义网格类结构,并初始化class Mesh{Public:vector<Vertex> vertices;vector<GLuint> indices;vector<Texture> textures;Mesh(vector<Vertex> vertices, vector<GLuint> indices, vector<Texture> texture);Void Draw(Shader shader);private:GLuint VAO, VBO, EBO;void setupMesh();}void setupMesh(){glGenVertexArrays(1, &this->VAO);glGenBuffers(1, &this->VBO);glGenBuffers(1, &this->EBO);glBindVertexArray(this->VAO);glBindBuffer(GL_ARRAY_BUFFER, this->VBO);glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex),&this->vertices[0], GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint),&this->indices[0], GL_STATIC_DRAW);// 设置顶点坐标指针glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)0);// 设置法线指针glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, Normal));// 设置顶点的纹理坐标glEnableVertexAttribArray(2);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, TexCoords));glBindVertexArray(0);}2.定义用于渲染的函数:void Draw(Shader shader){GLuint diffuseNr = 1;GLuint specularNr = 1;for(GLuint i = 0; i < this->textures.size(); i++){glActiveTexture(GL_TEXTURE0 + i); // 在绑定纹理前需要激活适当的纹理单元// 检索纹理序列号(N in diffuse_textureN)stringstream ss;string number;string name = this->textures[i].type;if(name == "texture_diffuse")ss << diffuseNr++; // 将GLuin输入到string streamelse if(name == "texture_specular")ss << specularNr++; // 将GLuin输入到string streamnumber = ss.str();glUniform1f(glGetUniformLocation(shader.Program, ("material." + name + number).c_str()), i);glBindTexture(GL_TEXTURE_2D, this->textures[i].id);}glActiveTexture(GL_TEXTURE0);// 绘制MeshglBindVertexArray(this->VAO);glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);glBindVertexArray(0);3.编写顶点着色器和片段着色器的代码:#version 330 corelayout(location = 0) in vec3 position;layout(location = 1) in vec3 normal;layout(location = 2) in vec2 texCoords;out vec2 TexCoords;uniform mat4 model;uniform mat4 view;uniform mat4 projection;void main(){gl_Position = projection * view * model * vec4(position, 1.0f);TexCoords = texCoords;}#version 330 corein vec2 TexCoords;out vec4 color;uniform sampler2D texture_diffuse1;void main(){color = vec4(texture(texture_diffuse1, TexCoords));}4.把3D模型导入OpenGL:void loadModel(string path){Assimp::Importer import;const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);if(!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode){cout << "ERROR::ASSIMP::" << import.GetErrorString() << endl;return;}this->directory = path.substr(0, path.find_last_of('/'));this->processNode(scene->mRootNode, scene);}void processNode(aiNode* node, const aiScene* scene){// 添加当前节点中的所有Meshfor(GLuint i = 0; i < node->mNumMeshes; i++){aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];this->meshes.push_back(this->processMesh(mesh, scene));}// 递归处理该节点的子孙节点for(GLuint i = 0; i < node->mNumChildren; i++){this->processNode(node->mChildren[i], scene);}}5.优化:vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName) {vector<Texture> textures;for(GLuint i = 0; i < mat->GetTextureCount(type); i++){aiString str;mat->GetTexture(type, i, &str);GLboolean skip = false;for(GLuint j = 0; j < textures_loaded.size(); j++){if(textures_loaded[j].path == str){textures.push_back(textures_loaded[j]);skip = true;break;}}if(!skip){ // 如果纹理没有被加载过,加载之Texture texture;texture.id = TextureFromFile(str.C_Str(), this->directory);texture.type = typeName;texture.path = str;textures.push_back(texture);this->textures_loaded.push_back(texture); // 添加到纹理列表textures}}return textures;}五、实验结果六、实验体会这次实验是做模型加载,在之前的实验中,我们通过在程序中指定的立方体数据,绘制立方体,看起来还是很乏味。
这次实验做模型加载,通过加载丰富的模型,能够丰富我们的场景,变得好玩。
当然它也比之前的实验更复杂,要理解Mesh网格、知道如何载入obj模型,实验代码虽然简洁,但是理解起来比较困难,需要反复看代码,才能真正理解透彻。