OpenGL ES渲染管线概述

渲染管线一般是由显示芯片GPU内部处理图形信号的并行处理单元组成,这些并行处理单元之间是独立的,从另一个角度看,渲染管线实际上也是一系列绘制过程,这一系列过程的输入是待绘制物体的相关描述信息,输出的是要显示的图像帧数据。

OpenGL ES管线主要包括:

读取顶点数据—>顶点着色器—>组装图元—>光栅化图元—>片元着色器—>写入帧缓冲区—>显示到屏幕上

  • 读取顶点数据指的是将待绘制的图形的顶点数据传递给渲染管线中。
  • 顶点着色器最终生成每个定点的最终位置,执行顶点的各种变换,它会针对每个顶点执行一次,确定了最终位置后,OpenGL就可以把这些顶点集合按照给定的参数类型组装成点,线或者三角形。
  • 组装图元阶段包括两部分:图元的组装和图元处理,图元组装指的是顶点数据根据设置的绘制方式参数结合成完整的图元,例如点绘制方式中每个图元就只包含一个点,线段绘制方式中每个图源包含两个点;图元处理主要是剪裁以使得图元位于视景体内部的部分传递到下一个步骤,视景体外部的部分进行剪裁。视景体的概念与投影有关。
  • 光栅化图元主要指的是将一个图元离散化成可显示的二维单元片段,这些小单元称为片元。一个片元对应了屏幕上的一个或多个像素,片元包括了位置,颜色,纹理坐标等信息,这些值是由图元的顶点信息进行插值计算得到的。
  • 片元着色器为每个片元生成最终的颜色,针对每个片元都会执行一次。一旦每个片元的颜色确定了,OpenGL就会把它们写入到帧缓冲区中。

在OpenGL ES2.0中主要的两个部分就是上面的可编程顶点着色器和片段着色器。学习OpenGL ES主要是要了解渲染管线,了解CPU的渲染过程,主要编程工作在于顶点着色器和片元着色器的编写。

绘制一个六边形

效果如图所示

六边形类

