Android OpenGL ES 学习(四) -- 正交投影

这篇具有很好参考价值的文章主要介绍了Android OpenGL ES 学习(四) -- 正交投影。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

OpenGL 学习教程
Android OpenGL ES 学习(一) – 基本概念
Android OpenGL ES 学习(二) – 图形渲染管线和GLSL
Android OpenGL ES 学习(三) – 绘制平面图形
Android OpenGL ES 学习(四) – 正交投屏
Android OpenGL ES 学习(五) – 渐变色
Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序
Android OpenGL ES 学习(七) – 纹理
代码工程地址: https://github.com/LillteZheng/OpenGLDemo.git

这里的内容基本参考于 https://www.jianshu.com/p/51a405bc52ed ,这里再补充些矩阵相关的知识。

这里先简单解决变形的问题,关于 OpenGL 更多图形矩阵变换,等后面再详细讲。

一. 归一化设备坐标

在OpenGL中,我们要渲染的所有物体都要映射到x轴、y轴、z轴上的[-1, 1]范围内,这个范围内的坐标被称为归一化设备坐标,其独立于屏幕的实际尺寸或者形状。
OpenGL 的坐标 它是个正方形的:
opengl 正交投影,Android 音视频,音视频,OpenGL

而手机屏幕是长方形的,横竖屏的效果都不一样。同样的比例,视觉上是不一样的,比如绘制一个半径为 0.5 的圆,效果却是一个椭圆:
opengl 正交投影,Android 音视频,音视频,OpenGL

二. 解决方案

解决此问题,可以把一个物品的坐标,通过平移,缩放的方式,塞到到这个归一化坐标里面就可以了。
可以使用 正交投屏 来处理变形的问题,因为正交投影,没有远近距离的关系。

opengl 正交投影,Android 音视频,音视频,OpenGL

比如一个手机是竖屏,分辨率 1920x1080 ,怎么样把它放到 [-1,1] 里面?
有两个步骤

  1. 以短边为基准,比如 1080,取值为 [-1,1],那边长边缩放后 n = 长/宽 就是 [-n,n],比如 1920/1080 ≈ 1.78
  2. 顶点着色器,在设置坐标位置的时候,从 [-n,n] 换算到 [-1,1] 范围内即可。

三. 代码实现

上面的步骤中,第一步比较好实现,在内容变化后,以短边为基准,拿到宽高的比例。
第二步如何实现?
在 OpenGL 中,我们使用 vec4 ,即4分量,图形的变量,使用的是矩阵,而OpenGL中使用的是列向量,如[xyzw]T,所以与矩阵相乘时,矩阵在前,向量在后。

知道了原理之后,我们代码实现上需要解决以下几个问题:

  1. 如何获得一个矩阵,可以把坐标范围从[-N,N]换算为[-1,1]的范围内
  2. 如何将矩阵传递到GLSL中
  • 对于问题1,Android提供了Matrix.orthoM这个方法来处理矩阵。
  • 对于问题2,与获取顶点索引类似,可以再GLSL中声明一个mat4类型的矩阵变量,获取其索引,再传递值给它

在之前多边形的代码中,修改顶点代码如下,增加一个矩阵变量:

        /**
         * 顶点着色器:之后定义的每个都会传1次给顶点着色器
         * 修改顶部着色器的坐标值,即增加个举证x向量
         */
        private const val VERTEX_SHADER = """#version 300 es
                layout(location = 0) in vec4 a_Position;
                // mat4:4×4的矩阵
                uniform mat4 u_Matrix;
                void main()
                {
                 // 矩阵与向量相乘得到最终的位置
                    gl_Position = u_Matrix * a_Position;
                    gl_PointSize = 30.0;
                     
                }
        """
        private const val U_COLOR = "u_Color"
        private const val U_MATRIX = "u_Matrix"
        //单位矩阵,单位矩阵乘以任何数都等于乘数本身
        private val UnitMatrix = floatArrayOf(
            1f, 0f, 0f, 0f,
            0f, 1f, 0f, 0f,
            0f, 0f, 1f, 0f,
            0f, 0f, 0f, 1f
        )
      override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        GLES30.glClearColor(1f, 1f, 1f, 1f)
       	....
        uMatrix = getUniform(U_MATRIX)

    }

