OpenGL ES环境允许你以更接近于你眼睛看到的物理对象的方式来显示你绘制的对象。物理查看的模拟是通过对你所绘制的对象的坐标进行数学变换完成的:

  • Projection — 这个变换是基于他们所显示的GLSurfaceView的宽和高来调整绘制对象的坐标的。没有这个计算变换,通过OpenGL绘制的形状会在不同显示窗口变形。这个投影变化通常只会在OpenGL view的比例被确定或者在你渲染器的onSurfaceChanged()方法中被计算。想要了解更多的关于投影和坐标映射的相关信息,请看绘制对象的坐标映射。
  • Camera View — 这个换是基于虚拟的相机的位置来调整绘制对象坐标的。需要着重注意的是,OpenGL ES并没有定义一个真实的相机对象,而是提供一个实用方法,通过变换绘制对象的显示来模拟一个相机。相机视图变换可能只会在你的GLSurfaceView被确定时被计算,或者基于用户操作或你应用程序的功能来动态改变。

本课程描述怎样创建投影和相机视图并将其应用的到你的GLSurfaceView的绘制对象上。

定义投影

投影变化的数据是在你GLSurfaceView.Renderer类的onSurfaceChanged()方法中被计算的。下面的示例代码是获取GLSurfaceView的高和宽,并通过Matrix.frustumM()方法用它们填充到投影变换矩阵中。

// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16]; @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,mProjectionMatrix可以在onFrameDraw()方法中与下一部分的相机视图结合在一起。

注意:如果仅仅只把投影矩阵应用的到你绘制的对象中,通常你只会得到一个非常空的显示。一般情况下,你还必须为你要在屏幕上显示的任何内容应用相机视图。

定义相机视图

通过在你的渲染器中添加相机视图变换作为你绘制过程的一部分来完成你的绘制图像的变换过程。在下面的代码中,通过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);
}

应用投影和相机变换

为了使用在上一部分内容中展示的投影和相机视图变换的合并矩阵,首先要在之前Triangle类中定义的定点着色器代码中添加一个矩阵变量:

public class Triangle {

    private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
// the matrix must be included as a modifier of gl_Position
// Note that the uMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
" gl_Position = uMVPMatrix * vPosition;" +
"}"; // Use to access and set the view transformation
private int mMVPMatrixHandle; ...
}

下一步,修改你的图形对象的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); // Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}

一旦你正确的计算并应用投影和相机视图变换,你的绘图对象将会以正确的比例绘制,它看起来应该像下面这样:

现在你已经有一个可以以正确比例显示图形的应用了。后面的章节,我们可以了解如何为你的图形添加运动了。

Android OpenGL ES 开发(五): OpenGL ES 使用投影和相机视图的更多相关文章

  1. 【Android Developers Training】 65. 应用投影和相机视图

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

  2. 在Android中使用OpenGL ES开发第(四)节:相机预览

    笔者之前写了三篇Android中使用OpenGL ES入门级的文章,从OpenGL ES的相关概念出发,分析了利用OpenGL ES实现3D绘图的重要的两个步骤:定义形状和绘制形状,简单的绘制了一个三 ...

  3. Android OpenSL ES 开发:OpenSL ES利用SoundTouch实现PCM音频的变速和变调

    缘由 OpenSL ES 学习到现在已经知道 OpenSL ES 不仅能播放和录制PCM音频数据,还能改变声音大小.设置左声道或右声道播放.还能变速播放,可谓是播放音频的王者.但是变速有一点不好的就是 ...

  4. Android 音视频开发(五):使用 MediaExtractor 和 MediaMuxer API 解析和封装 mp4 文件

    一个音视频文件是由音频和视频组成的,我们可以通过MediaExtractor.MediaMuxer把音频或视频给单独抽取出来,抽取出来的音频和视频能单独播放: 一.MediaExtractor API ...

  5. Android OpenGL ES 开发(六): OpenGL ES 添加运动效果

    在屏幕上绘制图形只是OpenGL的相当基础的特点,你也可以用其他的Android图形框架类来实现这些,包括Canvas和Drawable对象.OpenGL ES为在三维空间中移动和变换提供了额外的功能 ...

  6. Android OpenSL ES 开发:Android OpenSL 介绍和开发流程说明

    一.Android OpenSL ES 介绍 OpenSL ES (Open Sound Library for Embedded Systems)是无授权费.跨平台.针对嵌入式系统精心优化的硬件音频 ...

  7. Android 音视频开发学习思路

    Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...

  8. Android音视频开发(1):H264 基本原理

    前言 H264 视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的.随着 x264/openh264 以及 ffmpeg 等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大 ...

  9. 在Android中使用OpenGL ES开发第(五)节:GLSL基础语法

    一.前期基础储备笔者之前的四篇文综述了Android中使用OpenGL ES绘制基本图形和实现了简单的相机预览,初次接触OpenGL ES开发的读者可能对其中新的概念比较迷惑,尤其是其中的顶点着色器( ...

随机推荐

  1. angular6、7 兼容ie9、10、11

    1. 找到 polyfill.ts 并打开注释 /** * This file includes polyfills needed by Angular and is loaded before th ...

  2. 用servlet进行用户名和密码校验

    用servlet进行用户名和密码校验 先来看看效果-- 这里为了方便查看,密码框并没有使用password输入框,而是使用了text框 总体来说思路还是比较简单 1.先来个form,配置好action ...

  3. Debian+Django+uWsgi+nginx+mysql+celery

    下载系统各种依赖 nano /etc/apt/sources.list 在Debian中使用apt-get安装软件包时经常会提示让你插入netinst的光盘: Media change: please ...

  4. RabbitMQ教程

    1.引言 RabbitMQ——Rabbit Message Queue的简写,但不能仅仅理解其为消息队列,消息代理更合适.RabbitMQ 是一个由 Erlang 语言开发的AMQP(高级消息队列协议 ...

  5. DDD - 概述 - 聚合 - 限界上下文 (四)

    最重要的一句话 DDD的所有有相关理论中,只有一句是至关重要的,但是也是最容易被忽略和最难做到的,抛弃传统的设计方式(思路)的思想,这句话起了决定性的作用,但是99%的人都忽略了或者在开始无法正视或理 ...

  6. 利用阿里云搭建frp实现外网远程桌面链接内网电脑

    主要应用场景:针对学生放假回家使用外网无法远程操作学校的服务器或者电脑,这里通过阿里云的云服务器搭建一个frp服务,实现内网穿透,从而可以直接通过远程桌面或者其他工具实现对校园网内的服务器或者电脑进行 ...

  7. Go之十大经典排序算法

    1.冒泡排序 func bubble_sort(li []int) { for i := 0; i < len(li)-1; i++ { exchange := false for j := 0 ...

  8. Jfianl框架定时器使用配置

    Jfianl 自2.3版本后就整合了定时器到框架中,赞一个: 下面我来总结下自己使用cron4j到达定时效果的经验,不足之处还请见谅: Cron4jPlugin是作为JFinal的Plugin而存在的 ...

  9. 2018年多校第三场第一题 A. Ascending Rating hdu6319

    比赛地址:http://acm.hdu.edu.cn/contests/contest_show.php?cid=804 题目编号:第一题 A. Ascending Rating  hdu6319 题 ...

  10. Linux之环境搭建(二)

    上一节介绍了PC机安装Ubuntu,本节来看看Ubuntu下安装VMWare,以及在VMWare中安装Windows10. 原本想使用免费的VMware Workstation Player 15,但 ...