public class SixShape {private FloatBuffer mVertexBuffer;private FloatBuffer mColorBuffer;private int mProgram;private int mPositionHandle;private int mColorHandle;private int muMVPMatrixHandle;public SixShape(float r) {initVetexData(r);}public void initVetexData(float r) {// 初始化顶点坐标float[] vertexArray = new float[8*3];// 初始化顶点颜色float[] colorArray=new float[8*4];int j = 0, k = 0;vertexArray[j++] = 0;vertexArray[j++] = 0;vertexArray[j++] = 0;colorArray[k++] = 1;colorArray[k++] = 1;colorArray[k++] = 1;colorArray[k++] = 0;for (int angle = 0; angle <= 360; angle += 60) {vertexArray[j++] = (float) (r*Math.cos(Math.toRadians(angle)));vertexArray[j++] = (float) (r*Math.sin(Math.toRadians(angle)));vertexArray[j++] = 0;colorArray[k++] = 1;colorArray[k++] = 0;colorArray[k++] = 0;colorArray[k++] = 0;}ByteBuffer buffer = ByteBuffer.allocateDirect(vertexArray.length * 4);buffer.order(ByteOrder.nativeOrder());mVertexBuffer = buffer.asFloatBuffer();mVertexBuffer.put(vertexArray);mVertexBuffer.position(0);ByteBuffer cbb=ByteBuffer.allocateDirect(colorArray.length*4);cbb.order(ByteOrder.nativeOrder());mColorBuffer=cbb.asFloatBuffer();mColorBuffer.put(colorArray);mColorBuffer.position(0);int vertexShader = loaderShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);int fragmentShader = loaderShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);mProgram = GLES20.glCreateProgram();GLES20.glAttachShader(mProgram, vertexShader);GLES20.glAttachShader(mProgram, fragmentShader);GLES20.glLinkProgram(mProgram);mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");mColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");}public void draw(float[] mvpMatrix) {GLES20.glUseProgram(mProgram);// 将顶点数据传递到管线,顶点着色器GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 3 * 4, mVertexBuffer);// 将顶点颜色传递到管线,顶点着色器GLES20.glVertexAttribPointer(mColorHandle, 4, GLES20.GL_FLOAT, false,4*4, mColorBuffer);// 将变换矩阵传递到管线GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mvpMatrix, 0);GLES20.glEnableVertexAttribArray(mPositionHandle);GLES20.glEnableVertexAttribArray(mColorHandle);// 绘制图元GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 8);}private int loaderShader(int type, String shaderCode) {int shader = GLES20.glCreateShader(type);GLES20.glShaderSource(shader, shaderCode);GLES20.glCompileShader(shader);return shader;}private String vertexShaderCode = "uniform mat4 uMVPMatrix;"+ "attribute vec3 aPosition;"+ "attribute vec4 aColor;"+ "varying  vec4 aaColor;"+ "void main(){"+ "gl_Position = uMVPMatrix * vec4(aPosition,1);"+ "aaColor = aColor;"+ "}";private String fragmentShaderCode = "precision mediump float;"+ "varying  vec4 aaColor;"+ "void main(){"+ "gl_FragColor = aaColor;"+ "}";}

六边形View

public class SixView extends GLSurfaceView{public SixView(Context context) {super(context);setEGLContextClientVersion(2);setRenderer(new MyRender());}class MyRender implements GLSurfaceView.Renderer {private SixShape circle;@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1);circle = new SixShape(0.5f);GLES20.glEnable(GLES20.GL_DEPTH_TEST);}// 投影矩阵private final float[] mProjectionMatrix = new float[16];// 视图矩阵private final float[] mViewMatrix = new float[16];// 模型矩阵private final float[] mMMatrix = new float[16];private final float[] mViewProjectionMatrix = new float[16];private final float[] mMVPMatrix = new float[16];@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {GLES20.glViewport(0, 0, width, height);float ratio= (float) width / height;// 设置正交投影Matrix.orthoM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 0, 5);// 设置视图矩阵Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 2,  0, 0, 0, 0, 1, 0);}@Overridepublic void onDrawFrame(GL10 gl) {GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);Matrix.multiplyMM(mViewProjectionMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);// 设置模型矩阵Matrix.setIdentityM(mMMatrix, 0);Matrix.translateM(mMMatrix,0,0,0,1);Matrix.rotateM(mMMatrix, 0, 30, 0, 0, 1);Matrix.multiplyMM(mMVPMatrix, 0, mViewProjectionMatrix, 0, mMMatrix, 0);circle.draw(mMVPMatrix);}}}

接下来在Activity中就可以使用这个View了。上面的例子虽然简单,但是包括了使用OpenGL ES编程的主要流程,包括生成顶点数据,编写顶点着色器,片元着色器,传递数据给顶点/片元着色器,这里最主要的就是着色器语言。此外包括投影,平移,旋转等操作。在后面会详细学习每个细节以及上面例子没有涉及到的光照,纹理等OpenGL的知识。

转载于:https://www.cnblogs.com/qhyuan1992/p/6071972.html

OpenGL ES入门相关推荐

  1. OpenGL ES入门(使用指南)

    转载地址:https://www.ict528.com/wpozv3sz3srrtywpoq1qvuyqooqxz1usvwr2uqoo.html. OpenGL ES 入门 一.前言 OpenGL ...

  2. OpenGL ES 入门之旅--灰度,旋涡,马赛克滤镜

    前情提要 这篇滤镜效果的实现是在上一篇分屏滤镜的基础上来进行实现的,同样的前提是可以利用GLSL加载一张正常的图片. 详情请参考上一篇OpenGL ES 入门之旅--分屏滤镜 下面步入这篇的正题: 灰 ...

  3. OpenGL ES入门详解

    http://blog.csdn.net/wangyuchun_799/article/details/7736928 版权声明:本文为博主原创文章,未经博主允许不得转载.  1.决定你要支持的Ope ...