在 gl 变化时,设置矩阵

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        GLES30.glViewport(0, 0, width, height)
        val aspectRatio = if (width > height) {
            width.toFloat() / height
        } else {
            height.toFloat() / width
        }
        // 1. 矩阵数组
        // 2. 结果矩阵起始的偏移量
        // 3. left:x的最小值
        // 4. right:x的最大值
        // 5. bottom:y的最小值
        // 6. top:y的最大值
        // 7. near:z的最小值
        // 8. far:z的最大值
        // 由于是正交矩阵,所以偏移量为0,near 和 far 也不起作用
        if (width > height){
           Matrix.orthoM(UnitMatrix,0,-aspectRatio,aspectRatio,-1f,1f,-1f,1f)
        }else{
            Matrix.orthoM(UnitMatrix,0,-1f,1f,-aspectRatio,aspectRatio,-1f,1f)
        }
        //更新 matrix 的值,即把 UnitMatrix 值,更新到 uMatrix 这个索引
        GLES30.glUniformMatrix4fv(uMatrix,1,false, UnitMatrix,0)
    }

near 和 far 这里,可以直接参考正交投影的公式
opengl 正交投影,Android 音视频,音视频,OpenGL
任何出现在近平面之前或远平面之后的坐标都会被裁剪掉,所以,这里的 near =-1,far =1,表示这个坐标的范围在 [-1,1] 这个区间内

参考:
哔哩哔哩 视频:https://www.bilibili.com/video/BV12t4y1c7zd/?spm_id_from=333.337.search-card.all.click
https://www.jianshu.com/p/51a405bc52ed文章来源地址https://www.toymoban.com/news/detail-540416.html

到了这里,关于Android OpenGL ES 学习(四) -- 正交投影的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android OpenGL ES 学习(五) -- 渐变色

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学习(三) – 绘制平面图形 Android OpenGL ES 学习(四) – 正交投屏 Android OpenGL ES 学习(五) – 渐变色 Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序 Android OpenG

    2024年02月07日
    浏览(31)
  • Android OpenGL ES 学习(一) -- 基本概念

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学习(三) – 绘制平面图形 Android OpenGL ES 学习(四) – 正交投屏 Android OpenGL ES 学习(五) – 渐变色 Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序 Android OpenG

    2024年01月23日
    浏览(29)
  • Android OpenGL ES 学习(八) –矩阵变换

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学习(三) – 绘制平面图形 Android OpenGL ES 学习(四) – 正交投影 Android OpenGL ES 学习(五) – 渐变色 Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序 Android OpenG

    2023年04月08日
    浏览(31)
  • Android OpenGL ES 学习(九) – 坐标系统和实现3D效果

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学习(三) – 绘制平面图形 Android OpenGL ES 学习(四) – 正交投影 Android OpenGL ES 学习(五) – 渐变色 Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序 Android OpenG

    2024年01月25日
    浏览(37)
  • Android OpenGL ES 学习(十) – GLSurfaceView 源码解析GL线程以及自定义 EGL

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学习(三) – 绘制平面图形 Android OpenGL ES 学习(四) – 正交投影 Android OpenGL ES 学习(五) – 渐变色 Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序 Android OpenG

    2024年02月05日
    浏览(33)
  • Android OpenGL ES 学习(十三) -离屏渲染FBO(截图)RBO, OES转 FBO

    Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学习(三) – 绘制平面图形 Android OpenGL ES 学习(四) – 正交投屏 Android OpenGL ES 学习(五) – 渐变色 Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序 Android OpenGL ES 学习(七) –

    2024年02月12日
    浏览(26)
  • 【Android OpenGL开发】OpenGL ES与EGL介绍

    OpenGL(Open Graphics Library)是一个跨编程语言、跨平台的编程图形程序接口,主要用于图像的渲染。 Android提供了简化版的OpenGL接口,即OpenGL ES。 早先定义 OpenGL ES 是 OpenGL 的嵌入式设备版本,用于移动端平台(Android、iOS),但由于嵌入式设备要求的是高性能,所以一些其它纯

    2024年02月04日
    浏览(77)
  • OpenGL-ES 学习(4)---- OpenGL-ES 坐标体系

    坐标体系 我们知道 OpenGL -ES 坐标系中每个顶点的 x,y,z 坐标都应该在 -1.0 到 1.0 之间,超出这个坐标范围的顶点都将不可见。 将一个物体(图像)渲染到屏幕上,通常经过将物体坐标转换为标准化设备坐标,然后再将标准化设备坐标转化为屏幕坐标的过程。 ( 将物体坐标转

    2024年02月19日
    浏览(27)
  • Android OpenGL ES实现简单绿幕抠图

    目录 正文 OES Filter BlendShader Filter 最后的效果 缺陷 实现绿幕抠图,其实想法很简单。 这里简单粗暴的使用着色器替换。 OES Filter 直接实现在相机预览上的Shader ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #extension GL_OES_EGL_image_external : require precision mediump float ;        

    2024年02月13日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包