计算机网络试验指导书
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《》
实验报告
专业
年级
姓名
学号
指导老师
实验室
使用日期
苏州大学计算机科学与技术学院统一印制
二零零二年八月
苏州大学计算机科学与技术学院
计算机图形学实验指导书(MFC和OpenGL版)
计算机图形学课题组
目录
实验一OpenGL程序设计
实验二二维基本图元的生成
实验三二维图元的填充
实验四二维图形的几何变换实验五二维裁剪
实验六自由曲线
前言
一、实验目的
1、培养学生动手编程解决实际问题的能力。
2 训练学生分析问题和调试程序的能力。
3 锻炼学生撰写科技实验论文的能力。
二、实验总体要求
1 问题分析
充分地分析和理解问题本身,弄清要求做什么,用什么算法。
2 程序设计
(1) 根据所采用的算法,设计数据结构,画出流程图并编程。
(2) 最后准备调试程序的数据及测试方案。
3 上机调试
(1)对程序进行编译,纠正程序中可能出现的语法错误。
(2) 调试前,先运行一遍程序看看究竟将会发生什么。
(3) 如果情况很糟,根据事先设计的测试方案并结合现场情况进行错误跟踪,包括单步调试、设置观察窗输出中间变量值等手段。
4 整理实习报告
三、实验报告
1 实习内容:采用的算法名称
2 问题描述:包括目标、任务、条件约束描述等。
3 设计:数据结构设计和核心算法设计。
主要功能模块的输入,处理(算法框架)和输出。
4 测试范例:测试结果的分析讨论,测试过程中遇到的主要问题及所采用的解决措施。
5 心得:包括程序的改进设想,经验和体会。
6 程序清单:源程序,其中包括变量说明及详细的注释。
实验1 OpenGL 程序设计
实验目的
巩固计算机图形学和C语言程序设计的相关知识,初步了解通用图形软件包,了解常见的图元的生成方法,学会图形显示设备的初始化及其交互式图形生成的过程,锻炼程序调试的技巧。
实验学时
2学时
实验类型
学习型实验
实验要求
初步了解OpenGL 程序设计结构;了解OpenGL 的基本数据类型、核心函数及辅助函数的使用。
四、实验内容
1、综述
这次试验的目的主要是使大家初步熟悉OpenGL这一图形系统的用法,编程平台是Visual C++,它对OpenGL 提供了完备的支持。
OpenGL 提供了一系列的辅助函数,用于简化Windows 操作系统的窗口操作,使我们能把注意力集中到图形编程上,这次试验的程序就采用这些辅助函数。
2、实验步骤
在VC 中新建项目
新建一个项目。
选择菜单File 中的New 选项,弹出一个分页的对话框,选中页Projects 中的Win32 Console Application 项,然后填入你自己的Project name,如Test,回车即可。
VC 为你创建一个工作区(WorkSpace),你的项目Test 就放在这个工作区里。
为项目添加文件
为了使用OpenGL,我们需要在项目中加入三个相关的Lib 文件:glu32.lib、glaux.lib、opengl32.lib,这三个文件位于c:\program files\Microsoft Visual Studio\vc98\lib 目录中。
选中菜单Project->Add To Project->Files 项(或用鼠标右键),把这三个文件加入项目,在FileView 中会有显示。
这三个文件请务必加入,否则编
译时会出错。
或者将这三个文件名添加到Project->Setting->Link->Object/library Modules 即可。
点击工具条中New Text File 按钮,新建一个文本文件,存盘为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);
}
2).OpenGL基础库设置
•更改头文件(在视图类的头文件中引用gl\gl.h gl\glu.h)
•连接OpenGL库(工程——设置——General/Use MFC in a Library, Link/OpenGL32.lib glu32.lib)
3).添加变量和函数
•添加变量并初始化
•CClientDC * MyDC;
•视图类的构造函数中MyDC=NULL;
•添加消息映射函数
•OnCreate()
•OnSize()
•OnDestroy()
4).在PreCreateWindow函数中将窗口的客户区设置为OpenGL能够支持的风格cs.style=WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS; 5).在OnCreate函数中
•定义像素存储格式
•PIXELFORMATDESCRIPTOR结构
•创建绘图上下文RC(Rendering Context)并使之当前化
•wglCreateContext()函数创建绘图上下文RC。
PIXELFORMATDESCRIPTOR pfd=
{ sizeof(PIXELFORMATDESCRIPTOR), // pfd的大小
1, //结构的版本号
PFD_DRAW_TO_WINDOW| //支持window
PFD_SUPPORT_OPENGL| //支持OpenGL
PFD_DOUBLEBUFFER, //双缓存
PFD_TYPE_RGBA, //RGBA颜色模式
24, //24位颜色深度缓存
0,0,0,0,0,0, //color bits ignored
0, //no alpha buffer
0, //shift bit ignored
0, //不使用累积缓存
0,0,0,0, //accum bits ignored
32, //32位z缓冲
0, //不使用模板缓存
0, //no auxiliary buffer
PFD_MAIN_PLANE, //选择主层面
0, //保留
0,0,0 //layer masks ignored
};
MyDC=new CClientDC(this);
//设置像素格式
int pixelFormat=ChoosePixelFormat(MyDC->GetSafeHdc(),&pfd); SetPixelFormat(MyDC->GetSafeDC(),pixelFormat,&pfd);
m_hRC=wglCreateContext(MyDC->m_hDC);
wglMakeCurrent(MyDC->GetSafeHdc(),m_hRC);
6).在OnSize函数中设置视场和视口
If(cy>0)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0,1.0,-1.0*cy/cx,1.0*cy/cx,5.0,9.0);
glViewport(0,0,cx,cy);
}
7).在OnDestroy函数:在OnDestroy成员中需要释放OnCreate成员中RC所占用的资源
HGLRC m_hRC;
m_hRC=wglGetCurrentContext();
wglMakeCurrent(NULL,NULL);
wglDeleteContext(m_hRC);
MyDC->DeleteDC();
8)在OnEraseBKgnd中将原来的返回语句换成返回TRUE;
9).在OnDraw中根据当前的视点、视距、观看方向等参数,设置合适的OpenGL视景体属性,使用户能够看到预期的场景外观
glClearColor(1.0f,1.0f,0.0f,1.0f);//背景为黄色
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-6.0f);
glBegin(GL_LINES); //OpenGL绘制直线命令
glColor3f(1.0,0.0,0.0); //设置当前颜色为红色
glVertex2f(0,0);
glVertex2f(1,1);
glColor3f(0.0,1.0,0.0); //设置当前颜色为绿色
glVertex2f(0.2f,0.0f);//
glVertex2f(1.2f,1.0f);
glEnd();
glFinish();
SwapBuffers(wglGetCurrentDC());
3、程序说明
每个函数的具体含义在程序注释中已作了叙述,不再多说。
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);
实验1使用通用图形软件包设计简单的交互
式图形
实验目的
巩固计算机图形学和C语言程序设计的相关知识,初步了解通用图形软件包,了解常见的图元的生成方法,学会图形显示设备的初始化及其交互式图形生成的过程,锻炼程序调试的技巧。
实验环境
计算机、Turbo C或其他C语言程序设计环境
实验类型
学习型实验
实验学时
2学时,必做实验。
实验内容
1、计算机中安装和配置Turbo C程序设计环境;
2、了解Turbo C的通用图形软件包的内容;
3、练习简单图元的生成(如直线、圆、长方形等)。
实验步骤
1、装和配置Turbo C程序设计环境;
2、了解Turbo C的通用图形软件包的内容;
3、编写生成简单的图元的程序;
4、调试程序,运行程序并观看运行结果;
5、对运行结果进行分析。
分析与思考
1、为、什么已经调试好的程序在不同的目录下的Turbo C程序设计环境中却不
能运行?
2、如何使所生成的图元在屏幕中央显示?
实验2 二维基本图元的生成
一、实验学时2学时
二、实验类型设计型实验
三、实验目的和要求
1、掌握二维基本图元直线段生成的DDA 算法,中点算法;
2、掌握二维基本图元圆弧生成的中点算法;
3、掌握对线型线宽的属性的控制。
四、实验内容
1、编程实现DDA、中点算法生成直线
2、中点扫描转换生成圆、椭圆
五、实验步骤
1)在VC中新建项目
2)添加菜单及相应的菜单命令函数(画线、画圆)
3)编码实现(参考书中相关代码);
五、建立工程步骤
1.在visual c++.net 中使用opnengl,建立项目的步骤:
2、在visual c++中的建立控制台项目的步骤:
实验三二维图元的填充
一、实验学时2学时
二、实验类型设计型实验
三、实验目的和要求
1、掌握二维图元填充的递归算法;
2、掌握二维图元填充的种子填充算法
四、实验内容
构造任意一个边界表示的多边形,假定该多边形内部是四连通的。
要求:
1、用递归算法实现对多边形内部的填充,要求内部颜色和边界不一致。
(参照教案进行)
2、用种子填充扫描线算法实现多边形内部的填充。
五、建立win32 应用程序工程。
1. 请在实验二中建立的项目基础上,添加填充的菜单项,建立相应的菜单命令寒暑,实现种子填充。
2. void BoundaryFill4(HDC,int,int,COLORREF,COLORREF);
void BoundaryFill4(HDC hdc,int x,int y,COLORREF boundarycolor,COLORREF newcolor)
{
COLORREF color;
color=GetPixel(hdc,x,y);
if((color != boundarycolor) && (color !=newcolor))
{
SetPixel(hdc,x,y,newcolor);
BoundaryFill4(hdc,x,y+1,boundarycolor,newcolor);
BoundaryFill4(hdc,x,y-1,boundarycolor,newcolor);
BoundaryFill4(hdc,x-1,y,boundarycolor,newcolor);
BoundaryFill4(hdc,x+1,y,boundarycolor,newcolor);
}
}
1、visual c++ 6.0 下的界面
接下来,请按实验二中的方法给上面建立的空项目添加文件“recursion.cpp”,由于同学们初次接触WIN32 编程,所以对于下文中很多代码可暂时不要求理解,重点了解红色代码。
递归算法源码如下:
// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN // just say no to MFC
#include <windows.h> // include all the windows headers
#include <windowsx.h> // include useful macros
// DEFINES ////////////////////////////////////////////////
// defines for windows
#define WINDOW_CLASS_NAME "WINCLASS1"
#define WINDOW_WIDTH 400
#define WINDOW_HEIGHT 300
// GLOBALS ////////////////////////////////////////////////
HWND main_window_handle = NULL; // globally track main window HINSTANCE hinstance_app = NULL; // globally track hinstance
void BoundaryFill4(HDC,int,int,COLORREF,COLORREF);
// FUNCTIONS //////////////////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
// this is the main message handler of the system
HDC hdc; // handle to a device context
HPEN hnewpen;
HPEN holdpen;
// what is the message
switch(message)
{
case WM_RBUTTONDOWN:
hdc=GetDC(hwnd);
hnewpen=CreatePen(PS_SOLID,1,RGB(0,255,0));
holdpen=(HPEN)SelectObject(hdc,hnewpen);
// 构造多边形
MoveToEx(hdc,30,40,NULL);
LineTo(hdc,60,40);
LineTo(hdc,90,100);
LineTo(hdc,60,150);
LineTo(hdc,30,150);
LineTo(hdc,30,40);
SelectObject(hdc,holdpen);
DeleteObject(hnewpen);
ReleaseDC(hwnd,hdc);
return(0);
break;
case WM_LBUTTONDOWN:
hdc = GetDC(hwnd);
BoundaryFill4(hdc,LOWORD(lParam),HIWORD(lParam),RGB(0,255,0),RGB(255,0,0)); // release the dc
ReleaseDC(hwnd,hdc);
return(0);
break;
case WM_DESTROY:
{
// kill the application, this sends a WM_QUIT message
PostQuitMessage(0);
// return success
return(0);
} break;
default:break;
} // end switch
// process any messages that we didn't take care of
return (DefWindowProc(hwnd, message, wParam, lParam));
} // end WinProc
// WINMAIN ////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
WNDCLASSEX winclass; // this will hold the class we create
HWND hwnd; // generic window handle
MSG message; // generic message
// first fill in the window class stucture
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// save hinstance in global
hinstance_app = hinstance;
// register the window class
if (!RegisterClassEx(&winclass))
return(0);
// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
WINDOW_CLASS_NAME, // class
"Scanline Fill Demo", // title
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,0, // initial x,y
WINDOW_WIDTH, // initial width
WINDOW_HEIGHT,// initial height
NULL, // handle to parent
NULL, // handle to menu
hinstance,// instance of this application
NULL))) // extra creation parms
return(0);
// save main window handle
main_window_handle = hwnd;
while(GetMessage(&message,NULL,0,0))
{
// translate any accelerator keys
TranslateMessage(&message);
// send the message to the window proc
DispatchMessage(&message);
} // end while
// return to Windows like this
return(message.wParam);
} // end WinMain
///////////////////////////////////////////////////////////
void BoundaryFill4(HDC hdc,int x,int y,COLORREF boundarycolor,COLORREF newcolor) {
COLORREF color;
color=GetPixel(hdc,x,y);
if((color != boundarycolor) && (color !=newcolor))
{
SetPixel(hdc,x,y,newcolor);
BoundaryFill4(hdc,x,y+1,boundarycolor,newcolor);
BoundaryFill4(hdc,x,y-1,boundarycolor,newcolor);
BoundaryFill4(hdc,x-1,y,boundarycolor,newcolor);
BoundaryFill4(hdc,x+1,y,boundarycolor,newcolor);
}
}
2、 中建立Win32 工程
更改项目中recursion.cpp 文件代码:
1)声明函数
void BoundaryFill4(HDC,int,int,COLORREF,COLORREF);
2)修改LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)函数中
代码,把visualc++6.0 介绍的recursion.cpp 中的WndProc 函数体复制即可。
3)在recursion.cpp 文件末尾添加BoundaryFill4 函数。
实验四二维图形的几何变换
一、实验学时2学时
二、实验类型设计型实验
三、实验目的和要求
1、掌握二维图形的基本几何变换,如平移、旋转、缩放、对称、错切变换;
2、掌握OpenGL 中模型变换函数,实现简单的动画技术。
四、实验内容
1.在实验三的基础上,再添加一个主菜单项(几何变换)
2.在主菜单下添加子菜单项(平移、旋转、缩放)
3.建立相应的菜单命令函数
4.实现基本的几何变换
代码如下:
//平移
mx=1+mx;
my=4;
mz=-13;
Invalidate(FALSE);(mx,my,mz为三方向的平移量)
//旋转
if (r<330)
{
r=r+30;
}
else
{
r=0;
}
Invalidate(FALSE);(r为旋转角度)
//放缩
sx=sx+1;
sy=sy+1;
sz=sz+1;
Invalidate(FALSE);(sx,sy,sz分别为三方向的放缩系数)
在绘图部分(OnDraw函数中),添加几何变换代码(建议将绘图代码编写为自定义函数)glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//画点
glPushMatrix();
glPointSize(4);
glTranslatef (-5+mx, 3,-13);
glRotatef(r,1.0,1.0,1.0);
glScalef(sx,sy,sz);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_POINTS);//
glVertex3f( 0.0f, 1.0f,-1.0f);//a点
glVertex3f(-1.0f,-1.0f, 0.0f);//b点
glVertex3f( 1.0f,-1.0f, 0.0f);//c点
glEnd();
glPopMatrix();
//画三角形
glPushMatrix();
glTranslatef ( -1+mx, 3,-13);
glRotatef(r,1.0,1.0,1.0);
glScalef(sx,sy,sz);
glColor3f(0.0f, 1.0f, 0.0f);
glBegin(GL_LINE_LOOP); //
glVertex3f( 0.0f, 1.0f,-1.0f);//a点 glVertex3f(-1.0f,-1.0f, 0.0f);//b点 glVertex3f( 1.0f,-1.0f, 0.0f);//c点 glEnd();
glPopMatrix();
//画三角形面
glPushMatrix();
glTranslatef ( 4+mx, 3,-13);
glRotatef(r,1.0,1.0,1.0);
glScalef(sx,sy,sz);
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_POLYGON);//
glVertex3f( 0.0f, 1.0f,-1.0f);//a点
glVertex3f(-1.0f,-1.0f, 0.0f);//b点
glVertex3f( 1.0f,-1.0f, 0.0f);//c点 glEnd();
glPopMatrix();
//画四边形面
glPushMatrix();
glTranslatef (-5+mx, -3,-13);
glRotatef(r,1.0,1.0,1.0);
glScalef(sx,sy,sz);
glColor3f(1.0f, 1.0f, 0.0f);
glBegin(GL_POLYGON);//
glVertex3f(0.0f,0.0f ,0.0f);//a点
glVertex3f(1.0f,0.0f, 0.0f);//b点
glVertex3f(1.0f,0.0f,-1.0f);//c点
glVertex3f(0.0f,0.0f,-1.0f);//d点 glEnd();
glPopMatrix();
//画正方体
glPushMatrix();
glTranslatef ( 0+mx, -3,-13);
glRotatef(r,1.0,1.0,1.0);
glScalef(sx,sy,sz);
glColor3f(0.0f, 1.0f, 1.0f);
glBegin(GL_QUAD_STRIP);//
glVertex3f(0.0f,0.0f ,0.0f);//a0点 glVertex3f(0.0f,1.0f ,0.0f);//a1点 glVertex3f(1.0f,0.0f, 0.0f);//b0点 glVertex3f(1.0f,1.0f, 0.0f);//b1点 glVertex3f(1.0f,0.0f,-1.0f);//c0点 glVertex3f(1.0f,1.0f,-1.0f);//c1点
glVertex3f(0.0f,0.0f,-1.0f);//d0点
glVertex3f(0.0f,1.0f,-1.0f);//d1点
glVertex3f(0.0f,0.0f ,0.0f);//a0点
glVertex3f(0.0f,1.0f ,0.0f);//a1点
glEnd();
glFlush(); // 更新窗口
S wapBuffers(wglGetCurrentDC());
1、下面的代码采用GLUT 库,实现了一个矩形在窗口中匀速转动(单击鼠标右键停止转动),请修改代码,实现矩形在窗口内沿着水平线匀速移动。
/*
* double.c
* This is a simple double buffered program.
* Pressing the left mouse button rotates the rectangle.
* Pressing the right mouse button stops the rotation.
*/
#include <GL/glut.h>
#include <stdlib.h>
static GLfloat spin = 0.0;
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin, 0.0, 0.0, 1.0);
glColor3f(1.0, 1.0, 1.0);
glRectf(-10.0, -10.0, 10.0, 10.0);
glPopMatrix();
glutSwapBuffers();
}
void spinDisplay(void)
{
spin = spin + 2.0;
if (spin > 360.0)
spin = spin - 360.0;
glutPostRedisplay();
}
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT);
}
void reshape(int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity();
glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();
}
void mouse(int button, int state, int x, int y) {
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) glutIdleFunc(spinDisplay);
break;
case GLUT_MIDDLE_BUTTON:
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) glutIdleFunc(NULL);
break;
default:
break;
}
}
/*
* Request double buffer display mode.
* Register mouse input callback functions
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
2、课堂教学中关于模型变化讲解时,对一个三角形分别实现平移、缩放、旋转等变化的源码及效果图。
请以该例为蓝本,实现3 题的代码编写。
源码:
#include <GL/glut.h>
#include <stdlib.h>
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void draw_triangle(void)
{
glBegin (GL_LINE_LOOP);
glVertex2f(0.0, 25.0);
glVertex2f(25.0, -25.0);
glVertex2f(-25.0, -25.0);
glEnd();
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0);
glLoadIdentity ();
glColor3f (1.0, 1.0, 1.0);
draw_triangle ();
glEnable (GL_LINE_STIPPLE); glLineStipple (1, 0xF0F0); glLoadIdentity ();
glTranslatef (-20.0, 0.0, 0.0);
draw_triangle ();
glLineStipple (1, 0xF00F); glLoadIdentity ();
glScalef (1.5, 0.5, 1.0);
draw_triangle ();
glLineStipple (1, 0x8888); glLoadIdentity ();
glRotatef (90.0, 0.0, 0.0, 1.0);
draw_triangle ();
glDisable (GL_LINE_STIPPLE);
glFlush ();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
if (w <= h)
gluOrtho2D (-50.0, 50.0, -50.0*(GLfloat)h/(GLfloat)w, 50.0*(GLfloat)h/(GLfloat)w);
else
gluOrtho2D (-50.0*(GLfloat)w/(GLfloat)h,
50.0*(GLfloat)w/(GLfloat)h, -50.0, 50.0); glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
实验结果图:
3、已知某三角形的三顶点坐标为{50.0,25.0},{150.0,25.0},{100.0,100.0}。
要求:(1)创建一个长宽分别为600、600 的窗口,窗口的左上角位于屏幕坐标(100,100)处。
(提示:请试着将gluOrtho2D 函数参数,使得绘制的三角形尽可能居中显示)
(2)绘制一个由上述顶点所描绘的三角形,实现该三角形进行下列的几何变化:首先使三
角形沿着其中心的x 轴,y 轴方向缩小50%;然后沿着中心旋转90 度;最后沿着y 轴平移100 个
单位。
实验结果如下图所示:
实验五二维裁剪
一、实验学时2学时
二、实验类型设计型实验
三、实验目的和要求
1、掌握二维图形的基本裁剪算法,如编码算法、中点分割算法、Liang-Barsky 算法;
2、掌握OpenGL 中矩阵堆栈函数的使用,实现简单的组合变换。
四、实验内容
1、采用Liang-Barsky算法
要求:1)单击鼠标左键,运行窗口出现裁剪窗口及待裁剪线段;
2)单击鼠标右键,窗口呈现出裁剪后的裁剪窗口及裁剪线段。
2、下面的程序绘制的是一个简单的太阳系,其中包括一个太阳和一颗行星,它们使用同球体绘制函数实现。
当按下键盘“D”或“d”时,行星将实现自转;按下键盘“Y”或“y”时,行星将绕太阳公转。
1、采用Liang-Barsky 算法,编程实现教材177 页6.15 题。
(其他裁剪算法同学们可作为课
后练习)
要求:1)单击鼠标左键,运行窗口出现裁剪窗口及待裁剪线段,效果图如左下图;
2)单击鼠标右键,窗口呈现出裁剪后的裁剪窗口及裁剪线段,效果图如右下图。
提示:1)关于鼠标的交互操作,请同学们参考实验四中的第1 题;
2)绘制图形的函数,建议放在回调函数mouse(int button,int state,int x,int y)中,而display()函数中可只保留glClear (GL_COLOR_BUFFER_BIT)清除颜色缓存这个函数。
3)考虑到该裁剪窗口和裁剪线段的大小,建议将reshape()函数中的正交投影函数参数
变为glOrtho(-5.0, 5.0, -5.0, 5.0, -1.0, 1.0);
2、下面的程序绘制的是一个简单的太阳系,其中包括一个太阳和一颗行星,它们使用同球体绘制函数实现。
当按下键盘“D”或“d”时,行星将实现自转;按下键盘“Y”或“y”
时,行星将绕太阳公转。
请同学们认真读懂每一段代码,然后试着修改这段程序,实现
1)将行星的中心倾斜;
2)给行星加上卫星。
#include <GL/glut.h>
#include <stdlib.h>
static int year = 0, day = 0;
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glPushMatrix();
// glutWireSphere中第一、二、三个参数分别表示半径,经度线数、纬度线数
glutWireSphere(1.0, 20, 16); /* draw sun */
glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);
glTranslatef (2.0, 0.0, 0.0);
glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);
glutWireSphere(0.2, 10, 8); /* draw smaller planet */
glPopMatrix();
glutSwapBuffers();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void keyboard (unsigned char key, int x, int y)
{
switch (key) {
case 'd':
day = (day + 10) % 360;
glutPostRedisplay();
break;
case 'D':
day = (day - 10) % 360;
glutPostRedisplay();
break;
case 'y':
year = (year + 5) % 360;
glutPostRedisplay();
break;
case 'Y':
year = (year - 5) % 360;
glutPostRedisplay();
break;
case 27:
exit(0);
break;
default:
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
实验六自由曲线
一、实验学时2学时
二、实验类型设计型实验
三、实验目的和要求
1、掌握Hermite 曲线生成算法;
2、掌握Bezier 曲线的定义生成算法、离散生成算法;
3、掌握B 样条曲线的定义生成算法。
四、实验内容
假设窗口的宽高分别是600,600个像素单位,定义的裁剪窗口由函数
gluOrtho2D(-50.0,50.0,-50.0,50.0)决定。
1、已知空间点两点P0(-40.0,-40.0,0.0)、P1(10.0,-200.0,0.0)及该点上的切向量分别为R0(30.0,240.0,0.0),R1(30.0,-240.0,0.0)。
试编程实现Hermite曲线的绘制。
2、已知空间四点P0(-40.0,-40.0,0.0)、P1(-10.0,200.0,0.0)、P2(10.0,-200.0,0.0)、P3(40.0,40.0,0.0),根据Bezier曲线的定义编程绘制曲线。
3、已知空间四点P0(-40.0,-40.0,0.0)、P1(-10.0,200.0,0.0)、P2(10.0,-200.0,0.0)、P3(40.0,40.0,0.0),根据Bezier曲线的离散生成算法绘制曲线。
4、已知空间四点P0(-40.0,-40.0,0.0)、P1(-10.0,200.0,0.0)、P2(10.0,-200.0,0.0)、P3(40.0,40.0,0.0),根据B样和曲线的定义绘制曲线。
实验2 直线和椭圆的绘制
实验目的
1、通过实验,进一步理解和掌握DDA和中点算法;
2、掌握以上算法生成直线段、椭圆或圆的基本过程;
3、通过编程,会在TC环境下完成用DDA或中点算法实现直线段、椭圆或圆的绘
制。
实验环境
计算机、Turbo C或其他C语言程序设计环境
实验学时
4学时,必做实验。
实验内容
用DDA算法或中点(Besenham)算法实现直线段、椭圆或圆的绘制。
实验步骤
1、算法、原理清晰,有详细的设计步骤;
2、依据算法、步骤或程序流程图,用C语言编写源程序;
3、编辑源程序并进行调试;
4、进行运行测试,并结合情况进行调整;
5、对运行结果进行保存与分析;
6、打印源程序或把源程序以文件的形式提交;
7、按格式书写实验报告。
分析与思考
1.为何在程序运行时,有的椭圆或圆仅在屏幕左上角显示了一部分?
2.用中点算法生成的椭圆,为何在半径较大时,图形的失真严重?
实验3 区域填充和图形的裁剪
实验目的
1、通过实验,进一步理解和掌握扫描线填充算法;
2、掌握用扫描线填充算法进行区域填充的基本过程;
3、通过编程,会在TC环境下用扫描线填充算法编程实现一个饼型图的绘制;
4、通过实验,进一步理解和掌握Sutherland 裁剪算法;
5、掌握用Sutherland 裁剪算法裁减多边形的基本过程;
6、通过编程,会在TC环境下用Sutherland 算法编程实现用矩形窗口对多边形的裁
剪。
实验环境
计算机、Turbo C或其他C语言程序设计环境
实验学时
4学时,必做实验
实验内容
1、用扫描线填充算法编程实现一个彩色饼型图的绘制;
2、用Sutherland 算法编程实现用矩形窗口对多边形的裁剪。
实验步骤
1、算法、原理清晰,有详细的设计步骤;
2、依据算法、步骤或程序流程图,用C语言编写源程序;
3、编辑源程序并进行调试;
4、进行运行测试,并结合情况进行调整;
5、对运行结果进行保存与分析;
6、打印源程序或把源程序以文件的形式提交;
7、按格式书写实验报告。
分析与思考
1.能否在程序的运行中,使得图形的显示逐步进行,以观察程序的运行过程?
2.对上述的运行方式请改进程序并运行之。
实验4 BEZIER曲线和B样条曲线的绘制实验目的
1、通过实验,进一步理解和掌握生成BEZIER曲线的算法;
2、掌握BEZIER曲线的基本生成过程;
3、通过编程,会在TC环境下编程实现三次BEZIER曲线的绘制;
4、通过实验,进一步理解和掌握生成B样条曲线的算法;
5、掌握B样条曲线的基本生成过程;
6、通过编程,会在TC环境下编程实现三次B样条曲线的绘制。
实验环境
计算机、Turbo C或其他C语言程序设计环境
实验学时
4学时,必做实验
实验内容
1、编程实现三次BEZIER曲线的绘制;
2、编程实现三次B样条曲线的绘制。
实验步骤
1、算法、原理清晰,有详细的设计步骤;
2、依据算法、步骤或程序流程图,用C语言编写源程序;
3、编辑源程序并进行调试;
4、进行特殊模式的运行测试,并结合情况进行调整;
5、对运行结果进行保存与分析;
6、打印源程序或把源程序以文件的形式提交;
7、按格式书写实验报告。
分析与思考
1、考虑用三次BEZIER或B样条曲线绘制小松鼠等复杂图案;
2、能否写出三次BEZIER和B样条曲线的转换程序。
实验5 设计实验
实验目的
1、通过实验,综合运用计算机图形学的知识、原理和算法;
2、掌握具有真实感图形的生成过程;
3、通过编程,会在TC环境下编程实现真实感图形的绘制。
实验环境
计算机、Turbo C或其他C语言程序设计环境
实验学时
4学时,必做实验
实验内容
自选算法,绘制具有真实感的三维物体,以下为参考内容:
(1)人造卫星绕地球运行的模拟;
(2)发出光芒的闪闪红星;
(3)飘动的红旗等。
实验步骤
1、算法、原理清晰,有详细的设计步骤;
2、依据算法、步骤或程序流程图,用C语言编写源程序;
3、编辑源程序并进行调试;
4、进行特殊模式的运行测试,并结合情况进行调整;
5、对运行结果进行保存与分析;
6、打印源程序或把源程序以文件的形式提交;
7、按格式书写实验报告。
分析与讨论
1、考虑如何实现真实感图形交互控制,以达到灵活的控制效果。
2、考虑如何实现真实感图形的多幅图动画显示效果的设计与实现。