华北电力大学科技学院
实验报告
|
|
实验名称 OpenGL基本图元绘制实验
课程名称 计算机图形学
|
|
专业班级: 学生姓名:
学 号: 成 绩:
指导教师:姜丽梅 实验日期:
二、所用仪器、设备
Windows 系统,Visual C++,OpenGL及GLUT库
三、实验方法与步骤
先配置环境
C:\Program Files\Microsoft Visual Studio\VC98\Include\GL
C:\WINDOWS\system32
C:\Program Files\Microsoft Visual Studio\VC98\Lib
然后通过VC++进行编译,源代码如:
四:源代码
实验一:
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
#include <GL/glut.h>
#include <math.h>
#define DEG_TO_RAD 0.017453
static GLfloat theta = 0.0;
GLfloat r = 1.0; //设置三角形的初始颜色
GLfloat g = 0.0;
GLfloat b = 0.0;
int singleb,doubleb;
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);//三角形换色
glColor3f(r, g,b);
r = r - 0.002;
g = g + 0.002;
b = b + 0.001;
if(r < 0.001)
{
r = 1.0;
g = 0.0;
b = 0.0;
}
glBegin(GL_POLYGON);
glVertex2f(cos(DEG_TO_RAD*theta), sin(DEG_TO_RAD*theta));
glVertex2f(cos(DEG_TO_RAD*(theta+120)), sin(DEG_TO_RAD*(theta+120)));
glVertex2f(cos(DEG_TO_RAD*(theta+240)), sin(DEG_TO_RAD*(theta+240)));
glEnd();
glutSwapBuffers();
}
void spinDisplay (void)//转动
{
theta = theta + 1.0;
if (theta > 360.0)
theta = theta - 360.0;
glutPostRedisplay();
}
void spinDisplay1(void)
{
glutPostRedisplay();
}
void myReshape(int w, int h)//指定平面上一个矩形裁剪区域,
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
gluOrtho2D(-1., 1., -1.*(GLfloat)h/(GLfloat)w, 1.*(GLfloat)h/(GLfloat)w);
else
gluOrtho2D(-1.*(GLfloat)w/(GLfloat)h, 1.*(GLfloat)w/(GLfloat)h, -1., 1.);
}
void mouse(int button,int state,int x,int y) //鼠标定义
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if(state == GLUT_DOWN )
{
glutIdleFunc(spinDisplay1);
}
break;
case GLUT_RIGHT_BUTTON:
if(state == GLUT_DOWN)
glutIdleFunc(spinDisplay);
break; default: break;
}
}
void main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(500, 500);
glutCreateWindow("spinning square");
glClearColor(0.0, 0.0, 0.0, 1.0);
glutDisplayFunc(display);
glutReshapeFunc(myReshape);
glutIdleFunc(spinDisplay);
glutMouseFunc(mouse);
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(600, 100);
glutInitWindowSize(500, 500);
doubleb=glutCreateWindow("spinning square");
glClearColor(1.0, 1.0, 0.0, 0.1);
glutDisplayFunc(display);
glutReshapeFunc(myReshape);
glutIdleFunc(spinDisplay);
glutMouseFunc(mouse);
glutMainLoop();
}
实验二:
#include "stdafx.h"
#include <stdlib.h>
#include <GL/glut.h>
GLfloat vertices[][3] = {{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{1.0,1.0,-1.0},
{-1.0,1.0,-1.0}, {-1.0,-1.0,1.0},{1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0}};
static GLfloat theta[] = {0.0,0.0,0.0};
static GLint axis = 2;
static GLdouble viewer[]= {0.0, 0.0, 5.0};
void polygon(int a, int b, int c , int d)
{
glBegin(GL_POLYGON);
glVertex3fv(vertices[a]); glVertex3fv(vertices[b]);
glVertex3fv(vertices[c]); glVertex3fv(vertices[d]);
glEnd();
}
void colorcube()
{
//正前面
glColor3f(1,1,1); polygon(4,5,6,7); //正背面
glColor3f(1.0,0,0); polygon(0,3,2,1);
glColor3f(0,1,0); polygon(2,3,7,6); glColor3f(0,0,1); polygon(0,4,7,3);
glColor3f(1,1,0); polygon(1,2,6,5); glColor3f(0,1,1); polygon(0,1,5,4);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearDepth(1); glLoadIdentity(); //更新视点位置
gluLookAt(viewer[0],viewer[1],viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(theta[0], 1.0, 0.0, 0.0); glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0); colorcube();
glutSwapBuffers();
}
void keys(unsigned char key, int x, int y)
{/* 用 x, X, y, Y, z, and Z 键 移动视点 */
if(key == 'x') viewer[0]-= 1.0;
if(key == 'X') viewer[0]+= 1.0;
if(key == 'y') viewer[1]-= 1.0;
if(key == 'Y') viewer[1]+= 1.0;
if(key == 'z') viewer[2]-= 1.0;
if(key == 'Z') viewer[2]+= 1.0;
display();
}
void myReshape(int w, int h)
{ glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); glLoadIdentity();
if(w<=h) glFrustum(-2.0, 2.0, -2.0 * (GLfloat) h/ (GLfloat) w,
2.0* (GLfloat) h / (GLfloat) w, 2.0, 20.0);
else glFrustum(-2.0, 2.0, -2.0 * (GLfloat) w/ (GLfloat) h,
2.0* (GLfloat) w / (GLfloat) h, 2.0, 20.0);
/* 或者用gluPerspective(45.0, w/h, 1.0, 10.0); */
glMatrixMode(GL_MODELVIEW);
}
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0;
if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1;
if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2;
theta[axis] += 2.0;
if( theta[axis] > 360.0 ) theta[axis] -= 360.0;
display();
}
int _tmain(int argc, _TCHAR* argv[])
{
//glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(300, 300);
glutCreateWindow("cube");
glutDisplayFunc(display);
glutReshapeFunc(myReshape);
glutMouseFunc(mouse);
glutKeyboardFunc(keys);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return 0;
}
五:实验结果与数据处理
实验一:程序运行后,弹出两个窗口,里面的三角形旋转的同时逐渐变色;
可用鼠标控制,点击左键三角形停止旋转,点击右键三角形继续旋转。
实验二:运行程序,弹出一个黑色正方形,内有一个三维的正方体,当点击鼠标时正方体会转动,正方体的各个面的颜色均不相同。 按住键盘中z,x,y可以变大变小。
六:试验结论
通过一周的试验,感觉受益匪浅,学到了很多课堂上学不到的,我进一步加深了对于基本画图算法的理解。另外,通过实验训练了自己的编程能力,同时熟悉了OpenGL绘图的函数和流程,也进一步巩固了相关的知识。对图形的变换开始并不了解但是经过自己看书知道图形变换并不是那么难的,知道图形变换的几个函数。在这个坐标系中,可以对物体实施平移glTranslatef()、旋转glRotatef()和放大缩小glScalef()。
七、所附实验输出的结果或数据
实验一:
实验二:
第二篇:计算机图形学课程设计-20xx
计算机图形学课程设计
内容及要求
一、 总体目标和要求
目标:深入研究算法,以某个(或某类)图形学算法为目标,深入研究。继而策划、设计并实现一个能够表现该算法原理的或完整过程的演示系统,并能从某些方面作出评价和改进意见。通过完成一个完整程序,经历策划、设计、开发、测试、总结和验收各阶段,达到:
u 巩固和实践计算机图形学课程中的理论和算法;
u 学习表现计算机图形学算法的技巧;
u 培养认真学习、积极探索的精神。
总体要求:策划、设计并实现一个能够充分表现某个图形学算法的演示系统,界面要求美观大方,能清楚地演示算法执行的每一个步骤。
开发环境:Viusal C++ 6.0 或者更高版本
工具库的限制:不允许使用任何图形软件包,如OpenGL,DirectX,Java3D等。但可应用如文件读取(特别是图像文件读取、外部模型文件读取)、数据组织(如STL)等非图形工具。
项目选择:选择以下所列程序中的两个即可,具体见第三节。
二、 时间节点和分值
课程设计的时间安排上分若干阶段,每个阶段有相应截止时间、要求、分值和评分标准。总分为100分。作业的提交方式参见附录。
第11周周五(20##-11-9)中午12:00之前,以班级为单位把报告打印稿交到胡涛老师办公室,滞后提交的作业将扣除相应分值直至全部扣除。
要求:
至少提交至概要设计报告,并有一个原型系统。
概要设计确定使用的开发环境,整体模块结构等,可参见相关国家标准文档,但不必完全依照。
原型系统能够基本实现该算法,为以后表现该算法作准备。
评分标准:
清晰的功能列表,算法表现策略,合理且明确的进度安排。中期检查将参照此进度安排。
规范、翔实的概要设计报告,功能正确的原型系统。
三、 内容与要求
作业分为九项内容,只要做其中两项即可。
1) 简单图形的生成
内容:
直线的生成
①DDA法 ②中点画线法 ③Bresenham法
圆的生成
①中点法 ② Bresenham法
椭圆的生成
① 中点法 ② Bresenham法
要求:
Ø 将象素网格表现出来,建立网格坐标系
Ø 用橡皮筋的形式输入参数
Ø 鼠标移动时,显示鼠标当前位置
Ø 显示判别式的计算过程和下一点的选择策略
Ø 记录生成点的坐标,建议用表的形式
Ø 图形生成过程可以重复进行
Ø 建议在一个程序中实现上述算法
2) 多边形区域填充
内容:
种子填充算法;扫描线填充算法;扫描线种子填充算法;边填充算法;栅栏填充算法
要求:
Ø 将象素网格表现出来,建立网格坐标系
Ø 用橡皮筋的形式输入多边形
Ø 鼠标移动时,显示鼠标当前位置
Ø 种子填充算法中用鼠标选择种子点,用表格的形式显示堆栈存储的象素,象素出栈或入栈的过程要显示出来。关键是要将象素填充的顺序表现出来。
Ø 扫描线算法中先显示一条自上而下的扫描线,如果不与多边形相交,则直接向下移动,否则需要填充多边形内的交点。多边形形成以后,要显示边表的内容,扫描线移动的时候,要动态改变活性边表的内容,一条边加入活性边表或从活性边表中删除需要给出提示。
3) 二维裁剪
内容:
线段裁剪
窗口为长方形:①Cohen-SutherLand算法 ②中点分割算法 ③Liang-Barsky 算法
窗口为任意多边形:Cyrus-Beck算法
多边形裁剪
Sutherland-Hodgman算法,Weiler-Atherton算法(任意多边形互裁剪)
要求:
Ø 将象素网格表现出来,建立网格坐标系
Ø 用橡皮筋的形式输入剪裁线段或多边形
Ø 对于线段裁剪,线段被窗口的四条边裁剪的过程要显示出来
Ø 对于中点分割算法,要显示线段一步步分割的过程
Ø Liang-Barsky 算法和Cyrus-Beck算法要显示矢量的计算和选择t参数的过程
Ø Sutherland-Hodgman多边形裁剪过程需先输入一多边形,然后用窗口四边裁剪的过程中要显示顶点增删的过程。
Ø Weiler-Atherton算法需要指明裁剪多边形和被裁剪多边形,从而决定交点的分类
Ø 可以根据程序的需要决定是否在一个程序中完成。
4) 直线和多边形的反走样
内容:实现以下四种反走样的方法:提高分辨率、超采样、连续区域采样、离散区域采样
要求:
Ø 将象素网格表现出来,建立网格坐标系
Ø 用橡皮筋输入一条直线或多边形,线的宽度可以设置,为一整数
Ø 对于提高分辨率方法,首先用网格象素法表示一条直线或多边形,然后将网格缩小,观察直线的变化
Ø 超采样法需要根据经过的不同子象素的数目决定该象素的亮度
Ø 连续区域采样需要根据直线所占象素面积来决定象素的亮度
Ø 离散区域采样将所占面积离散化,根据所占象素点的数目决定亮度,需要考虑加权模板,模板的大小为奇数
Ø 如以上点需要计算,则必须显示计算步骤
5) 曲线曲面生成
内容:
曲线:Bezier曲线、二次B样条曲线、三次B样条曲线、Nurbs曲线
曲面:Ferguson曲面、Bezier曲面、三次B样条曲面、Nurbs曲面、Coons曲面
要求:
对于曲线:
Ø 采用橡皮筋方法输入型值点
Ø 第n个点为鼠标当前位置,使得曲线的形状随鼠标变化
Ø 输入的点存入表格中
Ø 在完成一段曲线后,可以移动型值点的位置产生新的曲线
Ø Nurbs曲线需要输入权因子
Ø 可以显示曲线的型值点多边形
对于曲面:
Ø 采用键盘输入点的坐标
Ø 曲面生成后,可以用鼠标操纵多角度观察,曲面有两种方式切换:网格曲面和光滑曲面(光滑曲面需要加上一个缺省光照)
6) 图形变换
内容:简单图形的平移、旋转、缩放
要求:
可以产生一些基本几何体(球,椭球体,圆锥,长方体,四面体等),大小先利用缺省值,然后在点取物体,在菜单上选择操作方式,程序应该能自动生成变换矩阵并显示出来。另外还可以定义变换,放入变换列表,将若干个变换组合起来形成统一的变换矩阵,然后一下实施变换操作。
7) 简单几何体的消隐
内容:简单几何体(球,椭球体,圆锥,长方体,四面体等)的生成和消隐
要求:
体用线框形式表示,可以在消隐和未消隐之间切换,用鼠标可以操纵形体的位置的角度,包括自消隐和互消隐(多个物体之间的消隐)。
8) 纹理映射
内容:将纹理映射到简单的曲面上
要求:
纹理应该可以自定义,也可以导入外面的纹理图片
曲面包括:平面,二次曲面,Bezier曲面,三次B样条曲面,曲面可以导入外面的图形文件,也可以在程序中生成。
能任意指定映射关键点,能消除纹理走样。
9) 光源效果
内容:演示光源效果
要求:
可以添加光源,删除光源,对每一个光源进行命名;对每一个光源可以进行编辑,包括散射参数,镜面参数,光源位置参数,聚光方向,聚光指数,聚光角度,聚光终止角度,三个衰减系数等。还可以对环境光进行调整,调整采用滑动条的形式。需要制作高光效果,光源效果作用在一个球体上,球体可以指定材质,插值方式分面片模型、Phong模型和Gouraud模型三种可以从不同的角度实时观察。
注:
作业提交方式与做一图形系统的方式相同。
欢迎大家有好的想法,设计出美观大方,表现力好,有创意的程序。
上面列出的是最基本的要求,如果大家能提出更好的建议,请提出来。