OpenGL实验教程 v30重点讲义资料Word格式.docx

上传人:b****7 文档编号:22179350 上传时间:2023-02-02 格式:DOCX 页数:171 大小:848.60KB
下载 相关 举报
OpenGL实验教程 v30重点讲义资料Word格式.docx_第1页
第1页 / 共171页
OpenGL实验教程 v30重点讲义资料Word格式.docx_第2页
第2页 / 共171页
OpenGL实验教程 v30重点讲义资料Word格式.docx_第3页
第3页 / 共171页
OpenGL实验教程 v30重点讲义资料Word格式.docx_第4页
第4页 / 共171页
OpenGL实验教程 v30重点讲义资料Word格式.docx_第5页
第5页 / 共171页
点击查看更多>>
下载资源
资源描述

OpenGL实验教程 v30重点讲义资料Word格式.docx

《OpenGL实验教程 v30重点讲义资料Word格式.docx》由会员分享,可在线阅读,更多相关《OpenGL实验教程 v30重点讲义资料Word格式.docx(171页珍藏版)》请在冰豆网上搜索。

OpenGL实验教程 v30重点讲义资料Word格式.docx

首先从开始->

所有程序->

MicrosoftVisualC++6.0菜单中打开VC,也可单击文件:

\ProgramFiles\MicrosoftVisualStudio\VisualC++6\Common\MSDev98\Bin\msdev.exe打开VC,在VC中选择File->

New->

Project,然后选择Win32ConsoleApplication,输入一个工程名,设为Pixel,然后按OK。

在弹出的对话框左边点ApplicationSettings,选择Aemptyproject并勾上,选择Finish。

在VC中选择File->

Files页,然后选择C++SourceFile,勾选“Addtoproject”,并在下面输入一个文件名,如为test1,然后按OK。

随后将实验示范代码拷入该文件即可. 

 

实验1像素点的生成

1.实验目的:

熟悉编程环境;

了解光栅图形显示器的特点;

了解计算机绘图的特点;

利用VC+OpenGL作为开发平台设计程序,以能够在屏幕上生成任意一个像素点为本实验的结束。

2.实验内容:

(1) 

了解和使用VC的开发环境,理解简单的OpenGL程序结构;

(2) 

掌握OpenGL提供的基本图形函数,尤其是生成点的函数。

3.实验原理:

(1)基本语法

常用的程序设计语言,如C、C++、Pascal、Fortran和Java等,都支持OpenGL的开发。

这里只讨论C版本下OpenGL的语法。

OpenGL基本函数均使用gl作为函数名的前缀,如glClearColor();

实用函数则使用glu作为函数名的前缀,如gluSphere()。

OpenGL基本常量的名字以GL_开头,如GL_LINE_LOOP;

实用常量的名字以GLU_开头,如GLU_FILL。

一些函数如glColor*()(定义颜色值),函数名后可以接不同的后缀以支持不同的数据类型和格式。

如glColor3b(...)、glColor3d(...)、glColor3f(...)和glColor3bv(...)等,这几个函数在功能上是相似的,只是适用于不同的数据类型和格式,其中3表示该函数带有三个参数,b、d、f分别表示参数的类型是字节型、双精度浮点型和单精度浮点型,v则表示这些参数是以向量形式出现的。

OpenGL定义了一些特殊标识符,如GLfloat,GLvoid。

它们其实就是C中的float和void。

在gl.h文件中可以看到以下定义:

……

typedeffloatGLfloat;

typedefvoidGLvoid;

一些基本的数据类型都有类似的定义项。

(2)程序的基本结构

OpenGL程序的基本结构可分为三个部分:

第一部分是初始化部分。

主要是设置一些OpenGL的状态开关,如颜色模式(RGBA或ALPHA)的选择,是否作光照处理(若有的话,还需设置光源的特性),深度检验,裁剪等等。

这些状态一般都用函数glEnable(...),glDisable(…)来设置,…表示特定的状态。

第二部分设置观察坐标系下的取景模式和取景框位置大小。

主要利用了三个函数:

函数voidglViewport(left,top,right,bottom):

设置在屏幕上的窗口大小,四个参数描述屏幕窗口四个角上的坐标(以象素表示);

函数voidglOrtho(left,right,bottom,top,near,far):

设置投影方式为正交投影(平行投影),其取景体积是一个各面均为矩形的六面体;

函数voidgluPerspective(fovy,aspect,zNear,zFar):

设置投影方式为透视投影,其取景体积是一个截头锥体。

第三部分是OpenGL的主要部分,使用OpenGL的库函数构造几何物体对象的数学描述,包括点线面的位置和拓扑关系、几何变换、光照处理等等。

以上三个部分是OpenGL程序的基本框架,即使移植到使用MFC的Windows程序中,也是如此。

只是由于Windows自身有一套显示方式,需要进行一些必要的改动以协调这两种不同显示方式。

(3)状态机制

OpenGL的工作方式是一种状态机制,它可以进行各种状态或模式设置,这些状态或模式在重新改变它们之前一直有效。

