OpenGL中不设置模型,投影,视口,所绘制的几何图形的坐标只能是-1到1(X轴向右,Y轴向上,Z轴垂直屏幕向外)。

产生目标场景的过程类似于用照相机进行拍照:

(1)把照相机固定在三角架上,并让他对准场景

从不同位置观察场景(视图变换)

(2)对场景进行安排,使各个物体在照片中的位置是我们所希望的

移动,旋转或者放大缩小场景中的物体(模型变换)

(3)选择照相机镜头,并调整放大倍数(调焦)

显示物体时,可以选择物体是如何投影到屏幕上(投影变换)

(4)确定照片的大小,放大照片还是缩小照片

把图形画下来,是要占据整个屏幕还是屏幕的一部分(视口变换)

  OpenGL中的各种转换是通过矩阵运算实现的,具体的说,就是当发出一个转换命令时,该命令会生成一个4X4阶的转换矩阵(OpenGL中的物体坐标一律采用齐次坐标,即(x, y, z, w),故所有变换矩阵都采用4X4矩阵),当前矩阵与这个转换矩阵相乘,从而生成新的当前矩阵。例如,对于顶点坐标v ,转换命令通常在顶点坐标命令之前发出,若当前矩阵为C,转换命令构成的矩阵为M,则发出转换命令后,生成的新的当前矩阵为CM,这个矩阵再乘以顶点坐标v,从而构成新的顶点坐标CMv。上述过程说明,程序中绘制顶点前的最后一个变换命令最先作用于顶点之上。这同时也说明,OpenGL编程中,实际的变换顺序与指定的顺序是相反的。

  

一、视点变换

void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble upx,GLdouble upy,GLdouble upz);
  该函数定义了视点矩阵,并用该矩阵乘以当前矩阵。eyex,eyey,eyez定义了视点的位置;centerx、centery和centerz变量指定了观测点(目标)的位置,该点通常为相机所瞄准的场景中心轴线上的点;upx、upy、upz变量指定了向上向量的方向。
二、模型变换,视图变换,在Opengl中统一称为“模型视图变换”, 对应的矩阵统一称为模型视图矩阵, glModeView();
  模型、视图变换在进行模型视图变换之前,应先设置当前操作的矩阵为"模型视图矩阵",通过设置glMatrixMode( GL_MODELVIEW),
  在进行变换之前把当前矩阵设置为单位矩阵glLoadIdentity();如果不进行单位化,所有的后续操作都是在当前矩阵的前提下进行的。
1、模型平移
 
glTranslate{fd}(TYPE x,TYPE y,TYPE z);
  该函数用指定的x,y,z值沿着x轴、y轴、z轴平移物体(或按照相同的量值移动局部坐标系)
2、模型旋转
glRotate{fd}(TYPE angle,TYPE x,TYPE,y,TYPE z);
  该函数中第一个变量angle制定模型旋转的角度,单位为度,后三个变量表示以原点(0,0,0)到点(x,y,z)的连线为轴线逆时针旋转物体。例如,glRotatef(45.0,0.0,0.0,1.0)的结果是绕z轴旋转45度。
3、模型缩放
glScale{fd}(TYPE x,TYPE y,TYPE z);
  该函数可以对物体沿着x,y,z轴分别进行放大缩小。函数中的三个参数分别是x、y、z轴方向的比例变换因子(x,y,z 三个参数表示在 x, y ,z 轴放大或者缩小的比例)。缺省时都为1.0,即物体没变化。(小于1表示缩小,大于1表示放大)程序中物体Y轴比例为2.0,其余都为1.0,就是说将立方体变成长方体。
 
三、投影变换
  投影变换的目的就是定义一个视景体,使得视景体外多余的部分裁剪掉,最终进入图像的只是视景体内的有关部分。投影包括透视投影(Perspective Projection)正视投影(Orthographic Projection)两种。

(1)OpenGL透视投影函数有两个

1. 其中函数glFrustum()的原型为:

void glFrustum(;GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);

 它创建一个透视视景体。其操作是创建一个透视投影矩阵,并且用这个矩阵乘以当前矩阵。这个函数的参数只定义近裁剪平面的左下角点和右上角点的三维空间坐标,即(left,bottom,-near)和(right,top,-near);最后一个参数far是远裁剪平面的Z负值,其左下角点和右上角点空间坐标由函数根据透视投影原理自动生成。near和far表示离视点的远近,它们总为正值。

2、glPerspective( GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far)

创建一个表示对称透视视图平截头体的矩阵,并把它与当前矩阵相乘。fovy是YZ平面上视野的角度,范围【0,180】。aspect是这个平截头体的纵横比,也就是宽度除于高度。near和far值分别是观察点与近侧裁剪平面以及远侧裁剪平面的距离(沿Z轴负方向)这两个值都是正的。

正投影的主要函数

