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. js实现多个小球碰撞

    实现思路:小球的移动,是通过改变小球的left和top值来改变,坐标分别为(x,y)当x/y值加到最大,即加到父级的宽度或者高度时,使x值或者y值减小,同理当x值或者y值减到最小时,同样的使x值或者y ...

  2. 如何进行PDF页码编排,如何调整PDF页码顺序

    PDF文件的页码顺序如何进行调整?许多小伙伴们都不知道,我们在编辑的时候只知道PDF文件的编辑方法,但是调整页码的顺序我们或许不会,但是如何去进行操作呢?看小编的方法吧!如果我们想要修改PDF文件中的 ...

  3. git clone下载代码

    下载master代码git clone http://username:password@git.wondershare.cn/XXX.git 下载指定develop分支代码git clone -b ...

  4. ASP.NET Core快速入门学习笔记(第1章:介绍与引入)

    课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务1:课程介绍 任务2:环境安装 下载地址:https://dotnet.m ...

  5. Nginx 自定义添加Response Headers 修改server

    之前说过如何隐藏Response Headers中 X-Powered-By 修改php.ini expose_php = Off service php-fpm reload 隐藏Nginx版本号  ...

  6. SharePoint修改左上角文字的命令行

    $webapp = Get-SPWebApplication “http://test-spweb1” --需要修改的站点$webapp.SuiteNavBrandingText = “XXXXXX” ...

  7. python之socketserver实现并发

    python之socketserver实现并发 服务端 import socketserver #socketserver模块是用来实现并发 # 我们自己的类里一定要继承socketserver.Ba ...

  8. ISP PIPLINE (十) HDR

    在讲HDR之前先理解一些概念,要知道为什么进行HDR? 再去想如何进行HDR. 自然界的中光强度很宽,而人眼对高亮,极暗环境的细节分辨能力比较弱.而摄像头记录的范围更窄,真正的HDR技术就是记录视觉范 ...

  9. Simple 杂题练手记

    Problem 1 世界上最可爱的珂朵莉 时间限制:C/C++ 1秒,空间限制:C/C++ 65536K 题目描述 我永远喜欢珂朵莉~! 有两个长为n的序列a[i]与b[i] 你可以把任意不多于x个a ...

  10. Python函数zip-map

    >>> list(zip([1,3,5,7],[2,4,6,8]))[(1, 2), (3, 4), (5, 6), (7, 8)] 把两个列表合成一个 也可以用map函数: > ...