OpenGL下坐标系统解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL下坐标系统解析相关的知识,希望对你有一定的参考价值。

参考技术A OpenGL中的物体、世界、照相机坐标系都属于右手坐标系,而规范化设备坐标系使用左手坐标系。

OpenGL每次顶点着色后,我们的可见顶点都为规范化设备坐标(Normalized Device Coordinate,NDC)。也就是说每个顶点的x,y,z都应该在-1到1之间,超过这个范围的顶点将是不可见的。
通常情况下我们会自己设定一个坐标范围,之后再在顶点着色器中将这些坐标转化为规范化设备坐标。然后把规范化设备坐标传入光栅器(Rasterizer),将它们变换为屏幕上的二维坐标和像素。
将坐标变换为规范化设备坐标,接着再转化为屏幕坐标的过程通常是分步进行的,类似于流水线那样子。在流水线中,物体的顶点最终转化为屏幕坐标之前还会被变换到多个坐标系统(Coordinate System)。将物体的坐标变换到几个过渡坐标系统(Intermediate Coordinate System)的优点在于,在这些特定的坐标系统中,一些操作或运算更加方便和容易,这一点很快就会变得很明显。对我们来说比较重要的总共有5个不同的坐标系统:

就是一个顶点在最终被转化为片元之前需要经历的所有不同状态。为了将坐标从一个坐标系变换到另一个坐标系,我们需要用到几个变换矩阵,最重要的几个分别是模型(Model)、观察(View)、投影(Projection)三个矩阵。物体顶点的起始坐标在局部空间(Local Space),这里称它为局部坐标(Local Coordinate),它在之后会变成世界坐标(World Coordinate),观测坐标(View Coordinate),裁剪坐标(Clip Coordinate),并最后以屏幕坐标(Screen Coordinate)的形式结束。

在3D图形学中常用的坐标系:

世界坐标系:世界坐标系是系统的绝对坐标系,在没有建立用户坐标系之前画面上所有的点的坐标都可以在该坐标系的原点来确定自己的位置,世界坐标系始终是固定不变的。

物体坐标系:每个物体都有它们独立的坐标系,当物理移动或改变方向时,该物体相关联的坐标系将随之移动或改变方向。

物体坐标系是以物体本身而言,比如,我向你发指令“向前走一步”,是向你的物体坐标系指令。我并不知道你会向哪个绝对的方向移动。比如说,当你开车时,有人会说向左转,有人说向东。但是,向左转是物体坐标系的概念,而向东则是世界坐标系中的。

在某种情况下,我们可以理解物体坐标系为模型坐标系。因为模型顶点的坐标都是在模型坐标系中描述的。

惯性坐标系:指的是世界坐标系到物体坐标系的“半途”。惯性坐标系的原点和物体坐标系的原点重合,但惯性坐标系的轴平行于世界坐标系的轴。

OpenGL然后对裁剪坐标执行透视除法从而将它们变换到标准化设备坐标。OpenGL会使用 glViewPort 内部的参数将标准化设备坐标映射到屏幕坐标,每个坐标都关联了屏幕上的一个点,这个过程称为视口变换。

局部坐标系(模型坐标系)是为了方便构造模型而设立的坐标系,建立模型时我们无需关心最终对象显示在屏幕哪个位置。模型变换的主要目的是通过变换使得用顶点属性定义或者3d建模软件构造的模型,能够按照需要,通过缩小、平移等操作放置到场景中合适的位置。通过模型变换后,物体放置在一个全局的世界坐标系中,世界坐标系是所有物体交互的一个公共坐标系。

OPENGL之矩阵

前面的若干重要概念中描述了OPENGL中的几个重要变换,而矩阵是线性代数中的重要数学工具,它被用来对这些变换进行数学上的实现。

矩阵主要有以下几种:

模型视图矩阵:模型视图矩阵是个4*4的矩阵,代表经过变换的坐标系统,我们可以用这个坐标系统放置物体并设置其方向,顶点坐标以单列矩阵的形式表示,乘以模型视图矩阵,产生与视觉坐标系统相对应的经过变换的新坐标(顶点坐标*模型视图矩阵=与视觉坐标系统对应的新坐标

对模型视图矩阵进行修改

以下是对模型视图矩阵进行修改的例子:

移动

glTranslatef(GLfloat x,Glfloat y,GLfloat z);

例如: 若我们想将绘制对象沿着y轴向上移动10个单位,

glTranslatef(0.0f,10.0f,0.0f)

  旋转

glRotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)

  解释:将绘制对象沿着向量(x,y,z)旋转angle度(旋转轴:(x,y,z),旋转角度(angle))

 

缩放

glScalef(GLfloat x,GLfloat y,GLfloat z);

  以上是对模型视图矩阵的修改,但是我们应该注意到,这种对矩阵的修改是累加性的,即第二次的修改是在第一次修改的基础上进行的,每一次的修改并非独立的,

,为了是每一次的修改独立,符合渲染流水线的工业思想,于是就有了单位矩阵

单位矩阵

 

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

  

单位矩阵数学上的定义是:对角线为1,其他部位全为0,在OPENGL中的定义是:把模型视图矩阵重置回原点

 

矩阵堆栈:

glPushMatrix()

保存当前模型视图矩阵变换状态

glPopMatrix()

  

恢复栈顶元素保存的模型视图矩阵变换状态

glGet(GL_MAX_MODELVIE_STACK_DEPTH)
或者
glGet(GL_MAX_PROJECTION_STACK_DEPTH)

  以上两个函数分别用来获得模型视图矩阵堆栈的深度和投影和投影矩阵堆栈的深度

矩阵堆栈的深度:能保存的最多矩阵数

如果超过了堆栈深度:产生GL_STACK_OVERFLOW错误(上溢)

如果试图从一个空堆栈中弹出一个矩阵值:产生GL_STACK_UNDERFLOW错误(下溢)

 

以上是关于OpenGL下坐标系统解析的主要内容,如果未能解决你的问题,请参考以下文章

cocoscreator调是opengl

统一D3D与OpenGL坐标系统

openGL坐标系

openGL中的坐标系

OpenGL里的坐标系统以及其变换

初识OpenGL (-)坐标系统(Coordinate System)