OpenGL中的投影使用


在OpenGL中,投影矩阵指定了可视区域的大小和形状。对于正投影与透视投影这两种不同的投影类型,它们分别有各自的用途。

正投影

它适用于2D图形,如文本、建筑画图等。在它的应用场合,我们希望在屏幕上展示准确的物体大小和度量。

透视投影

它使用透视除法,对距离观察者较远的物体进行缩短和收缩。由于可视区域前端和后端的宽度度量方法并不同样,导致两个逻辑大小同样的物体,当它们分别位于可视区域的前面和后面时,前者看上去要比后者大一些。

下图展示了平截头体(frustum)所定义的透视投影,它的观察方向是从狭窄端到宽阔端。工具函数gluPerspective能够方便的定义一个平截头体:

void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far);

參数 fovy表示垂直方向的视野角度,aspect表示宽度与高度的纵横比,near与far表示近端和远端裁剪平面之间的距离。

以下的代码设置使用了透视投影,展示了一个由太阳(黄色)、地球(红色)、月亮(灰色)三者构成的运动系统。这是一个经典的嵌套变换的样例,我们使用矩阵堆栈将一个物体依据还有一个物体进行变换,执行结果如图所看到的:

/* 程序清单 4-3

* 2014/5/18

*/

#include
<glut.h>

#include
<math.h>

// 旋转的步进值

static float fMoonRot =0.0f;

static float fEarthRot= 0.0f;

// 设置渲染状态

void SetupRC()

{

// 设置清除窗体的颜色(黑色背景)

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

// 设置画图颜色为绿色

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

// 打开深度測试

glEnable(GL_DEPTH_TEST);

}

// 绘制场景(显示回调函数)

void RenderScene()

{

// 用当前的清除颜色清除窗体

glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);

// 保存矩阵状态(模型视图矩阵)

glMatrixMode(GL_MODELVIEW);

glPushMatrix();

// 平移坐标系,注意是相对于视觉坐标的位置

glTranslatef(0.0f, 0.0f, -300.0f);

// 绘制太阳

glColor3ub(255, 255, 0);

glutSolidSphere(15.0f, 15, 15);

// 旋转坐标系,累加效果

glRotatef(fEarthRot, 0.0f, 1.0f, 0.0f);

// 绘制地球

glColor3ub(255, 0, 0);

// 平移坐标系,累加效果

glTranslatef(105.0f, 0.0f, 0.0f);

// 设置地球的旋转步进

fEarthRot += 5.0f;

if(fEarthRot > 360.0f) {

fEarthRot = 0.0f;

}

glutSolidSphere(15.0f, 15, 15);

// 绘制月球

glColor3ub(200, 200, 200);

// 旋转坐标系,累加效果

glRotatef(fMoonRot, 0.0f, 1.0f, 0.0f);

// 平移坐标系,累加效果

glTranslatef(30.0f, 0.0f, 0.0f);

// 设置月亮的旋转步进

fMoonRot += 15.0f;

if(fMoonRot > 360.0f) {

fMoonRot = 0.0f;

}

glutSolidSphere(6.0f, 15, 15);

// 恢复矩阵状态(当前坐标系与视觉坐标重合)

glPopMatrix();

// 交换缓冲区,显示画面

glutSwapBuffers();

}

// 当窗体大小改变时由GLUT函数库调用

void ChangeSize(GLsizei w, GLsizei h)

{

// 窗体的纵横比

GLfloat fAspect;

if (0== h) {

h = 1;

}

// 将视口设置为窗体的大小

glViewport(0, 0, w, h);

// 计算窗体的纵横比

fAspect = (GLfloat)w / (GLfloat)h;

// 设置当前操作的矩阵为投影矩阵

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

度视野,近、远平面为1.0和425.0

gluPerspective(45.0f,fAspect, 1.0, 425.0);

// 设置当前操作的矩阵为模型视图矩阵

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

次窗体重绘事件

void TimerFunc(intvalue)

{

glutPostRedisplay();

glutTimerFunc(100, TimerFunc, 1);

}

int main(int argc,char *argv[])

{

// 传递命令行參数,并对GLUT函数库进行初始化

glutInit(&argc, argv);

// 设置创建窗体时的显示模式(双缓冲区、RGB颜色模式)

glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);

// 设置窗体的初始大小

glutInitWindowSize(480, 320);

// 创建窗体

glutCreateWindow("Bounce");

// 设置显示回调函数

glutDisplayFunc(RenderScene);

// 设置当窗体的大小发生变化时的回调函数

glutReshapeFunc(ChangeSize);

// 设置计时器函数

glutTimerFunc(100, TimerFunc, 1);

// 设置渲染状态

SetupRC();

// 启动GLUT框架的执行,一经调用便不再返回,直到程序终止

glutMainLoop();

return0;

}

