专栏首页Flutter入门Android OpenGL ES(二)-正交投影

Android OpenGL ES(二)-正交投影

上文Android OpenGL ES(一)-开始描绘一个平面三角形中我们已经成功描绘了一个三角形。但是奇怪的是,按照我们的坐标。期望得到的应该是一个等腰三角形。但是最后的结果,确实一个扁平的三角形。

OpenGL ES世界的基本元素

着色器 坐标系。矩阵 纹理 ... 本文主要涉及的部分是矩阵。

直接开始

我们先快速过一下矩阵的基础知识

矩阵基础知识

单位矩阵

单位矩阵.png

任何一个矩阵乘以单位矩阵,都依旧是器本身。

平移矩阵

平移矩阵.png

平移矩阵和单位矩阵和类似。但是向量[x,y,z,1]前乘这个平移矩阵后的结构就是平移矩阵中定义的偏移量。

这里需要注意的。第四个变量其实是w。而在OpenGL中,如果我们不去定义这个w。默认就是1.

OpenGL的坐标系

归一化设备坐标

我们之前定义的坐标系。是OpenGL中的坐标系。x,y,z都映射到了[-1,1]的范围内。这个范围内的坐标我们称之为归一化设备坐标。他是独立于屏幕实际的尺寸和形状的。

 private static float TRIANGLE_COORDS[] = {
            //Order of coordinates: X, Y, Z
            0.5f, 0.5f, 0.0f, // top
            -0.5f, -0.5f, 0.0f, // bottom left
            0.5f, -0.5f, 0.0f   // bottom right
    };

归一化设备坐标.png

但是显而易见的,我们的手机的宽高比,明显不可能是1:1。而我们设置视口(ViewPort)时,又使用了初始化传入的宽和高。

手机的宽高.png

设置viewport的代码

  @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        //在窗口改变的时候调用
        GLES20.glViewport(0,0,width,height);
    }

虚拟空间坐标系

我们应该停止直接在归一化坐标上工作,转而在虚拟空间坐标系中工作。 调整坐标空间。我们需要将虚拟空间坐标转换成归一化设备坐标,让OpenGL可以正确的渲染它们。 这种操作就是使用正交投影

正交立方体内的场景.png

一个正交投影.png

正交投影

正交投影其实可以当作是一个正视图。 我们可以调用这个方法来得到正交矩阵。

/ * float[] 目标数组。只要的有16个元素,才能存储正交投影矩阵
 * mOffset 结果矩阵起始的偏移量
 * left    x轴的最小范围
 * right   x轴的最大范围
 * bottom  y轴的最小范围
 * top     y轴的最大范围
 * near    z轴的最小范围
 * far     z轴的最大范围
**/
 Matrix.orthoM(mProjectionMatrix, 0, -aspectRatio, aspectRatio, -1, 1f, -1.f, 1f);

得到的矩阵如下图

正交投影矩阵.png

  • 和平移矩阵相似 回到开头我们复习的平移矩阵。是不是两者是否相似。 我们可以理解为,其实就是将坐标缩放和平移到我们的归一化坐标中。
  • 和平移矩阵不同 当时有一个地方不同的是z轴的正负。 原因是归一化的设备坐标系使用的是左手。而OpenGL使用的是右手。所以要转化成归一化坐标,就需要反过来。

代码实现

基于上一节的代码做下面的修改。 其实还是我们的上一节总结的套路。

着色器定义属性=>代码传递更新

我们需要着色器的代码中定义一个矩阵的常量。再将计算好的矩阵。传入其中

更新着色器的代码

在着色器中定义一个matrix,并与position相乘。

//定义一个matrix。相当于4x4的矩阵
uniform mat4 u_Matrix;
attribute vec4 a_Position;
void main() {
    //与position相乘
    gl_Position =u_Matrix* a_Position;
}

计算矩阵

onSurfaceChanged生命周期方法中,计算我们的投影矩阵。

   //投影矩阵
   private float[] mProjectionMatrix = new float[16];

   @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        super.onSurfaceChanged(gl, width, height);
        //主要还是长宽进行比例缩放
        float aspectRatio = width > height ?
                (float) width / (float) height :
                (float) height / (float) width;

        if (width > height) {
            //横屏。需要设置的就是左右。
            Matrix.orthoM(mProjectionMatrix, 0, -aspectRatio, aspectRatio, -1, 1f, -1.f, 1f);
        } else {
            //竖屏。需要设置的就是上下
            Matrix.orthoM(mProjectionMatrix, 0, -1, 1f, -aspectRatio, aspectRatio, -1.f, 1f);
        }
    }

激活属性。并传递值

在生命周期方法onDrawFrame中。

 @Override
    public void onDrawFrame(GL10 gl) {
        super.onDrawFrame(gl);

        //传递给着色器
        GLES20.glUniformMatrix4fv(uMatrix,1,false,mProjectionMatrix,0);

        //...
    }

结果

结果.png

和我们预想的结果一样。撒花~~

总结一下,我们从这这章节的内容了解到了下面这些使用的知识点:

  1. 矩阵的知识回顾
  2. 正交投影变换

但是我们现在还依然是平面的图。因为正交投影其实相当于正视图。 后面我们会先根据这章的内容画出其他图形。 然后再将其变成三维的样子。

整体的代码位置:https://github.com/deepsadness/OpenGLDemo5

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android模块化编译速度解决方案模块化完整方案

    在Project目录下添加我们需要的公共的假数据。 如下图所示的是,在编译circle这个module为Application时,自动会在文件夹位置,添加对应...

    deep_sadness
  • Kotlin中的后备字段backing fieldKotlin中的backing field

    什么是Kotlin中的后备字段backing field?这个问题确实困扰了我很久。

    deep_sadness
  • Vue 脚手架项目分析

    babel-preset-env是一个新的预设,可以让你指定一个环境并自动使能需要的插件。 支持拥有超过1%市场份额的浏览器

    deep_sadness
  • python中矩阵相加函数sum()

    py3study
  • 【每日一题】1445: [蓝桥杯][历届试题]最大子阵

    节日快乐,筒子们! 不过小编还是给大家准备了每日一题! 2333 题目描述 给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。 其...

    编程范 源代码公司
  • 线性代数--MIT18.06(二十六)

    特征值的性质我们已经知道了,由于是对称矩阵的性质,我们再看下它的特征向量,因为特征向量正交,基于十七讲的内容,我们总可以将正交向量矩阵转化为正交矩阵,因此我们就...

    fireWang
  • 列出Windows域中所有的机器

    我所在的部门大概管理了300+台Windows终端,最近开始采用域的方式来进行管理。(别笑我们土,原来手工修改Windows口令太痛苦了。)

    大江小浪
  • Octave入门之数据操作—ML Note28

    机器学习最离不开的就是数据。我们使用Octave写机器学习代码的时候,如何将硬盘上的数据导入Octave中?如何将这些数据放入矩阵?如何将计算的结果数据保存下来...

    讲编程的高老师
  • 自然场景文本检测识别技术综述

    番外 青蛇: 姐, 图像文本检测和识别领域现在的研究热点是什么? 白蛇: 白纸黑字的扫描文档识别技术已经很成熟,而自然场景图像文本识别的效果还不理想。倾斜字、艺...

    SIGAI学习与实践平台
  • OCR大突破:Facebook推出大规模图像文字检测识别系统——Rosetta

    作者 | Fedor Borisyuk,Albert Gordo,Viswanath Sivakumar

    AI科技大本营

扫码关注云+社区

领取腾讯云代金券