在编写代码的时候有几个点理解不好:
问题一:
做矩阵操作时,发现平移的量,还有某些图形的尺寸基本都是个小数,这个小数指的是什么?
问题二:
cameraFrame.moveForward(10);
是向哪个方向移动的?这个10
指的是什么?
相信有些初学的朋友会发现同样的误区,这是由于坐标系知识点不够扎实导致。接下来我们来完善下这个知识点。
世界坐标系
首先需要明确下:
- 在
OpenGL
中,世界坐标系是以屏幕中心为原点(0, 0, 0)
,且始终不变 - 窗口范围按此单位恰好是
(-1,-1)
到(1,1)
即屏幕左下角(-1,-1),屏幕右上角(1,1)
- 世界坐标系是右手坐标系,具有以下特点
a. 右边为+x方向 b. 上边为+y方向 c. 垂直屏幕向外为+z方向
问题一解析:
通过对窗口及世界坐标系展示,我们可以看出,一个屏幕如果我们平移或者设置图形尺寸大小比较大,就会超出屏幕展示
GLFrame
使用forward
GLFrame
默认构造函数会将物体初始化为:
- 位置在
(0,0,0)
点 - 屏幕上方为
+y
方向 forward
为(0,0,-1)
朝向世界坐标系的-z(垂直于纸面向里) 意思就是当向里跑的时候,就是向着垂直纸面向里的方向跑。
- 屏幕左方为
+x
方向
在相机坐标系【右手坐标系】:相机位于原点(0, 0, 0)
a. 竖直向上为`+y`
b. 相机正对方向为`+z`
c 根据右手法则可以判断`+x`在屏幕左方
以上为GLFrame
的默认构造,该默认构造很适合相机,但是并不适合模型。
所以在设置模型时,我们有时会设置如下:
modelFrame.SetForwardVector(0, 0, 1);
问题二解析
如果cameraFram
保持初始化构造,那么直接moveForward(10)
,就是想屏幕里即-z
(世界坐标系)方向行走10
个单位。
如果使用以下配置。
# 相当于将原来的正方向为-z,改为+z
cameraFrame.SetForwardVector(0, 0, 1);
那么调用moveForward(10);
就是向着屏幕外方向走10
个单位。
注意此时朝向为屏幕外,可能看不到我们在屏幕里面绘制的值,需要再旋转照相机180
度的方向才可以看到。
由此,我们发现,对于相机来说,最好还是保持其原有方向:
向前就是向着屏幕里面,也就是世界坐标系的-z
,同时也方便我们直观去观察。
发散回溯 —— OpenGL
坐标系
看到上面分析让我产生一个纠结点,如果不同的坐标系(物体,世界,惯性,相机)还不一样,有的是左手系,有的是右手系,那不是坑死了。
最后翻阅资料了解到,原来一开始的疏忽导致后续一系列的理解误区。
知识点如下:
OpenGL
坐标系(物体、世界、照相机,惯性)属于右手坐标系- 设备坐标系,属于左手坐标系
配图如下:
发散延伸 —— 坐标系转换流程
绘制物体时的坐标系。程序刚初始化时,世界坐标系和当前绘图坐标系是重合的。 只有对当前绘图坐标系进行平移,伸缩,变换后,世界坐标系和当前绘图坐标系不再重合。
物体的顶点起始坐标是局部坐标,之后会转换为世界坐标、观察者坐标、裁剪坐标等。
转换流程参考下图:
总结
坐标系知识如果大轮廓搞混乱,后续理解方向会出现很多误区。针对这次的使用,无非就是坐标系知识理解不够扎实,最后又回溯到最根本位置:OpenGL
坐标系都是右手系。
参考: