计算机图形学上机实验指导
- 格式:doc
- 大小:284.50 KB
- 文档页数:30
实验指导书刘文涛2013目录第一章图形学实验环境和要求 (4)1.1 VC++实验环境 (4)1.1.1 基本环境 (4)1.1.1 开发图形程序的一般流程 (7)1.1.3 基本绘图函数介绍 (11)1.2 OpenGL (22)1.2.1 OpenGL介绍 (22)1.2.2 OpenGL开发环境 (24)1.2.3 OpenGL函数 (24)1.2.4 回调函数 (25)1.2.4 一个典型OpenGL例程 (26)1.3 实验要求 (29)1.3.1 实验内容 (29)1.3.2 实验方法 (29)1.3.3 实验效果 (30)第二章直线生成算法 (30)2.1 实验原理 (30)2.1.1 DDA算法 (30)2.1.2 Bresenham算法 (30)2.2 实验内容 (30)2.3 参考示例程序 (30)第三章圆和椭圆生成算法 (32)3.1 实验原理 (32)3.2 实验内容 (32)3.3 参考示例程序1 (32)3.4 参考示例程序2 (33)第四章裁剪算法 (35)4.1 实验原理 (35)4.2 实验内容 (35)4.3 示例程序 (35)4.3.1 参考例子1 (35)4.3.2参考例子2 (38)第五章二维变换 (40)5.1 实验原理 (40)5.2 实验内容 (40)5.3 示例程序 (40)5.3.1参考例子1 (40)第六章三维变换 (44)6.1 实验原理: (44)6.2 实验内容 (45)6.3示例程序 (45)第七章填充算法 (47)7.1 实验原理: (47)7.2 实验内容 (47)7.3示例程序 (47)第八章曲线曲面 (50)8.1 实验原理 (50)8.2 实验内容 (50)8.3示例程序 (51)8.3.1 参考例子(1) (51)8.3.2 参考例子(2) (52)8.3.3 参考例子(3) (54)8.3.4 参考例子(4) (56)第九章真实感图形绘制 (59)9.1 实验原理 (59)9.2 实验内容 (59)9.3示例程序 (59)9.3.1参考例子(1) (59)9.3.2参考例子(2) (61)9.3.3参考例子(3) (63)第十章动画 (66)10.1 实验原理 (66)10.2 实验内容 (66)10.3示例程序 (66)10.3.1 参考例子 (66)参考文献: (72)第一章图形学实验基础1.1 VC++实验环境1.1.1 基本环境Microsoft Visual C++ 6.0 是微软推出的功能强大的可视化C/C++语言编译器,运行在Windows 9x/2000/NT等平台上,可以建立32位应用程序。
计算机图形学实验报告姓名:学号:班级:目录实验一OpenGL程序结构练习 (3)实验二基本图形生成 (6)实验三交互式控制 (9)实验四图形基本变换 (12)实验五三维图形生成及显示 (15)实验六三维图形生成及显示 (19)实验一OpenGL程序结构练习【实验目的】1.熟悉C语言环境下OpenGL的使用方法;2.了解OpenGL程序的基本结构。
【实验原理】绝大多数OpenGL程序具有类似的结构,包含下述函数main():定义回调函数,打开一个或多个具有指定属性的窗口,进入事件循环(最后一条可执行语句)init():设置状态变量、视图、属性、回调、显示函数、输入和窗口函数#include <GL/glut.h> // glut.h includes gl.h and glu.hvoid display(){ ……}void init(){ ……}int main( intargc, char **argv){ ……}【实验内容】1.了解程序中各个结构的功能;2.用OpenGL生成三角形。
【实验步骤及结果】1.导入OpenGL的glut32.lib和glut.h文件:将.lib文件存放到C 语言程序文件夹的Library下,.h文件放到Include下;导入应用程序扩展文件glut32.dll,存放到system文件夹下。
2.打开VC 6.0,新建工程,并命名为text1,如图1.图 13.在工程text1下新建源文件,并命名为text1.cpp。
4.编写代码并编译链接,如图2所示。
图 25.运行,结果如图3所示。
图 3实验二基本图形生成【实验目的】1.熟悉OpenGL的程序结构,并了解各部分的功能。
2.学会应用OpenGL语言绘制出点,线,多边形。
【实验原理】1.GLUT函数glutInit使得应用程序可以获取命令行参数并初始化系统。
glutInitDisplayMode设置窗口的属性、RGB颜色、单缓冲区、属性按照逻辑或组合在一起。
计算机图形学上机实验报告实验名称:用DDA算法生成直线姓名:***班级:信息与计算科学学号:**********一:DDA 算法的思想精髓实现直线段光栅化的最简单的方法就是解直线的微分方程。
设直线的起点坐标为 (x s , y s ),终点坐标为 (x e , y e ),那么该直线的微分方程是:()m x x y y dx dy se s e =--=其离散解为:x x x y y y y y y s e s e i i i ∆--+=∆+=+1或: y y y x x x x x x s e s e i i i ∆--+=∆+=+1这里 (x i , y i ) 是直线上一点的坐标值。
式(3.2.1)和(3.2.2)表示所求直线 y 值和 x 值关于相应增量的逐次递归关系,递归初值为直线的起点。
DDA (Digital Differential Analyzer) 算法即数字微分分析算法就是基于式(3.2.1)或(3.2.2)对直线进行光栅化的算法。
在一个坐标轴上以单位间隔对直线采样,以决定另一个坐标轴上最靠近直线的对应整数值。
(1)当直线斜率 0 ≤ m ≤ 1 时,则按单位 x 间隔(D x = 1)取样并计算每个连续的 y 值:m y y i i +=+1(2)当 -1≤ m ≤ 0 时,则仍按单位 x 间隔(D x =-1)取样并计算每个连续的 y 值:m y y i i -=+1(3)当 m >1 时,则将 x 和 y 交换,这就是说,按单位 y 间隔(D y = 1) 取样并计算每个连续的 x 值:11-++=m x x i i(4)当 m <- 1 时,则同样交换 x 和 y 交换,并按 D y =- 1间隔取样计算每个连续的 x 值:11-+-=m x x i i应用上面的算式,解可以设计斜率为任意值的直线。
二:程序代码:#include<stdio.h>#include<graphics.h>#include<math.h>void lineDDA(int xs,int ys,int xe,int ye,int c){int i;float x=xs,y=ys;float xIncrement ,yIncrement,steps,dx=xe-xs,dy=ye-ys; steps=abs(dx);if(abs(dy)>abs(dx))steps=abs(dy);xIncrement=dx/steps;yIncrement=dy/steps;putpixel(x,y,c);for(i=1;i<=steps;i++){x+=xIncrement;y+=yIncrement;putpixel(x,y,c);}}main(){int gdriver=DETECT;int gmode;initgraph(&gdriver,&gmode,""); setbkcolor(MAGENTA); lineDDA(10,14,20,50,1); getch();closegraph();}三:程序截图如下:四:试验心得体会:(1)DDA算法生成直线是非常快的,但是有一点需要注意的,就是x,y的数值类型。
KMUSTTeaching 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 withOpenGL, Third Edition, Pearson Education, Inc., 2003.(4) F.S. Hill, JR:Computer Graphics Using OpenGL Second Edition, PearsonEducation, Inc., 2003.(5) James D. Foley et al.: Computer Graphics—Principles and Practice, SecondEdition in C, Pearson Education, Inc., 2002.(6) 朱家义:Visual C++程序设计,机械工业出版社,2003。
《计算机图形学》课程实验指导一.实验总体方案1.教学目标与基本要求(1)掌握教材所介绍的图形算法的原理;(2)掌握通过具体的平台实现图形算法的方法,培养相应能力;(3)通过实验培养具有开发一个基本图形软件包的能力。
2. 实验平台与考核实验主要结合OpenGL设计程序实现各种课堂教学中讲过的图形算法为主。
程序设计语言主要以C/C++语言为主,开发平台为Visual C++。
每次实验前完成实验报告的实验目的、实验内容、实验原理、实验代码四部分并接受抽查,实验完成后完成实验结果、实验体会两部分,本次实验课结束前提交。
3. 实验步骤(1) 预习教材与实验指导相关的算法理论及原理;(2) 仿照教材与实验指导提供的算法,利用VC+OpenGL进行实现;(3) 调试、编译、运行程序,运行通过后,可考虑对程序进行修改或改进。
二. 实验具体方案实验预备知识OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。
1)与C语言紧密结合:OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的。
如果你曾经接触过TC的graphics.h,你会发现,使用OpenGL 作图甚至比TC更加简单;2)强大的可移植性:微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统。
而OpenGL 不仅用于 Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。
并且,OpenGL 的基本命令都做到了硬件无关,甚至是平台无关;3) 高性能的图形渲染:OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。
总之,OpenGL是一个非常优秀的图形软件接口。
OpenGL官方网站(英文)下面将对Windows下的OpenGL编程进行简单介绍。
计算机图形学实验指导书袁科计算机技术实验中心目录实验一实现DDA、中点画线算法和Bresenham画线算法 (24)实验二实现Bezier曲线 (25)实验三实现B样条曲线 (26)实验四实现多边形填充的边界标志算法 (27)实验五实现裁剪多边形的Cohen-Sutherland算法 (28)实验六二维图形的基本几何变换 (30)实验七画图软件的编制 (31)实验一实现DDA、中点画线算法和Bresenham画线算法【实验目的】1、掌握直线的多种生成算法;2、掌握二维图形显示原理。
【实验环境】VC++6.0/ BC【实验性质及学时】验证性实验,2学时,必做实验【实验内容】利用任意的一个实验环境,编制源程序,分别实现直线的三种生成算法,即数字微分法(DDA)、中点画线法以及Bresenham画线算法。
【实验原理】1、数字微分法(Digital Differential Analyzer,DDA)算法思想:基于直线的微分方程来生成直线。
ε=1/max(|△x|,|△y|)max(|△x|,|△y|)=|△x|,即|k|≤1 的情况:max(|△x|,|△y|)=|△y|,此时|k|≥1:2、中点画线法算法思想:每次在最大位移方向上走一步,另一方向是否走步取决于误差项的判断。
3、Bresenham画线算法算法思想:其基本思想同中点算法一样,即每次在最大位移方向上走一步,而另一个方向是否走步取决于误差项的判断。
【实验要求】1.上交源程序;2.上交实验报告,实验报告内容如下:(1) 实验名称(2) 实验目的(3) 算法实现的设计方法及程序流程图(4) 程序结果分析【分析与思考】(1) 上述所阐述的三个算法,其基本算法只能适用于直线的斜率(|K|<=1) 的情形,如何将上述算法进行推广,使其能够处理任意斜率的直线?(2) 计算机显示屏幕的坐标圆心在哪里,与我们平时的习惯有什么差异,如何协调二者?实验二 实现Bezier 曲线【实验目的】1、掌握Bezier 曲线的定义;2、能编程实现N 次Bezier 曲线的绘制与显示。
《计算机图形学》上机实验报告一、实验设计在曲线上按参数t进行for循环200次,每次将ti=i/200代入参数方程计算出一个点。
将这些点连成折线段即可。
glBegin(GL_LINE_STRIP);for(… )glVertex(xi,yi);glEnd();二、关键代码// test4.cpp : 此文件包含 "main" 函数。
程序执行将在此处开始并结束。
//#include"pch.h"#include<cstdio>#include<cmath>#include<GL/glut.h>const GLfloat Pi = 3.1415926536f;//定义点集struct data {GLfloat x;GLfloat y;}Point[201];void init() //初始化函数{glClearColor(1.0, 1.0, 1.0, 0.0); //设置背景颜色glMatrixMode(GL_PROJECTION); // 设置投影参数gluOrtho2D(0.0, 600.0, 0.0, 400.0); // 设置场景的大小}void mydisplay() //显示函数{glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0); //设置线条颜色glPointSize(2); //设置点的大小glTranslatef(100.0f, 0.0f, 0.0f); //平移图形glScalef(0.5f, 0.5f, 0.0f); //缩小图像0.5倍glRotatef(60.0f, 1.0f, 0.0f, 0.0f); //沿x轴旋转60度glBegin(GL_LINE_STRIP);for (int i = 1; i <= 200; i++){GLfloat t = i / 200.0;Point[i].x = 200.0 + 50.0 * (2.0 * cos(2.0 * Pi*t) - cos(4.0 * Pi*t)); //参数曲线Point[i].y = 150.0 + 50.0 * (2.0 * sin(2.0 * Pi*t) - sin(4.0 * Pi*t)); //参数曲线glVertex2i(Point[i].x, Point[i].y); //绘制曲线}glEnd();glFlush();}int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow("绘制曲线及图形变换");init();glutDisplayFunc(&mydisplay);glutMainLoop();return 0;}三、实验结果截图。
计算机图形学实验指导书【】第一章计算机图形学的软件开发环境计算机图形学中的程序都是用C语言编写的,Turbo C和Visual C++常见的两种C语言开发环境,Turbo C是在Dos环境下开发,而Visual C++是在Windows环境下开发。
1.1、在Turbo C环境下开发应用程序一些高级语言都扩充了图形功能,这使得用户可以不需配备专门的图形软件,就能在计算机上进行图形工作。
Turbo C 2.0包含有460多个库函数,其中有 70 多个图形函数,这些函数包括了绘图、处理图象及图素、屏幕及视图区控制、颜色及线型设置、状态查询和出错处理等,这使得 TurboC具有很强的图形功能。
1.图形显示器的工作方式IBM PC 机的显示器可以在两种基本视频方式下工作:一种是文本方式;另一种是图形方式。
( 1 )文本方式在文本方式下,屏幕上可以显示的最小单位是字符,字符在屏幕上以行、列排列,即我们通常见到的情况。
文本方式不同,屏幕上所显示字符的行数和列数也不一样,颜色也会有所区别。
Turbo C 支持 6 种不同的文本显示方式。
( 2 )图形方式在图形方式下,屏幕上可以控制的最小单元称作像素 ( pixel ) ,它是组成图形的基本元素,一般叫作“点”。
通常把屏幕上所包含像素的个数叫做分辨率。
分辨率越高,显示的图形越细致、质量越好,这是显而易见的。
在图形方式下,屏幕上每个像素的显示位置用点坐标系来描述。
在该坐标系中,屏幕左上角为坐标系的原点,坐标值为 ( 0 , 0 ) ; 水平方向为X轴,自左向右;垂直方向为Y轴,自上向下。
见下图。
点坐标系中坐标值的范围决定于所用显示器的分辨率。
分辨率不同,水平方向上和垂直方向上的点数也不同,即其 maxx 、maxy 的数值不同。
就我们常用的 VGA 显示器来说,它通常所用的分辨率为6405480 ,即它的 maxx 值为 639 , maxy 的值为479。
2. 图形函数及其用法Turbo C 的图形函数均在一个头文件“ graphics.h” 中定义。
计算机图形学上机实验报告计算机科学与技术学院班级:学号:姓名:指导教师:完成日期:实验一:基本图元绘制一. 实验目的1. 了解如何利用OpenGL库绘制图形2. 理解glut程序框架3. 理解窗口到视区的变换4. 理解OpenGL实现动画的原理二. 实验内容1. 实现中点Bresenham算法画直线2. 实现改进Bresenham算法画直线3. 实现圆的绘制三. 实验结果1.DDA算法画直线2. 中点Bresenham算法画直线3. 改进Bresenham算法画直线4. Bresenham算法画圆四. 源程序#include <windows.h>#include <gl/glut.h>#include "stdio.h"int m_PointNumber = 0; //动画时绘制点的数目int m_DrawMode = 4; //绘制模式 1 DDA算法画直线// 2 中点Bresenham算法画直线// 3 改进Bresenham算法画直线// 4 八分法绘制圆// 5 四分法绘制椭圆//绘制坐标线void DrawCordinateLine(void){int i = 0 ;//坐标线为黑色glColor3f(0.0f, 0.0f ,0.0f);glBegin(GL_LINES);for (i=10;i<=250;i=i+10){glVertex2f((float)(i), 0.0f);glVertex2f((float)(i), 250.0f);glVertex2f(0.0f, (float)(i));glVertex2f(250.0f, (float)(i));}glEnd();}//绘制一个点,这里用一个正方形表示一个点。
void putpixel(GLsizei x, GLsizei y){glRectf(10*x,10*y,10*x+10,10*y+10);}void DDACreateLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num){//设置颜色glColor3f(1.0f,0.0f,0.0f);//对画线动画进行控制if(num == 1)printf("DDA画线算法:各点坐标\n");else if(num==0)return;//画线算法的实现GLsizei dx,dy,epsl,k;GLfloat x,y,xIncre,yIncre;dx = x1-x0;dy = y1-y0;x = x0;y = y0;if(abs(dx) > abs(dy)) epsl = abs(dx);else epsl = abs(dy);xIncre = (float)dx / epsl ;yIncre = (float)dy / epsl ;for(k = 0; k<=epsl; k++){putpixel((int)(x+0.5), (int)(y+0.5));if (k>=num-1) {printf("x=%f,y=%f,取整后x=%d,y=%d\n", x, y, (int)(x+0.5),(int)(y+0.5));break;}x += xIncre;y += yIncre;if(x >= 25 || y >= 25) break;}}void BresenhamLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num){glColor3f(1.0f,0.0f,0.0f);if(num == 1)printf("中点Bresenham算法画直线:各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei dx,dy,d,UpIncre,DownIncre,x,y,xend=0;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}x=x0;y=y0;dx=x1-x0;dy=y1-y0;d=dx-2*dy;UpIncre=2*dx-2*dy;DownIncre=-2*dy;while (x<=x1){putpixel(x,y);if (x>=num-1) {break;}x++;if(d<0){y++;d+=UpIncre;}else d+=DownIncre;if(x >= 50 || y >= 50) break;}}void Bresenham2Line(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);if(num == 1)printf("改进的Bresenham算法画直线:各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei x,y,dx,dy,e;dx=x1-x0;dy=y1-y0;e=-dx;x=x0;y=y0;while (x<=x1){putpixel(x,y);if (x>=num-1) {break;}x++;e=e+2*dy;if(e>0){y++;e=e-2*dx;}if(x >= 50 || y >= 50) break;}}void BresenhamCircle(GLsizei x, GLsizei y, GLsizei r, GLsizei num){glColor3f(1.0f,0.0f,0.0f);if(num == 1)printf("Bresenham算法画圆:各点坐标及判别式的值\n");x=0,y=r;GLsizei d=1-r;while (x<y){putpixel(x,y);if (x>=num) {break;}putpixel(y,x);if (x>=num) {break;}putpixel(-y,x);if (x>=num) {break;}putpixel(-x,y);if (x>=num) {break;}putpixel(-x,-y);if (x>=num) {break;}putpixel(-y,-x);if (x>=num) {break;}putpixel(y,-x);if (x>=num) {break;}putpixel(x,-y);if(d<0)d+=2*x+3;else{d+=2*(x-y)+5;y--;}x++;}}//初始化窗口void Initial(void){// 设置窗口颜色为蓝色glClearColor(1.0f, 1.0f, 1.0f, 1.0f);}// 窗口大小改变时调用的登记函数void ChangeSize(GLsizei w, GLsizei h){if(h == 0) h = 1;// 设置视区尺寸glViewport(0, 0, w, h);// 重置坐标系统glMatrixMode(GL_PROJECTION);glLoadIdentity();// 建立修剪空间的范围if (w <= h)glOrtho (0.0f, 250.0f, 0.0f, 250.0f*h/w, 1.0, -1.0);elseglOrtho (0.0f, 250.0f*w/h, 0.0f, 250.0f, 1.0, -1.0); }// 在窗口中绘制图形void ReDraw(void){//用当前背景色填充窗口glClear(GL_COLOR_BUFFER_BIT);//画出坐标线DrawCordinateLine();switch(m_DrawMode){case 1:DDACreateLine(0,0,20,15,m_PointNumber);break;case 2:BresenhamLine(0,0,20,15,m_PointNumber);break;case 3:Bresenham2Line(1,1,8,6,m_PointNumber);break;case 4:BresenhamCircle(5,5,18,m_PointNumber);break;default:break;}glFlush();}//设置时间回调函数void TimerFunc(int value){if(m_PointNumber == 0)value = 1;m_PointNumber = value;glutPostRedisplay();glutTimerFunc(500, TimerFunc, value+1);}//设置键盘回调函数void Keyboard(unsigned char key, int x, int y){if (key == '1') m_DrawMode = 1;if (key == '2') m_DrawMode = 2;if (key == '3') m_DrawMode = 3;if (key == '4') m_DrawMode = 4;m_PointNumber = 0;glutPostRedisplay();}//void main(void)int main(int argc, char* argv[]){glutInit(&argc, argv);//初始化GLUT库OpenGL窗口的显示模式glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(800,600);glutInitWindowPosition(100,100);glutCreateWindow("基本图元绘制程序");glutDisplayFunc(ReDraw);glutReshapeFunc(ChangeSize);glutKeyboardFunc(Keyboard);//键盘响应回调函数glutTimerFunc(500, TimerFunc, 1);// 窗口初始化Initial();glutMainLoop(); //启动主GLUT事件处理循环return 0;}实验二:日地月模型一. 实验目的1. 理解OpenGL中的变换过程2. 理解透视投影与平行投影的不同3. 了解深度测试二. 实验内容1. 通过变换调整观察的位置与方向2. 实现太阳、地球和月亮的运动模型三. 实验结果太阳、地球和月亮的运动模型图1.图2.图3.四. 源程序#include <windows.h>#include <gl/gl.h>#include <gl/glu.h>#include <gl/glut.h>void Initial(){glEnable(GL_DEPTH_TEST); // 启用深度测试glFrontFace(GL_CCW); // 指定逆时针绕法表示多边形正面glClearColor(1.0f, 1.0f, 1.0f, 1.0f ); //背景为白色}void ChangeSize(int w, int h){if(h == 0) h = 1;// 设置视区尺寸glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();// 设置修剪空间GLfloat fAspect;fAspect = (float)w/(float)h;gluPerspective(45.0, fAspect, 1.0, 500.0);/*if (w <= h)glOrtho (-nRange, nRange, nRange*h/w, -nRange*h/w, -nRange*2.0f, nRange*2.0f);elseglOrtho (-nRange*w/h, nRange*w/h, nRange, -nRange, -nRange*2.0f, nRange*2.0f); */glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void RenderScene(void){// 绕原子核旋转的角度static float fElect1 = 0.0f;static float f2=0.0f;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 重置模型视图矩阵glMatrixMode(GL_MODELVIEW);glLoadIdentity();//将图形沿z轴负向移动glTranslatef(0.0f, 0.0f, -250.0f);// 绘制红色的原子核glColor3f(1.0f, 0.0f, 0.0f);glutSolidSphere(50.0f, 15, 15);// 当前绘制颜色变为黄色glColor3f(0.0f, 0.0f, 0.0f);//绘制第一个电子//保存当前的模型视图矩阵glRotatef(fElect1, 0.0f, 1.0f, 0.0f);//绕y轴旋转一定的角度glTranslatef(80.0f, 0.0f, 0.0f);//平移一段距离glutSolidSphere(12.0f, 15, 15);//画出电子// 恢复矩阵// 第二个电子glPushMatrix();glRotatef(45.0f, 0.0f, 0.0f, 1.0f);glRotatef(f2, 0.0f, 1.0f, 0.0f);glTranslatef(-20.0f, 0.0f, 0.0f);glutSolidSphere(6.0f, 15, 15);glPopMatrix();/* // 第三个电子glPushMatrix();glRotatef(-45.0f,0.0f, 0.0f, 1.0f);glRotatef(fElect1, 0.0f, 1.0f, 0.0f);glTranslatef(0.0f, 0.0f, 60.0f);glutSolidSphere(6.0f, 15, 15);glPopMatrix();*/// 增加旋转步长fElect1 += 10.0f;f2=fElect1*6;if(fElect1 > 360.0f){fElect1 = 10.0f;}glutSwapBuffers();}void TimerFunc(int value){glutPostRedisplay();glutTimerFunc(100, TimerFunc, 1);}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutCreateWindow("日地月模型");glutReshapeFunc(ChangeSize);glutDisplayFunc(RenderScene);glutTimerFunc(500, TimerFunc, 1);Initial();glutMainLoop();return 0;}。
计算机图形学上机实验报告实验一:kock分形雪花图案的绘制一、实验目的与要求目的:1.通过实验初步了解OPENGL。
2通过上机编程掌握OPENGL的画图机理和OPENGL。
要求:1.了解分形绘图的过程。
二、实验内容以Kock曲线为例,说明分形图形是如何生成的。
Kock曲线的初始生成元是一条直线段,生成规则是将直线段均分为三等分,首尾两端保持不变,中间用两端等长且互成60度角的直线段代替。
迭代公式如下:分别迭代1,3,6次,并记录结果。
三、实验结果实验结果图如下:3-1第一次分形3-2三次分形3-3六次分形四、体会通过这次实验了解到了分形系统的从图元到图形的形成过,分形在图形学的应用中,可以用来表示岩层、云、水、树、等。
并且亲手实现了“雪花”的分形图形。
通过迭代次数可控制图形的不同。
掌握了分形系统的形成过程。
完成了此次试验目的。
五、源程序void drawline(pt pt1, pt pt2)//绘制线{glBegin(GL_LINES);glVertex2d(pt1.x, pt1.y);glVertex2d(pt2.x, pt2.y);glEnd();}void drawkoch(pt pt1, pt pt2, int n)//n为确定的迭代次数{pt p1, p2, p3, p4, p5;glColor3f(0.0, 0.0, 0.0);p1.x = pt1.x;p1.y = pt1.y;p2.x = pt2.x;p2.y = pt2.y;if (n == 1){ drawline(p1, p2); }if (n>1){p3.x = p1.x + (-p1.x + p2.x) / 3;p3.y = p1.y + (-p1.y + p2.y) / 3;p4.x = p1.x + 2 * (-p1.x + p2.x) / 3;p4.y = p1.y + 2 * (-p1.y + p2.y) / 3;p5.x = (p4.x - p3.x) / 2 - (p4.y - p3.y)*sqrt(3.0) / 2 + p3.x;p5.y = (p4.y - p3.y) / 2 + (p4.x - p3.x)*sqrt(3.0) / 2 + p3.y;drawkoch(p1, p3, n - 1);drawkoch(p3, p5, n - 1);drawkoch(p5, p4, n - 1);drawkoch(p4, p2, n - 1);}if (n == 0)exit(0);}void display(void){glClear(GL_COLOR_BUFFER_BIT);pt p1, p2, p3;p1.x = 30;p1.y = 30;p2.x = 110;p2.y = 30;p3.x = 70;p3.y = 30 + 40 * sqrt(3.0);int n;do{//循环改变迭代次数glClear(GL_COLOR_BUFFER_BIT);printf("请输入Koch雪花的迭代次数,或输入0退出:");scanf("%d", &n);drawkoch(p1, p3, n);drawkoch(p3, p2, n);drawkoch(p2, p1, n);glFlush();} while (n != 0);}int main(int argc, char**argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowPosition(50, 100);glutInitWindowSize(500, 400);glutCreateWindow("KOCHCURVE");init();glutDisplayFunc(display);glutMainLoop();return 0;}实验二:星球环绕模型一、实验目的与要求目的:1.通过实验初步了解OpenGL中的深度测试缓存器算法。
计算机图形学上机实验指导指导教师:张加万老师助教:张怡2009-10-10目录1.计算机图形学实验(一) – OPENGL基础 ..................................... - 1 -1.1综述 (1)1.2在VC中新建项目 (1)1.3一个O PEN GL的例子及说明 (1)2.计算机图形学实验(二) – OPENGL变换 ..................................... - 5 -2.1变换 (5)3.计算机图形学实验(三) - 画线、画圆算法的实现....................... - 9 -3.1MFC简介 (9)3.2VC6的界面 (10)3.3示例的说明 (11)4.计算机图形学实验(四)- 高级OPENGL实验...................... - 14 -4.1光照效果 (14)4.2雾化处理 (16)5.计算机图形学实验(五)- 高级OPENGL实验........................ - 20 -5.1纹理映射 (20)5.2反走样 (24)6.计算机图形学实验(六) – OPENGL IN MS-WINDOWS .......... - 27 -6.1 实验目标: (27)6.2分形 (28)1.计算机图形学实验(一) – OpenGL基础1.1综述这次试验的目的主要是使大家初步熟悉OpenGL这一图形系统的用法,编程平台是Visual C++,它对OpenGL提供了完备的支持。
OpenGL提供了一系列的辅助函数,用于简化Windows操作系统的窗口操作,使我们能把注意力集中到图形编程上,这次试验的程序就采用这些辅助函数。
本次实验不涉及面向对象编程,不涉及MFC。
1.2在VC中新建项目1.2.1新建一个项目选择菜单File中的New选项,弹出一个分页的对话框,选中页Projects中的Win32 Console Application项,然后填入你自己的Project name,如Test,回车即可。
VC为你创建一个工作区(WorkSpace),你的项目Test就放在这个工作区里。
1.2.2为项目添加文件为了使用OpenGL,我们需要在项目中加入三个相关的Lib文件:glu32.lib、glaux.lib、opengl32.lib,这三个文件位于c:\program files\microsoft visualstudio\vc98\lib目录中。
选中菜单Project->Add To Project->Files项(或用鼠标右键),把这三个文件加入项目,在FileView中会有显示。
这三个文件请务必加入,否则编译时会出错。
或者将这三个文件名添加到Project->Setting->Link->Object/library Modules 即可。
点击工具条中New Text File按钮,新建一个文本文件,存盘为Test.c作为你的源程序文件,再把它加入到项目中,然后就可以开始编程了。
1.3一个OpenGL的例子及说明1.3.1源程序请将下面的程序写入源文件Test.c,这个程序很简单,只是在屏幕上画两根线。
#include <windows.h>#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h>//初始化OpenGL场景void myinit (void){glClearColor (0.0, 0.0, 0.0, 0.0); //将背景置成黑色glShadeModel (GL_FLAT); //设置明暗处理}//用户的绘图过程void CALLBACK display(void){glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除缓存glBegin(GL_LINES); //开始画一根白线glColor3f (1.0f, 1.0f, 1.0f); //设置颜色为白色//设置第一根线的两个端点,请注意:OpenGL坐标系的原点是在屏幕左下角glVertex2f(10.0f, 50.0f);glVertex2f(110.0f, 50.0f);glColor3f (1.0f, 0.0f, 0.0f); //设置颜色为红色//设置第二根线的两个端点glVertex2f(110.0f, 50.0f);glVertex2f(110.0f, 150.0f);glEnd(); //画线结束glFlush (); //绘图结束}////主过程:// 初始化Windows的窗口界面// 并初始化OpenGL场景,绘图int main(int argc, char** argv){auxInitDisplayMode (AUX_RGB); //初始化显示模式,采用RGB彩色系统。
auxInitPosition (0, 0, 400, 150); //初始化窗口位置、大小auxInitWindow ("Display Lists"); //初始化窗口,设置标题myinit ();auxMainLoop(display); //循环运行display过程,display由用户编写return(0);}1.3.2程序说明每个函数的具体含义在程序注释中已作了叙述,不再多说。
OpenGL的函数在格式上很有特点,它以gl为前缀,并且函数名的最后一个字母指出所用的数据类型,如:glColor3f(),字母f指明要使用浮点数。
字母前的数字指明参数个数或指明二维还是三维,如:glVertex2f()是要设置二维的点。
OpenGL采用的是状态机的方式,用户设定一种状态,程序照此运行。
如:glBegin(GL_LINES)设定画线状态(GL_LINES是OpenGL已定义好的常量),glColor3f()设定绘图所用颜色。
main()函数中的几个aux前缀函数是OpenGL提供的辅助库,用以初始化窗口,大家不必深究,我们关注的是display()函数,它是我们真正绘图的地方。
函数glColor3f()以RGB方式设置颜色,格式为:glColor3f(red,green,blue),每种颜色值在(0.0, 1.0)之间。
为了能显示更多的颜色,最好把系统设置成16位真彩色模式。
函数glVertex2f(x, y)设置二维顶点。
函数glBegin(UINT State)、glEnd()是最基本的作图函数,下面对它作一介绍。
如上所述,OpenGL是一个状态机,glBegin(UINT State)可以设定如下状态:GL_POINTS 画点GL_LINES 画线,每两个顶点(Vertex)为一组GL_LINE_STRIP 画线,把若干个顶点顺次连成折线GL_LINE_LOOP 画线,把若干个顶点顺次连成封闭折线GL_TRIANGLES 画三角形,每三个顶点为一组GL_QUADS 画四边形,每四个顶点为一组GL_POLYGON 画多边形还有GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS_STRIP 等等。
大家可以把每一种状态都试一试。
程序可以有多组glBegin()、glEnd()并列的形式,如:... ...glBeing(GL_LINES);......glEnd();glBeing(GL_QUADS);... ...glEnd();... ...除了上述的基本图元外,函数glRectf(x1, y1, x2, y2)可以画一个矩形,但这个函数不能放在glBegin()和glEnd()之间,下面的两句程序是画一个蓝色的矩形。
glColor3f (0.0f, 0.0f, 1.0f);glRectf(10.0f, 10.0f, 50.0f,50.0f);教材中给出的例子,同学们可以对这些代码也进行测试。
2.计算机图形学实验(二) – OpenGL变换2.1变换下面向大家介绍OpenGL中坐标变换的方法,以下这个例子是模拟机器人的手臂,用上下左右键可以挥动。
#include <windows.h>#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h>void myinit(void);void CALLBACK elbowAdd (void);void CALLBACK elbowSubtract (void);void CALLBACK shoulderAdd (void);void CALLBACK shoulderSubtract (void);void CALLBACK display(void);void CALLBACK myReshape(GLsizei w, GLsizei h);static int shoulder = 0, elbow = 0;//shoulder:肩部角度,elbow:肘部角度//下面四个函数是用户的键盘事件处理程序void CALLBACK elbowAdd (void){ elbow = (elbow + 5) % 360;}void CALLBACK elbowSubtract (void){ elbow = (elbow - 5) % 360;}void CALLBACK shoulderAdd (void){ shoulder = (shoulder + 5) % 360;}void CALLBACK shoulderSubtract (void){ shoulder = (shoulder - 5) % 360;}//用户的绘图过程void CALLBACK display(void){glClear(GL_COLOR_BUFFER_BIT);glColor3f (1.0, 1.0, 1.0);glPushMatrix();//把当前的变换矩阵压入OpenGL内部栈中,用以保存当前矩阵//画机器人的上臂glTranslatef (-1.0, 0.0, 0.0);//用平移矩阵乘当前矩阵,格式为:glTranslatef(x,y,z) glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0);//用旋转矩阵乘当前矩阵,格式//为glRotatef (角度,x轴,y//轴,z轴)//这里是绕Z轴旋转glTranslatef (1.0, 0.0, 0.0); //再用平移矩阵乘当前矩阵,注意顺序auxWireBox(2.0, 0.4, 1.0); //辅助库函数,画一个三维的//Box,格式为: //auxWireBox(width, height, depth)//画机器人的前臂,请注意平移矩阵和旋转矩阵的变化glTranslatef (1.0, 0.0, 0.0);glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0);glTranslatef (1.0, 0.0, 0.0);auxWireBox(2.0, 0.4, 1.0);glPopMatrix(); //恢复刚才的矩阵glFlush(); //结束绘图}void myinit (void){ glShadeModel (GL_FLAT);}//在窗口改变大小时调用void CALLBACK myReshape(GLsizei width, GLsizei height){glViewport(0, 0, width, height); //定义视口glMatrixMode(GL_PROJECTION); //定义投影变换模式glLoadIdentity(); //用单位矩阵替换当前变换矩阵gluPerspective(65.0, (GLfloat) width/(GLfloat) height, 1.0, 20.0);//建立一个透视投影矩阵,并乘当前矩阵,格式为:// gluPerspective(视域的角度,宽高比,//视点到近裁剪面的距离(总为正),//视点到远裁剪面的距离(总为正))glMatrixMode(GL_MODELVIEW); //定义造型变换模式glLoadIdentity(); //用单位矩阵替换当前变换矩阵glTranslatef (0.0, 0.0, -5.0); //用平移矩阵乘当前矩阵}// 主过程:// 初始化Windows的窗口界面// 并初始化OpenGL场景,并处理输入事件,如:键盘,鼠标的操作int main(int argc, char** argv){auxInitDisplayMode (AUX_SINGLE | AUX_RGB);auxInitPosition (0, 0, 400, 400);auxInitWindow ("Composite Modeling Transformations");myinit ();//定义键盘处理程序,格式:auxKeyFunc(按键的虚拟代码,用户的处理函数名)auxKeyFunc (AUX_LEFT, shoulderSubtract);//函数shoulderSubtract()处理左//方向键auxKeyFunc (AUX_RIGHT, shoulderAdd);//函数shoulderAdd()处理右方向键auxKeyFunc (AUX_UP, elbowAdd); //函数elbowAdd()处理上方向键auxKeyFunc (AUX_DOWN, elbowSubtract);//函数elbowSubtract()处理下方向//键auxReshapeFunc (myReshape); //定义窗口大小改变时调用的函数auxMainLoop(display); //循环运行display过程,display由用户编写return(0);}这个例子涉及了三维的造型,出现了许多新函数。