Win32 OpenGL编程(9) 投影变换
Win32 OpenGL编程(9) 投影变换
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
讨论新闻组及文件
提要
在前文(系列文章(7),以下简称XO7,系列其他文章类似)中的照相机比喻中提到了4种3D变换,如下:
1.确定照相机的位置的过程对应于“视图变换”(Viewing Transformations)
2.确定物体位置的过程对应于“模型变换”(Modeling Transformations)
3.确定照相机放大倍数的过程对应于“投影变换”(Projection Transformations)
4.确定照片大小的过程对应于“视口变换”(Viewport Transformations)
XO7中我们讲的是第一种变换视图变换,即改变观察者本身的位置,视角等的变换效果,XO8中讲的是第二种变换模型变换,本文开始继续按顺序讲解下一个3D变换过程,投影变换。
正投影
投影变换的过程就像是照相机选镜头的过程,目的是确定视野,其实说起来投影一词,我在学习工程制图的时候就接触过了,不知道大家是否学过这门课程,工程制图就是一种将三维空间的事物设想投影在二维空间中,然后画下来,工程中应用非常广泛,那时候学的那些剖面图什么的,也是累死我了-_-!OpenGL就可以模拟这样的过程,并且名字和工程制图中的名字是一样的,叫正投影。
OpenGL以glOrtho来指定一个正交平行的矩形,屏幕上显示的就是此物体在此矩形的正面的投影。在XO2中用过的gluOrtho2D实际上是此函数的一个去掉Z轴坐标的简化版,而glOrtho包括的参数nearVal,farVal表示此矩形的前,后两面,超出此矩形范围的图形将会被裁掉。
《OpenGL Programming Guide 》:
glOrtho — multiply the current matrix with an orthographic matrix
C Specification
void glOrtho( GLdouble left,
GLdouble right,
GLdouble bottom,
GLdouble top,
GLdouble nearVal,
GLdouble farVal);
Parametersleft, right
Specify the coordinates for the left and right vertical clipping planes.
bottom, topSpecify the coordinates for the bottom and top horizontal clipping planes.
nearVal, farValSpecify the distances to the nearer and farther depth clipping planes.
These values are negative if the plane is to be behind the viewer.
用此函数,通过调整nearVal与farVal我们可以实现类似工程制图中的剖面的效果,见下例:
GLfloat gfNear = 1.0;//这里进行所有的绘图工作 voidSceneShow(GLvoid) {glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-1.0, 1.0, -1.0, 1.0, gfNear, -1.0); glPushMatrix();DrawSmoothColorPyramid(0.5);glPopMatrix(); glFlush(); } /// intGame_Main(void*parms = NULL, intnum_parms = 0) {DWORD dwStartTime; dwStartTime = GetTickCount();// this is the main loop of the game, do all your processing // here // for now test if user is hitting ESC and send WM_CLOSE if(KEYDOWN(VK_ESCAPE))SendMessage(ghWnd,WM_CLOSE,0,0); if(KEYDOWN(VK_UP)){gfNear -= 0.01;} if(KEYDOWN(VK_DOWN)){gfNear += 0.01;} SceneShow(); // 控制帧率 while (GetTickCount() - dwStartTime < TIME_IN_FRAME){Sleep(1);} // return success or failure or your own return code here return (1); } // end Game_Main
glMatrixMode(GL_PROJECTION);
透视投影
上述的正投影仅仅存在于想象之中,主要是工程制图(或者CAD)中能够正确反映物体的真实尺寸,现实中我们看东西,越远的越小,越近的越大,并且所有物体最终会消失在远方(地平线),OpenGL常用于VR(虚拟现实),这样程度的视觉仿真效果自然是有的,在OpenGL中,这样投影叫做透视投影。OpenGL提供了两个函数用于指定透视投影,两个函数仅仅是参数表示的方式不同,事实上效果是一样的。
《OpenGL Programming Guide 》:
glFrustum — multiply the current matrix by a perspective matrix
C Specification
void glFrustum( GLdouble left,
GLdouble right,
GLdouble bottom,
GLdouble top,
GLdouble nearVal,
GLdouble farVal);
Parametersleft, right
Specify the coordinates for the left and right vertical clipping planes.
bottom, topSpecify the coordinates for the bottom and top horizontal clipping planes.
nearVal, farValSpecify the distances to the near and far depth clipping planes.
Both distances must be positive.gluPerspective — set up a perspective projection matrix
C Specification
void gluPerspective( GLdouble fovy,
GLdouble aspect,
GLdouble zNear,
GLdouble zFar);
Parametersfovy
Specifies the field of view angle, in degrees, in the y direction.
aspectSpecifies the aspect ratio that determines
the field of view in the x direction.
The aspect ratio is the ratio of x (width) to y (height).
zNearSpecifies the distance from the viewer to the near clipping plane
(always positive).
zFarSpecifies the distance from the viewer to the far clipping plane
(always positive).
事实上,glFrustum指定的方式与glOrtho很像,参数意义也一致,仅仅是使用后OpenGL使用的投影方式不同,gluPerspective函数指定的方式是模拟观察者(照相机)的视角,用fovy指定观察者的上下视角(及在y-z平面上观察的角度),aspect指定观察宽度与高度的比,然后用zNear指定离观察者较近的截面,用zFar指定离观察者较远的截面(都指离观察者的距离),下例展示了原来那个三角锥从远方的一个小点然后到放大到原来大小的过程:
GLfloat gfDis = 5.0; //这里进行所有的绘图工作 voidSceneShow(GLvoid) {glMatrixMode(GL_PROJECTION);glLoadIdentity();glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 5.0); glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0.0, 0.0, gfDis, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0); glPushMatrix();DrawSmoothColorPyramid(0.5);glPopMatrix(); glFlush(); } intGame_Main(void*parms = NULL, intnum_parms = 0) {DWORD dwStartTime; dwStartTime = GetTickCount();// this is the main loop of the game, do all your processing // here // for now test if user is hitting ESC and send WM_CLOSE if(KEYDOWN(VK_ESCAPE))SendMessage(ghWnd,WM_CLOSE,0,0); if(KEYDOWN(VK_UP)){gfDis -= 0.01f;} if(KEYDOWN(VK_DOWN)){gfDis += 0.01f;} SceneShow(); // 控制帧率 while (GetTickCount() - dwStartTime < TIME_IN_FRAME){Sleep(1);} // return success or failure or your own return code here return (1); } // end Game_Main
gluLookAt(0.0, 0.0, gfDis, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0);
来调整观察者的位置,通过上下键调节,会模拟出一种慢慢走近三角锥的过程,三角锥也是随着走近由小慢慢变大。
实际上最重要的还是
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 5.0);
三句确定的透视投影方式。
为节省篇幅仅贴出关键片段,完整源代码见我博客源代码的2008-10-28/glPerspective 目录,获取方式见文章最后关于获取博客完整源代码的说明。
小结:
相对来说,个人认为投影变换是属于OpenGL中重要但是确较难理解的一部分,动态变化上述函数的参数,准确理解上述函数中每个参数的意义是种不错的学习途径,其中Nate Robin的OpenGL教程有个很形象的教学程序,推荐给大家(实际上为《OpenGL Programming Guide 》中推荐的),http://www.xmission.com/~nate/tutors.html 中有下载的。对应投影变换的教程为projection一例。
参考资料
1. 《OpenGL Reference Manual 》,OpenGL参考手册
2. 《OpenGL 编程指南》(《OpenGL Programming Guide 》),Dave Shreiner,Mason Woo,Jackie Neider,Tom Davis 著,徐波译,机械工业出版社
3. 《Nehe OpenGL Tutorials》,Nehe著,在http://nehe.gamedev.net/ 上可以找到教程及相关的代码下载,(有PDF版本教程下载)Nehe自己还做了一个面向对象的框架,作为演示程序来说,这样的框架非常合适。也有中文版 ,各取所需吧。
4. 《OpenGL入门学习》 ,eastcowboy著,这是我在网上找到的一个比较好的教程,较为完善,而且非常通俗。这是第一篇的地址:http://bbs.pfan.cn/post-184355.html
本OpenGL系列其他文章
1. 《 Win32 OpenGL 编程(1)Win32下的OpenGL编程必须步骤 》
2. 《Win32 OpenGL编程(2) 寻找缺失的OpenGL函数 》
3. 《Win32 OpenGL编程(3) 基本图元(点,直线,多边形)的绘制 》
4. 《Win32 OpenGL编程(4) 2D图形基础(颜色及坐标体系进阶知识) 》
5. 《Win32 OpenGL编程(5)顶点数组详细介绍 》
6.《Win32 OpenGL编程(6) 踏入3D世界 》
7.《Win32 OpenGL编程(7) 3D视图变换——真3D的关键 》
8.《Win32 OpenGL编程(8) 3D模型变换及其组合应用 》
应用举例:《Win32 OpenGL编程系列 2D例子 -- 七巧板图形绘制 》
完整源代码获取说明
由于篇幅限制,本文一般仅贴出代码的主要关心的部分,代码带工程(或者makefile)完整版(如果有的话)都能用Mercurial在Google Code中下载。文章以博文发表的日期分目录存放,请直接使用Mercurial克隆下库:
https://blog-sample-code.jtianling.googlecode.com/hg/
Mercurial使用方法见《分布式的,新一代版本控制系统Mercurial的介绍及简要入门 》
要是仅仅想浏览全部代码也可以直接到google code上去看,在下面的地址:
http://code.google.com/p/jtianling/source/browse?repo=blog-sample-code
原创文章作者保留版权 转载请注明原作者 并给出链接
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
Win32 OpenGL编程(9) 投影变换相关推荐
- Win32 OpenGL 编程(1)Win32下的OpenGL编程必须步骤
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Win3 ...
- Win32 OpenGL 编程
Win32 OpenGL 编程(1)Win32下的OpenGL编程必须步骤 一. 前言 人生在于折腾,继续折腾吧. OpenGL 编程的红宝书< OpenGL Programming Gu ...
- Win32 OpenGL编程 5 顶点数组详细介绍
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Win3 ...
- Win32 OpenGL编程系列 2D例子 -- 七巧板图形绘制
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie 讨论新闻组及文件 OpenGL系列文章都已经写到3D部分了,但是感觉2D的例子还是少了点,特意弄个外 ...
- Win32 OpenGL编程(4) 2D图形基础(颜色及坐标体系进阶知识)
Win32 OpenGL 编程 (4) 2D 图形基础(颜色及坐标体系进阶知识) write by 九天雁翎 (JTianLing) -- blog.csdn.net/vagrxie 讨论新闻组及文件 ...
- Qt下的OpenGL 编程(3)绘制平面几何体
一. 提要 之前的一篇教程已经搭建好了Qt下的OpenGL的编程环境,几天要来学习的就是OpenGL的2D绘图. 2D作为绘图的基础,还是很值得去好好学习,比如迪卡尔坐标,透视设置等等,而所谓的3D, ...
- OpenGL编程入门学习
OpenGL编程入门学习 非常详细的教程,很适合初学者 本文转自:http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html === ...
- OpenGL编程指南7:视图-
1.前言 计算机图形学的要点就是创建三维物体的二维图像(图像必须是二维的,因为他是在平面的屏幕上显示的).但是,当我们决定怎样在屏幕上绘图时,必须使用三维坐标的方式考虑. 为了把一个物体的三维坐标变成 ...
- OpenGL编程轻松入门(一)
OpenGL编程轻松入门(一) (由同事黄燕创作) 本文介绍了有关OpenGL的基本知识,主要涉及颜色.绘制几何体.坐标变换.堆栈操作.显示列表.光照和材质.纹理映射.特殊效果.曲面和曲线的绘制. ...
最新文章
- Custom Client Side Drag and Drop Behavior in ASP.NET AJAX
- 小米履带机器人充电时一直响_小米有品上线擦地机器人,每天放出去溜一圈,老婆夸我家务做的好...
- [总结]Asp.net中的页面乱码的问题
- Machine Learning week 3 quiz : Regularization
- 科大星云诗社动态20220115
- Signalr2_消息弹窗
- 神经网络模型遇到瓶颈?这些Tricks让你相见恨晚!
- 实现织梦dedecms百度主动推送(实时)网页抓取
- python dict hash_Python Hashmap/Dicti
- python3读取多行数据合并_python3 数据规整化:清理、转换、合并、重塑(一)
- “物联网开发实战”学习笔记-(一)硬件开发环境的搭建
- 神州十二号载人飞船和空间站对接成功 我们的目标是星辰大海!
- 指南针经纬度分秒格式转换10进制经纬度
- aspose利用word模板生成word、PDF
- e8 c 虚拟服务器,电信光猫e8-c怎么设置拨号方式上网
- macOS:实现 声音内录 不用其它App
- TortoiseSVN安装及导入已有SVN仓库
- RT-Thread Env工具下 scons命令构建工程 SConscript和Kconfig修改示例
- 静态库与动态库之间的区别
- 冯诺依曼体系结构+操作系统