Android OpenGL ES(四)----调整屏幕的宽高比(二)

简介: Android OpenGL ES(四)----调整屏幕的宽高比(二)

5.正交投影


要定义正交投影,我们将使用Android的Matrix类,它在android.opengl包中。这个类有一个称为orthoM()的方法,它可以为我们生成一个正交投影。


我们来看一下orthoM()参数:


orthom(float[] m,int mOffset,float left,float rigth,float bottom,float top,float near,float far)


float[] m:目标数组,这个数组长度至少有16个元素,这样它才能存储正交投影矩阵。


int mOffset:结果矩阵起始的偏移值。


float left:X轴的最小范围。


float right:X轴的最大范围。


float bottom:Y轴的最小范围。


float top:Y轴的最大范围。


float near:Z轴的最小范围。


float far:Z轴的最大范围。


当我们调用这个方法的时候,它应该产生下面的正交投影矩阵:

18.png

这个正交投影矩阵会把所有在左右之间,上下之间和远近之间的事物映射到归一化设备坐标中从-1到1的范围,在这个范围内所有事物在屏幕上都是可见的。


主要的区别就是Z轴有一个负值符号,它的效果是反转Z坐标。这就意味着,物体离得越远,Z坐标的负值会越来越小。之所以这样完全是历史和传统的原因。



6.左手与右手坐标系统


为了更好的理解Z轴问题,我们需要理解左手坐标系统与右手坐标系统之间的区别。想知道一个坐标系统是左手的还是右手的,你拿出一只手,把大拇指指向X轴正值方向,然后把食指指向Y轴正值方向。


现在,把你的中指指向Z轴。如果你需要用左手做这些,那你看到的就是一个左手坐标系统;如果你需要用右手,那你看到的就是一个右手坐标系统。把你的中指指向Z轴,记住要把大拇指指向X轴方向,食指指向Y轴正值方向。如下图:


19.png

其实左手还是右手选择都没关系,只是一个简单的转换。归一化设备坐标使用的是左手坐标系统,而在OpenGL的早期版本,默认使用的确实右手坐标系统,其使用Z的负值增加表示距离增加。这就是为什么Android的Matrix会默认生成反转Z的矩阵。


7.更新程序


7.1更新着色器

修改前一章的顶点着色器中的代码如下:

uniform mat4 u_Matrix;
attribute vec4 a_Position;    
 attribute vec4 a_Color;
 varying vec4 v_Color;
 void main()                    
 {
     v_Color=a_Color;
     gl_Position = u_Matrix*a_Position;
     gl_PointSize = 10.0;
 }


我们这里添加了一个新的uniform定义的“u_Matrix”,并把它定义为一个mat4类型,意思是这个uniform代表一个4*4的矩阵。更新位置负值那一行:

gl_Position =u_Matrix*a_Position;

我们没有传递数组中定义的位置,而是传递那个位置与一个矩阵的乘积。它意味着顶点数组不用再被翻译为归一化设备的坐标了,其将被理解为存在于这个矩阵所定义的虚拟坐标空间中。这个矩阵会把坐标从虚拟坐标空间变化回归一化设备坐标。


7.2添加矩阵数组和一个新的uniform

打开上一节的LYJRenderer添加成员变量:

private static final String U_MATRIX="u_Matrix";

我们还需要一个顶点数组存储矩阵:

private final float[] projectionMatrix=new float[16];


我们也需要一个整型值用于保存那个矩阵uniform的位置:


private int uMatrixLocation;

然后我们只需要在onSurfaceCreated()中加入如下代码:

uMatrixLocation=GLES20.glGetUniformLocation(program,U_MATRIX);


7.3创建正交投影矩阵

更新onSurfaceChanged(),在GLES20.glViewport()调用后面加入如下代码:

final float aspectRatio=width>height?(float)width/(float)heigth:(float)height/(float)width;
if(width>height){
orthoM(projectionMatrix,0,-aspectRatio,aspectRatio,-1f,1f,-1f,1f);
}else{
orthoM(projectionMatrix,0,-1f,1f,-aspectRatio,aspectRatio,-1f,1f);
}


这段代码会创建一个正交投影矩阵,这个矩阵会把屏幕的当前方向计算在内。注意在Android中不只有一个Matrix类,因此你要确保导入了android.opengl.Matrix。


我们首先计算了宽高比,它使用宽和高中的较大值除以宽和高的较小值。不管是竖屏还是横屏,这个值都一样。


7.4传递矩阵给着色器

在LYJRenderer中的onDrawFrame()中,我们在glClear()调用之后加入如下代码:

GLES20.glUniformMatrix4fv(uMatrixLocation,1,false,projectionMatrix,0);


相关文章
|
6月前
|
JavaScript Android开发
使用贝叶斯曲线滑动安卓屏幕(autojsPro7)
使用贝叶斯曲线滑动安卓屏幕(autojsPro7)
237 0
|
6月前
|
开发工具 Android开发
rk平台Android12屏幕永不休眠
rk平台Android12屏幕永不休眠
110 1
|
2月前
|
编解码 开发工具 Android开发
Android平台实现屏幕录制(屏幕投影)|音频播放采集|麦克风采集并推送RTMP或轻量级RTSP服务
Android平台屏幕采集、音频播放声音采集、麦克风采集编码打包推送到RTMP和轻量级RTSP服务的相关技术实现,做成高稳定低延迟的同屏系统,还需要有配套好的RTMP、RTSP直播播放器
|
5月前
|
Android开发
Android 自定义View 测量控件宽高、自定义viewgroup测量
Android 自定义View 测量控件宽高、自定义viewgroup测量
93 0
|
5月前
|
开发工具 Android开发 git
Android自定义View——可以设置最大宽高的FrameLayout
Android自定义View——可以设置最大宽高的FrameLayout
264 0
|
5月前
|
JSON Android开发 数据格式
Android动态添加view设置view大小(宽高)
Android动态添加view设置view大小(宽高)
136 0
|
6月前
|
Shell Android开发
ADB更改Android设备屏幕显示方向
ADB更改Android设备屏幕显示方向
351 5
|
6月前
|
Android开发
获取Android设备屏幕大小
获取Android设备屏幕大小
123 3
|
6月前
|
Java Android开发
Android开发之使用OpenGL实现翻书动画
本文讲述了如何使用OpenGL实现更平滑、逼真的电子书翻页动画,以解决传统贝塞尔曲线方法存在的卡顿和阴影问题。作者分享了一个改造后的外国代码示例,提供了从前往后和从后往前的翻页效果动图。文章附带了`GlTurnActivity`的Java代码片段,展示如何加载和显示书籍图片。完整工程代码可在作者的GitHub找到:https://github.com/aqi00/note/tree/master/ExmOpenGL。
155 1
Android开发之使用OpenGL实现翻书动画
|
6月前
|
Android开发 开发者
Android开发之OpenGL的画笔工具GL10
这篇文章简述了OpenGL通过GL10进行三维图形绘制,强调颜色取值范围为0.0到1.0,背景和画笔颜色设置方法;介绍了三维坐标系及与之相关的旋转、平移和缩放操作;最后探讨了坐标矩阵变换,包括设置绘图区域、调整镜头参数和改变观测方位。示例代码展示了如何使用这些方法创建简单的三维立方体。
78 1
Android开发之OpenGL的画笔工具GL10