open gl 三维图形设计与制作

22
Open GL Open GL 三三三三三三三三三 三三三三三三三三三 三三三三三三 三三三三三三 三三三三三三三三三 三三三三三三三三三 三三三 三三三

Upload: ralph-alvarez

Post on 03-Jan-2016

58 views

Category:

Documents


0 download

DESCRIPTION

Open GL 三维图形设计与制作. 上海交通大学 机械与动力工程学院 赵现朝. 第三章 OpenGL 中的坐标变换. OpenGL 变换是本篇的重点内容,它包括计算机图形学中最基本的三维变换,即视点 - 模型变换、投影变换、裁剪变换、视口变换,以及针对 OpenGL 的特殊变换概念理解和用法,如相机模拟、矩阵堆栈等。学好了这章,才开始真正走进三维世界。 3.1 坐标变换的基本概念 运行例子 Sample3_1.dsw ,引出各种变换的概念。 3.1.1 视点变换 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Open GL 三维图形设计与制作

Open GLOpen GL三维图形设计与制作三维图形设计与制作

Open GLOpen GL三维图形设计与制作三维图形设计与制作

上海交通大学上海交通大学机械与动力工程学院机械与动力工程学院

赵现朝赵现朝

Page 2: Open GL 三维图形设计与制作

第三章 第三章 OpenGLOpenGL 中的坐标变换中的坐标变换 OpenGLOpenGL 变换是本篇的重点内容,它包括计算机图形学变换是本篇的重点内容,它包括计算机图形学中最基本的三维变换,即视点中最基本的三维变换,即视点 -- 模型变换、投影变换、裁剪变模型变换、投影变换、裁剪变换、视口变换,以及针对换、视口变换,以及针对 OpenGLOpenGL 的特殊变换概念理解和用法,的特殊变换概念理解和用法,如相机模拟、矩阵堆栈等。学好了这章,才开始真正走进三维如相机模拟、矩阵堆栈等。学好了这章,才开始真正走进三维世界。世界。

3.1 3.1 坐标变换的基本概念坐标变换的基本概念 运行例子 运行例子 Sample3_1.dsw Sample3_1.dsw ,引出各种变换的概念。,引出各种变换的概念。

3.1.1 3.1.1 视点变换视点变换 相当于照相时改变相机的位置和拍摄方向。默认情况下,相相当于照相时改变相机的位置和拍摄方向。默认情况下,相机和拍摄物体都位于场景的原点位置,并且相机的初始方向指机和拍摄物体都位于场景的原点位置,并且相机的初始方向指向向 zz 轴负方向。例程中用轴负方向。例程中用 glTranslatef( )glTranslatef( ) 来进行视点变换操作,来进行视点变换操作,该该

Page 3: Open GL 三维图形设计与制作

函数三个参数分别指定了相机沿函数三个参数分别指定了相机沿 xx 、、 yy 和和 zz 轴平轴平移量的大小。移量的大小。

3.1.2 3.1.2 模型变换模型变换 模型变换相当于确定物体在场景中的摆放方式。模型变换相当于确定物体在场景中的摆放方式。

可以对模型进行平移、旋转以及缩放。缩放用的可以对模型进行平移、旋转以及缩放。缩放用的指令为 指令为 glScalefglScalef (),三个参数分别说明沿三个(),三个参数分别说明沿三个坐标轴方向缩放的比例。坐标轴方向缩放的比例。

模型变换和视点变换的对偶性。模型变换和视点变换的对偶性。3.1.33.1.3 投影变换投影变换 投影变换相当于选择相机的镜头,它决定观察范投影变换相当于选择相机的镜头,它决定观察范

围的大小和物体投影到屏幕上的方式。围的大小和物体投影到屏幕上的方式。 OpenGLOpenGL提供了两种基本的投影变换模式,即透视投影方提供了两种基本的投影变换模式,即透视投影方

Page 4: Open GL 三维图形设计与制作

式和正射投影方式。式和正射投影方式。 透视投影透视投影——“——“近大远小”;创建逼真的三维 近大远小”;创建逼真的三维 图像;图像; 正射投影正射投影————不变大小直接投影到屏幕。不变大小直接投影到屏幕。 特殊场合使用,比如建筑蓝图特殊场合使用,比如建筑蓝图

