计 算 机 图 形 学
上机心得
指导教师:
姓 名:
学 号:何朝良 王奎 10260107
计算机图形学是利用计算机研究图形的表示、生成、处理和显示的科学。简单地说,计算机图形学的主要研究内容就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。图形通常由点、线、面、体等几何元素和灰度、色彩、线型、线宽等非几何属性组成。从处理技术上来看,图形主要分为两类,一类是基于线条信息表示的,如工程图、等高线地图、曲面的线框图等,另一类是明暗图,也就是通常所说的真实感图形。经过30多年的发展,计算机图形学已成为计算机科学中最为活跃的分支之一,并得到广泛的应用。
在科技高度发展的今天,计算机在人们之中的作用越来越突出。而C语言作为一种计算机的语言,我们学习它,有助于我们更好的了解计算机,更好的学习计算机图形学。因此,C语言对我们计算机图形学的学习尤其重要,而我们也需要一定的C语言基础知识。
在这个学期里,我们班级的学生在计算机图形学老师何老师的带领下进行了计算机图形学的上机实践学习。在这之前,我们已经对C语言这门课程学习了一个学期,对其有了一定的了解和掌握,这对我们计算机图形的学习打下了良好的基础。但是,万事开头难,在计算机图形学的上机实践的过程中还是遇到了一些问题。
上机实验是学习计算机图形学必不可少的实践环节,上课学习到的知识都需要通过C语言编程做出程序来真正掌握它。对于计算机图形学的学习目的,可以概括为图形的表示、图形的生成、图形的处理和显示,这些都必须通过充分的实际上机操作才能完成。我们上机实验总共包括七个, 每个实验之前老师都会给我们做详细的介绍,具体的操作步骤老师也给了一个参考书,这样的话,我们在上机过程中也省去了很多麻烦,节约了很多时间。因此,我们才有了充裕的时间来理解实验原理,并结合自己的想象力,编写出属于自己的程序。
学习计算机图形学除了课堂讲授以外,必须保证有不少于课堂讲授学时的上机时间。因为学时所限,课程安排在周四晚上统一上机实验,所以我们需要有效地利用上机实验的机会,尽快掌握理解计算机图形学的基础知识,为今后的继续学习打下一个良好的基础。课程上机实验的目的,不仅仅是验证教材和讲课的内
容、检查自己所编的程序是否正确,课程安排的上机实验的目的可以概括为如下几个方面:
加深对课堂讲授内容的理解
课堂上要讲授许多关于计算机图形学的知识和原理,听起来十分枯燥无味,也不容易记住,死记硬背是不可取的。然而要使用C程序这个工具解决实际学习中的问题,通过多次上机练习,,在理解的基础上就会自然而然地掌握计算机图形学图形生成的算法和处理方式。对于一些内容自己认为在课堂上听懂了,但上机实践中会发现原来理解的偏差,编写出来的程序无法运行,这是由于大部分学生C语言基础只是不够牢固的原因。
学习计算机图形学不能停留在学习它的程序语言,而是利用学到的知识编写C语言程序来验证自己的想法,深入理解图形生成的原理,解决实际问题。即把C语言作为工具,描述解决实际问题的步骤,由计算机帮助我们解题。只有通过上机才能检验自己是否掌握C语言、自己编写的程序是否能够正确运行、对计算机的理解是否到位。
通过上机实验来验证自己编制的程序是否正确,恐怕是大多数同学在完成老师作业时的心态。但是在程序设计领域里这是一定要克服的传统的、错误的想法。因为在这种思想支配下,可能你会想办法去"掩盖"程序中的错误,而不是尽可能多地发现程序中存在的问题。而且计算机图形学上机实验是依附在C语言编程基础之上的,我们对图形生成算法的理解要通过C程序才能体现出来。
通过这次为数不多的几天计算机实践学习,我们巩固了一些关于C语言的知识,理解了我们计算机图形学的理论知识,这对我们将来到社会工作将会有莫大的帮助。同时它让我知道计算机图形的强大和瑰丽之处,虽然我们学的都是基本的生成算法,但是通过老师展示的几个计算机图形学高级程序,我们才了解到计算机图形学可以做出非常华丽的视觉效果,而且只要你努力,任何东西都不会太难。
最后,还是很庆幸能学到计算机图形学这样的一门课程,在学习本课程的同时,已经涉及了很多的学科,让我们更有能力成为全方位、多特色的新世纪人才。编程能力、思维能力都获得了提高,真是一举多得。
KMUST
Teaching Records
昆明理工大学
《上机实验指导书》
课程名称: 计算机图形学 所在系(部): 国资院测绘系 学年学期: 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) (美)安杰尔(Edward Angel)著;李桂琼,张文祥译: OpenGL程序设计指南(第二版),北京:清华大学出版社,2005.
(3) Edward Angel: Interactive Computer Graphics—A Top-Down Approach with
OpenGL, Third Edition, Pearson Education, Inc., 2003.
(4) F.S. Hill, JR:Computer Graphics Using OpenGL Second Edition, Pearson
Education, Inc., 2003.
(5) James D. Foley et al.: Computer Graphics—Principles and Practice, Second
Edition in C, Pearson Education, Inc., 2002.
(6) 朱家义:Visual C++程序设计,机械工业出版社,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):关于OpenGL
OpenGL(“Open Graphics Library”)是图形硬件的软件接口。OpenGL包括大约250个不同的函数,程序员可以使用这些函数设定要绘制的物体和操作,来制作交互的三维应用程序。
OpenGL 是专业图形处理,科学计算等高端应用领域的标准图形库。它的主要竞争对手是微软的Direct3D。OpenGL曾长期处于技术上的领先地位,但近年来 Direct3D也迎头赶上。目前这两种图形API在性能上可说是旗鼓相当。不过OpenGL支持众多的操作系统,而Direct3D只在Windows 平台上可用。因此OpenGL仍然广受瞩目。
你可以在OpenGL的官方网站http://www.OpenGL.org的Documentation中下载到官方教程和例子程序:The OpenGL Programming Guide,这就是著名的red book(“红皮书”)。 如果你英语不好,那么推荐你阅读: 《OpenGL超级宝典》是一本相当不错的中文教程。可以在/forumdisplay.php?fid=29找到它的例子代码
《OpenGL编程权威指南》是red book的中文译本,它的例子也就是red book的例子。
附注(2):怎样安装GLUT库?
OpenGL的例子大都需要用到OpenGL应用工具包:GLUT库,下面讲讲怎样安装它:
Windows下VC++ 6.0下的安装:
1. 下载GLUT库:/resources/libraries/glut/glutdlls37beta.zip
2. 将压缩包内的
glut.h放到 C:\Program Files\Microsoft Visual Studio\VC98\Include\GL目录下
glut32.lib放到 C:\Program Files\Microsoft Visual Studio\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++Source File。在右边健入要建立的文件名(如ex1),
并选择存储路径 ,(如D:\ ),完成后按确定,进入源代码编辑窗口。注意,为了使生成的文件不会搞乱,最好事先在D盘下创建一个文件夹(如D:\EX1),保存exl文件。
3)在源代码窗口内写入程序源代码。
4)完成后按Ctrl+F7(Link),这时VC++会提示你是否创建工程,请选择是(yes),则自
动建立工程文件ex1
5)在编译连接之前,先进入主菜单的“工程(Project)”菜单,选中Settings,设置工程
的编译和和连结选项。
6)在Project Setting 对话框中,选“连结(Link)”卡,在改选项卡中的“Objiect\library
modules”一栏中加入opengl32.lib、glu32.lib、glut32.lib这三个OpenGL的连接库。单击OK按钮,此工程文件就可以在OpenGL要求的环境中进行编译了。
7)在Build菜单中选中Compile或Build进行编译连接。
8)选中Build菜单中的Execute执行。
5、参考代码
#include<windows.h>
#include<gl/glut.h>
/*背景颜色设置函数*/
void ini()
{
glClearColor(1.0,1.0,1.0,1.0); //设置背景颜色为白色
}
/*绘制茶壶的线框图函数*/
void RenderScene(void)
{
}
void main(int argc, char**argv)
{
glutInit(&argc,argv); //初始化GLUT库 glClear(GL_COLOR_BUFFER_BIT); //用设定的颜色来刷新指定的缓冲区 glColor4f(0.0,0.0,1.0,1.0); //设置作图颜色为蓝色 glutWireTeapot(0.5); //绘制一个茶壶的线框图 glFlush(); //刷新OpenGL中的命令队列和缓冲区,使所有未被执行的OpenGL命令得到执行
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); //设置窗口显示为单缓冲RGB颜色模式
glutInitWindowSize(600,600); //设置窗口大小为600*600
glutInitWindowPosition(100,100); //设置窗口左上角坐标为(100,100)
glutCreateWindow("Teapot"); //窗口名称为Teapot
ini(); //调用函数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>
void myinit(void)
{
}
void DrawPolygon()
{
}
void display(void)
{
GLubyte fly[]={ 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, 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(); /*设置背景颜色*/ glClearColor(1.0,1.0,1.0,0.0);
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逆时针反面
}
void myreshape(int w,int h)
{ glEnable(GL_POLYGON_STIPPLE); //激活GL_POLYGON_STIPPLE glPolygonStipple(fly); glTranslatef(90.0,80.0,0.0); DrawPolygon(); glFlush();
}
glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);
int main(int argc,char**argv)
{
}
glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(300,300); glutInitWindowPosition(150,150); glutCreateWindow("Polygon"); myinit(); glutDisplayFunc(display); glutReshapeFunc(myreshape); glutMainLoop(); return 0;
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>
void myinit(void)
{
glClearColor(1.0,1.0,1.0,0.0); //设置背景颜色为白色
}
/*绘制三角形*/
void DrawTriangle()
{
glBegin(GL_TRIANGLES);
glVertex2f(20.0,20.0);
glVertex2f(80.0,30.0);
glVertex2f(50.0,70.0);
glEnd();
}
void display(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();
}
void myreshape(int w,int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}
int main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(200,200);
glutInitWindowPosition(200,200);
glutCreateWindow("Transform");
myinit();
glutDisplayFunc(display);
glutReshapeFunc(myreshape);
glutMainLoop();
return 0;
}
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()的功能为:激活深度比较功能,指定刷新缓冲区的颜色
void myinit()
{
glEnable(GL_DEPTH_TEST); /*激活OpenGL的GL_DEPTH_TEST功能,进行深度比较
操作并更新深度缓冲区*/
glClearColor(0.0f,0.0f,0.0f,1.0f); /*指定当用glClear()清除颜色缓冲区时
用的R、G、B、alpha值*/
}
//绘图函数
void drawSphere(GLenum mode) /*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();
//将第四个球体命名为4
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();
}
//定义鼠标响应函数
#define BUFFER_LENGTH 64 /*定义宏BUFFER_LENGTH的值为64*/
void MouseCallback(int button, int state, int x, int y)
/* 鼠标响应函数名称为MouseCallback(),该函数须包含三个参数:button--取值为GLUT_LEFT_BUTTON或GLUT_RIGHT_BUTTON;stata--取值为GLUT_DOWN或GLUT_UP;x,y--鼠标当前位置的坐标值。*/ {
GLuint selectBuff[BUFFER_LENGTH]; /*定义一个数组selectBuff[],类型为无符号整型,
长度为BUFFER_LENGTH*/
GLint hits, viewport[4]; /*定义一个整型变量hits 记录选中的图形数,整型数组
viewport[]长度为4。*/
if(button!=GLUT_LEFT_BUTTON && state!=GLUT_DOWN)return; /*如果没有按下左键
则return,否则执行下句*/
//建立选择数组
glSelectBuffer(BUFFER_LENGTH, selectBuff);/*为选择模式产生的值建立一个缓冲
区。说明:函数glSelectBuffer(GLsizei size,GLfloat*buffer)的功能--为选择模式建立一个缓冲区,存储返回选择数据。缓冲区的大小为size,buffer是一个指向无符号整型数组的指针。selectBuff为指向数组selectBuffer[]的首地址的指针。*/
//获得当前观察边界坐标
glGetIntegerv(GL_VIEWPORT, viewport); /*说明:函数GetIntegerv(GLenum
pname,Glint *params)当pname取GL_VIEWPORT时,参数params返回4个值,这些值分
别代表视口的x和y窗口坐标及它的宽度和高度。*/
glMatrixMode(GL_PROJECTION); /*指定后续矩阵操作的对象是投影矩阵堆栈。*/
glPushMatrix(); /*把当前的矩阵栈压下一层,把当前的矩阵复制后放入当前层.*/ //进入选择模式
glRenderMode(GL_SELECT); /*函数glRenderMode(GLenum mode)用于设置光栅化的模式。
参数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(GLdouble x, 指定窗口坐标中的一个局部观察区域中点的x坐标
GLdouble y, 指定窗口坐标中的一个局部观察区域中点的y坐标 GLdouble delX, 指定窗口坐标中的一个局部观察区域的宽度 GLdouble delY, 指定窗口坐标中的一个局部观察区域的高度 GLint *viewport 指定当前视口(从调用函数glGetIntegerv()时起) ); */
/*建立一个投影矩阵,该矩阵可以用来限制在视口中的一个较小的范围内进行的绘图操作,
可以有效地确定光标附近的那些对象将被绘出。用例程gluPickMatrix()来约束光标附近的一个小范围中的绘之操作。*/
gluPerspective(45.0f,1.0f,100.0,425.0); /* 函数gluPerspective(GLdouble fovy, 指定y方向的取景区域的角度 GLdouble aspect, 指定x方向的用来取景区域的高宽比。高宽比 是x(宽度)与y(高度)的比率。 GLdouble zNear, 指定视点到最近的剪切平面的距离。(正数) GLdouble zFar 指定视点到最近的剪切平面的距离。(负数) ); */ /* 例程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()在屏幕上绘图的函数
void display(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()将清空
这些缓冲区,使所有已发布的命令尽可能快地执行。*/
}
void myReshape(int w, int h)
{
if(h==0)h=1;
glViewport(0,0,w,h); /*设置视口。glViewport(Glint x, 视口像素矩形左下角的x坐标 Glint y, 视口像素矩形左下角的x坐标
GLsizei width, 视口宽度 GLsizei height 视口高度 ); */
/*当一个GL环境被第一次连接到一个窗口时,参数width和height按此窗口的大小设置。*/
glMatrixMode(GL_PROJECTION); /*指定后续矩阵操作的对象是投影矩阵堆栈。*/ glLoadIdentity(); /*用单位矩阵替换当前的矩阵*/
gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,1.0,50.0); /*建立一个透视投影矩阵。 说明:gluPerspective(GLdouble fovy, 指定y方向的取景区域的角度()
GLdouble aspect, 指定x方向的用来取景区域的高宽比。
高宽比是x(宽度)与y(高度)的比率。
此处视口宽高比等于窗口的宽高比w/h。
GLdouble zNear, 指定视点到最近的剪切平面的距离。(正数) GLdouble zFar 指定视点到最近的剪切平面的距离。(负数) ); */ glMatrixMode(GL_MODELVIEW); /*指定后续矩阵操作的对象是模型视图矩阵堆栈。*/
glLoadIdentity(); /*用单位矩阵替换当前的矩阵,用该单位矩阵承载将要进行的图形变
换。*/
}
int main(int argc, 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处理循环。时间循环包括鼠标、键盘、绘制及窗口的事件。
*/
return 0;
}
在该程序中,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-20 OpenGL中的选择示例
第二部分参考代码:用鼠标选择的程序Pick
#include <stdlib.h> //预处理语句,包含C标准库函数头文件 #include <stdio.h> //包含C标准输入输出头文件
#include <GL/glut.h> //包含OpenGL GL/GLUT库头文件
void init()
{
glClearColor (0.0, 0.0, 0.0, 0.0); //指定刷新缓冲区颜色
}
//绘图函数:
void drawObjects(GLenum mode)
{
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);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
drawObjects(GL_RENDER);
glFlush();
}
/* processHits prints out the contents of the
* selection array
*/
void processHits (GLint hits, GLuint buffer[])
{
unsigned int i, j;
GLuint names, *ptr;
printf ("hits = %d\n", hits);
ptr = (GLuint *) buffer;
for (i = 0; i < hits; i++)
{ /* for each hit */
names = *ptr;
ptr+=3;
for (j = 0; j < names; j++)
{ /* for each name */
if(*ptr==1) printf ("red rectangle\n");
else printf ("blue rectangle\n");
ptr++;
}
printf ("\n");
}
}
//定义鼠标响应函数
#define SIZE 512
void mouse(int button, int state, int x, int y)
{
GLuint selectBuf[SIZE]; //定义一个数组selectBuff[],类型为无符号整型,长度为BUFFER_LENGTH GLint hits; //定义一个整型变量hits 记录选中的图形数,整型数组viewport[]长度为4。 GLint viewport[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 ();
/* create 5x5 pixel picking region near cursor location */
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();
}
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D (-2.0, 2.0, -2.0, 2.0); glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key,
int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
}
}
/* main loop */ int main(int argc, 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();
return 0;
}
第三部分参考代码:参照第二部分pick.cpp代码,修改第一部分的Select.cpp代码,输出hits的值,并打印所选球体的颜色。
#include <windows.h> //包含 widows API 函数的头文件
#include <stdlib.h> //包含 C语言 标准函数库 stdlib的头文件
#include <stdio.h> //包含 C语言 标准输入输出函数库 stdio的头文件
#include <GL/glut.h> //包含 OpenGL图形函数库GL及实用库函数库glut的头文件
void myinit()
{
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f,0.0f,0.0f,1.0f);
}
//绘图函数
void drawSphere(GLenum mode)
{
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(); */
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); drawSphere(GL_RENDER);
glFlush();
}
void processHits(GLuint hits, GLuint buffer[])
{
unsigned int i, j; /*定义无符号整形变量i,j*/
GLuint names, *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 */ { /* for each hit */ /*每次点击*/ names = *ptr; /*令变量name的值等于指针*ptr指向地址的值*/ ptr+=3; /*ptr=ptr+3, ptr每次增加3个字节 */ for (j = 0; j < names; j++) /*j=0每次增加1循环到name */ { /* for each name */ /*每个name */
}
if(*ptr==1) printf ("red rectangle\n"); /*如果*ptr=1, 打打印red rectangle 并 换行*/ else printf ("pink rectangle\n"); /*否则打印blue rectangle,换行。*/ ptr++; /* ptr增加1 */ } printf ("\n"); /*换行*/ }
//定义鼠标响应函数
#define BUFFER_LENGTH 64
void MouseCallback(int button, int state, int x, int y) {
GLuint selectBuff[BUFFER_LENGTH]; /*定义一个数组selectBuff[],类型为无符号整型, 长度为BUFFER_LENGTH*/ GLint hits,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);
}
void myReshape(int w, int h)
{
if(h==0)h=1;
glViewport(0,0,w,h); /*设置视口。 glViewport(Glint x, 视口像素矩形左下角的x坐标 Glint y, 视口像素矩形左下角的x坐标 GLsizei width, 视口宽度 GLsizei height 视口高度 ); */
/*当一个GL环境被第一次连接到一个窗口时,参数width和height按此窗口的大小设置。*/
glMatrixMode(GL_PROJECTION); /*指定后续矩阵操作的对象是投影矩阵堆栈。*/
glLoadIdentity(); /*用单位矩阵替换当前的矩阵*/
gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,1.0,50.0); /*建立一个透视投影矩阵。 说明:gluPerspective(GLdouble fovy, 指定y方向的取景区域的角度()
GLdouble aspect, 指定x方向的用来取景区域的高宽比。 高宽比是x(宽度)与y(高度)的比率。 此处视口宽高比等于窗口的宽高比w/h。 GLdouble zNear, 指定视点到最近的剪切平面的距离。(正数) GLdouble zFar 指定视点到最近的剪切平面的距离。(负数) ); */ glMatrixMode(GL_MODELVIEW); /*指定后续矩阵操作的对象是模型视图矩阵堆栈。*/ glLoadIdentity(); /*用单位矩阵替换当前的矩阵,用该单位矩阵承载将要进行的图形变换。*/ }
int main(int argc, 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处理循环。时间循环包括鼠标、键盘、绘制及窗口的事件。*/ return 0;
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>
void myinit(void)
{
}
void display(void)
{
/*第二个八面体*/
/*第四个八面体*/ glPopMatrix(); /*旋转变换*/ glRotatef(15.0,0.0,1.0,0.0); //绕Y周旋转15.0度 /*平移变换*/ glTranslatef(2.3,2.3,0.0); /*第三个八面体*/ glPopMatrix(); //当前操作矩阵出栈,它下面的矩阵作为当前矩阵 glPushMatrix(); /*平移变换*/ glTranslatef(-0.0,2.3,0.0); /*比例变换*/ glScalef(0.8,0.5,1.2); glColor3f(0.0,1.0,0.0); glutWireOctahedron(); glPushMatrix(); //把当前操作矩阵压入矩阵栈堆 /*平移变换*/ glTranslatef(2.0,1.0,0.0); glColor3f(1.0,0.0,0.0); glutWireOctahedron(); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); //指定当前的矩阵操作类型为模型视图矩阵 glLoadIdentity(); /*第一个八面体*/ glTranslatef(-1.0,-1.0,-5.0); // glColor3f(0.0,0.0,0.0); glutWireOctahedron(); glClearColor(1.0,1.0,1.0,0.0);
}
glColor3f(0.0,0.0,1.0); glutWireOctahedron(); glFlush();
void myreshape(int w, int h) {
}
int main(int argc, char**argv) {
} glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(250,250); glutInitWindowPosition(200,200); glutCreateWindow("3DTransform"); myinit(); glutDisplayFunc(display); glutReshapeFunc(myreshape); glutMainLoop(); return 0; 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();
运行结果:
2)透视投影程序
/*本程序对一个八面体进行模型变换*/ #include<windows.h>
#include<GL/glut.h>
void myinit(void)
{
}
void display(void)
{
/*第二个八面体*/
/*第三个八面体*/ glPushMatrix(); //把当前操作矩阵压入矩阵栈堆 /*平移变换*/ glTranslatef(2.0,1.0,0.0); glColor3f(1.0,0.0,0.0); glutWireOctahedron(); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); //指定当前的矩阵操作类型为模型视图矩阵 glLoadIdentity(); /*第一个八面体*/ glTranslatef(-1.0,-1.0,-5.0); // glColor3f(0.0,0.0,0.0); glutWireOctahedron(); glClearColor(1.0,1.0,1.0,0.0);
}
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();
void myreshape(int w, int h) {
}
int main(int argc, char**argv) {
glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(250,250); glutInitWindowPosition(200,200); glutCreateWindow("3DTransform"); myinit(); glutDisplayFunc(display); glutReshapeFunc(myreshape); glutMainLoop(); 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();
} return 0;
运行结果:
3)图形裁剪程序
/*有两个附加裁剪平面的茶壶绘制程序*/
#include<windows.h>
#include<GL/glut.h>
void myinit(void)
{
glClearColor(1.0,1.0,1.0,0.0); glShadeModel(GL_FLAT);
}
void display(void)
{
/*设置平面方程*/
GLdouble eqn1[4]={0.0,1.0,0.0,0.0}; //Ax+By+Cz+D=0,y=0,z-x 平面 下面 GLdouble eqn2[4]={1.0,0.0,0.0,0.0}; //Ax+By+Cz+D=0,x=0,y-z 平面 左面
glClear(GL_COLOR_BUFFER_BIT); /*设置线段的颜色为蓝色*/ glColor3f(0.0,0.0,1.0); // RGB RED=0.0 GREEN=0.0 BLUE=1.0 /*裁剪下半部分*/ glClipPlane(GL_CLIP_PLANE0, eqn1); glEnable(GL_CLIP_PLANE0); /*裁剪左半部分*/ glClipPlane(GL_CLIP_PLANE1, eqn2); glEnable(GL_CLIP_PLANE1); glutWireTeapot(0.6);
glFlush();
}
int main(int argc, char**argv)
{
glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(200,200); glutInitWindowPosition(150,150); glutCreateWindow("ClipTeapot"); myinit(); glutDisplayFunc(display); glutMainLoop(); return 0;
}
运行结果:
2.7 上机7:OpenGL三维物体表示编程练习(2学时)
1.目的要求:
1)熟悉OpenGL中标准二次曲面的绘制方法;
2)熟悉OpenGL中一维、二维求值器函数绘制曲线曲面的方法。
2.实验内容:
a)在VC++6.0环境中编写一程序,绘制一个用经线和纬线绘制的旋转椭球体代表地球。
椭球的长轴、短轴的长度、经线之间的间隔和纬线之间的间隔请同学们自己设计。 b)在VC++6.0环境中编写一程序,用OpenGL中的一维求值器函数绘制一条有五个控制
点的贝塞尔曲线(控制点坐标请同学参考书中例题自己决定)。
c)在VC++6.0环境中,利用OpenGL的二维求值器函数glMap2f(),编程绘制一个Bezeir
曲面(参考p178-180)。
d)在VC++6.0环境中,利用OpenGL的gluNurbsSurface()函数来绘制一个带光照效果
的NURBS曲面(参考p189-191)。
3.主要仪器设备及软件
PC计算机, VC++6.0,GLUT库
2.8 上机8:真实感图形的生成与处理练习
1.目的要求:
1)熟悉OpenGL中有关光照模型、光源设置、材质定义的方法。
2.实验内容:
a)在VC++6.0环境中利用OpenGL编程,绘制一个多面体和一个光源。当点击鼠标时,
光源围绕着多面体的中心旋转一定的角度,并获得在该移动光源照射下多面体的光照效果。(参考p280-281)。
b)在VC++6.0环境中,利用OpenGL编程,绘制在相同的光照条件下,八种不同材质属
性的球体(参考p284-285)。
3.主要仪器设备及软件
PC计算机, VC++6.0,GLUT库。
(完)
计算机图形学感想小学期的导论课里老师们从偏微分方程代数学组合概率论非线性方程组解法计算数学简介几何学最优化运筹学和计算机图形学八个…
计算机图形学学习心得体会计算机科学与技术与技术班学号1计算机图形学计算机图形学ComputerGraphics简称CG狭义上是一种…
让设计成为现实我对计算机图形学的认识10049410级景观一班苏莞琴计算机图形学包含的主要内容计算机图形学ComputerGrap…
第一章绪论计算机图形学的基本概念计算机图形学是研究怎样用数字计算机生成处理和显示图形的一门学科图形计算机图形学的研究对象构成图形的…
对计算机图形学课程学习的心得体会通过一个学期的学习,了解了什么是计算机图形学、什么是图形API、为什么需要计算机图形学以及计算机图…
计算机图形学心得体会姓名:学号:20xx03284班级:计科11202序号:31院系:计算机科学学院通过一个学期的学习,经过老师细…
对计算机图形学课程学习的心得体会通过一个学期的学习,了解了什么是计算机图形学、什么是图形API、为什么需要计算机图形学以及计算机图…
计算机图形学学习心得体会计算机科学与技术与技术班学号1计算机图形学计算机图形学ComputerGraphics简称CG狭义上是一种…
计算题图形学课程学习体会计算机图形学是研究用计算机生成处理和显示图形的一门学科他的重要性体现在人们越来越强烈的需要和谐的人机交互环…
让设计成为现实我对计算机图形学的认识10049410级景观一班苏莞琴计算机图形学包含的主要内容计算机图形学ComputerGrap…
计算机图形学总结首先,感谢老师一个学期以来的教导,您的授课真的让我受益匪浅。您不仅教会了我们很多新颖的知识,还让我们对一些事情有了…