Android OpenGL ES 开发教程(16):Viewing和Modeling(MODELVIEW) 变换
Viewing和Modeling 变换关系紧密,对应到相机拍照为放置三角架和调整被拍物体位置及角度,通常将这两个变换使用一个modelview 变换矩阵来定义。对于同一个坐标变换,可以使用不同的方法来想象这个变换,比如将相机向某个方向平移一段距离,效果等同于将被拍摄的模型(model)向相反的方向平移同样的距离(相对运动)。两个不同的空间想象方法对于理解坐标变换各有其优缺点。你可以使用适合自己理解能力的方法来想象空间坐标变换。
下面我们使用一个由两个坐标变换组成的简单例子开始介绍MODELVIEW变换:一个变换为逆时针绕Z轴旋转45度,另一个变换为为沿X轴平移。 假定需要绘制的物体的尺寸和平移的距离相比要小的多从而你可以跟容易的看到平移效果。这个物体初始位置在坐标系的原点。
如果先旋转物体然后再平移,旋转后的物体的位置在X轴上面,但如果先平移后绕原点旋转物体,最终物体会出现在y=x 的直线上:
可以看到坐标变换的次序直接影响到最终的变换结果。所有的Viewing和Modeling 变换操作都可以使用一个4X4 的矩阵来表示,所有后续的glMultMatrix*() 或其它坐标变换指令 会使用一个新的变换矩阵M于当前modelview矩阵C相乘得到一个新的变换矩阵CM。然后所有顶点坐标v 都会和这个新的变换矩阵相乘。 这个过程意味着最后发出的坐标变换指令实际上是第一个应用到顶点上的:CMv 。因此一种来理解坐标变换次序的方法是:使用逆序来指定坐标变换。
比如下面代码:
gl.glMatrixMode(GL_MODELVIEW); gl.glLoadIdentity(); //apply transformation N gl.glMultMatrixf(N); //apply transformation M glMultMatrixf(M); //apply transformation L gl.glMultMatrixf(L); //draw vertex ...
上面代码,modelview 矩阵依次为I(单位矩阵),N,NM最终为NML ,最终坐标变换的结果为 NMLv ,也就是N(M(Lv)) ,v首先与L相乘,结果Lv 再和M相乘,所得结果MLv 再和N相乘。可以看到坐标变换的次序和指令指定的次序正好相反。而实际代码运行时,坐标无需进行三次变换运算,顶点v 只需和计算出的最终变换矩阵NML 相乘一次就可以了。
因此如果你采用世界坐标系(原点和X,Y,Z轴方向固定)来思考坐标变换,代码中坐标变换指令的次序和 顶点和矩阵相乘的次序相反。比如,还是上面的例子,如果你想最终的物体出现在X轴上,此时必须是先旋转后平移,可以使用如下代码(R代表选择矩阵,T 代表平移矩阵)
gl.glMatrixMode(GL_MODELVIEW); gl.glLoadIdentity(); //translation gl.glMultMatrixf(T); //rotation gl.glMultMatrixf(R); draw_the_object()
另外一种想象坐标变换的方法是忘记这种固定的坐标系统,而是使用物体本身的局部坐标系统,这种局部坐标系和物体的相对位置是固定的。 所有的坐标变换操作都是针对物体的局部坐标系。使用这种方法,代码中矩阵相乘的次序和相对局部坐标系坐标变换的次序是一致的。(不关使用哪种方法来想象坐标变换,最终同样变换结果代码都是一样的,只是理解的方法不同)。还是使用上面旋转平移的例子。想象一个和物体连接一起的局部坐标系,如下图红色的坐标系,想象所有的坐标变换都是相对这个局部坐标系的,要使物体最终出现在y=x 上,可以想象先转动物体及其局部坐标系(R),然后再平移物体及其局部坐标系(T),这时代码的顺序和相对于物体局部坐标系的次序是相同的。
gl.glMatrixMode(GL_MODELVIEW); gl.glLoadIdentity(); //rotation gl.glMultMatrixf(R); //translation gl.glMultMatrixf(T); draw_the_object()
使用物体局部坐标系,可以更好的了解理解如机械手和太阳系之类的图形系统。
Android OpenGL ES 的GLU包有一个辅助函数gluLookAt提供一个更直观的方法来设置modelview 变换矩阵:
void gluLookAt(GL10 gl, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
- eyex,eyey,eyez 指定观测点的空间坐标。
- tarx,tary,tarz ,指定被观测物体的参考点的坐标。
- upx,upy,upz 指定观测点方向为“上”的向量。
注意: 这些坐标都采用世界坐标系。
Android OpenGL ES 开发教程(16):Viewing和Modeling(MODELVIEW) 变换相关推荐
- Android OpenGL ES 开发教程(20):颜色Color
OpenGL ES 支持的颜色格式为RGBA模式(红,绿,蓝,透明度).颜色的定义通常使用Hex格式0xFF00FF 或十进制格式(255,0,255), 在OpenGL 中却是使用0-1之间的浮点数 ...
- Android OpenGL ES 开发教程(24):Depth Buffer
OpenGL ES 中Depth Buffer 保存了像素与观测点之间的距离信息,在绘制3D图形时,将只绘制可见的面而不去绘制隐藏的面,这个过程叫"Hidden surface remova ...
- 【Android OpenGL ES 开发 (一)】使用c++开发opengles 与 日志功能 及 加载assets
创建OpenGLES视口 1.App窗口改成OpenGL窗口,是通过java调用C++,在以下位置修改如下内容 package com.example.learnogles;import androi ...
- 【Android OpenGL ES 开发 (二)】渲染管线与Shader
计算出每一帧耗费的时间 1.在头文件中加入time.h,cpp中实现如下计算时间接口 float GetFrameTime(){static unsigned long long lastTime=0 ...
- 【Android OpenGL ES 开发 (零)】创建一个新的工程
创建符合要求的AndroidApp 使用Android Studio开发,Android Studio下载地址 1.先创建Native C++ 2.项目相关添加 3.使用C++11标准 学习使用JNI ...
- 【Android OpenGL ES 开发 (四)】纹理相关(一)
纹理贴图的原理 1.作用:可以用来渲染视频. 2.纹理坐标 生成OpenGL中的纹理对象 1.像素数据想要绘制出来需要先变成纹理 2.创建纹理放在GPU上 GLuint CreateTexture2D ...
- 【Android OpenGL ES 开发 (五)】纹理相关(二)
纹理放大和缩小的过滤参数 1.使用线性插值效果最佳 2.通过修改 float maxscale = 4.0f //放大 float minscale = 0.5f //缩小 vertices[0] ...
- 【Android OpenGL ES 开发 (三)】Shader 扩展
编译Shader代码 1.封装一个编译shader的接口 GLuint CompileShader(GLenum shaderType,const char *shaderCode){GLuint s ...
- Android OpenGL ES 画出三棱锥
如今VR这么火,感觉有必要学学OpenGL.什么是OpenGL ES ,OpenGL ES (OpenGL for Embedded System ) 为适用于嵌入式系统的一个免费二维和三维图形库.O ...
最新文章
- 整理前端工作中的可复用代码(二):拓展spark-md5,支持计算网络文件md5
- Java好学吗 没基础能学会吗
- shp2sde命令行方式向arcsde批量导入数据脚本的生成步骤
- 欠条和借条傻傻分不清?小心借出的钱要不回!
- jmeter 高并发测试报告_JMeter分布式测试
- python脚本打包rpm_python程序打包rpm包
- 在Windows下删除Linux系统的方法
- python开发板卡驱动开发_一款能让你发挥无限创意的MicroPython开发板—TPYBoard开发板测...
- 机器学习入门——多项式回归
- 网络黑客节庆狂欢 趋势科技见招拆招
- 计算机桌面无法新建文件夹,Win7桌面不能新建文件夹和修改文件名怎么办?
- excel求回归直线方程的公式_如何用excel做线性回归分析-用excel做线性回归分析求回归方程...
- 查看html源代码编码,查看网页源代码全是乱码,但前台页面可以正常显示
- 2015年8月18日工作日志--------赵鑫
- Mac电脑使用:您的安全性偏好设置仅允许安装来自App Store和被认可的开发者的应用(解决方法)
- 基于运动学模型的轨迹跟踪控制
- 安卓键盘加上数字_安卓键盘键值对照表
- 以太网/串口连接开发板
- ElasticSearch支持根据英文或者数字进行模糊查询
- SSDsim simulation function:simulate()