1、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)。注意,near和far都是正值。只有在视景体里的物体才能显示出来,我感觉你最后两个参数取得有点问题,而且你改成0,0后,视景体深度没有了,整个视景体都被压成个平面了,当然就显示不正确了。

3、glOrtho2D( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)

创建一个表示把二维坐标投影到屏幕上的矩阵,并把当前矩阵与它相乘,裁剪区域为矩形。

把像素绘制到屏幕上glViewport()定义视口,前两个参数最左下方,后两个参数宽度和高度。

4、视口变换

在窗口中定义一个像素矩形,最终的图像将映射到这个矩形中。

glViewport( Glint x, Glint y, GLsizei width, GLsizei height );XY指定了视口的左下角,WH指定了视口的高度和宽度。在默认情况下,视口的初始值是(0,0,winwidth,winheight)。

视口的纵横比一般和视景体的纵横比相同。当窗口的大小发生变化时,并不会自动影响视口,应用程序应该检测窗口大小改变事件。

六、矩阵栈的操作

1.模型转换与视点转换:

void glLoadMatrix{fd}(const TYPE *m)

   设置当前矩阵中的元素值。函数参数*m是一个指向16个元素(m0, m1, ..., m15)的指针,这16个元素就是当前矩阵M中的元素,其排列方式如下

  M = | m0 m4 m8 m12 |
    | m1 m5 m9 m13 |
    | m2 m6 m10 m14 |
    | m3 m7 m11 M15 |

  矩阵以列作为主要的排列方式。

2. void glMultMatrix{fd}(const TYPE *m)

  用当前矩阵去乘*m所指定的矩阵,并将结果存放于*m中。当前矩阵可以是用glLoadMatrix() 指定的矩阵,也可以是其它矩阵变换函数的综合结果。

  该方法用任意矩阵去乘以当前矩阵,该方法不返回任何值。

  说明:

 The glMultMatrix function multiplies the current matrix by the one specified in m. That is, if M is the current matrix and T is the matrix passed to glMultMatrix, then M is replaced with M • T.

  如果M是当前矩阵, T是该方法中的参数指定的矩阵。则该方法调用之后,当前矩阵变为 M = M * T.

The current matrix is the projection matrix, modelview matrix, or texture matrix, determined by the current matrix mode (see glMatrixMode).

The m parameter points to a 4x4 matrix of single-precision or double-precision floating-point values stored in column-major order. That is, the matrix is stored as shown in the following image.

3. glMatrixMode

  指定当前矩阵类型:可以设置以下矩阵类型。

  

Value Meaning
GL_MODELVIEW

Applies subsequent matrix operations to the modelview matrix stack.【模型视图矩阵】

GL_PROJECTION

Applies subsequent matrix operations to the projection matrix stack.【投影矩阵】

GL_TEXTURE

Applies subsequent matrix operations to the texture matrix stack.【纹理矩阵】

4.矩阵堆栈操作:glPushMatrix(),glPopMatrix()
说明,OpenGL中有两个最基本的矩阵,模型视景矩阵和投影矩阵,它们都有相应的矩阵堆栈,这些矩阵的当前值就是在矩阵堆栈中的最顶层元素。对于转换操作,发出转换命令后生成的新的当前矩阵就存储在矩阵堆栈中,因此,我们可以利用矩阵堆栈存储当前值,并在需要的时候将当前值弹出堆栈。
举例来说,我们现在需要绘制一个自行车,设置自行车的两个轮子相对于坐标原点是对称的。我们可以这样绘制:将坐标系原点移动到前车轮中心,然后进行绘制,完成后,计算前车轮中心到后车轮中心的距离,并将坐标系原点移动到后车轮中心,再绘制后车轮。显然,这种绘制顺序是不科学的,如果需要绘制更多的对称物体,那么这种计算量会非常大,而且容易产生错误。
这种问题,我们使用矩阵堆栈可以很容易得到解决。在绘制前车轮之前,将当前矩阵保存在矩阵堆栈中,然后将坐标原点移动到前车轮中心,绘制前车轮,绘制结束后,将保存的当前矩阵弹出矩阵堆栈,这时堆栈顶部的矩阵仍为原坐标系,下一步只需相对于原坐标系移动相应距离到后车轮进行绘制,这样,所有物体的位置都是相对于原坐标系进行设置,程序计算量得到缩减,而且不容易出错误。

 
 