设计,设计, CADCAD 等。等。上例中的函数,上例中的函数, glFrustumglFrustum ()() ..3.1.4 3.1.4 视口变换视口变换 相当于确定照片的大小,指定图像在计算机屏幕上所占的相当于确定照片的大小,指定图像在计算机屏幕上所占的

区域。 区域。 指令:指令: glViewport();glViewport();

3.1.5 3.1.5 通用矩阵操作命令通用矩阵操作命令 多数变换都对应于相应的变换矩阵,多数变换都对应于相应的变换矩阵, OpenGLOpenGL 就是实现就是实现

将物体的各个顶点通过各种变换矩阵的作用映射到屏幕上将物体的各个顶点通过各种变换矩阵的作用映射到屏幕上的过程。所以的过程。所以 OpenGLOpenGL 提供了一些必不可少的通用矩阵操提供了一些必不可少的通用矩阵操作命令。作命令。

void glMatrixModevoid glMatrixMode (( Glenum modeGlenum mode ))————选择变换选择变换什么矩阵(模型变换什么矩阵(模型变换 GL_MODELVIEWGL_MODELVIEW 、投影、投影GL_PROJECTIONGL_PROJECTION 、纹理、纹理 GL_TEXTUREGL_TEXTURE )) ..

Page 5: Open GL 三维图形设计与制作

void glLoadIdentity(void)——void glLoadIdentity(void)—— 置为单位阵;置为单位阵; void glLoadMatrix{fd}(const Gldouble *m)void glLoadMatrix{fd}(const Gldouble *m)

void glMultMatrix{fd}(const Gldouble *m)void glMultMatrix{fd}(const Gldouble *m)

3.2 3.2 三维图形显示流程三维图形显示流程

世界坐标系中的三维物体

三维几何变换

投影变换

裁剪变换

视口变换

Page 6: Open GL 三维图形设计与制作

3.3 3.3 视点-模型变换视点-模型变换 两者是对偶的,在几何学中统一为几何变两者是对偶的,在几何学中统一为几何变

换。换。3.1.1 3.1.1 平移变换平移变换 相机和物体初始位置一般都位于坐标系相机和物体初始位置一般都位于坐标系

原点,相机指向原点,相机指向 zz 轴负向,一般都需要通轴负向,一般都需要通过坐标平移变换才能看到物体。过坐标平移变换才能看到物体。

Page 7: Open GL 三维图形设计与制作

语句:语句: void glTranslate{fd}(void glTranslate{fd}(TYPE x, TYPE y, TYPE TYPE x, TYPE y, TYPE

z,z,))

例如 例如 glTranslatef(-3.0, 0.0, 0.0); xglTranslatef(-3.0, 0.0, 0.0); x 负向平移负向平移

3.3.2 3.3.2 旋转变换旋转变换语句:语句: void glRotate{fd} }(void glRotate{fd} }(TYPE angle, TYPE TYPE angle, TYPE

x x ,, TYPE y, TYPE z,TYPE y, TYPE z,)) ;;结合结合 Sample3_1Sample3_1 举例演示举例演示

Page 8: Open GL 三维图形设计与制作

3.3.3 3.3.3 缩放和镜像变换缩放和镜像变换语句:语句: void glScale{fd} void glScale{fd} ((TYPE x, TYPE y, TYPE z,TYPE x, TYPE y, TYPE z,))

当参数值为当参数值为 -1.0-1.0 时,表示将物体关于对应的轴线进行镜像。时,表示将物体关于对应的轴线进行镜像。3.3.4 3.3.4 组合变换组合变换 平移和旋转等变换的组合,它们都是通过矩阵的乘法来平移和旋转等变换的组合,它们都是通过矩阵的乘法来

实现的,但矩阵乘法是不满足交换率的,因此变换的顺序实现的,但矩阵乘法是不满足交换率的,因此变换的顺序不同,产生的效果也不同。不同,产生的效果也不同。