  4. Android OpenGL ES 入门系列(一) --- 了解OpenGL ES的前世今生

    转载请注明出处 本文出自Hansion的博客 OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,针对手机.PDA和游戏主机等嵌 ...

  5. OpenGL/OpenGL ES入门:渲染YUV数据实践

    纹理:GPU中的一块数据结构,YUV数据先经过采样,转成rgb显示. 着色器代码,先通过compile编译成GPU能识别的机器语言,再交由GPU进行显示. shader着色器,texture纹理,Ut ...

  6. OpenGL ES入门 基本概念篇

    前言 OpenGL是一种包含了一系列可以操作图形图像函数的图形编程接口的规范标准,它规范了每个函数该如何执行以及它们的输出值,OpenGL ES是OpenGL的一个精简子集,主要用于手持和嵌入式设备, ...

  7. 笔谈OpenGL ES(三)

    昨天下午以及今天一天,公司安排了新员工培训课程,占用了自己的一些时间,但是也了解到一些新的有利于自身的东西.进公司就要进有完善公司体系和制度的公司,小公司真的是没搞头的,我体验过,反正小公司以后是不会 ...

  8. 利用 OpenGL ES 给视频播放器和相机做个字符画滤镜

    该原创文章首发于微信公众号:字节流动 最后不少朋友问,"OpenGL ES 入门后怎么学习写一些滤镜?","怎么学习 shader ?". 最近请教了一些大佬, ...

  9. Android OpenGL ES 应用(一)

    OpenGL已经成了3D的一个"标准" 因为它能跨平台,接口也比较丰富,几乎大部分的手机3D游戏都和OpenGL有关系. 当然还有微软有direct X 但只能在微软平台上使用. ...

最新文章

  1. Android学习笔记——Intents 和 Intent Filters(二)
  2. centos挂载u盘只读_完美解决linux下U盘文件只读的问题
  3. VTK:Points之ExtractSurface
  4. 一个非常巧妙的 hashcode 算法 return h (length-1);
  5. 伏安特性曲线实验报告_电化学扩散层,Cottrell equation,取样电流伏安法
  6. 信息学奥赛一本通 1411:区间内的真素数 | OpenJudge NOI 1.13 23:区间内的真素数
  7. c语言用指针求Amn,[工学]第5章数据结构C语言描述耿国华.ppt
  8. 用C#实现将html文件转换为chm文件
  9. Spring Security整合KeyCloak保护Rest API
  10. 离群值是什么意思_ESD—检验离群值
  11. 在VM安装最新版Linux镜像
  12. 阿里云购买云服务器流程及注意事项(新手用户必看图文教程)
  13. 今日头条一个身份证可以注册几个头条号
  14. ISO7816 智能卡 接口
  15. vue+elementUI+vue-i18n 实现国际化
  16. 招标流程及注意事项_资讯详情
  17. 搜狗站群之搜狗泛目录实现搜狗大量泛收录
  18. flash 第六章 课后练习
  19. 财务内部收益率用计算机怎么算,财务内部收益率的计算
  20. 计算机组成原理实验二

热门文章

  1. 报错 ValueError: too many values to unpack (expected 2)
  2. 【Pytorch神经网络实战案例】06 逻辑回归拟合二维数据
  3. LeetCode 2201. 统计可以提取的工件(哈希)
  4. LeetCode 2135. 统计追加字母可以获得的单词数(位运算+哈希)
  5. LeetCode MySQL 1873. 计算特殊奖金(case when then else end)
  6. LeetCode 1771. 由子序列构造的最长回文串的长度(最长回文子序)
  7. LeetCode 1063. 有效子数组的数目(单调栈)
  8. 程序员面试金典 - 面试题 17.23. 最大黑方阵(DP)
  9. 剑指Offer - 面试题54. 二叉搜索树的第k大节点(二叉树循环遍历)
  10. LeetCode 49. 字母异位词分组(哈希)