Android官方开发文档Training系列课程中文版:OpenGL绘图之应用投影与相机视图

简介: 原文地址:http://android.xsoftlab.net/training/graphics/opengl/projection.html##transform在OpenGL ES环境中,投影相机View可以将所绘制的图形模拟成现实中所看到的物理性状。

原文地址:http://android.xsoftlab.net/training/graphics/opengl/projection.html##transform

在OpenGL ES环境中,投影相机View可以将所绘制的图形模拟成现实中所看到的物理性状。这种物理模拟是通过改变对象的数字坐标实现的:

  • 投影 - 这基于GLSurfaceView的高宽的坐标转换而实现。如果不采用这种计算,所绘制的对象就会由于窗口的不平等比例所曲解。投影转换只有在OpenGL视图的比例被确定或渲染器的onSurfaceChanged()方法发生改变后才会被计算。有关更多OpenGL的坐标映射关系,请参见Mapping Coordinates for Drawn Objects
  • 相机视图 - 这基于虚拟相机的位置转变而实现。要着重注意OpenGL并没有定义真实的相机对象,而是提供了一种通过转换图形对象来模拟相机的方法。一个相机视图转换只有在GLSurfaceView被确定的时候才会开始计算,或者基于用户的行为或者应用的功能而动态的发生改变。

这节课描述了如何创建一个投影相机视图,并将其应用到图形的绘制中。

定义投影

投影转换的数据计算位于GLSurfaceView.RendereronSurfaceChanged()方法。下面的代码先取得了GLSurfaceView的高度与宽度,然后使用Matrix.frustumM()方法将数据填充到投影转换的Matrix中。

// 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);
}
AI 代码解读

这些代码会填充投影矩阵:mProjectionMatrix,它可以被用来与相机视图转换整合。

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);
}
AI 代码解读

应用投影转换及相机转换

为了可以使用上面所整合完毕的矩阵,首先需要将该矩阵变量添加到上节课程所定义的顶点渲染器中:

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;
    ...
}
AI 代码解读

接下来,修改绘制物体对象的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);
}
AI 代码解读

如果有正确的计算结果以及正确的使用了整合后的矩阵,那么图形会以正确的比例被绘制出来,最后看起来的效果应该是这样子的:

现在程序就可以正常显示比例正常的图形了,是时候为图形添加动作了。

目录
打赏
0
0
0
0
1
分享
相关文章
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
89 1
安卓应用开发中的自定义视图
【9月更文挑战第37天】在安卓开发的海洋中,自定义视图犹如一座座小岛,等待着勇敢的探索者去发现其独特之处。本文将带领你踏上这段旅程,从浅滩走向深海,逐步揭开自定义视图的神秘面纱。
69 3
未来触手可及:探索新兴技术的趋势与应用安卓开发中的自定义视图:从基础到进阶
【8月更文挑战第30天】随着科技的飞速发展,新兴技术如区块链、物联网和虚拟现实正在重塑我们的世界。本文将深入探讨这些技术的发展趋势和应用场景,带你领略未来的可能性。
探索软件测试的艺术:从基础到高级安卓应用开发中的自定义视图
【8月更文挑战第29天】在软件开发的世界中,测试是不可或缺的一环。它如同艺术一般,需要精细的技巧和深厚的知识。本文旨在通过浅显易懂的语言,引领读者从软件测试的基础出发,逐步深入到更复杂的测试策略和工具的使用,最终达到能够独立进行高效测试的水平。我们将一起探索如何通过不同的测试方法来确保软件的质量和性能,就像艺术家通过不同的色彩和笔触来完成一幅画作一样。
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
安卓开发中的自定义视图:从入门到精通
【9月更文挑战第19天】在安卓开发的广阔天地中,自定义视图是一块充满魔力的土地。它不仅仅是代码的堆砌,更是艺术与科技的完美结合。通过掌握自定义视图,开发者能够打破常规,创造出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战应用,一步步展示如何用代码绘出心中的蓝图。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往创意和效率的大门。让我们一起探索自定义视图的秘密,将你的应用打造成一件艺术品吧!
110 10
安卓应用开发中的自定义视图基础
【9月更文挑战第13天】在安卓开发的广阔天地中,自定义视图是一块神奇的画布,它允许开发者将想象力转化为用户界面的创新元素。本文将带你一探究竟,了解如何从零开始构建自定义视图,包括绘图基础、触摸事件处理,以及性能优化的实用技巧。无论你是想提升应用的视觉吸引力,还是追求更流畅的交互体验,这里都有你需要的金钥匙。
安卓开发中的自定义视图控件
【9月更文挑战第14天】在安卓开发中,自定义视图控件是一种高级技巧,它可以让开发者根据项目需求创建出独特的用户界面元素。本文将通过一个简单示例,引导你了解如何在安卓项目中实现自定义视图控件,包括创建自定义控件类、处理绘制逻辑以及响应用户交互。无论你是初学者还是有经验的开发者,这篇文章都会为你提供有价值的见解和技巧。
93 3
Android平台实现屏幕录制(屏幕投影)|音频播放采集|麦克风采集并推送RTMP或轻量级RTSP服务
Android平台屏幕采集、音频播放声音采集、麦克风采集编码打包推送到RTMP和轻量级RTSP服务的相关技术实现,做成高稳定低延迟的同屏系统,还需要有配套好的RTMP、RTSP直播播放器
113 0
探索安卓开发中的自定义视图##
【9月更文挑战第6天】 在安卓应用开发的世界里,自定义视图如同绘画艺术中的色彩,它们为界面设计增添了无限可能。通过掌握自定义视图的绘制技巧,开发者能够创造出既符合品牌形象又提升用户体验的独特界面元素。本文将深入浅出地介绍如何从零开始构建一个自定义视图,包括基础框架搭建、关键绘图方法实现、事件处理机制以及性能优化策略。准备好让你的安卓应用与众不同了吗?让我们开始吧! ##

热门文章

最新文章