例如,当前颜色就是一个状态变量,在这个状态改变之前,绘制的每个象素都将使用该颜色,直到当前颜色被设置为其它颜色为止。

OpenGL中大量地使用了这种状态机制,如颜色模式、投影模式、单双显示缓存区的设置、背景色的设置、光源的位置和特性等等。

许多状态变量可以通过glEnable()、glDisable()这两个函数来设置成有效或无效状态,如是否设置光照、是否进行深度检测等;

在被设置成有效状态之后,绝大部分状态变量都有一个缺省值。

通常情况下,可以用下列四个函数来获取某个状态变量的值:

glGetBooleanv()、glGetDouble()、glGetFloatv()和glGetIntegerv()。

究竟选择哪个函数应该根据所要获得的返回值的数据类型来决定。

还有些状态变量有特殊的查询函数,如glGetLight*()、glGetError()和glPolygonStipple()等。

另外,使用glPushAttrib()和glPopAttrib()函数,可以存储和恢复最近的状态变量的值。

只要有可能,都应该使用这些函数,因为它们比其它查询函数的效率更高。

4.实验代码:

一个简单的OpenGL程序如下:

(注意,如果需要编译并运行,需要正确安装GLUT,安装方法如预备知识中所述)

#include 

<

GL/glut.h>

void 

myDisplay(void)

{

glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0f,1.0f,1.0f);

glRectf(-0.5f,-0.5f,0.5f,0.5f);

glBegin(GL_TRIANGLES);

glColor3f(1.0f,0.0f,0.0f);

glVertex2f(0.0f,1.0f);

glColor3f(0.0f,1.0f,0.0f);

glVertex2f(0.8f,-0.5f);

glColor3f(0.0f,0.0f,1.0f);

glVertex2f(-0.8f,-0.5f);

glEnd();

glPointSize(3);

glBegin(GL_POINTS);

glVertex2f(-0.4f,-0.4f);

glVertex2f(0.0f,0.0f);

glVertex2f(0.4f,0.4f);

glFlush();

}

int 

main(int 

argc, 

char 

*argv[])

glutInit(&

argv);

glutInitDisplayMode(GLUT_RGB 

GLUT_SINGLE);

glutInitWindowPosition(100, 

100);

glutInitWindowSize(400, 

400);

glutCreateWindow("

HelloOpengl!

"

);

glutDisplayFunc(myDisplay);

glutMainLoop();

return 

0;

该程序的作用是在一个黑色的窗口中央画一个矩形、三角形和三个点。

下面对各行语句进行说明:

首先,需要包含头文件#include 

,这是GLUT的头文件。

本来OpenGL程序一般还要包含<

GL/gl.h>

和<

GL/glu.h>

,但GLUT的头文件中已经自动将这两个文件包含了,不必再次包含;

然后看main函数。

*argv[]),这个是带命令行参数的main函数。

注意main函数中的各语句,除了最后的return之外,其余全部以glut开头。

这种以glut开头的函数都是GLUT工具包所提供的函数,下面对用到的几个函数进行介绍;

1)glutInit,对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。

其格式比较固定,一般都是glutInit(&

argv)就行;

2)glutInitDisplayMode,设置显示方式,其中GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX(表示使用索引颜色)。

GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)。

更多信息,以后的实验教程会有讲解介绍;

3)glutInitWindowPosition,设置窗口在屏幕中的位置;

4)glutInitWindowSize,设置窗口的大小;

5)glutCreateWindow,根据前述设置的信息创建窗口。

参数将被作为窗口的标题。

注意:

窗口被创建后,并不立即显示到屏幕上。

需要调用glutMainLoop才能看到窗口;

6)glutDisplayFunc,设置一个函数,当需要进行画图时,这个函数就会被调用。

(暂且这样理解);

7)glutMainLoop,进行一个消息循环。

(现在只需知道这个函数可以显示窗口,并且等待窗口关闭后才会返回。

在glutDisplayFunc函数中,我们设置了“当需要画图时,请调用myDisplay函数”。

于是myDisplay函数就用来画图。

观察myDisplay中的三个函数调用,发现它们都以gl开头。

这种以gl开头的函数都是OpenGL的标准函数,下面对用到的函数进行介绍:

1)glClearColor(0.0,0.0,0.0,0.0):

将清空颜色设为黑色(为什么会有四个参数?

);

2)glClear(GL_COLOR_BUFFER_BIT):

将窗口的背景设置为当前清空颜色;

3)glRectf,画一个矩形。

四个参数分别表示了位于对角线上的两个点的横、纵坐标;

4)glFlush,保证前面的OpenGL命令立即执行(而不是让它们在缓冲区中等待)。

5.思考题

左图是示范程序的结果,能否在原有结果基础上添加三条直线组成新的三角形?

(如右图所示)

请在实验报告的实验结果将改动结果写出.

示范程序结果 

注:

本博客实验教程的配套教材为《计算机图形学》(徐文鹏编)已由机械工业出版社于2009年2月出版。

实验2 

直线生成算法的实现

理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法。

根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果;

指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告;

(3) 

根据示范代码,将其改造为圆的光栅化算法,写入实验报告;

(4) 

了解和使用OpenGL的生成直线的命令,来验证程序运行结果。

示范代码原理参见教材直线光栅化一节中的DDA算法。

下面介绍下OpenGL画线的一些基础知识和glutReshapeFunc()函数。

(1)数学上的直线没有宽度,但OpenGL的直线则是有宽度的。

同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。

可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。

这里的线由一系列顶点顺次连结而成,有闭合和不闭合两种。

前面的实验已经知道如何绘“点”,那么OpenGL是如何知道拿这些顶点来做什么呢?

是一个一个的画出来,还是连成线?

或者构成一个多边形?

或是做其它事情呢?

为了解决这一问题,OpenGL要求:

指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略),并由glBegin来指明如何使用这些点。

例如:

glBegin(GL_POINTS);

glVertex2f(0.0f, 

0.0f);

glVertex2f(0.5f, 

glEnd();

则这两个点将分别被画出来。

如果将GL_POINTS替换成GL_LINES,则两个点将被认为是直线的两个端点,OpenGL将会画出一条直线。

还可以指定更多的顶点,然后画出更复杂的图形。

另一方面,glBegin支持的方式除了GL_POINTS和GL_LINES,还有GL_LINE_STRIP,GL_LINE_LOOP,GL_TRIANGLES,GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN等,每种方式的大致效果见下图:

图B-2OpenGL几何图元类型

(声明:

该图片来自www.opengl.org,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,希望没有触及到版权问题。

(2)首次打开窗口、移动窗口和改变窗口大小时,窗口系统都将发送一个事件,以通知程序员。

如果使用的是GLUT,通知将自动完成,并调用向glutReshapeFunc()注册的函数。

该函数必须完成下列工作:

Ÿ 

重新建立用作新渲染画布的矩形区域;

定义绘制物体时使用的坐标系。

如:

voidReshape(intw,inth)

glViewport(0,0,(GLsizei)w, 

(GLsizei)h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);

在GLUT内部,将给该函数传递两个参数:

窗口被移动或修改大小后的宽度和高度,单位为像素。

glViewport()调整像素矩形,用于绘制整个窗口。

接下来三个函数调整绘图坐标系,使左下角位置为(0, 

0),右上角为(w,h)。

#include<

voidLineDDA(intx0,inty0,intx1,inty1/*,intcolor*/)

x,dy,dx,y;

floatm;

dx=x1-x0;

dy=y1-y0;

m=dy/dx;

y=y0;

glColor3f(1.0f,1.0f,0.0f);

glPointSize

(1);

for(x=x0;

x<

=x1;

x++)

glVertex2i(x,(int)(y+0.5));

y+=m;

voidmyDisplay(void)

glRectf(25.0,25.0,75.0,75.0);

glPointSize(5);

glVertex2f(0.0f,0.0f);

LineDDA(0,0,200,300);

glBegin(GL_LINES);

glVertex2f(100.0f,0.0f);

glVertex2f(180.0f,240.0f);

voidInit()

glShadeModel(GL_FLAT);

intmain(intargc,char*argv[])

argc,argv);

glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);

glutInitWindowPosition(100,100);

glutInitWindowSize(400,400);

HelloWorld!

Init();

glutReshapeFunc(Reshape);

return0;

glShadeModel选择平坦或光滑渐变模式。

GL_SMOOTH为缺省值,为光滑渐变模式,GL_FLAT为平坦渐变模式。

扩展:

平滑直线绘制

math.h>

voiddisplay(){

glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_LINE_SMOOTH);

glHint(GL_LINE_SMOOTH,GL_NICEST);

glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

glLineWidth

(1);

glBegin(GL_LINES);

for(inti=0;

i<

180;

i++){

glVertex2f(0,0);

glVertex2f(0.5*cos(2*i*3.14159/180),0.5*sin(2*i*3.14159/180));

}

glEnd();

glutSwapBuffers();

intmain(intargc,char*argv[])

glutInit(&

glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);

glutInitWindowSize(1000,480);

glutInitWindowPosition(50,50);

glutCreateWindow("

ModelTransform"

glutDisplayFunc(display);

glClearColor(0,0,0,0);

glShadeModel(GL_SMOOTH);

glutMainLoop();

return0;

效果:

思考:

为什么圆不圆?

实验3线段裁剪

了解二维图形裁剪的原理(点的裁剪、直线的裁剪、多边形的裁剪),利用VC+OpenGL实现直线的裁剪算法。

理解直线裁剪的原理(Cohen-Surtherland算法)

利用VC+OpenGL实现直线的编码裁剪算法,在屏幕上用一个封闭矩形裁剪任意一条直线。

调试、编译、修改程序。

编码裁剪算法的主要思想是:

对于每条线段,分为三种情

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1