比如物体先绕比如物体先绕 ZZ 轴转轴转 4545度再沿度再沿 XX 轴平移轴平移 55 个单位,与个单位,与先沿先沿 XX 轴平移轴平移 55 个单位,再绕个单位,再绕 ZZ 轴转轴转 4545度的结果是完全度的结果是完全不同的。不同的。

Page 9: Open GL 三维图形设计与制作

3.4 3.4 投影变换投影变换 投影变换是一种很关键的图形变投影变换是一种很关键的图形变

换,换, OpenGL OpenGL 中只提供了两种投影方式,中只提供了两种投影方式,一种是正射投影,另一种是透视投影。不一种是正射投影,另一种是透视投影。不管是调用哪种投影函数,为了避免不必要管是调用哪种投影函数,为了避免不必要的变换,其前面必须加上以下两句:的变换,其前面必须加上以下两句:

glMatrixMode(GL_PROJECTION);glMatrixMode(GL_PROJECTION);

glLoadIdentity();glLoadIdentity();

事实上,投影变换的事实上,投影变换的目的目的就是定义一个就是定义一个视景体,使得视景体外多余的部分裁剪掉,视景体,使得视景体外多余的部分裁剪掉,最终图像只是视景体内的有关部分。本节最终图像只是视景体内的有关部分。本节将详细讲述投影变换的概念以及用法。将详细讲述投影变换的概念以及用法。

Page 10: Open GL 三维图形设计与制作

3.4.13.4.1 透视投影透视投影 透视投影符合人们心理习惯,即离视点透视投影符合人们心理习惯,即离视点

近的物体大,离视点远的物体小,远到极近的物体大,离视点远的物体小,远到极点即为消失,成为灭点。它的视景体类似点即为消失,成为灭点。它的视景体类似于一个顶部和底部都被切除掉的棱椎,也于一个顶部和底部都被切除掉的棱椎,也就是棱台。这个投影通常用于动画、视觉就是棱台。这个投影通常用于动画、视觉仿真以及其它许多具有真实性反映的方面。仿真以及其它许多具有真实性反映的方面。OpenGLOpenGL 透视投影函数也有两个,其中函透视投影函数也有两个,其中函数数 glFrustum() glFrustum() ,它所形成的视景体如图所,它所形成的视景体如图所示。示。 nearnear 和和 farfar 表示离视点的远近,它们表示离视点的远近,它们总为正值。总为正值。

Page 11: Open GL 三维图形设计与制作

glFrustum(GLdouble glFrustum(GLdouble leftleft, Gldouble , Gldouble rightright, Gldouble , Gldouble bottombottom, , Gldouble Gldouble toptop, Gldouble , Gldouble nearnear , Gldouble , Gldouble farfar))

Page 12: Open GL 三维图形设计与制作

另一个函数是:void gluPerspective( GLdouble fovy,GLdouble

aspect,GLdouble zNear,GLdouble zFar); 它也创建一个对称透视视景体,但它的参数定义与前面的不同,如图所示。其操作是创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵。参数 fovy 定义视野在 X-Z 平面的角度,范围是 [0.,180.] ;参数 aspect 是投影平面宽度与高度的比率;参数 zNear 和 Far 分别是远近裁剪面沿 Z 负轴到视点的距离,它们总为正值。

Page 13: Open GL 三维图形设计与制作

3.4.2 3.4.2 正射投影正射投影 (Orthographic Projection)(Orthographic Projection)

    正射投影又叫平行投影。这种投影的视景体正射投影又叫平行投影。这种投影的视景体是一个矩形的平行管道,也就是一个长方体,如是一个矩形的平行管道,也就是一个长方体,如图所示。正射投影的最大一个特点是无论物体距图所示。正射投影的最大一个特点是无论物体距离相机多远,投影后的物体大小尺寸不变。这种离相机多远,投影后的物体大小尺寸不变。这种投影通常用在建筑蓝图绘制和计算机辅助设计等投影通常用在建筑蓝图绘制和计算机辅助设计等方面,这些行业要求投影后的物体尺寸及相互间方面,这些行业要求投影后的物体尺寸及相互间的角度不变,以便施工或制造时物体比例大小正的角度不变,以便施工或制造时物体比例大小正确。确。

Page 14: Open GL 三维图形设计与制作
Page 15: Open GL 三维图形设计与制作

