OpenGL坐标系解析(顶点从对象坐标系到屏幕坐标系的计算流程)

2019-05-13  本文已影响0人  lb_

上篇博客(OpenGL专有名词解析)讲到了物体变换位置有一种方法通过坐标系变化,但由于OpenGL中坐标系统不是简短几句话能描述的,因此我们专门开篇梳理一下OpenGL的坐标系统。

要详细了解OpenGL中多重坐标系, 首先我们需要了解从我们开发者构造的坐标系(Local/Object Space)转换到屏幕上坐标系 (Screen Coordinates)显示的具体过程。


图1 - 坐标系统计算过程

上图描绘了物体从局部对象坐标系统到屏幕坐标系转换的详细流程, 列举一下OpenGL中的坐标系。

在OpenGL中,这个转变过程可以看做下图


图2 - OpenGL顶点计算流程

OpenGL中Model和View一般用做一个模型视图变换矩阵ModelViewMatrix来处理。

下面我们通过矩阵的演变过程来看下计算流程:


图3 - 顶点矩阵计算流程

[Tips]以上变换流程中, 哪些是开发者需要做的,哪些是OpenGL会自动处理的呢?

流程详解:

1. 从模型坐标系(局部/对象坐标系 Object Coordinates)到世界坐标系(World Coordinates)

模型坐标系主要用于设计模型,在此阶段我们无需关心最终对象显示在屏幕哪个位置(因为决定显示在哪还需要加上摄像机来决定)。
在OpenGL中缓存对象(buffer object)中保存,以及旧版本中使用的glVertex3f等函数指定的都是局部坐标系中的坐标。

所谓从模型坐标系转换到世界坐标系,也就是将物体局部坐标转换到世界坐标系下坐标。

模型变换包括平移(translation)、旋转(rotation)、缩放(scaling)等等。

简单来说,这个过程主要做的事情就是我们在做仿射变化时通过调用modelViewMatrix的translation,Rotate,Scale等方法,将物体变化记录到模型视图矩阵当中。当然,如果不进行变化, 那就是默认情况。

2.从世界坐标系(World Coordinates)到照相机坐标系(Eye Coordinates)

 //MoveForward 平移
        cameraFrame.MoveForward(0.1f);

//RotateWorld 旋转
        cameraFrame.RotateWorld(angular, 0.0f, 1.0f, 0.0f);
右边为照相机显示内容,也就是屏幕显示结果(裁剪和投影效果前)

3.从照相机坐标系(Eye Coordinates)到裁剪坐标系(Clip Coordinates)

相机坐标系到裁剪坐标系是通过投影完成的。

OpenGL中我们使用视景体GLFrustum来创建投影矩阵,设置投影方式。

投影就是将物体投影到投影平面的过程。因为OpenGL使用的是虚拟相机成像模型,因此也使用了正交投影和透视投影两种方式。

实际上,投影有很多种类,这里稍微整理下常见的平行投影(正投影)和透视投影。

[Tips]因为人眼的特殊生理性,一般二维图形我们采用正投影,三维使用透视投影。
正投影和透视投影

4.从裁剪坐标系(Clip Coordinates)到规范化设备坐标系(NDC)

这个过程就是透视除法的过程,在OpenGL中无须我们自己处理。它会在顶点着色器处理后的阶段完成。

5.从规范化设备坐标系(NDC)到屏幕坐标系(Window Coordinates)

这个过程也就是视口变换,我们在glViewport指定后OpenGL自动处理。同过程4, 也是在顶点着色器处理后的阶段完成。

视口变换——从NDC到屏幕坐标
视变换是将规范化设备坐标(NDC)转换为屏幕坐标的过程,如下图所示:


视口变换

视口变化通过函数:
glViewport(GLint sxsx , GLint sysy , GLsizei wsws , GLsizei hshs);
glDepthRangef(GLclampf nsns , GLclampf fsfs );

两个函数来指定。其中(sxsx,sysy)表示窗口的左下角,nsns和 fsfs指定远近剪裁平面到屏幕坐标的映射关系。视口变换矩阵的推导可以参考前面的投影矩阵和视口变换矩阵一节。用上面的glViewport和glDepthRangef函数指定参数后,视口变换由OpenGL自动执行,不需要额外代码。

参考文章:

上一篇 下一篇

猜你喜欢

热点阅读