OpenGL中的投影使用
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中的投影使用的更多相关文章
- OpenGL中的拾取模式( Picking)
1. Opengl中的渲染模式有三种:(1)渲染模式,默认的模式:(2)选择模式, (3)反馈模式.如下 GLint glRenderMode(GLenum mode) mode可以选取以下三种模式之 ...
- CSharpGL(6)在OpenGL中绘制UI元素
CSharpGL(6)在OpenGL中绘制UI元素 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo,更适合入 ...
- OpenGL中各种坐标系的理解[转]
OPENGL坐标系可分为:世界坐标系和当前绘图坐标系. 世界坐标系:在OpenGL中,世界坐标系是以屏幕中心为原点(0, 0, 0),且是始终不变的.你面对 屏幕,你的右边是x正轴,上面是y正轴,屏幕 ...
- OpenGL中glPushMatrix和glPopMatrix的原理
glPushMatrix.glPopMatrix操作事实上就相当于栈里的入栈和出栈. 很多人不明确的可能是入的是什么,出的又是什么. 比如你当前的坐标系原点在你电脑屏幕的左上方.如今你调用glPush ...
- OpenGL中glRotatef()函数究竟对矩阵做了什么
OpenGL中glRotatef()函数究竟对矩阵做了什么 我们知道OpenGL中维持着两套矩阵,一个是模型视图矩阵(model view matrix),另一个是投影矩阵(projection ma ...
- 【opengl】OpenGL中三维物体显示在二维屏幕上显示的变换过程
转自:http://blog.sina.com.cn/s/blog_957b9fdb0100zesv.html 为了说明在三维物体到二维图象之间,需要经过什么样的变换,我们引入了相机(Camera)模 ...
- OpenGL中glFrustum()和gluPerspective()的相互转换
OpenGL中在窗口的大小发生变化的时候会触发resize()函数,这里会传入一个新的宽和高,在resize()函数中我们会设置投影矩阵,在可以使用OpenGL基础函数glFrustum()函数和gl ...
- OpenGL中各种坐标系的理解
转载:https://blog.csdn.net/meegomeego/article/details/8686816 OPENGL坐标系可分为:世界坐标系和当前绘图坐标系. 世界坐标系以屏幕中心为原 ...
- opengl中场景变换|2D与3D互转换(转)
opengl中场景变换|2D与3D互转换 我们生活在一个三维的世界——如果要观察一个物体,我们可以: 1.从不同的位置去观察它.(视图变换) 2.移动或者旋转它,当然了,如果它只是计算机里面的物体,我 ...
随机推荐
- MySQL简单使用
1.启动MySQL服务器实际上上篇已讲到如何启动MySQL.两种方法:一是用winmysqladmin,如果机器启动时已自动运行,则可直接进入下一步操作.二是在DOS方式下运行 d:/mysql/bi ...
- QEvent整理归纳:140种类型,29个继承类,7个函数,3种事件来源
140种事件类型: QEvent::None QEvent::AccessibilityDescription QEvent::AccessibilityHelp QEvent::Accessibil ...
- linux权限掩码
我的博客:www.while0.com 主要是在新建文件或目录的时候,控制新文件或目录的默认权限. 文件:新建文件默认没有x权限,故新建文件在umask为000时最大权限是666. 目录:新建目录默认 ...
- C#程序集使用强名字(Strong Name)签名/强名称签名
强名称签名的方法: 强签名: 1. 可以将强签名的dll注册到GAC,不同的应用程序可以共享同一dll. 2. 强签名的库,或者应用程序只能引用强签名的dll,不能引用未强签名的dll,但是未强签名的 ...
- 数学:lucas定理的总结
今天考试的题目中有大组合数取模,不会唉,丢了45分,我真是个弱鸡,现在还不会lucas. 所以今天看了一下,定理差不多是: (1)Lucas定理:p为素数,则有: 即:lucas(n,m,p)=c(n ...
- Hay Points
Hay Points TimeLimit: 1 Second MemoryLimit: 32 Megabyte Totalsubmit: 1022 Accepted: 602 Descript ...
- 向Git证明自己的身份,Git别名配置
一.向Git证明自己的身份 在安装完Git后,第一步就是向Git说明自己的身份,通过如下两个命令证明: git config --global user.name "myusername&q ...
- 排序算法_MergeSort
算法思想: 分治自顶而下实现归并排序: 分治法的三个步骤 设归并排序的当前区间是R[low..high],分治法的三个步骤是:①分解:将当前区间一分为二,即求分裂点 ...
- ManagerDay-2
新工作开始了两个星期 基本没有什么产出,主要还是适应新岗位和学东西.作为一个由高级开发转初级PM的人,要学要接触的还有太多. 公司给我安排了一个刚刚起步的项目,可能也是我从业三年接触到的最大的一个项目 ...
- 安卓开发无法识别手机原因之一:手机SDK比工程要求的最小SDK低
创建工程时,设置限制的最小SDK: 如果你手机的内核版本比你工程的设置的最小SDK低,则不显示 来自为知笔记(Wiz)