OpenGL模型视图变换、投影变换、视口变换的理解的更多相关文章

  1. 简单理解OpenGL模型视图变换

    前几天学习了OpenGL的绘图原理(其实就是坐标的不停变换变换),看到网上有个比较好的例程,于是学习了下,并在自己感兴趣的部分做了注释. 首先通过glMatrixMode(GL_MODELVIEW)设 ...

  2. [计算机图形学]视图变换:MVP变换、视口变换

    目录 一.MVP变换 1. 模型变换 1.1 缩放矩阵 1.2 旋转矩阵 1.3 平移矩阵 2. 视角变换 3. 投影变换 二.Viewport变换 一.MVP变换 MVP变换是模型变换(M).视角变 ...

  3. OpenGL 模型视图投影矩阵 仿射矩阵

    矩阵基础知识 要对矩阵进行运算,必须先要了解矩阵的计算公式,这个知识的内容涉及到了线性代数. 我们知道在Cocos2dx中,有关于平移,旋转,缩放等等操作,都必须要进行矩阵的乘法. 只需要一张图就能理 ...

  4. OpenGL的视图变换、模型变换、投影变换、视口变换

    产生目标场景的过程类似于用照相机进行拍照: (1) 把照相机固定在三角架上,并让他对准场景从不同位置观察场景(视图变换) gluLookAt (2) 对场景进行安排,使各个物体在照片中的位置是我们所希 ...

  5. OpenGl学习笔记3之模型变换、视图变换、投影变换、视口变换介绍

    模型变换.视图变换.投影变换.视口变换介绍 opengl中存在四种变换,分别是模型变换,视图变换,投影变换,视口变换.这四种变换是图形渲染的基本操作,实质上这四种变换都是由矩阵乘法表示(这些操作都是由 ...

  6. WebGL简易教程(五):图形变换(模型、视图、投影变换)

    [toc] 1. 概述 通过之前的教程,对WebGL中可编程渲染管线的流程有了一定的认识.但是只有前面的知识还不足以绘制真正的三维场景,可以发现之前我们绘制的点.三角形的坐标都是[-1,1]之间,Z值 ...

  7. OpenGL学习笔记4——模型视图变换

    以日月地为例的一个模型视图变换.绕了比较多的弯路,下面是几个注意点总结. 注意点: 1.GL函数对模型的操作是基于当前局部坐标系,即模型坐标系而非世界坐标系,二者只在第一次初始化完毕之后才重合: 2. ...

  8. OpenGL(五) 三维变换之模型视图矩阵

    计算机三维图形学中,一个基本的任务是如何描述三维空间中一个物体位置的变化,也就是如何 描述物体的运动.通常情况下,物体位置的变化包含三个基本的变化:平移.旋转和缩放,物体的运动也可以用这三个基本的运动 ...

  9. WebGL或OpenGL关于模型视图投影变换的设置技巧

    目录 1. 具体实例 2. 解决方案 1) Cube.html 2) Cube.js 3) 运行结果 3. 详细讲解 1) 模型变换 2) 视图变换 3) 投影变换 4) 模型视图投影矩阵 4. 存在 ...

随机推荐

  1. 组队打代码 !!! ——Alpha项目冲刺

    Alpha阶段 - 博客链接合集 队伍名称: 代码那些事儿 学号 姓名 211606320 刘佳 211606313 李佳 211606303 陈水莲 211606302 曾丽丽 211606338 ...

  2. HTML 练习 做简历表

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. node.js实时编译,不需要重启

    npm -g install supervisor 全局安装这个,然后编译依一次文件就可以了,之后修改这个文件不用编译也可以了

  4. 新手C#SQL Server使用记录2018.08.10

    主键(PrimaryKey):主键就是每个数据行(记录)的唯一标识,不会有重复值的列(字段)才能当做主键.一个表可以没有主键,但是这样会很难处理表,因此一般情况表都要设置主键. 主键有两张选用策略,分 ...

  5. Swagger与SpringMVC整合

    依赖管理   在整合之前,需要把所有使用到的依赖包全部引入.网上很多文章只是简单告诉读者引入swagger-springmvc-1.0.2.jar包,但是随后你发现这远远不够,还需要很多包,如下所示: ...

  6. Majority Element(ARRAY-BINARY SEARCH)

    QUESTION Given an array of size n, find the majority element. The majority element is the element th ...

  7. mongo远程登录

    1. 进入数据库: use admin db.addUser("foo","foo"); ps:高版本用db.createUser创建. 2. 改配置 如/et ...

  8. 【校招面试 之 C/C++】第3题 为什么要内存对齐?以及内存对齐的方式

    1.为什么要进行内存对? 参考:https://blog.csdn.net/a369000753/article/details/51188915 所谓内存对齐,是为了让内存存取更有效率而采用的一种编 ...

  9. maven的配置及仓库的配置

    1.maven的配置 1.1.注意:电脑上需要安装jdk. 1.2.配置MAVEN_HOME,再在path中配置到bin这一层. (1)配置MAVEN_HOME:我的电脑--->右击---> ...

  10. LFS(Linux From Scratch)学习

    一.简介 LFS──Linux from Scratch,就是一种从网上直接下载源码,从头编译LINUX的安装方式.它不是发行版,只是一个菜谱,告诉你到哪里去买菜(下载源码),怎么把这些生东西( ra ...