OpenGL 正射投影函数共有两个,一个函数是: void glOrtho(GLdouble left,GLdouble

right,GLdouble bottom,GLdouble top, GLdouble near,GLdouble far)

  它创建一个平行视景体。实际上这个函数的操作是创建一个正射投影矩阵,并且用这个矩阵乘以当前矩阵。其中近裁剪平面是一个矩形,矩形左下角点三维空间坐标是 (left,bottom,-near) ,右上角点是(right,top,-near) ;远裁剪平面也是一个矩形,左下角点空间坐标是 (left,bottom,-far) ,右上角点是(right,top,-far) 。如果没有其他变换,正射投影的方向平行于 Z 轴,且视点朝向 Z 负轴。

这意味着物体在视点前面时 far 和 near 都为负值,物体在视点后面时 far 和 near 都为正值。

Page 16: Open GL 三维图形设计与制作

另一个函数是: void gluOrtho2D(GLdouble left,GLdouble

right,GLdouble bottom,GLdouble top)  它是一个特殊的正射投影函数,主要用于二维图像到二维屏幕上的投影。它的 near 和

far缺省值分别为 -1.0 和 1.0 ,所有二维物体的 Z 坐标都为 0.0 。因此它的裁剪面是一个左

下角点为 (left,bottom) 、右上角点为(right,top) 的矩形。

Page 17: Open GL 三维图形设计与制作

3.5 3.5 视口变换视口变换 运用相机模拟方式,我们很容易理解视口变换就是类似运用相机模拟方式,我们很容易理解视口变换就是类似

于照片的放大与缩小。在计算机图形学中,它的定义是将于照片的放大与缩小。在计算机图形学中,它的定义是将经过几何变换、投影变换和裁剪变换后的物体显示于屏幕经过几何变换、投影变换和裁剪变换后的物体显示于屏幕窗口内指定的区域内,这个区域通常为矩形,称为视窗口内指定的区域内,这个区域通常为矩形,称为视口。口。 OpenGLOpenGL 中相关函数是:中相关函数是:

glViewport(GLint x,GLint y,GLsizei width, GLsizei height); glViewport(GLint x,GLint y,GLsizei width, GLsizei height); 这个函数定义一个视口。函数参数这个函数定义一个视口。函数参数 (x,y)(x,y) 是视口在屏是视口在屏

幕窗口坐标系中的左下角点坐标,参数幕窗口坐标系中的左下角点坐标,参数 widthwidth 和和 heightheight 分分别是视口的宽度和高度。缺省时,参数值即别是视口的宽度和高度。缺省时,参数值即(0,0,winWidth,winHeight)(0,0,winWidth,winHeight) 指的是屏幕窗口的实际尺寸大指的是屏幕窗口的实际尺寸大小。所有这些值都是以象素为单位,全为整型数。小。所有这些值都是以象素为单位,全为整型数。

注意,在实际应用中,视口的长宽比率总是等于视景体注意,在实际应用中,视口的长宽比率总是等于视景体裁剪面的长宽比率。如果两个比率不相等,那么投影后的裁剪面的长宽比率。如果两个比率不相等,那么投影后的图像显示于视口内时会发生变形,如图所示。另外,屏幕图像显示于视口内时会发生变形,如图所示。另外,屏幕窗口的改变一般不明显影响视口的大小。因此,在调用这窗口的改变一般不明显影响视口的大小。因此,在调用这个函数时,最好实时检测窗口尺寸,及时修正视口的大小,个函数时,最好实时检测窗口尺寸,及时修正视口的大小,保证视口内的图像能随窗口的变化而变化,且不变形。保证视口内的图像能随窗口的变化而变化,且不变形。

Page 18: Open GL 三维图形设计与制作
Page 19: Open GL 三维图形设计与制作

