Opengl ES系列学习--序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_22657459/article/details/89395495

     之前一直都想好好学习一下Opengl ES,因为自己想往图形界面处理方向集中发展,这样的目标对Opengl ES的要求也是不能少的,推荐两本书:《OpenGL ES应用开发实践指南 Android卷》《OPENGL ES 3.0编程指南中文原书第2版》,CSDN上也有其他朋友分享的,但是都要四五十个积分,有点抠门了,我这里是百度云盘,免费下载,第一个密码是36ve,第二个密码是8e3f,另外自己把两本书的代码全部整理了下,Github下载链接:Opengl ES Source Code,所有项目使用AndroidStudio运行,全部都可直接运行,收集了Opengl ES2.0和Opengl ES3.0的代码。

     如果大家是零基础开始学习的话,作为一个踩坑过来的人,强烈推荐先看《OpenGL ES应用开发实践指南  Android卷》,如果先看3.0的话,根本没有一点眉目,最重点的vertex_shader和fragment_shader根本无法理解,把书看了三四遍,仍然一头雾水。另外,看书的同时,不能光看,必须要自己照着写,新建一个空白项目,一行一行手写,这样才能慢慢理解其中的原理。

     我们学习Opengl ES的重点内容有几个:

     一、通过不断的研究里边的源码、修改、测试,要重点掌握顶点着色器和片断着色器的原理。顶点着色器和片断着色器应该说是Opengl的核心,如果能熟练掌握这两个着色器,那么你可以使用它们创建出非常炫的效果。对Application而言,这两个着色器就是通过framework提供的API来进行控制的,它们都是直接运行在GPU上的一段代码。

     二、通过Android提供的Opengl ES的API接口,如何控制顶点着色器和片断着色器中的变量,从而实现炫丽的界面功能。

     三、学习过程中,还必须耐心的理解Matrix类中常用的方法,比如setIdentityM创建单位矩阵、translateM创建平移矩阵、multiplyMM将两个矩阵相乘等等,全部都涉及到数学运算,确实非常头疼,如果不关心数学运算的话,我们就简单知道它能实现什么样的功能就可以了。

     当然,实现功能的同时,出错肯定是少不了的,所以我们还得学会调试,强烈推荐使用Graphics API Debugger分析工具,单独针对界面渲染出的,功能非常强大,安装包下载地址:Graphics API Debugger,使用方法非常简单,一定注意,使用的时候,要关闭AndroidStudio,否则无法连接设备。

     下面的内容就整理一下自己看过之后得到的一些经验,方便大家查阅,网上相关的资料搜了下,好像很少,对初学者来说效率非常低,希望自己的整理能给大家节省一些时间。

1:比如在如下的顶点着色器中定义了一个类型为uniform的浮点型变量u_Time,我们就可以调用glGetUniformfv(program.program, program.getuTimeLocation(), floatBuffer)来时时获取到它的值。

uniform mat4 u_Matrix;

/**  该值和a_ParticleStartTime相等  **/
uniform float u_Time;

/**  该值是在创建粒子发射器时传入的,值不变,就是粒子最初始的位置  **/
attribute vec3 a_Position;

/**  该值是在创建粒子发射器时传入的,值不变  **/
attribute vec3 a_Color;

/**  该值是在创建粒子发射器时传入的,值不变,y方向0.5,x和z都是0  **/
attribute vec3 a_DirectionVector;

/**  该值等于(System.nanoTime() - globalStartTime) / 1000000000f  **/
attribute float a_ParticleStartTime;

/**  该值和a_Color相等,值不变  **/
varying vec3 v_Color;
varying float v_ElapsedTime;

void main() {
    v_Color = a_Color;
    v_ElapsedTime = u_Time - a_ParticleStartTime;
    vec3 currPosition = a_Position + (a_DirectionVector * v_ElapsedTime);
    gl_Position = u_Matrix * vec4(currPosition, 1.0);
    gl_PointSize = 10.0;
}

2:理解2.0中的varying类型,该类型我开始以为是插值的意思,如下图,两点之间其他的点都是以起始和终止两个点的颜色进行插值,其实不是,varying的作用就是把顶点着色器中定义的变量传递给片断着色器,在3.0中把它改为了out,这样就非常形象了。

3:Matrix.rotateM(float[] m, int mOffset, float a, float x, float y, float z)方法是对第一个参数矩阵m进行旋转,比如我要把矩阵m沿X方向旋转60度,那么就应该这样调用:Matrix.rotateM(m, 0, 60, 1f, 0f, 0f);要把矩阵m沿Z轴旋转-20度,那么就应该这样调用:Matrix.rotateM(m, 0, -20, 0f, 0f, 1f)。API会使用了,我们还必须要明白其中的道理,当我们要旋转物体时,伸出右手,把大拇指对着旋转目标轴的正方向,其他手指卷曲的方向就是旋转的正方向,反之则是负方向。比如我们要沿X轴旋转,那么我们右手大拇指应该向右,掌心正对我们,向着我们身体的方向就是正方向,反着我们身体的则是负方向;比如我们要沿Y轴旋转,那么我们右手大拇指应该向上,掌心朝左侧,朝左侧转动的方向就是旋转的正方向,朝右侧转动的方向则是负方向。我们看看下面的示例图就会更清楚了。

     第一幅图是没有任何旋转的,我们要达到第二幅图的样子,可以判定,图片是绕X轴旋转的,伸出右手,拇指向右,图片是向着我们的身体转到这个角度的,和我们其他手指的方向相同,所以是正角度,这个角度的值是60度,所以我们应该这样调用:Matrix.rotateM(modelMatrix, 0, 60f, 1f, 0f, 0f);再看第三幅图,很明显,它是背离我们身体的,和其他手指的方向相反,角度为60度,所以我们应该这样调用:Matrix.rotateM(modelMatrix, 0, -60f, 1f, 0f, 0f)。

4:在网上查找的Opengl ES的中文手册,可供参考:OpenGL shader GLSL 中文手册

5:点光和方向光在数学上都是相似的,然而,我们需要记住两个关键的不同点:
1)对于方向光,我们只存储指向其光源的向量,因为这个向量对于场景中的所有点都是一样的;对于点光则相反,我们将存储其光源的位置,用这个位置计算场景中每个点指向这个光源的向量。
2)在实际生活中,点光源的亮度会随着距离的平方降低,这叫作平方反比定律。我们将使用点光源的位置计算出其与场景中每个点的距离。

猜你喜欢

转载自blog.csdn.net/sinat_22657459/article/details/89395495