OpenGL中的投影使用的更多相关文章

  1. OpenGL中的拾取模式( Picking)

    1. Opengl中的渲染模式有三种:(1)渲染模式,默认的模式:(2)选择模式, (3)反馈模式.如下 GLint glRenderMode(GLenum mode) mode可以选取以下三种模式之 ...

  2. CSharpGL(6)在OpenGL中绘制UI元素

    CSharpGL(6)在OpenGL中绘制UI元素 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo,更适合入 ...

  3. OpenGL中各种坐标系的理解[转]

    OPENGL坐标系可分为:世界坐标系和当前绘图坐标系. 世界坐标系:在OpenGL中,世界坐标系是以屏幕中心为原点(0, 0, 0),且是始终不变的.你面对 屏幕,你的右边是x正轴,上面是y正轴,屏幕 ...

  4. OpenGL中glPushMatrix和glPopMatrix的原理

    glPushMatrix.glPopMatrix操作事实上就相当于栈里的入栈和出栈. 很多人不明确的可能是入的是什么,出的又是什么. 比如你当前的坐标系原点在你电脑屏幕的左上方.如今你调用glPush ...

  5. OpenGL中glRotatef()函数究竟对矩阵做了什么

    OpenGL中glRotatef()函数究竟对矩阵做了什么 我们知道OpenGL中维持着两套矩阵,一个是模型视图矩阵(model view matrix),另一个是投影矩阵(projection ma ...

  6. 【opengl】OpenGL中三维物体显示在二维屏幕上显示的变换过程

    转自:http://blog.sina.com.cn/s/blog_957b9fdb0100zesv.html 为了说明在三维物体到二维图象之间,需要经过什么样的变换,我们引入了相机(Camera)模 ...

  7. OpenGL中glFrustum()和gluPerspective()的相互转换

    OpenGL中在窗口的大小发生变化的时候会触发resize()函数,这里会传入一个新的宽和高,在resize()函数中我们会设置投影矩阵,在可以使用OpenGL基础函数glFrustum()函数和gl ...

  8. OpenGL中各种坐标系的理解

    转载:https://blog.csdn.net/meegomeego/article/details/8686816 OPENGL坐标系可分为:世界坐标系和当前绘图坐标系. 世界坐标系以屏幕中心为原 ...

  9. opengl中场景变换|2D与3D互转换(转)

    opengl中场景变换|2D与3D互转换 我们生活在一个三维的世界——如果要观察一个物体,我们可以: 1.从不同的位置去观察它.(视图变换) 2.移动或者旋转它,当然了,如果它只是计算机里面的物体,我 ...

随机推荐

  1. POJ 1905 Expanding Rods 二分答案几何

    题目:http://poj.org/problem?id=1905 恶心死了,POJ的输出一会要lf,一会要f,而且精度1e-13才过,1e-12都不行,错了一万遍终于对了. #include < ...

  2. python加密解密

    from Crypto.Cipher import Blowfish  #easy_install pycrypto可以获得

  3. WebApp触屏版网站开发要点

    所谓的触屏版网站其实也是WebApp的一种展示形式,主要是依赖HTML+CSS+Javascript这三个关键因素来实现,相比较原生客户端程序来说优点就是开发周期短.升级简单.维护成本低,因为从根本上 ...

  4. 【HDU 1133】 Buy the Ticket (卡特兰数)

    Buy the Ticket Problem Description The "Harry Potter and the Goblet of Fire" will be on sh ...

  5. [转贴]sizeof 和strlen的区别

    1. 编译时计算运算符sizeof,可用类型或变量做参数,计算占用内存的大小.sizeof后若是类型必须加括弧,若是变量名可不加括弧.sizeof(x)可用来定义数组维数.如:printf(" ...

  6. VC下载文件显示进度条

    VC下载文件显示进度条 逗比汪星人2009-09-18上传   by Koma http://blog.csd.net/wangningyu http://download.csdn.net/deta ...

  7. windows桌面添加右键环境

    1.组合键win + R,输入regedit,回车   打开注册表编辑器 2.找到目录中[HKEY_CLASSES_ROOT\Directory\Background\shell]对其右键,新建一个项 ...

  8. zabbix监控zookeeper

    在github找到一个不错的模板,直接导入使用.下载地址: https://github.com/zhujinhe/zookeeper-zabbix-template 监控项监控类型为外部检查 zab ...

  9. Hive JSON数据处理的一点探索

    背景   JSON是一种轻量级的数据格式,结构灵活,支持嵌套,非常易于人的阅读和编写,而且主流的编程语言都提供相应的框架或类库支持与JSON数据的交互,因此大量的系统使用JSON作为日志存储格式.   ...

  10. TCP三次握手和连接关闭过程详解

    1.建立连接协议(三次握手) (1)客户端发送一个带SYN标志的TCP报文到服务器.这是三次握手过程中的报文1. (2) 服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和S ...