opengl:新手翻译的FAQ--可视和转换(学opengl两个月)



原文参考点是http://www.opengl.org/wiki/index.php/Viewing_and_Transformations
很像没翻译完发现自己没那么多闲工夫也没那么牛逼有些地方没看懂我又不是那个什么xpersoft我知道自己错地方大把而且还有道题目没翻译出来自己高数第 2册根本没及格现在正在狂补假如错了指点下谢谢了定最快休正

观察和转换
----------------------------------------------------------------------------------
内容:
01.相机如何在OpenGL中工作?
02.我怎样才可以移动我视点,或者是相机,在我场景中?
03.我相机该去哪,模型视点矩阵还是投射矩阵?
04.我该如何执行个缩放操作?
05.给出当前模型视点矩阵,我如何才可以确定相机物体空间位置?
06.我怎样才可以使照相机在我场景中围绕个点转?
07.如何自动计算个观察点可以显示全部场景?(我知道边界球体和向上分量(boundingsphere
andupvector).)
08.gluLookAt是如何工作?
09.我怎样才可以得到个在场景正中间点?
10.我把我gluLookAt放在我投影矩阵中,现在雾,光线,纹理贴图都不能正确工作了,究竟
发生什么了?
11.我怎样才可以建造个立体视觉?
12.我不能使转换正常工作,哪里才可以知道更多有关矩阵东西?
13.OpenGL矩阵是纵排列,还是横排列?
14.OpenGL坐标单位是什么?
15.坐标是如何转换?坐标空间有什么区别?
16.我如何样才可以转换我场景中个物体或者给每个物体都有单独变换?
17.如何才可以在3D渲染图上绘制2D图?
18.我如何才可以饶过OpenGL矩阵转换,而直接把2D坐标光栅化?
19.使用绝对坐标和相对坐标优缺点在哪呢?
20.我怎样才可以画个场景中区别视图?
21.我如何样才可以使我物体围绕个固定坐标系统转换,而不是本地坐标系统?
22.相对于使用gluPerspective,使用glFrustum优缺点?
23.我怎样才可以glFrustum来匹配gluPerspective?
24.我怎样才可以画个全屏幕矩形?
25.对于个给定物体空间坐标,我如何确定相应屏幕坐标?
26.如何样才可以找到个屏幕上点物体空间坐标?
27.怎样才可以找到个被模型视点矩阵转换过顶点坐标?
28.怎样计算观察者到给定点物体空间距离?
29.在窗口被重定义大小后我如何样才可以保持我比例系数?
30.我如何样才可以使OpenGL使用左手坐标系?
31.怎样转换个物体是它可以指向或者紧跟着另个场景中物体或点
32.我如何才可以使用倾角,仰角,斜角来转换个物体?
33.我怎样才可以渲染个镜面?
34.我怎样才可以做我自己透视缩放?



1.OpenGL照相机是如何工作?

OpenGL是非常注意,这里是没有照相机.更确切说是,这个站相机总是位于眼空间坐标处(0.0,0.0,0.0,0.0).为了给出移动相机效果,你必须反向移动你场景,把转换矩阵放入模型视点矩阵来实现.这就是通常被引用视点转换.

在实际练习中,这是个和相机转换相等等式,但更有效率,更多模型转换 和相机转换被连接到了个单独矩阵中去.因此,但相机且只有相机在模型视点当中时,这些操作是必须被执行.比如,当安置个光源在世界坐标系时候当视点转换且只有视点转换被应用于模型视点矩阵时候,它是必须被重安置.
---------------------------------------------------------------------------------
2.我如何才可以移动我眼睛,或者相机在我场景中?

OpenGL并没有使用相机模型来提供个接口完成这项工作.然后,GLU库提供了个gluLookAt,它可以确定个眼睛位置,个可以看,有向上向量,在物体空间中坐标.这个可以根据它参数,计算出它相机反向转换然后在乘以系统当前矩阵.
----------------------------------------------------------------------------------
3.我照相机该去哪儿,模型视点矩阵还是投影矩阵?

