Part I 空气曲棍球 Chapter5(5.5 Adding an Orthographic Projection)

5.5 增加正侧投影(Adding an Orthographic Projection)

    现在我们可以在项目中添加正交投影并且修复桌面压缩的问题了。

5.5.1 更新着色器(Updating the Shader)

    首先是更新着色器以便使用我们提供的矩阵对顶点位置进行变换,如果你还没有打开项目AirHockeyOrtho,那现在打开并按照如下代码更新着色器simple_vertex_shader.glsl:

//AirHockeyOrtho/res/raw/simple_vertex_shader.glsl
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类型变量代表一个4x4的矩阵,同时按如下代码更新顶点赋值:

//AirHockeyOrtho/res/raw/simple_vertex_shader.glsl
gl_Position = u_Matrix * a_Position;

    在这里并不是直接传递顶点数据,而是把矩阵与位置向量相乘,这将会执行前面我们介绍过的矩阵乘法操作,这也意味着我们的顶点数组将不再解释为规范化设备坐标系,而是解释为matrix定义的虚拟视界坐标;矩阵matrix将会执行从虚拟视界坐标到规范化设备坐标的转换。

5.5.2 增加投影矩阵(Adding the Matrix Array and a New Uniform)

    打开AirHockeyRenderer并在顶部增加如下定义:

//AirHockeyOrtho/src/com/airhockey/android/AirHockeyRenderer.java
private static final String U_MATRIX = "u_Matrix";

    这个变量将会持有我们在顶点着色器中定义的uniform变量的名字,我们还定义了如下变量存储matrix矩阵:

//AirHockeyOrtho/src/com/airhockey/android/AirHockeyRenderer.java
private final float[] projectionMatrix = new float[16];

    定义如下integer类型变量存储matrix在OpenGL中的位置引用:

//AirHockeyOrtho/src/com/airhockey/android/AirHockeyRenderer.java
private int uMatrixLocation;

    在onSurfaceCreated()中增加如下代码获得matrix的位置引用:

//AirHockeyOrtho/src/com/airhockey/android/AirHockeyRenderer.java
uMatrixLocation = glGetUniformLocation(program, U_MATRIX);

5.5.3 创建正交投影矩阵(Creating the Orthographic Projection Matrix)

    下一步是更新onSurfaceChanged(),在glViewport()调用的后面增加如下代码:

//AirHockeyOrtho/src/com/airhockey/android/AirHockeyRenderer.java
final float aspectRatio = width > height ?
(float) width / (float) height :
(float) height / (float) width;
if (width > height) {
    // Landscape
    orthoM(projectionMatrix, 0, -aspectRatio, aspectRatio, -1f, 1f, -1f, 1f);
} else {
    // Portrait or square
    orthoM(projectionMatrix, 0, -1f, 1f, -aspectRatio, aspectRatio, -1f, 1f);
}

    这部分代码将会根据屏幕的方向创建一个正交投影矩阵,它将会设置一个虚拟视界坐标系,在Android中有多个Matrix类,你需要确定你导入的是android.opengl.Matrix中的类。
    首先计算屏幕比例,用大边除以小边,这个值不管是横屏还是竖屏都是一样的。
    然后调用方法orthoM(float[] m, int mOffset, float left, float right, float bottom, float top, float near, float far),假如我们在横屏模式,则将会拉伸坐标系宽度为-aspectRatio到aspectRatio,高度仍然保持为-1到1;假如我们在竖屏模式,将会拉伸高度而保持宽度为-1到1。

5.5.4 把矩阵传递给着色器(Sending the Matrix to the Shader)

    最后一步是将矩阵传递给着色器,在onDrawFrame()中glClear()的后面增加代码:    

//AirHockeyOrtho/src/com/airhockey/android/AirHockeyRenderer.java
glUniformMatrix4fv(uMatrixLocation, 1, false, projectionMatrix, 0);

5.5.5 运行结果(Viewing Our Changes)

    现在项目在横屏模式及竖屏模式下运行截图如下:


5.5.6 更新顶点数据(Updating the Table Data)

    现在桌面在竖屏和横屏模式下的显示都保持一致,这正是我们所要的,但是看起来并不是很正确;现在更新顶点数组让桌面看起来更高(仅仅更新tableVerticesWithTriangles的y坐标),如下:

//AirHockeyOrtho/src/com/airhockey/android/AirHockeyRenderer.java
float[] tableVerticesWithTriangles = {
    // Order of coordinates: X, Y, R, G, B
    // Triangle Fan
       0f,    0f, 1f, 1f, 1f,
    -0.5f, -0.8f, 0.7f, 0.7f, 0.7f,
     0.5f, -0.8f, 0.7f, 0.7f, 0.7f,
     0.5f,  0.8f, 0.7f, 0.7f, 0.7f,
    -0.5f,  0.8f, 0.7f, 0.7f, 0.7f,
    -0.5f, -0.8f, 0.7f, 0.7f, 0.7f,
    // Line 1
    -0.5f,    0f,   1f,   0f,   0f,
     0.5f,    0f,   1f,   0f,   0f,
    // Mallets
       0f, -0.4f,   0f,   0f,   1f,
       0f,  0.4f,   1f,   0f,   0f
}

    现在竖屏及横屏模式下的运行结果如下:

    现在看起来更新一个现实中的桌面了,而且在横屏及竖屏模式下保持显示效果一致。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值