3.5 3.5 裁剪变换裁剪变换 在在 OpenGLOpenGL 中,空间物体的三维裁剪变换包括两个部中,空间物体的三维裁剪变换包括两个部分:视景体裁剪和附加平面裁剪。视景体裁剪已经包含在分:视景体裁剪和附加平面裁剪。视景体裁剪已经包含在投影变换里,前面已述,这里不再重复。下面简单讲一下投影变换里,前面已述,这里不再重复。下面简单讲一下平面裁剪函数的用法。平面裁剪函数的用法。 除了视景体定义的六个裁剪平面(上、下、左、右、除了视景体定义的六个裁剪平面(上、下、左、右、前、后)外,用户还可自己再定义一个或多个附加裁剪平前、后)外,用户还可自己再定义一个或多个附加裁剪平面,以去掉场景中无关的目标,如图所示。面,以去掉场景中无关的目标,如图所示。

Page 20: Open GL 三维图形设计与制作

附加平面裁剪函数为:附加平面裁剪函数为:  void glClipPlane(GLenum void glClipPlane(GLenum planeplane,Const GLdouble ,Const GLdouble *equation*equation););

函数定义一个附加的裁剪平面。其中参数函数定义一个附加的裁剪平面。其中参数 equationequation指向一个拥有四个系数值的数组,这四个系数分别是裁指向一个拥有四个系数值的数组,这四个系数分别是裁剪平面剪平面 Ax+By+Cz+D=0Ax+By+Cz+D=0 的的 AA 、、 BB 、、 CC 、、 DD 值。因此,值。因此,由这四个系数就能确定一个裁剪平面。参数由这四个系数就能确定一个裁剪平面。参数 planeplane 是是GL_CLIP_PLANEi(i=0,1,...)GL_CLIP_PLANEi(i=0,1,...) ,指定裁剪面号。,指定裁剪面号。 在调用附加裁剪函数之前,必须先启动在调用附加裁剪函数之前,必须先启动glEnable( GL_CLIP_PLANEi)glEnable( GL_CLIP_PLANEi) ,使得当前所定义的裁剪,使得当前所定义的裁剪平面有效;当不再调用某个附加裁剪平面时,可用平面有效;当不再调用某个附加裁剪平面时,可用glDisable(GL_CLIP_PLANEi)glDisable(GL_CLIP_PLANEi) 关闭相应的附加裁剪功能。关闭相应的附加裁剪功能。

Ax+By+Cz+D<0Ax+By+Cz+D<0 的部分将被裁剪掉。的部分将被裁剪掉。

Page 21: Open GL 三维图形设计与制作

3.7 3.7 矩阵堆栈的使用矩阵堆栈的使用

学过计算机的人也许都知道这个使用频学过计算机的人也许都知道这个使用频率极高的名词率极高的名词——“——“堆栈”。固名思义,堆栈堆栈”。固名思义,堆栈指的是一个顶部打开底部封闭的柱状物体,指的是一个顶部打开底部封闭的柱状物体,通常用来存放常用的东西。这些东西从顶部通常用来存放常用的东西。这些东西从顶部依次放入,但取出时也只能从顶部取出,即依次放入,但取出时也只能从顶部取出,即“先进后出,后进先出”。在计算机中,它“先进后出,后进先出”。在计算机中,它常指在内存中开辟的一块存放某些变量的连常指在内存中开辟的一块存放某些变量的连续区域。因此,续区域。因此, OpenGLOpenGL 的矩阵堆栈指的就的矩阵堆栈指的就是内存中专门用来存放矩阵数据的某块特殊是内存中专门用来存放矩阵数据的某块特殊区域。区域。

Page 22: Open GL 三维图形设计与制作

矩阵堆栈对复杂模型运动过程中的多个变换操作之间的联系与独立十分有利。因为所有矩阵操作函数如glLoadMatrix() 、 glMultMatrix() 、 glLoadIdentity() 等只处理当前矩阵或堆栈顶部矩阵,这样堆栈中下面的其它矩阵就不受影响。堆栈操作函数有以下两个: void glPushMatrix(void); void glPopMatrix(void); 第一个函数表示将所有矩阵依次压入堆栈中,顶部矩阵是第二个矩阵的备份;压入的矩阵数不能太多,否则出错。第二个函数表示弹出堆栈顶部的矩阵,令原第二个矩阵成为顶部矩阵,接受当前操作,故原顶部矩阵被破坏;矩阵堆栈操作与压入矩阵的顺序刚好相反,编程时要特别注意矩阵操作的顺序。