这GL_PROJECTION矩阵只能够包含投影变换,它转换眼坐标到裁减坐标.

这GL_MODELVIEW矩阵,正如它名字所暗示那样,包含了模型和视点转换,它将会转换物体空间坐标到眼坐标.请记住把相机转换代码放入GL_MODELVIEW矩阵中去不要放入GL_PROJECTION 去.

考虑投影矩阵就好像在描述照相机特性样,例如fieldofview,focallength,fisheyelens,etc.考虑模型视点矩阵,就好像你和照相机位置,以及你朝向.

在gamedevFAQ有更多描述两个矩阵信息.

读SteveBakers\'s文章有关滥用投影.这篇文章是被高度评价和推荐.它帮助了很多OpenGL员们.
----------------------------------------------------------------------------------
4.我如何执行个缩放操作?

个简单来缩放思路方法就是使用统模型视点矩阵.然后,这通常容易导致假如模型被放太大会被zNear和zFar所裁减.

个更好思路方法就是通常对投影视景体进行宽和高限制.

例如,你通常会根据用户输入,来提供个缩放参数,可能是个浮点数.当设置了个1.0值后,将会没有缩放操作执行.更大值会有更大缩放,和更多有关视景体限制,而更小值将会导致相反情况.制造这种效果代码有可能像这样:

floatzoomFactor;/*全局变量,假如你需要,可以通过用户输入来改变,值为1.0*/



/*来设置投影矩阵.可能会来自段典型重定义穿口大小句柄.将会
给出重画大小宽和高整数值.使用正确画面比例系数和缩放因子建造个投影矩阵*/
voidProjectMatrix(width,height)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(50.0*zoomFactor,(float)width/(float)height,zNear,zFar);
/*zNear和zFar将会由你来填入*/
}

为了代替gluPerspective,你有可能使用glFrustum.这里有点小窍门技巧,这个左,右,底,顶部参数,还有近平面参数,也会影响到可视域.假设你想保持个固定zNear面距离(非常合理假设),glFrustum代码可能会看起来如下:

glFrustum(left*zoomFactor,right*zoomFactor,
bottom*zoomFactor,top*zoomFactor,
zNear,zFar);
glOrtho也是类似.
----------------------------------------------------------------------------------
5.给出了当前模型视点矩阵,我如何确定相机物体空间位置?

这个"相机"或者视点在眼坐标中是在(0.0,0.0,0.0).当你把它转换成(0,0,0,1)并和模型视点矩阵逆矩阵相乘时,得出来向量就是相机物体空间坐标.

OpenGL并没有思路方法(使用glGet*相关)来得到模型视点矩阵逆矩阵.你需要使用自己代码来计算它.
----------------------------------------------------------------------------------
6.我怎样才可以使我场景中照相机围绕个顶点在转动?

你可以在同样场景中通过平移/转动场景/物体来模拟轨道.例如,围绕个在Y轴上物体,而且不间断望向原点,有可能会这样写:

gluLookAt(camera[0],camera[1],camera[2],/*相机位置*/
0,0,0, /*相机朝向原点*/
0,1,0);/*正Y轴方向*/
glRotatef(orbitDegree,0.0f,1.0f,0.0f);/*围绕Y轴*/
/*...旋转角度,也可以来自于鼠标运动*/

glCallList(SCENE); /*绘制场景*/
假如你坚持使用物理移动这个相机位置,那么在把它放进你模型视点转换中的前你必须得转换当前相机位置向量.

在任意种事件中我都建议你研究下gluLookAt(如果你已经没有是用它了);
----------------------------------------------------------------------------------
7.我如何才可以自动计算个点使它可以显示我场景中全部模型(我知道球体范围和向上向量)?

接下来是来自DaveShreiner设置个可视系统.

