Android OpenGL ES(十三)通用的矩阵变换指令 .
Android OpenGL ES 对于不同坐标系下坐标变换,大都使用矩阵运算的方法来定义和实现的。这里介绍对应指定的坐标系(比如viewmodel, projection或是viewport) Android OpenGL ES支持的一些矩阵运算及操作。
OpenGL ES 中使用四个分量(x,y,z,w)来定义空间一个点,使用4个分量来描述3D坐标称为齐次坐标 :所谓齐次坐标就是将一个原本是n维的向量用一个n+1维向量来表示。 它有什么优点呢? 许多图形应用涉及到几何变换,主要包括平移、旋转、缩放。
以矩阵表达式来计算这些变换时,平移是矩阵相加,旋转和缩放则是矩阵相乘,综合起来可以表示为:
p’ = m1*p + m2(m1旋转缩放矩阵, m2为平移矩阵, p为原向量 ,p’为变换后的向量)。
引入齐次坐标的目的主要是合并矩阵运算中的乘法和加法,表示为p’ = M*p的形式。即它提供了用矩阵运算把二维、三维甚至高维空间中的一个点集从一个坐标系变换到另一个坐标系的有效方法。
它可以表示无穷远的点。n+1维的齐次坐标中如果h=0,实际上就表示了n维空间的一个无穷远点。对于齐次坐标[a,b,h],保持a,b不变,|V|=(x1*x1,y1*y1,z1*z1)^1/2的过程就表示了标准坐标系中的一个点沿直线 ax+by=0 逐渐走向无穷远处的过程。
为了实现viewing, modeling, projection 坐标变换,需要构造一个4X4 的矩阵M,对应空间中任意一个顶点vertex v , 经过坐标变换后的坐标 v’=Mv
矩阵本身可以支持加减乘除,对角线全为1的4X4 矩阵成为单位矩阵Identity Matrix 。
- 将当前矩阵设为单位矩阵的指令 为glLoadIdentity().
- 矩阵相乘的指令glMultMatrix*() 允许指定任意矩阵和当前矩阵相乘。
- 选择当前矩阵种类glMatrixMode(). OpenGL ES 可以运行指定GL_PROJECTION,GL_MODELVIEW等坐标系,后续的矩阵操作将针对选定的坐标。
- 将当前矩阵设置成任意指定矩阵glLoadMatrix*()
- 在栈中保存当前矩阵和从栈中恢复所存矩阵,可以使用glPushMatrix()和glPopMatrix()
- 特定的矩阵变换平移glTranslatef(),旋转glRotatef() 和缩放glScalef()
OpenGL使用了右手坐标系统,右手坐标系判断方法:在空间直角坐标系中,让右手拇指指向x轴的正方向,食指指向y轴的正方向,如果中指能指向z轴的正方向,则称这个坐标系为右手直角坐标系。

Translate平移变换
方法public abstract void glTranslatef (float x, float y, float z) 用于坐标平移变换。
在上个例子中我们把需要显示的正方形后移了4个单位,就是使用的坐标的平移变换,可以进行多次平移变换,其结果为多个平移矩阵的累计结果,矩阵的顺序不重要,可以互换。

Rotate旋转
方法public abstract void glRotatef(float angle, float x, float y, float z)用来实现选择坐标变换,单位为角度。 (x,y,z)定义旋转的参照矢量方向。多次旋转的顺序非常重要。

比如你选择一个骰子,首先按下列顺序选择3次(绿色:X轴,蓝色:Y轴,红色:Z轴):
gl.glRotatef(90f, 1.0f, 0.0f, 0.0f);
gl.glRotatef(90f, 0.0f, 1.0f, 0.0f);
gl.glRotatef(90f, 0.0f, 0.0f, 1.0f);

然后打算逆向旋转回原先的初始状态,需要有如下旋转:

或者如下旋转:
gl.glRotatef(90f, 0.0f, 0.0f, -1.0f);
gl.glRotatef(90f, 0.0f, -1.0f, 0.0f);
gl.glRotatef(90f, -1.0f, 0.0f, 0.0f);
Translate & Rotate (平移和旋转组合变换)
在对Mesh(网格,构成三维形体的基本单位)同时进行平移和选择变换时,坐标变换的顺序也直接影响最终的结果。
比如:先平移后旋转, 旋转的中心为平移后的坐标。

先选择后平移: 平移在则相对于旋转后的坐标系:

一个基本原则是,坐标变换都是相对于变换的Mesh本身的坐标系而进行的。
Scale(缩放)
方法public abstract void glScalef (float x, float y, float z)用于缩放变换。
下图为使用gl.glScalef(2f, 2f, 2f) 变换后的基本,相当于把每个坐标值都乘以2.

Translate & Scale(平移和缩放组合变换)
同样当需要平移和缩放时,变换的顺序也会影响最终结果。
比如先平移后缩放:
gl.glTranslatef(, , );
gl.glScalef(0.5f, 0.5f, 0.5f);

如果调换一下顺序:
gl.glScalef(0.5f, 0.5f, 0.5f);
gl.glTranslatef(, , );
结果就有所不同:

矩阵操作,单位矩阵
在进行平移,旋转,缩放变换时,所有的变换都是针对当前的矩阵(与当前矩阵相乘),如果需要将当前矩阵回复最初的无变换的矩阵,可以使用单位矩阵(无平移,缩放,旋转)。
public abstract void glLoadIdentity()
在栈中保存当前矩阵和从栈中恢复所存矩阵,可以使用
public abstract void glPushMatrix()
和
public abstract void glPopMatrix()
在进行坐标变换的一个好习惯是在变换前使用glPushMatrix保存当前矩阵,完成坐标变换操作后,再调用glPopMatrix恢复原先的矩阵设置。
Android OpenGL ES(十三)通用的矩阵变换指令 .的更多相关文章
- Android OpenGL ES 开发教程 从入门到精通
感谢,摘自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ...
- Android OpenGL ES(五)GLSurfaceView .
Android OpenGL ES 相关的包主要定义在 javax.microedition.khronos.opengles GL 绘图指令 javax.microedition.khrono ...
- Android OpenGL ES(三)OpenGL ES API 命名习惯 .
OpenGL ES是个跨平台的3D图形开发包规范,最常见的实现是采用C语言实现的,Android OpenGL ES 实现上是使用Java 语言对底层的C接口进行了封装,因此在android.open ...
- [工作记录] Android OpenGL ES: non-square texture - continue
previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...
- Android OpenGL ES(十二):三维坐标系及坐标变换初步 .
OpenGL ES图形库最终的结果是在二维平面上显示3D物体(常称作模型Model)这是因为目前的打部分显示器还只能显示二维图形.但我们在构造3D模型时必须要有空间现象能力,所有对模型的描述还是使用三 ...
- Android OpenGL ES(八)绘制点Point ..
上一篇介绍了OpenGL ES能够绘制的几种基本几何图形:点,线,三角形.将分别介绍这几种基本几何图形的例子.为方便起见,暂时在同一平面上绘制这些几何图形,在后面介绍完OpenGL ES的坐标系统和坐 ...
- Android OpenGL ES .介绍
引自:http://blog.csdn.net/hgl868/article/details/6971624 1. OpenGL ES 简介 Android 3D引擎采用的是OpenGL ES. ...
- Android OpenGL ES(七)基本几何图形定义 .
在前面Android OpenGL ES(六):创建实例应用OpenGLDemos程序框架 我们创建了示例程序的基本框架,并提供了一个“Hello World”示例,将屏幕显示为红色. 本例介绍Ope ...
- Android OpenGL ES(六)创建实例应用OpenGLDemos程序框架 .
有了前面关于Android OpenGL ES的介绍,可以开始创建示例程序OpenGLDemos. 使用Eclipse 创建一个Android项目 Project Name: OpenGLDemos ...
随机推荐
- c语言正则表达式
标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数Philip Hazel的Perl-Compatible Regular Expression库 ...
- Java 集合 JDK1.7的LinkedList
Java 集合 JDK1.7的LinkedList @author ixenos LinkedList LinkedList是List接口的双向链表实现,JDK1.7以前是双向循环链表,以后是双向非循 ...
- linux命令 awk
awk的工作流程如下: 读入有 '\n' 换行符分割的一跳记录,然后将记录按指定的域分隔划分域,填充域,$0 表示所有域, $1 表示第一个域, $n 表示第n个域.默认域分隔符为“空白键”或者“[t ...
- kissy小记
<script> KISSY.add('demo',function(S ,require, exports, module){ var Node = require('node'); v ...
- Tyvj-TOM的无穷序列
背景 蛟川书院模拟试题 描述 TOM有一个无穷序列中如下:110100100010000100000.....请你帮助TOM找出在这个无穷序列中指定位置上的数字 输入格式 第一行一个正整数N,表示询问 ...
- ThinkPHP模板
[MVC模式] M:Model 数据模型层,负责数据操作 V:View 视图层,负责显示视图 C:Controller 控制器,实现业务逻辑 tp框架url地址可以由以下四种 http://网址/in ...
- ural 1013. K-based Numbers. Version 3(动态规划)
1013. K-based Numbers. Version 3 Let’s consider K-based numbers, containing exactly N digits. We def ...
- Git客户端SourceTree回滚到远程仓库和切换分支
使用SourceTree将远程仓库回滚到某一次提交 原理:在本地需要回滚的commit上创建一个分支,将该分支合并到远程仓库. 步骤 1.在需要回滚的commit上右键创建分支 创建分支 2.输入新的 ...
- 找回XP中的搜索助理
平台:GHOST版XP 问题:按下F3键后,打开的搜索界面没有搜索助理,比较难看.打开C:\WINDOWS\srchasst目录,发现该目录下空空如也,显然搜索助理文件已经被删除了. 解决: 1.准备 ...
- OpenVPN客户端解析
windows版本的VPN客户端,实际上就是一个外壳,创建了图形界面,托盘,和 右键菜单, 在connect的动作里,实际上是通过cmd调用 openvpn.exe openvpn --config ...