注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。

原文链接:http://developer.android.com/training/graphics/opengl/projection.html


在OpenGL ES环境中,投影和相机视图允许你显示绘图对象时,可以以一个更加酷似于你用肉眼看到的真实物体。这个物理视图的仿真是使用绘制对象坐标的数学变换实现的:

  • 投影(Projection) - 这个变换会基于显示它们的GLSurfaceView的长和宽,来调整绘图对象的坐标。如果没有这个计算,那么用OpenGL ES绘制的对象会由于视图窗口比例的不匹配而发生形变。一个投影变换一般仅需要在渲染器的onSurfaceChanged()方法中,OpenGL视图的比例建立时或发生变化时才被计算。关于更多OpenGL ES投影和坐标映射的知识,可以阅读Mapping Coordinates for Drawn Objects
  • 相机视图(camera view) - 这个变化会基于一个虚拟相机位置改变绘图对象的坐标。注意到OpenGL ES并没有定义一个实际的相机对象,但是取而代之的,它提供了一些辅助方法,通过变化绘图对象的显示来模拟相机。一个相机视图变换可能仅在你建立你的GLSurfaceView时计算一次,也可能根据用户的行为或者你的应用的功能进行动态调整。

这节课将解释如何创建一个投影和一个相机视图,并应用它们到GLSurfaceView中的绘制图像上。


一). 定义一个投影

投影变换的数据会在你的GLSurfaceView.Renderer类中的onSurfaceChanged()方法中被计算。下面的代码首先接收GLSurfaceView的高和宽,然后用它来填充一个投影变换矩阵(Matrix),使用Matrix.frustumM()方法:

@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height); float ratio = (float) width / height; // this projection matrix is applied to object coordinates
// in the onDrawFrame() method
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}

该代码填充了一个投影矩阵:mProjectionMatrix,在下一节中,你可以在onDrawFrame()将它和一个相机视图变换结合起来。

Note:

在你的绘图对象上只应用一个投影变换会导致一个看上去很空的显示。一般而言,你必须同时为每一个要在屏幕上显示的任何东西实现一个相机视图。


二). 定义一个相机视图

通过添加一个相机视图变换作为绘图过程的一部分,以此来完成你的绘图对象变换的所有步骤。在下面的代码中,使用Matrix.setLookAtM()方法来计算相机视图变换,然后与之前计算的投影矩阵结合起来。结合后的变换矩阵传递给绘制图像:

@Override
public void onDrawFrame(GL10 unused) {
...
// Set the camera position (View matrix)
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); // Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0); // Draw shape
mTriangle.draw(mMVPMatrix);
}

三). 应用投影和相机变换

为了使用在之前章节中结合了的相机视图变换和投影变换,修改你的图形对象的draw()方法,接收结合的变换并将其应用到图形上:

public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
... // get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); // Pass the projection and view transformation to the shader
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0); // Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
...
}

一旦你正确地计算了投影变换和相机视图变换,并应用了它们,你的图形就会以正确的比例画出,看上去会像是这样:

图1. 应用了投影变换和相机视图变换的三角形

现在你有了一个能以正确的比例显示你的图形的应用了,下面就该为图形添加一些动画效果了!

【Android Developers Training】 65. 应用投影和相机视图的更多相关文章

  1. 【Android Developers Training】 61. 序言:使用OpenGL ES显示图像

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  2. 【Android Developers Training】 50. 控制相机

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  3. 【Android Developers Training】 66. 添加动画

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  4. 【Android Developers Training】 64. 绘制形状

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  5. 【Android Developers Training】 101. 显示快速联系人挂件(Quick Contact Badge)

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  6. 【Android Developers Training】 99. 获取联系人详细信息

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  7. 【Android Developers Training】 98. 获取联系人列表

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  8. 【Android Developers Training】 16. 暂停和恢复一个Activity

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  9. 【Android Developers Training】 75. 使用NSD

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

随机推荐

  1. 清理我的 Mac

    在Macbook使用久之后,会发现本来还富裕的硬盘,变得越来越少,尤其现在Macbook使用容量很小的固态硬盘.在此种情况下,该如何清理Macbook垃圾文件,以保证Macbook有足够空间做其他事情 ...

  2. 在web项目启动时,使用监听器来执行某个方法

    在web项目中有很多时候需要在项目启动时就执行一些方法,而且只需要执行一次,比如:加载解析自定义的配置文件.初始化数据库信息等等,在项目启动时就直接执行一些方法,可以减少很多繁琐的操作. 这里写了个简 ...

  3. 配置网络yum源

    有的时候服务器需要下载一些软件,是本地yum源没有的,这时候需要配置网络yum源 #cd  /etc/yum.repos.d/ 把这个目录下的配置文件备份,改名:或者是把文件里边的enabled=1的 ...

  4. 【WPF】三维模型中的“照相机”

    WPF 部分支持三维模型,为啥说是部分支持?毕竟 WPF 的侧重点还是在应用开发上,虽然也有些游戏是用 WPF 开发的,不过,老周想啊,如果真要开发游戏,最好用专门的框架,WPF 应当用于开发应用功能 ...

  5. 028hibernate缓存(性能优化策略)

    一级缓存 二级缓存 查询缓存 缓存是为了提高性能 变化不是很大,相对静态的对象放入缓存 对象的创建比较耗时

  6. 001---Hibernate简介( 开源O/R映射框架)

    该系列教程是使用hibernate3,hibernate4和3有区别(集成spring,使用等),请注意 001---Hibernate简介(开源O/R映射框架) ORM(Object Relatio ...

  7. SharePoint 服务器端对象迁移文件夹

    最近有个需求,写个定时迁移文件夹的小程序,因为计时器任务比较繁琐,所以选择了控制台程序.然后,用windows的计划任务执行,也许,会有广大朋友需要类似的功能,简单的分享一下代码逻辑,功能非常简单,希 ...

  8. php实现批量修改文件名称

    场景叙述:比如我要将D:\WWW\img\Gastroenterology这个文件夹下图片要重新命名成1.jpg,2.jpg.......这样的有规律名字, 如下图: 那么我们就可以利用php的ren ...

  9. [原创]CentOS下Mysql双机互为备份

    一.环境: 1.安装Centos-6.5-x64位系统的机器两台: host1:192.168.2.3 host2:192.168.2.4  (互相能ping通) 2.安装Mysql. 命令:Yum ...

  10. 深入tornado中的http1connection

    前言 tornado中http1connection文件的作用极其重要,他实现了http1.x协议. 本模块基于gen模块和iostream模块实现异步的处理请求或者响应. 阅读本文需要一些基础的ht ...