《计算机图形学》上机实验指导_第1页
《计算机图形学》上机实验指导_第2页
《计算机图形学》上机实验指导_第3页
《计算机图形学》上机实验指导_第4页
《计算机图形学》上机实验指导_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

KMUSTTeachingRecords昆明理工高校《上机实验指导书》课程名称:计算机图形学所在系(部):国资院测绘系学年学期:2012—2013学年第2学期授课专业班级:地信101/土管101/测绘101班级人数:27/24/56讲授老师:李向新教材名称:计算机图形学课程总学时:64;总学分:理论学时:38;实验(或实践)学时:上机学时:32;辅导(或答疑)学时:系主任签章:

第1部分计算机图形学上机实验大纲1。1目的与任务计算机图形学上机是计算机图形学课程的组成部分之一,是掌握计算机图形学课程内容的一个重要实践环节。通过上机实验,一方面可以让同学巩固课堂所学的计算机图形学基础理论,另一方面能让同学掌握基本的OpenGL的编程方法及技能,掌握使用OpenGL绘制基本图形,进行2D及3D维图形变换,生成曲线曲面及构建具有真实感的3D场景。1.2基本要求1.了解OpenGL在计算机图形学中的应用基础知识。2。掌握基本的OpenGL的编程方法及技能.3.学会使用OpenGL绘制基本图形。4.学会使用OpenGL进行2D及3D维图形变换、生成曲线曲面及构建具有真实感的3D场景。1.3内容及学时支配上机1:glut工具包的安装及使用2学时上机2:OpenGL编程练习2学时上机3:OpenGL中基本几何图形的绘制2学时上机4:二维图形变换编程练习2学时上机5:交互式绘图技术编程练习2学时上机6:三维图形变换编程练习2学时上机7:OpenGL三维物体表示编程练习2学时上机8:真实感图形的生成与处理上机2学时合计16学时1。4教学参考书(1)成思源等编著:计算机图形学,冶金工业出版社,2003。(2)(美)安杰尔(EdwardAngel)著;李桂琼,张文祥译:OpenGL程序设计指南(其次版),北京:清华高校出版社,2005。(3)EdwardAngel:InteractiveComputerGraphics-ATop-DownApproachwithOpenGL,ThirdEdition,PearsonEducation,Inc。,2003.(4)F。S.Hill,JR:ComputerGraphicsUsingOpenGLSecondEdition,PearsonEducation,Inc.,2003。(5)JamesD.Foleyetal.:ComputerGraphics—PrinciplesandPractice,SecondEditioninC,PearsonEducation,Inc。,2002。(6)朱家义:VisualC++程序设计,机械工业出版社,2003。(7)和平鸽工作室编:三维图形系统—开发与有用技术,清华高校出版社,2003.第2部分上机实验指导内容及参考代码2。1上机1:glut工具包的安装及使用(2学时)1.目的要求:熟识OpenGL的应用工具包GLUT的安装和使用。2。实验内容:在VC++6.0环境中,编写一程序绘制GLUT中的三维茶壶模型,并上机运行.3。主要仪器设备及软件PC计算机,VC++6.0,GLUT库4、内容及要求1)下载和安装GLUT工具。见附注(1)、(2).2)编写一程序绘制GLUT中的三维茶壶模型。目的在于理解和体会在VC++6。0环境下OpenGL编程的基本步骤。见附注(3)3)工程名称和C++源文件名称为teapot_同学姓名(中文)(如teapot_徐航)。4)编译、连接、运行完成后将工程文件(扩展名为.dsp的文件)和程序源文件(扩展名为.cpp的文件)打包压缩(压缩包的文件名为你的班级姓名学号,如:GIS101徐航200810103106)。将压缩后的文件发给学委,学委再将全班的收集后打包压缩,发送至lxxjpn@qq.com.邮件主题名称为上机一班级姓名(如:上机1_GIS101)。附注(1):关于OpenGLOpenGL(“OpenGraphicsLibrary”)是图形硬件的软件接口。OpenGL包括大约250个不同的函数,程序员可以使用这些函数设定要绘制的物体和操作,来制作交互的三维应用程序。OpenGL是专业图形处理,科学计算等高端应用领域的标准图形库。它的主要竞争对手是微软的Direct3D.OpenGL曾长期处于技术上的领先地位,但近年来Direct3D也迎头赶上。目前这两种图形API在性能上可说是旗鼓相当。不过OpenGL支持众多的操作系统,而Direct3D只在Windows平台上可用.因此OpenGL仍然广受瞩目.你可以在OpenGL的官方网站http://www.OpenGL.org的Documentation中下载到官方教程和例子程序:TheOpenGLProgrammingGuide,这就是闻名的redbook(“红皮书")。如果你英语不好,那么推举你阅读:《OpenGL超级宝典》是一本相当不错的中文教程。可以在http://www.vrforum.cn/forumdisplay。php?fid=29找到它的例子代码《OpenGL编程权威指南》是redbook的中文译本,它的例子也就是redbook的例子.附注(2):怎样安装GLUT库?OpenGL的例子大都需要用到OpenGL应用工具包:GLUT库,下面讲讲怎样安装它:Windows下VC++6。0下的安装:1.下载GLUT库:http://www。opengl.org/resources/libraries/glut/glutdlls37beta.zip2.将压缩包内的glut。h放到C:\ProgramFiles\MicrosoftVisualStudio\VC98\Include\GL名目下glut32.lib放到C:\ProgramFiles\MicrosoftVisualStudio\VC98\Lib名目下glut32.dll放到C:\windows\systom32名目下。附注(3):Windows下的VC++环境中创建简洁的OpenGL程序基本过程(设所要创建的文件名为ex1)完成GLUT库的安装后,在VC++6。0环境下创建一个OpenGL程序并运行:1)打开VC++应用程序,在主菜单的“文件(File)”菜单下选择“新建(New)”选项。这时会弹出一个窗口,在弹出的窗口中选择“文件(Files)”卡。2)在“文件(Files)”卡的窗口中选择C++SourceFile。在右边健入要建立的文件名(如ex1),并选择存储路径,(如D:\),完成后按确定,进入源代码编辑窗口。注意,为了使生成的文件不会搞乱,最好事先在D盘下创建一个文件夹(如D:\EX1),保存exl文件。3)在源代码窗口内写入程序源代码。4)完成后按Ctrl+F7(Link),这时VC++会提示你是否创建工程,请选择是(yes),则自动建立工程文件ex15)在编译连接之前,先进入主菜单的“工程(Project)”菜单,选中Settings,设置工程的编译和和连结选项。6)在ProjectSetting对话框中,选“连结(Link)”卡,在改选项卡中的“Objiect\librarymodules”一栏中加入opengl32。lib、glu32.lib、glut32.lib这三个OpenGL的连接库。单击OK按钮,此工程文件就可以在OpenGL要求的环境中进行编译了。7)在Build菜单中选中Compile或Build进行编译连接。8)选中Build菜单中的Execute执行。5、参考代码#include〈windows.h>#include〈gl/glut.h〉/*背景颜色设置函数*/voidini(){ glClearColor(1.0,1。0,1。0,1。0);//设置背景颜色为白色}/*绘制茶壶的线框图函数*/voidRenderScene(void){ﻩglClear(GL_COLOR_BUFFER_BIT);//用设定的颜色来刷新指定的缓冲区ﻩglColor4f(0。0,0.0,1.0,1。0);//设置作图颜色为蓝色ﻩglutWireTeapot(0。5);//绘制一个茶壶的线框图 glFlush();//刷新OpenGL中的命令队列和缓冲区,使全部未被执行的OpenGL命令得到执行}voidmain(intargc,char**argv){ﻩglutInit(&argc,argv);//初始化GLUT库ﻩglutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//设置窗口显示为单缓冲RGB颜色模式ﻩglutInitWindowSize(600,600);//设置窗口大小为600*600glutInitWindowPosition(100,100);//设置窗口左上角坐标为(100,100)ﻩglutCreateWindow("Teapot");//窗口名称为Teapotini();//调用函数ini()设置背景为白色 glutDisplayFunc(RenderScene);//调用绘制茶壶的线框图函数glutMainLoop();//开头运行程序}2.2上机2:OpenGL编程初步练习(2学时)1.目的要求:熟识OpenGL中基本几何图形点和线的绘制方法。2。实验内容:完成综合练习三中7题的上机作业.3.主要仪器设备及软件PC计算机,VC++6.0,GLUT库4.上机内容及要求编写一个程序,在蓝色窗口中绘制一红色的正方形,且正方形大小可随窗口尺寸转变而调整.(代码可参考教科书p305的内容。)2。3上机3:OpenGL中基本几何图形的绘制(2学时)1.目的要求:熟识OpenGL中多边形的绘制及填充方法。2.实验内容:在VC++6。0环境中编写一程序,用不同的方式绘制多边形,并上机运行.3.主要仪器设备及软件PC计算机,VC++6.0,GLUT库4.参考代码#include〈windows.h>#include<GL/glut。h>voidmyinit(void){ﻩ/*设置背景颜色*/ﻩglClearColor(1.0,1.0,1.0,0.0);}voidDrawPolygon(){ﻩglBegin(GL_POLYGON);ﻩglVertex2f(20。0,10.0);ﻩglVertex2f(60.0,30.0);ﻩglVertex2f(70.0,45.0); glVertex2f(40.0,75.0);ﻩglVertex2f(10.0,60.0);ﻩglEnd();}voiddisplay(void){ﻩGLubytefly[]={ﻩ0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,ﻩ0x03,0x80,0x01,0xC0,0x06,0xC0,0x03,0x60, 0x04,0x60,0x06,0x20,0x04,0x30,0x0C,0x20,ﻩ0x04,0x18,0x18,0x20,0x04,0x0C,0x30,0x20,ﻩ0x04,0x06,0x60,0x20,0x44,0x03,0xC0,0x22,ﻩ0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22, 0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,ﻩ0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,ﻩ0x66,0x01,0x80,0x66,0x33,0x01,0x80,0xCC,ﻩ0x19,0x81,0x81,0x98,0x0C,0xC1,0x83,0x30,ﻩ0x07,0xe1,0x87,0xe0,0x03,0x3f,0xfc,0xc0, 0x03,0x31,0x8c,0xc0,0x03,0x33,0xcc,0xc0, 0x06,0x64,0x26,0x60,0x0c,0xcc,0x33,0x30,ﻩ0x18,0xcc,0x33,0x18,0x10,0xc4,0x23,0x08,ﻩ0x10,0x63,0xC6,0x08,0x10,0x30,0x0c,0x08, 0x10,0x18,0x18,0x08,0x10,0x00,0x00,0x08}; glClear(GL_COLOR_BUFFER_BIT); /*设置线段的颜色*/ glColor3f(0.0,0.0,0。0);ﻩ/*第一个多边形采纳点绘制*/ﻩglPolygonMode(GL_FRONT,GL_POINT);ﻩglTranslatef(20.0,10.0,0。0);//平移ﻩDrawPolygon();ﻩ/*其次个多边形采纳线绘制*/ glPolygonMode(GL_FRONT,GL_LINE);ﻩglTranslatef(90.0,0.0,0。0);//平移ﻩDrawPolygon(); /*第三个多边形采纳填充模式绘制*/ glPolygonMode(GL_FRONT,GL_FILL);ﻩglTranslatef(90.0,0.0,0.0);//平移ﻩDrawPolygon();ﻩ/*第四个多边形为逆时针方向,并舍弃其背面*/ﻩglFrontFace(GL_CW);//指定多边形的正面,GL_CK顺时针正面ﻩglCullFace(GL_BACK);//指明何种多边形在转换成屏幕坐标时要删除,GL_BACK背面,cull选择ﻩglEnable(GL_CULL_FACE);//激活GL_CULL_FACEﻩglTranslatef(-190.0,80.0,0.0);ﻩDrawPolygon();/*第五个多边形采纳画模式绘制*/ glFrontFace(GL_CCW);//指定多边形的GL_CCK逆时针反面ﻩglEnable(GL_POLYGON_STIPPLE);//激活GL_POLYGON_STIPPLEﻩﻩglPolygonStipple(fly); glTranslatef(90.0,80。0,0.0);ﻩDrawPolygon(); glFlush();}voidmyreshape(intw,inth){ﻩglViewport(0,0,(GLsizei)w,(GLsizei)h);ﻩglMatrixMode(GL_PROJECTION);ﻩglLoadIdentity();ﻩgluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);}intmain(intargc,char**argv){ glutInit(&argc,argv);ﻩglutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);ﻩglutInitWindowSize(300,300);ﻩglutInitWindowPosition(150,150); glutCreateWindow("Polygon”);ﻩmyinit();ﻩglutDisplayFunc(display);ﻩglutReshapeFunc(myreshape);ﻩglutMainLoop(); return0;}2.4上机4:二维图形变换编程练习(2学时)1。目的要求:熟识OpenGL中多边形的绘制及填充方法。2.实验内容:在VC++6.0环境中编写一二维图形变换程序,并上机运行。3.主要仪器设备及软件PC计算机,VC++6.0,GLUT库4.要求:对顶点为V1V2V3的三角形进行平移、旋转、比例、错切等基本变换;并分别用不同的线型绘制变换后的三角形。三角形顶点的坐标为:V1(20。0,20.0),V2(80.0,30。0),V3(50.0,70。0).5.参考代码:#include〈windows.h>#include〈GL/glut。h>voidmyinit(void){glClearColor(1。0,1.0,1。0,0。0);//设置背景颜色为白色}/*绘制三角形*/voidDrawTriangle(){glBegin(GL_TRIANGLES);glVertex2f(20.0,20。0);glVertex2f(80.0,30.0);glVertex2f(50.0,70.0);glEnd();}voiddisplay(void){glClear(GL_COLOR_BUFFER_BIT);glColor3f(0。0,0.0,1。0);//设置线段的颜色为黑色/*第一个三角形用实线绘制*/glPolygonMode(GL_FRONT,GL_LINE);//正面,线填充DrawTriangle();ﻩglColor3f(1。0,0。0,0.0);//设置线段的颜色为黑色/*其次个三角形采纳虚线绘制*/glMatrixMode(GL_MODELVIEW);glLoadIdentity();glEnable(GL_LINE_STIPPLE);glLineStipple(1,0xF0F0);glTranslatef(90.0,0.0,0。0);//平移变换DrawTriangle();ﻩglColor3f(0。0,1.0,0.0);//设置线段的颜色为黑色 ﻩ/*第三个三角形采纳点绘制*/glLoadIdentity();glLineStipple(1,0x8888);glTranslatef(20.0,80.0,0.0);//平移变换glScalef(0.5,1.5,1.0);//比例变换DrawTriangle(); glColor3f(0.5,0。5,0。0);//设置线段的颜色为黑色/*第四个三角形采纳长虚线绘制*/glLoadIdentity();glLineStipple(1,0xF00F);glTranslatef(110.0,90.0,0.0);//平移变换glRotatef(30,0.0,0.0,1.0);//旋转变换DrawTriangle();glDisable(GL_LINE_STIPPLE);glFlush();}voidmyreshape(intw,inth){glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0。0,(GLdouble)w,0。0,(GLdouble)h);}intmain(intargc,char**argv){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(200,200);glutInitWindowPosition(200,200);glutCreateWindow("Transform");myinit();glutDisplayFunc(display);glutReshapeFunc(myreshape);glutMainLoop();return0;}2.5上机5:交互式绘图技术编程练习(2学时)1.目的要求:熟识OpenGL中多边形的绘制及填充方法。2.实验内容:在VC++6。0环境中的OpenGL交互式绘图技术编程练习,并上机运行。3.主要仪器设备及软件PC计算机,VC++6.0,GLUT库4.要求:本上机实验由三部分组成.第一部分:是书中6。4。1中的例题,主要练习用鼠标选择。在该程序中,drawSphere()分别绘制了四个圆球,并分别给它们命名为1、2、3和4。然后进行选择模式,并建立鼠标回调函数:glutMouseFunc(MouseCallback);在鼠标响应函数MouseCallback()中,通过按下鼠标左键,调用以下语句在鼠标位置周围建立一个局部的观察空间:gluPickMatrix(x,Viewport[3]-y,2,2,Viewport);在该空间下,推断与之相交的球体:drawSphere(GL_SELECT);如某一球体与该观察空间有相交,则被选中.最后退出选择模式,并返回选中记录:hits=glRenderMode(GL_RENDER);其次部分:用鼠标选择的程序Pick第三部分:参照其次部分pick。cpp代码,修改第一部分的Select。cpp代码,输出hits的值,并打印所选球体的颜色.第一部分参考代码:用鼠标选择的程序(Select)#include<windows.h〉#include〈GL/glut.h>//myinit()的功能为:激活深度比较功能,指定刷新缓冲区的颜色voidmyinit(){glEnable(GL_DEPTH_TEST);/*激活OpenGL的GL_DEPTH_TEST功能,进行深度比较操作并更新深度缓冲区*/glClearColor(0.0f,0.0f,0.0f,1。0f);/*指定当用glClear()清除颜色缓冲区时用的R、G、B、alpha值*/}//绘图函数voiddrawSphere(GLenummode)/*mode为一GL枚举类型的变量(如果一个变量你需要几种可能//存在的值,就可以被定义成为枚举类型).mode可以取:GL_RENDER渲染模式、GL_SELECT选择模式、GL_FEEDBACK反馈模式*/{ﻩglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);/*用GL_COLOR_BUFFER_BIT和GL_DEPTH_BUFFER_BIT的二进制规律或操作屏蔽指定的缓冲区,从而用glClearColor()设定的颜色值清除该缓冲区.*/glMatrixMode(GL_MODELVIEW);/*指定后续矩阵操作的对像是模式取景矩阵堆栈。*/ glPushMatrix();/*把当前的矩阵栈压下一层,把当前的矩阵复制后放入当前层。*/ //初始化名称堆栈ﻩglInitNames();/*在选择模式中,名称堆栈是区分绘图命令集中的命令的唯一标志。它由一个有序的的无符号整数集所构成.glInitNames()的作用是将它初始化成其默认的空堆栈*/glPushName(0);/*将0压入名称堆栈的顶部*/ﻩ //将第一个球体命名为lﻩglTranslatef(—3.0f,-2。0f,—10.0f);/*把当前矩阵乘上一个平移矩阵,产生x=—3。0,y=-2,z=-10。0的平移*/ﻩglColor3f(1.0,0.0,0。0);/*设置当前颜色*/if(mode==GL_SELECT)glLoadName(1);/*如果是mode=GL_SELECT则载入名称1到名称堆栈中,即用1来替换名称堆栈栈顶值。否则执行下句*/glutSolidSphere(1.0f,35,35);/*绘制一个半径为1。0球心在原点,经线数35,纬线数35的球*/ﻩﻩ//将其次个球体命名为2 glColor3f(1.0,0。0,1。0);/*设置当前颜色*/ﻩglPushMatrix();/*把当前的矩阵栈压下一层,把当前的矩阵复制后放入当前层.*/glTranslatef(3.0f,2。0f,0.0f);/*把当前矩阵乘上一个平移矩阵,产生x=3.0,y=2,z=0。0的平移*/if(mode==GL_SELECT)glLoadName(2);/*如果是GL_SELECT则执行下句,加载2到栈顶.否则跳过下句执行再下句*/glutSolidSphere(1。5f,35,30);/*绘制一个半径为1.5,球心在原点,经线数35,纬线数30的球*/ glPopMatrix();ﻩﻩ//将第三个球体命名为3 glPushMatrix(); glColor3f(0。0,1.0,0.0);ﻩglTranslatef(5.0f,5。0f,0。0f);ﻩif(mode==GL_SELECT)glLoadName(3);ﻩglutSolidSphere(0.5f,30,30);ﻩglPopMatrix();ﻩ//将第四个球体命名为4glPushMatrix();glColor3f(0.0,0.0,1。0);glTranslatef(5。0f,0。0f,0。0f);if(mode==GL_SELECT)glLoadName(4);glutSolidSphere(0。4f,30,30);glPopMatrix();}//定义鼠标响应函数#defineBUFFER_LENGTH64/*定义宏BUFFER_LENGTH的值为64*/voidMouseCallback(intbutton,intstate,intx,inty)/*鼠标响应函数名称为MouseCallback(),该函数须包含三个参数:button--取值为GLUT_LEFT_BUTTON或GLUT_RIGHT_BUTTON;stata-—取值为GLUT_DOWN或GLUT_UP;x,y-—鼠标当前位置的坐标值。*/{GLuintselectBuff[BUFFER_LENGTH];/*定义一个数组selectBuff[],类型为无符号整型,长度为BUFFER_LENGTH*/GLinthits,viewport[4];/*定义一个整型变量hits记录选中的图形数,整型数组viewport[]长度为4.*/if(button!=GLUT_LEFT_BUTTON&&state!=GLUT_DOWN)return;/*如果没有按下左键则return,否则执行下句*/ﻩ//建立选择数组glSelectBuffer(BUFFER_LENGTH,selectBuff);/*为选择模式产生的值建立一个缓冲区。说明:函数glSelectBuffer(GLsizeisize,GLfloat*buffer)的功能—-为选择模式建立一个缓冲区,存储返回选择数据.缓冲区的大小为size,buffer是一个指向无符号整型数组的指针。selectBuff为指向数组selectBuffer[]的首地址的指针。*/ﻩﻩ //获得当前观察边界坐标glGetIntegerv(GL_VIEWPORT,viewport);/*说明:函数GetIntegerv(GLenumpname,Glint*params)当pname取GL_VIEWPORT时,参数params返回4个值,这些值分别代表视口的x和y窗口坐标及它的宽度和高度.*/glMatrixMode(GL_PROJECTION);/*指定后续矩阵操作的对象是投影矩阵堆栈。*/ﻩglPushMatrix();/*把当前的矩阵栈压下一层,把当前的矩阵复制后放入当前层.*/ﻩﻩﻩ//进入选择模式glRenderMode(GL_SELECT);/*函数glRenderMode(GLenummode)用于设置光栅化的模式.参数mode可取GE_SELECT\GL_Render\GL_FEEDBACK三种.GL_SELECT模式下,不产生像素片段,也不转变帧缓存区中的内容。其返回值是由调用该函数时的绘图模式而不是由参数mode决定的。三种绘图模式的返回值如下:GL_Render=0;GL_FEEDBACK=传送到反馈缓冲区的值的个数;GL_SELECT=传送到选择缓冲区的命中记录个数。*/ﻩglLoadIdentity();/*用单位矩阵替换当前的矩阵*/ ﻩﻩ//在鼠标位置周围建立一个局部观察区域ﻩgluPickMatrix(x,viewport[4]-y,2,2,viewport);/*函数gluPickMatrix(GLdoublex,指定窗口坐标中的一个局部观察区域中点的x坐标ﻩ GLdoubley,指定窗口坐标中的一个局部观察区域中点的y坐标ﻩﻩGLdoubledelX,指定窗口坐标中的一个局部观察区域的宽度ﻩﻩGLdoubledelY,指定窗口坐标中的一个局部观察区域的高度ﻩﻩGLint*viewport指定当前视口(从调用函数glGetIntegerv()时起) ﻩ);*/ﻩ/*建立一个投影矩阵,该矩阵可以用来限制在视口中的一个较小的范围内进行的绘图操作,可以有效地确定光标四周的那些对象将被绘出。用例程gluPickMatrix()来约束光标四周的一个小范围中的绘之操作。*/ﻩgluPerspective(45.0f,1.0f,100.0,425.0);/*函数gluPerspective(GLdoublefovy,指定y方向的取景区域的角度ﻩﻩGLdoubleaspect,指定x方向的用来取景区域的高宽比。高宽比ﻩ 是x(宽度)与y(高度)的比率.ﻩﻩGLdoublezNear,指定视点到最近的剪切平面的距离。(正数) GLdoublezFar指定视点到最近的剪切平面的距离.(负数)ﻩﻩ);*/ﻩ/*例程gluPerspective()用来指定一个世界坐标系中的截椎体的取景区域.一般,例程gluPerspective()中的高宽比应该与相应的视口中的高宽比相匹配.例如,appect=2.0意味着取景区域在x方向的角度是它在y方向上的角度的2倍。这时,如果视口的宽度是高度的2倍,则它所显示的图像将没有扭曲变形。*/ﻩﻩ//进行图形的选取drawSphere(GL_SELECT);/*将drawSphere()的参数mode设置为选择模式GE_SELECT进行图形的选取。*///返回选中记录hits=glRenderMode(GL_RENDER);/*令hits等于glRenderMode(GL_RENDER)的返回值GL_SELECT的返回值为0*/ﻩglMatrixMode(GL_PROJECTION);/*指定后续矩阵操作的对象是投影矩阵堆栈.*/glPopMatrix();/*从当前矩阵堆栈中弹出一个矩阵,把当前矩阵替换为其下一层的矩阵.*/ﻩglMatrixMode(GL_MODELVIEW);/*指定后续矩阵操作的对象是投影矩阵堆栈。*/}//display()在屏幕上绘图的函数voiddisplay(void){glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);/*用GL_COLOR_BUFFER_BIT和GL_DEPTH_BUFFER_BIT的二进制规律或操作屏蔽指定的缓冲区,从而用glClearColor()设定的颜色值清除该缓冲区.*/drawSphere(GL_RENDER);/*用渲染模式GE_RENDER绘图*/glFlush();/*在有限时间内强制执行GL命令。说明:在不同的存储单元(包括网络缓冲区和图形加速器本身)中含有不同GL实现的缓冲区命令时,函数glFlush()将清空这些缓冲区,使全部已发布的命令尽可能快地执行.*/}voidmyReshape(intw,inth){if(h==0)h=1;ﻩglViewport(0,0,w,h);/*设置视口。glViewport(Glintx,视口像素矩形左下角的x坐标ﻩﻩ ﻩﻩﻩﻩGlinty,视口像素矩形左下角的x坐标ﻩﻩ ﻩﻩﻩﻩGLsizeiwidth,视口宽度ﻩﻩﻩﻩﻩﻩﻩGLsizeiheight视口高度ﻩﻩ);*/ﻩ/*当一个GL环境被第一次连接到一个窗口时,参数width和height按此窗口的大小设置。*/ﻩglMatrixMode(GL_PROJECTION);/*指定后续矩阵操作的对象是投影矩阵堆栈。*/ﻩglLoadIdentity();/*用单位矩阵替换当前的矩阵*/gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,1.0,50.0);/*建立一个透视投影矩阵。说明:gluPerspective(GLdoublefovy,指定y方向的取景区域的角度()ﻩﻩﻩﻩGLdoubleaspect,指定x方向的用来取景区域的高宽比。高宽比是x(宽度)与y(高度)的比率。此处视口宽高比等于窗口的宽高比w/h。ﻩﻩ GLdoublezNear,指定视点到最近的剪切平面的距离.(正数)ﻩﻩﻩﻩGLdoublezFar指定视点到最近的剪切平面的距离。(负数)ﻩ ﻩﻩﻩﻩ);*/ﻩﻩglMatrixMode(GL_MODELVIEW);/*指定后续矩阵操作的对象是模型视图矩阵堆栈。*/glLoadIdentity();/*用单位矩阵替换当前的矩阵,用该单位矩阵承载将要进行的图形变换。*/}intmain(intargc,char*argv[]){glutInit(&argc,argv);/*初始化GLUT库*/glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);/*初始化显示模式,建立一个带有双缓存、RGB颜色模型和深度缓存的窗口*/glutInitWindowSize(200,200);/*初始化窗口高和宽,指定了窗口以像素为单位的尺寸*/glutInitWindowPosition(200,200);/*初始化窗口位置*/glutCreateWindow("Select");/*创建一个OpenGL窗口,字符串Select为该窗口的窗口名*/myinit();/*调用myinit()函数激活深度比较功能,指定刷新缓冲区的颜色*/glutMouseFunc(MouseCallback);/*当发生按下或释放鼠标的一个键的大事时,调用鼠标回调函数MouseCallback加以响应*/glutReshapeFunc(myReshape);/*窗口大小被拖动转变时,调用myReshape函数在宽高变化后的窗口重绘图形.*/glutDisplayFunc(display);/*调用display函数,在前窗口中绘制图形。*/glutMainLoop();/*启动主GLUT处理循环。时间循环包括鼠标、键盘、绘制及窗口的大事。*/return0;}在该程序中,drawSphere()分别绘制了四个圆球,并分别给它们命名为1、2、3和4.然后进行选择模式,并建立鼠标回调函数:glutMouseFunc(MouseCallback):在鼠标响应函数MouseCallback()中,通过按下鼠标左键,调用以下语句在鼠标位置周围建立一个局部的观察空间:gluPickMatrix(x,Viewport[3]-y,2,2,Viewport);在该空间下,推断与之相交的球体:drawSphere(GL_SELECT);如某一球体与该观察空间有相交,则被选中。最后退出选择模式,并返回选中记录:hits=glRenderMode(GL—RENDER);以上程序的运行结果如图6—20所示。图6—20OpenGL中的选择示例其次部分参考代码:用鼠标选择的程序Pick#include〈stdlib.h>//预处理语句,包含C标准库函数头文件#include<stdio.h〉//包含C标准输入输出头文件#include<GL/glut。h〉//包含OpenGLGL/GLUT库头文件voidinit(){glClearColor(0。0,0。0,0.0,0。0);//指定刷新缓冲区颜色}//绘图函数:voiddrawObjects(GLenummode){if(mode==GL_SELECT)glLoadName(1);glColor3f(1.0,0.0,0.0);glRectf(-0.5,-0.5,1。0,1.0);if(mode==GL_SELECT)glLoadName(2);glColor3f(0。0,0.0,1。0);glRectf(-1.0,—1.0,0。5,0.5);}voiddisplay(){glClear(GL_COLOR_BUFFER_BIT);drawObjects(GL_RENDER);glFlush();}/*processHitsprintsoutthecontentsofthe*selectionarray*/voidprocessHits(GLinthits,GLuintbuffer[]){unsigni,j;GLuintnames,*ptr;printf("hits=%d\n",hits);ptr=(GLuint*)buffer;for(i=0;i<hits;i++){/*foreachhit*/names=*ptr;ptr+=3;for(j=0;j<names;j++){/*foreachname*/if(*ptr==1)printf(”redrectangle\n”);elseprintf("bluerectangle\n");ptr++;}printf(”\n");}}//定义鼠标响应函数#defineSIZE512voidmouse(intbutton,intstate,intx,inty){GLuintselectBuf[SIZE];//定义一个数组selectBuff[],类型为无符号整型,长度为BUFFER_LENGTHGLinthits;//定义一个整型变量hits记录选中的图形数,整型数组viewport[]长度为4.GLintviewport[4];//定义一个整型数组viewport[]长度为4。if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN){glGetIntegerv(GL_VIEWPORT,viewport);glSelectBuffer(SIZE,selectBuf);glRenderMode(GL_SELECT);glInitNames();glPushName(0);glMatrixMode(GL_PROJECTION);glPushMatrix();glLoadIdentity();/*create5x5pixelpickingregionnearcursorlocation*/gluPickMatrix((GLdouble)x,(GLdouble)(viewport[3]-y),5.0,5。0,viewport);gluOrtho2D(-2。0,2.0,—2.0,2.0);drawObjects(GL_SELECT);glMatrixMode(GL_PROJECTION);glPopMatrix();glFlush();hits=glRenderMode(GL_RENDER);processHits(hits,selectBuf);glutPostRedisplay();}}voidreshape(intw,inth){glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(—2。0,2。0,-2.0,2.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}voidkeyboard(unsignedcharkey,intx,inty){switch(key){case27:exit(0);break;}}/*mainloop*/intmain(intargc,char**argv){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(500,500);glutInitWindowPosition(100,100);glutCreateWindow(argv[0]);init();glutReshapeFunc(reshape);glutDisplayFunc(display);glutMouseFunc(mouse);glutKeyboardFunc(keyboard);glutMainLoop();return0;}第三部分参考代码:参照其次部分pick。cpp代码,修改第一部分的Select.cpp代码,输出hits的值,并打印所选球体的颜色。#include<windows.h>//包含widowsAPI函数的头文件#include〈stdlib。h>//包含C语言标准函数库stdlib的头文件#include<stdio。h>//包含C语言标准输入输出函数库stdio的头文件#include〈GL/glut.h>//包含OpenGL图形函数库GL及有用库函数库glut的头文件voidmyinit(){glEnable(GL_DEPTH_TEST);glClearColor(0.0f,0.0f,0。0f,1.0f);}//绘图函数voiddrawSphere(GLenummode){ﻩglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glPushMatrix();ﻩﻩglInitNames();glPushName(0);ﻩﻩglTranslatef(-3。0f,-2。0f,-10。0f);glColor3f(1。0,0。0,0.0);if(mode==GL_SELECT)glLoadName(1);glutSolidSphere(1。0f,35,35);ﻩglColor3f(1.0,0.0,1。0);glPushMatrix();glTranslatef(3.0f,2.0f,0.0f);if(mode==GL_SELECT)glLoadName(2);glutSolidSphere(1。5f,35,30);glPopMatrix();ﻩﻩ/*glPushMatrix();glColor3f(0.0,1.0,0.0);glTranslatef(5.0f,5.0f,0.0f);if(mode==GL_SELECT)glLoadName(3);glutSolidSphere(0。5f,30,30);glPopMatrix();glPushMatrix();glColor3f(0。0,0。0,1.0);glTranslatef(5。0f,0.0f,0.0f);if(mode==GL_SELECT)glLoadName(4);glutSolidSphere(0.4f,30,30);glPopMatrix();*/}voiddisplay(void){glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);drawSphere(GL_RENDER);glFlush();}voidprocessHits(GLuinthits,GLuintbuffer[]){ unsignedinti,j;/*定义无符号整形变量i,j*/ﻩGLuintnames,*ptr;/*定义GL无符号整形变量name用来存储对象的名字,指针变量*ptrﻩﻩ 存放其他变量地址的变量称为指针*/ﻩﻩﻩﻩﻩ printf("hits=%d\n",hits);/*屏幕打印hits的值,打印格式%d十进制小数,换行\n*/ﻩptr=(GLuint*)buffer;/*将buffer数组的首地址赋值给指针变量ptr,ﻩ ﻩﻩﻩﻩ亦即将指针ptr指向buffer数组的首地址ﻩﻩ ﻩ ﻩ(GLuint*)将buffer的类型强制转换为GLuint。*/ﻩ ﻩﻩﻩﻩﻩﻩ ﻩﻩﻩ ﻩfor(i=0;i<hits;i++)/*i=0每次增加1循环到hits*/ﻩ{/*foreachhit*//*每次点击*/ﻩnames=*ptr;/*令变量name的值等于指针*ptr指向地址的值*/ ptr+=3;/*ptr=ptr+3,ptr每次增加3个字节*/ﻩfor(j=0;j<names;j++)/*j=0每次增加1循环到name*/ﻩ{/*foreachname*//*每个name*/ﻩif(*ptr==1)printf("redrectangle\n”);/*如果*ptr=1,打打印redrectangle并换行*/ elseprintf("pinkrectangle\n”);/*否则打印bluerectangle,换行。*/ﻩptr++;/*ptr增加1*/ﻩ}ﻩprintf("\n”);/*换行*/ﻩ}}//定义鼠标响应函数#defineBUFFER_LENGTH64voidMouseCallback(intbutton,intstate,intx,inty){GLuintselectBuff[BUFFER_LENGTH];/*定义一个数组selectBuff[],类型为无符号整型,长度为BUFFER_LENGTH*/GLinthits,viewport[4];if(button!=GLUT_LEFT_BUTTON&&state!=GLUT_DOWN)return;glSelectBuffer(BUFFER_LENGTH,selectBuff);glGetIntegerv(GL_VIEWPORT,viewport);glMatrixMode(GL_PROJECTION);glPushMatrix();glRenderMode(GL_SELECT);glLoadIdentity();gluPickMatrix(x,viewport[3]—y,2,2,viewport);gluPerspective(45.0f,1.0f,1.0,425.0);drawSphere(GL_SELECT);hits=glRenderMode(GL_RENDER);processHits(hits,selectBuff);glutPostRedisplay();glMatrixMode(GL_PROJECTION);glPopMatrix();glMatrixMode(GL_MODELVIEW);}voidmyReshape(intw,inth){if(h==0)h=1;ﻩglViewport(0,0,w,h);/*设置视口.ﻩﻩﻩglViewport(Glintx,视口像素矩形左下角的x坐标ﻩﻩ ﻩ ﻩGlinty,视口像素矩形左下角的x坐标ﻩﻩﻩﻩ ﻩﻩﻩ ﻩﻩGLsizeiwidth,视口宽度ﻩﻩﻩﻩﻩ GLsizeiheight视口高度ﻩ);*/ﻩ/*当一个GL环境被第一次连接到一个窗口时,参数width和height按此窗口的大小设置。*/glMatrixMode(GL_PROJECTION);/*指定后续矩阵操作的对象是投影矩阵堆栈。*/glLoadIdentity();/*用单位矩阵替换当前的矩阵*/ﻩgluPerspective(45.0f,(GLfloat)w/(GLfloat)h,1。0,50.0);/*建立一个透视投影矩阵.ﻩﻩ说明:gluPerspective(GLdoublefovy,指定y方向的取景区域的角度()ﻩﻩ ﻩﻩﻩﻩGLdoubleaspect,指定x方向的用来取景区域的高宽比。 ﻩﻩﻩﻩ高宽比是x(宽度)与y(高度)的比率。ﻩﻩﻩﻩﻩ ﻩﻩﻩ 此处视口宽高比等于窗口的宽高比w/h。ﻩﻩﻩﻩ ﻩﻩGLdoublezNear,指定视点到最近的剪切平面的距离。(正数)ﻩ ﻩﻩﻩ ﻩGLdoublezFar指定视点到最近的剪切平面的距离.(负数) ﻩﻩ ﻩ);*/ﻩglMatrixMode(GL_MODELVIEW);/*指定后续矩阵操作的对象是模型视图矩阵堆栈。*/ﻩglLoadIdentity();/*用单位矩阵替换当前的矩阵,用该单位矩阵承载将要进行的图形变换。*/}intmain(intargc,char*argv[]){glutInit(&argc,argv);/*初始化GLUT库*/ﻩglutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);/*初始化显示模式,建立一个带有双缓存、RGB颜色模型和深度缓存的窗口*/ glutInitWindowSize(200,200);/*初始化窗口高和宽,指定了窗口以像素为单位的尺寸*/ﻩglutInitWindowPosition(200,200);/*初始化窗口位置*/ﻩglutCreateWindow(”Select");/*创建一个OpenGL窗口,字符串Select为该窗口的窗口名*/ﻩmyinit();/*调用myinit()函数激活深度比较功能,指定刷新缓冲区的颜色*/ glutMouseFunc(MouseCallback);/*当发生按下或释放鼠标的一个键的大事时,调用鼠标回调函数MouseCallback加以响应*/ glutReshapeFunc(myReshape);/*窗口大小被拖动转变时,调用myReshape函数在宽高变化后的窗口重绘图形。*/ﻩglutDisplayFunc(display);/*调用display函数,在前窗口中绘制图形。*/ﻩglutMainLoop();/*启动主GLUT处理循环。时间循环包括鼠标、键盘、绘制及窗口的大事。*/ﻩreturn0;}2。6上机6:三维图形变换上机练习(2学时)1。目的要求:熟识OpenGL中三维图形变换的方法。2。实验内容:在VC++6。0环境中编写:1)模型变换程序;2)透视投影程序;3)图形裁剪程序;并上机运行。3.主要仪器设备及软件PC计算机,VC++6.0,GLUT库参考代码:1)模型变换程序/*本程序对一个八面体进行模型变换*/#include<windows。h>#include<GL/glut.h>voidmyinit(void){ﻩglClearColor(1。0,1.0,1。0,0.0);}voiddisplay(void){ﻩglClear(GL_COLOR_BUFFER_BIT);ﻩglMatrixMode(GL_MODELVIEW);//指定当前的矩阵操作类型为模型视图矩阵ﻩglLoadIdentity();ﻩﻩ/*第一个八面体*/ glTranslatef(-1。0,-1.0,—5.0);//ﻩglColor3f(0.0,0.0,0.0); glutWireOctahedron();/*其次个八面体*/ﻩglPushMatrix();//把当前操作矩阵压入矩阵栈堆ﻩ/*平移变换*/ﻩglTranslatef(2.0,1。0,0。0); glColor3f(1.0,0.0,0.0);ﻩglutWireOctahedron(); /*第三个八面体*/ﻩglPopMatrix();//当前操作矩阵出栈,它下面的矩阵作为当前矩阵ﻩglPushMatrix();ﻩ/*平移变换*/ﻩglTranslatef(-0。0,2.3,0.0);ﻩ/*比例变换*/ﻩglScalef(0.8,0。5,1.2);ﻩglColor3f(0.0,1。0,0.0);ﻩglutWireOctahedron();ﻩ/*第四个八面体*/ﻩglPopMatrix(); /*旋转变换*/ﻩglRotatef(15.0,0。0,1.0,0。0);//绕Y周旋转15.0度ﻩ/*平移变换*/ glTranslatef(2。3,2.3,0.0); glColor3f(0.0,0.0,1。0);ﻩglutWireOctahedron();ﻩglFlush();}voidmyreshape(intw,inth){ if(h==0)ﻩ h=1;ﻩglViewport(0,0,(GLsizei)w,(GLsizei)w);ﻩglMatrixMode(GL_PROJECTION);ﻩglLoadIdentity();ﻩ/*透视投影*/ﻩgluPerspective(60.0,(GLfloat)w/(GLfloat)h,1。0,20。0);ﻩglMatrixMode(GL_MODELVIEW); glLoadIdentity();}intmain(intargc,char**argv){ﻩglutInit(&argc,argv);ﻩglutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);ﻩglutInitWindowSize(250,250);ﻩglutInitWindowPosition(200,200);ﻩglutCreateWindow(”3DTransform");ﻩmyinit();ﻩglutDisplayFunc(display);ﻩglutReshapeFunc(myreshape);ﻩglutMainLoop();ﻩreturn0;}运行结果:2)透视投影程序/*本程序对一个八面体进行模型变换*/#include〈windows.h〉#include<GL/glut.h〉voidmyinit(void){ﻩglClearColor(1.0,1.0,1.0,0.0);}voiddisp

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论