栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android OpenGL学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android OpenGL学习笔记

Demo效果:

效果图

最近做了个贴纸相机的项目,用到OPenGL渲染,一路下来,遇到许许多多的问题,现在写个文章,当做笔记。

OpenGL基础简介

CPU :  中央处理器,它集成了运算,缓冲,控制等单元,包括绘图功能.CPU将对象处理为多维图形,纹理(Bitmaps、Drawables等都是一起打包到统一的纹理)。

GPU: 一个类似于CPU的专门用来处理Graphics的处理器, 作用用来帮助加快格栅化操作,当然,也有相应的缓存数据(例如缓存已经光栅化过的bitmap等)机制。

格栅化 :  是 将图片等矢量资源,转化为一格格像素点的像素图,显示到屏幕上。

渲染机制分析渲染流程简介

     UI对象—->CPU处理为多维图形,纹理 —–通过OpeGL ES接口调用GPU—-> GPU对图进行光栅化(frame Rate ) —->硬件时钟(Refresh Rate)—-垂直同步—->投射到屏幕

      Android系统每隔16ms发出VSYNC信号(1000ms/60=16.66ms),触发对UI进行渲染, 如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps,为了能够实现60fps,这意味着计算渲染的大多数操作都必须在16ms内完成。

     正常情况下Android的GPU会在16ms完成页面的绘制,如果一帧画面渲染时间超过16ms的时候,垂直同步机制会让显示器硬件 等待GPU完成栅格化渲染操作,然后再次绘制界面,这样就会看起来画面停顿。当GPU渲染速度过慢,就会导致如下情况,某些帧显示的画面内容就会与上一帧的画面相同。

GPU 渲染效率比 CPU 高

     这点是  GPU、CPU 自身架构决定的,CPU 计算单元少,逻辑控制单元多,为的是执行维度、类型复杂的各种任务,毕竟 CPU 是中枢嘛~。GPU 计算单元多,逻辑控制单元少,专注于图形绘制、渲染, ALU 是计算单元,剩下的不用说大家也能猜到,所以但是把绘图、渲染任务从 CPU 切到 GPU 都是性能上的巨大提升.

OpenGl详解

      图形渲染管线包含很多部分,每个部分都将在转换顶点数据到最终像素这一过程中处理各自特定的阶段。我们会概括性地解释一下渲染管线的每个部分,让你对图形渲染管线的工作方式有个大概了解。

    首先,我们以数组的形式传递3个3D坐标作为图形渲染管线的输入,用来表示一个三角形,这个数组叫做顶点数据(Vertex Data);

       顶点数据是一系列顶点的集合。一个顶点(Vertex)是一个3D坐标的数据的集合。而顶点数据是用顶点属性(Vertex Attribute)表示的,它可以包含任何我们想用的数据,但是简单起见,我们还是假定每个顶点只由一个3D位置(译注1)和一些颜色值组成的。

 顶点着色器  --> 它把一个单独的顶点作为输入。顶点着色器主要的目的是把3D坐标转为另一种3D坐标(后面会解释),同时顶点着色器允许我们对顶点属性进行一些基本处理。

attribute vec4 vPosition; //变量 float[4]  一个顶点  java传过来的

attribute vec2 vCoord;  //纹理坐标

varying vec2 aCoord;

void main(){
    //内置变量: 把坐标点赋值给gl_position 就Ok了。
    gl_Position = vPosition;
    aCoord = vCoord;
}

 片段着色器 ---> 片段着色器的主要目的是计算一个像素的最终颜色,这也是所有OpenGL高级效果产生的地方。通常,片段着色器包含3D场景的数据(比如光照、阴影、光的颜色等等),这些数据可以被用来计算最终像素的颜色。

precision mediump float; // 数据精度
varying vec2 aCoord;

uniform sampler2D  vTexture;  // samplerExternalOES: 图片, 采样器

void main(){
    //  texture2D: vTexture采样器,采样  aCoord 这个像素点的RGBA值
    vec4 rgba = texture2D(vTexture,aCoord);  //rgba
//    gl_FragColor = vec4(1.-rgba.r,1.-rgba.g,1.-rgba.b,rgba.a);
    gl_FragColor = rgba;
}

| 内置变量      | 含义                               | 值数据类型 |
| ------------- | ---------------------------------- | ---------- |
| gl_PointSize    | 点渲染模式,方形点区域渲染像素大小 | float      |
| gl_Position      | 顶点位置坐标                                          | vec4     |
| gl_FragColor   | 片元颜色值                                             | vec4      |
| gl_FragCoord  | 片元坐标,单位像素                               | vec2     |
| gl_PointCoord | 点渲染模式对应点像素坐标                    | vec2      |

gl_Position

   `gl_Position`内置变量主要和顶点相关,出现的位置是顶点着色器语言的`main`函数中。  `gl_Position`内置变量表示最终传入片元着色器片元化要使用的顶点位置坐标。

   如果只有一个顶点,直接在给顶点着色器中设置内置变量`gl_Position`赋值就可以,内置变量`gl_Position`的值是四维向量`vec4(x,y,z,1.0)`,前三个参数表示顶点的xyz坐标值,第四个参数是浮点数`1.0`。

void main() {
  //顶点位置,位于坐标原点
  gl_Position = vec4(0.0,0.0,0.0,1.0);
}

   如果你想完全理解内置变量`gl_Position`,必须建立`逐顶点`的概念,如果javascript语言中出现一个变量赋值,你可以理解为仅仅执行一次,但是对于着色器中不能直接这么理解,如果有多个顶点,你可以理解为每个顶点都要执行一遍顶点着色器主函数`main`中的程序。

  多个顶点的时候,内置变量`gl_Position`对应的值是`attribute`关键字声明的顶点位置坐标变量`apos`,顶点位置坐标变量`apos`变量对应了javascript代码中多个顶点位置数据。