首先,计算所有在你场景中物体球体范围.这些将会提供给你两点信息:球体中心位置(让(cx,cy,cz)来记录这点)和它直径.

接下来,选择个zNear剪裁面距离值.大部分建议都是选择个大于,但接近数, 所以,让我们把它设为:

zNear=1.0;
zFar=zNear+diam;

按下面这种方式,组织你矩阵(对个正射投影矩阵)

GLdoubleleft=c.x-diam;
GLdoubleright=c.x+diam;
GLdoublebottom=c.y-diam;
GLdoubletop=c.y+diam;

glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(left,right,bottom,top,zNear,zFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;

这种思路方法会设置你物体在窗口正中心,伸展边界以符合.(i.e.,这个是假设你窗口比例系数为1.0).假如你窗口是非正方形,将会按上面方式计算左,右,上,下,在glOrtho以前放入下面逻辑代码段中.

GLdoubleaspect=(GLdouble)windowWidth/windowHeight;

(aspect<1.0){/*窗口高比宽长*/
bottom/=aspect;
top/=aspect;
}{
left*=aspect;
right*=aspect;
}

上面代码将会把你 场景中物体放在相对正确位置.假如你想试着去操作它(i.e.旋转,etc),你需要增加个可视转换.

个典型可视转换将会和模型视点矩阵想混和,而且看起来,应该是这样:

gluLookAt(0.0,0.0,2.0*diam,c.x,c.y,c.z,0.0,1.0,0.0);
----------------------------------------------------------------------------------
8.为什么gluLookAt不能工作?

这个通常是被不正确转换所导致.

假设你使用投影矩阵堆栈中gluPerspectivezNear,zFar来作为第 3,第 4个参数,你就必须设置模型视点矩阵堆栈上gluLookAt,并传递相应参数,使你物体,可以落在zNear和zFar的间.

当你正试图去了解可视转换时候,最好思路方法就是写些代码来做试验.让我们想你正在看个位于原点单位球体.你可能想按下面方式来设置你转换:



glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(50.0,1.0,3.0,7.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
gluLookAt(0.0,0.0,5.0,
0.0,0.0,0.0,
0.0,1.0,0.0);

非常重要点就是,知道投影和模型视点矩阵是如何起工作.

在这个例子中这个投影转换,设立了个50度可视角度观察域,和个窗口为1比例系数.这个zNear剪裁面是视点前 3个单位,这个zFar剪裁面是视点前7个单位.它们分配了个在Z轴长度为4视景体,对于个单位球体是绝对足够.

这个模型视点转换设置了眼坐标为(0.0,0.0,5.0),而所观看点是原点,也就是我们单位圆正中心.请注意这个眼坐标位置离观察点位置有5个单位距离.这点是相当重要,眼睛前面5个单位距离是在投影转换所定义视景体正中间.假如这个gluLookAt把眼睛设置在(0.0,0.0,1.0)它只会离原点个单位距离.它将会没有足够长度去包含物体在视景体中,物体将会被zNear所剪裁.

相同地,假如你把眼坐标设置在(0.0,0.0,10.0),10个单位离观察点距离,将会导致这个球体和视点有10个单位距离,并且被zFar剪裁面在7单位距离处,被剪裁.

假如这些东西,困扰着你,读OpenGL红皮书或者OpenGL详解(specication)中有有关转换内容.在你理解了物体空间坐标,眼坐标空间,和剪裁面坐标空间,这些上面知识,将会变非常容易,清晰.最好,在经常写些小测试来实战下.假如你在你中依然有相当困难来使用正确变换矩阵,那么写些更简单几何体测试是非常有意义.
--------------------------------------------------------------------------------
9.我如何去设置个精确点在场景中间显示?

gluLookAt是非常容易做到这个.简单设置你X,Y,和Z值作为你gluLookAt第 3,第 4,第5个参数.
---------------------------------------------------------------------------------
10.我把我gluLookAt放入我投影矩阵中,现在雾,光线,和纹理映射都不能正常工作了
是为什么?

这个通常是把转换放在矩阵中所导致,看下问题 3对这个问题解释.然后也有可能,是特殊光照问题,所导致,矩阵被放入模型视点矩阵中,然后定义了光照位置.当个光源点被定位在眼空间坐标中,i.e.和眼睛相关,它将会被重新定位到个单位矩阵在模型视点矩阵堆栈中时候.当可视矩阵被放入模型视点堆栈中时,原先世界坐标系中光源位置讲会被重定位.当个光源位置是和个转换物体相关时候,当物体模型矩阵和在模型视点矩阵堆栈中可视矩阵想乘时,这个光源也会被重新定位,请记住在任何光源被渲染前,它都有可能被重新定位.假如光源在结构中相对于眼睛在移动,那么每个结构都必须使用合适矩阵来进行重定位.
----------------------------------------------------------------------------------
11.我如何可以建造个立体视图?

立体视图就是通过展现观察者观察到左眼和右眼所看见画面来形成.这些图像必须正确匹配到显示器上,符合观察者实际所看到,更多习惯是使用多于3D图像.附加点就是这种思路方法会和被使用显示器技术有相当紧密联系.些图形系统和显示设备,会在硬件上支持立体视图和支持像左缓存Cache和右缓存Cache,另外就是在系统上支持双缓存Cache前缓存Cache和后缓存Cache.另外系统就会在显示屏幕显示两个视口来支持立体视图,并详细定义显卡模式来发送这些图像到显示屏幕.另外和此相关就是观察者通常带着个特殊眼镜,它会自动对图像进行拣选来以此来符合每个眼睛所看到.然而即使没有这些图像特性,个开发者仍然可以使用颜色过滤在些基于红或蓝色过滤器选择图像地方来实现立体视图,例如画左眼和右眼图像到到红,蓝帧缓中来实现这点.或者更加简单就是有多个系统或是图形显卡(或者块显卡)来产生两个完全分离视频信号,来分别画个左眼和右眼图像.这个视频将会被发送到正确眼睛中,使用个displayemployingpolarizingfilters或者个headmounteddisplay或者些别用户自己显示设备,执行些原理相同操作.

个OpenGL透视投影中,立体渲染设备将会使用合适操作来渲染到左眼和右眼(作图像掩码,分离上下文或是区别视口)并且匹配到和OpenGL投影相关观察者左眼和右眼几何图像到显示器上.这个最后OpenGL设备要求是这个在"虚拟"世界中眼睛位置必须得来自模型视点矩阵中分离瞳孔位置,这种分离会在眼空间坐标产生个转换但不会在别相同思路方法中被计算.

PaulBourke整理了很多有关立体OpenGL立体视图资料:

·3DStereoRenderingUsingOpenGL
·CalculatingStereoPairs
·CreatingAnaglyphsusingOpenGL
----------------------------------------------------------------------------------
12.我不能使转换正常工作.我可以从哪里得到更多有关矩阵知识?

个系统有关基础矩阵数学和线性代数知识已经超出这份FAQ范围.相关概念已经在美国高校数学课上解释过了

假如你知道这些基本概念,但还是有点糊涂(个共同问题就是经验),读下SteveBaker\'s
reviewofmatrixconcepts和他articleonEulerangles.



执行基本向量,矩阵, 4元数操作delphi代码可以在这里找到.
----------------------------------------------------------------------------------
13.OpenGL矩阵是行排列,还是纵排列?

出于编程原因,OpenGL矩阵是个在内存中依次相连16元素,转换部分占据了16元素矩阵中第13,14,15,16位置.

纵队排列相对横队排列纯粹就是种符号协定.注意自右和纵排列矩阵相乘将会产生和自左和行排列矩阵相乘产生同样结果.在OpenGL详解和OpenGL参考手册都使用了纵排列矩阵.你可以使用任意种,只要你清楚声明了

不辛地,使用在spec和蓝皮书中纵排列格式会在OpenGL社区中导致无止境困扰.纵排列格式会导致员不期望矩阵在内存中排列格式.

更多有关这方面内容,请点击:这儿.
----------------------------------------------------------------------------------
14.OpenGL坐标单位是什么?

最简短回答就是.只要你希望,它可以使用任何你所希望单位.

根据你几何数据库中内容,对于你可能非常方便处理OpenGL坐标单位,比如个毫米,或者光年,或者这其中任何距离(或大或小).

OpenGL也允许你自己定义你几何体使用区别值坐标系统.例如,你可能会发现在对飞机模型控制时候使用厘米,而对机身使用米,而对所飞行空间使用千米.OpenGL模型视点矩阵可以缩放区别坐标系统来形成同样眼坐标系统.

有义务来确定投影和模型视点矩阵构造所提供图像和观察者保持个合适距离,和合适可视域,以及能够保持zNear和zFar剪裁面在个合适范围内.个在微米程度缩放显示分子,例如,就不能把观察者放在个10英尺距离,60度观察域地方.
----------------------------------------------------------------------------------
15.坐标是如何转换?坐标空间有什么区别?

物体坐标被模型视点矩阵所转换来产生眼坐标.

眼坐标被投影矩阵所转换来产生裁减坐标.

裁减坐标X,Y,Z将会被裁减坐标W所除来产生设备规范标准化坐标.

设备规范标准化坐标会被视口参数所缩放和转移来产生窗口坐标.

物体坐标也就是当你提交给OpenGLglVertex*或着是glVertexPoer时候原始坐标.它将会显示你物体或者别你想渲染几何体坐标.

许多设计者使用世界坐标系统.物体通常在同个坐标系统中被模型化,缩放,平移,旋转都会在你建造世界中转换.世界坐标系统是通过存储在模型视点矩阵中模型转换而形成物体坐标转换而来.然而,OpenGL并没有世界坐标系统概念.世界坐标系统纯粹就是架构.

眼坐标是通过被模型视点矩阵转换物体坐标而来.这个模型视点矩阵中包含了模型转换和视点转换,它定义了观察者位于原点,而且朝向Z负半轴.

裁减坐标是由眼坐标通过投影转换而来.裁减坐标空间范围是从-Wc到Wc在所有 3个轴方向上,Wc是裁减坐标W值.OpenGL会裁减所有位于范围的外东西.

裁减坐标上所执行透视除法会产生标准设备规范标准化坐标,在 3个轴范围是从-1到1.

窗口坐标是来通过视口来缩放,平移设备规范标准化坐标转换而来.glViewport和glDepthRange参数控制这些转换.使用视口,你可以映射设备规范标准化坐标立方体到你窗口任何位置和深度缓存Cache中.

更多信息,请看OpenGLspecication,图解2.6
----------------------------------------------------------------------------------
16.我如何转换我场景中物体或者是给我场景中个物体都有单独转换?

OpenGL提供了矩阵堆栈来实现这个功能.这样就是使用模型视点矩阵堆栈.

个典型OpenGL次设置这个矩阵模式是使用glMatrixMode(GL_MODELVIEW)并且加载个可视转换,例如个到gluLookAt.更多信息可利用在gluLookAt.

然后这个代码渲染每个场景中物体使用他们自己转换通过包装这个glPushMatrix和glPopMatrix.例如:

glPushMatrix;
glRotatef(90.0,1.0,0.0,0.0);
gluCylinder(quad,1,1,2,36,12);
glPopMatrix;

上面代码渲染个圆柱体围绕X轴旋转90度.这个模型视点矩阵将会被重新存储为先前值在glPopMatrix后.相似序列可以渲染场景中并发物体.



Tags:  opengl驱动 opengl2.0 opengl模式 opengl

延伸阅读

最新评论

发表评论