@@ -24,7 +24,9 @@ OpenGL ES的绘制需要有以下步骤:
2424
2525 下一步,使用in关键字,在顶点着色器中声明所有的输入顶点属性(Input Vertex Attribute)。现在我们只关心位置(Position)数据,所以我们只需要一个顶点属性。GLSL有一个向量数据类型,它包含1到4个float分量,包含的数量可以从它的后缀数字看出来。由于每个顶点都有一个3D坐标,我们就创建一个vec3输入变量position。我们同样也通过layout (location = 0)设定了输入变量的位置值(Location)你后面会看到为什么我们会需要这个位置值。
2626
27- 为了设置顶点着色器的输出,我们必须把位置数据赋值给预定义的gl_Position变量,它在幕后是vec4类型的。在main函数的最后,我们将gl_Position设置的值会成为该顶点着色器的输出。由于我们的输入是一个3分量的向量,我们必须把它转换为4分量的。我们可以把vec3的数据作为vec4构造器的参数,同时把w分量设置为1.0f(我们会在后面解释为什么)来完成这一任务。
27+ 为了设置顶点着色器的输出,我们必须把位置数据赋值给预定义的gl_Position变量,它在幕后是vec4类型的。在main函数中只是将position的值转换后赋值给gl_Position。由于我们的输入是一个3分量的向量,我们必须把它转换为4分量的。我们可以把vec3的数据作为vec4构造器的参数,同时把w分量设置为1.0f(我们会在后面解释为什么)来完成这一任务。
28+
29+ 这个position的值是哪里进行赋值的呢? 是通过后面java代码中的draw函数来进行赋值的。每个顶点着色器都必须在gl_Position变量中输出一个位置。这个变量定义传递给管线下一个阶段的位置。
2830
2931- 编译着色器
3032
@@ -42,7 +44,7 @@ OpenGL ES的绘制需要有以下步骤:
4244 }
4345 ```
4446
45- 片段着色器只需要一个输出变量,这个变量是一个4分量向量,它表示的是最终的输出颜色,我们应该自己将其计算出来。我们可以用out关键字声明输出变量,这里我们命名为color。下面,我们将一个alpha值为1.0(1.0代表完全不透明)的橘黄色的vec4赋值给颜色输出。之后也是需要编译着色器。
47+ 片段着色器只需要一个输出变量,这个变量是一个4分量向量,它表示的是最终的输出颜色,我们应该自己将其计算出来。我们可以用out关键字声明输出变量,这里我们命名为color。下面,我们将一个alpha值为1.0(1.0代表完全不透明)的橘黄色的vec4赋值给颜色输出。之后也是需要编译着色器。片段着色器声明的这个输出变量color的值会被输出到颜色缓冲区。,然后颜色缓冲区再通过EGL窗口显示。
4648
4749- 着色器程序(Shader Program Object)
4850
@@ -56,7 +58,7 @@ OpenGL ES的绘制需要有以下步骤:
5658 glLinkProgram(shaderProgram);
5759 ```
5860
59- 链接完后需要使用glUseProgram方法,用刚创建的程序对象作为参数,以激活这个程序对象。
61+ 链接完后需要使用glUseProgram方法,用刚创建的程序对象作为参数,以激活这个程序对象。调用glUserProgram方法后,所有后续的渲染将用连接到这个程序对象的顶点和片段着色器进行。
6062
6163- 链接顶点属性
6264
@@ -86,12 +88,13 @@ OpenGL ES的绘制需要有以下步骤:
8688
8789下面需要实现GLSurfaceView.Render接口,实现要绘制的部分:
8890
91+ - 用EGL创建屏幕上的渲染表面(GLSurfaceView内部实现)
8992- 写顶点着色器和片段着色器文件。
9093- 加载编译顶点着色器和片段着色器。
9194- 确定需要绘制图形的坐标和颜色数据。
9295- 创建program对象,连接顶点和片断着色器,将坐标数据、颜色数据传到OpenGL ES程序中。]
9396- 设置视图窗口(viewport)。
94- - 使颜色缓冲区的内容显示到屏幕上 。
97+ - 使颜色缓冲区的内容显示到EGL窗口上 。
9598
9699
97100
@@ -112,9 +115,9 @@ Preferences -> Plugins -> 搜GLSL Support安装就可以了。
112115 ``` glsl
113116 // 声明着色器的版本
114117 #version 300 es
115- // 顶点着色器的顶点位置,输入一个名为vPosition的4分量向量,layout (location = 0)表示这个变量的位置是顶点属性0 。
118+ // 顶点着色器的顶点位置,输入一个名为vPosition的4分量向量,layout (location = 0)表示这个变量的位置是顶点属性中的第0个属性 。
116119 layout (location = 0) in vec4 vPosition;
117- // 顶点着色器的顶点颜色数据,输入一个名为aColor的4分量向量,layout (location = 1)表示这个变量的位置是顶点属性1 。
120+ // 顶点着色器的顶点颜色数据,输入一个名为aColor的4分量向量,layout (location = 1)表示这个变量的位置是顶点属性中的第1个属性 。
118121 layout (location = 1) in vec4 aColor;
119122 // 输出一个名为vColor的4分量向量,后面输入到片段着色器中。
120123 out vec4 vColor;
@@ -128,6 +131,8 @@ Preferences -> Plugins -> 搜GLSL Support安装就可以了。
128131 }
129132 ```
130133
134+ 大体意思:使用OpenGL ES3.0版本,将图形顶点数据采用4分向量的数据结构绑定到着色器的第0个属性上,属性的名字是vPosition,然后再有一个颜色的4分向量绑定到做色漆的第1个属性上,属性的名字是aColor,另外还会输出一个vColor,着色器执行的时候,会将vPosition的值传递给用来表示顶点最终位置的内建变量gl_Position,将顶点最终大小的gl_PointSize设置为10,并将aColor的值复制给要输出额vColor。
135+
131136- 片段着色器(fragment_simple_shade.glsl)
132137
133138 ``` glsl
@@ -210,12 +215,12 @@ class MyGLRenderer implements GLSurfaceView.Renderer {
210215 /* ****************1.声明绘制图形的坐标和颜色数据 end**************/
211216 public MyGLRenderer () {
212217 /* ***************2.为顶点位置及颜色申请本地内存 start************/
213- // 顶点位置相关
218+ // 将顶点数据拷贝映射到native内存中,以便OpenGL能够访问
214219 // 分配本地内存空间,每个浮点型占4字节空间;将坐标数据转换为FloatBuffer,用以传入给OpenGL ES程序
215- vertexBuffer = ByteBuffer . allocateDirect(triangleCoords. length * BYTES_PER_FLOAT )
216- .order(ByteOrder . nativeOrder())
217- .asFloatBuffer();
218- vertexBuffer. put(triangleCoords);
220+ vertexBuffer = ByteBuffer . allocateDirect(triangleCoords. length * BYTES_PER_FLOAT ) // 直接分配native内存
221+ .order(ByteOrder . nativeOrder()) // 和本地平台保持一致的字节序
222+ .asFloatBuffer(); // 将底层字节映射到FloatBuffer实例,方便使用
223+ vertexBuffer. put(triangleCoords); // 将顶点数据拷贝到native内存中
219224 // 将数组数据put进buffer之后,指针并不是在首位,所以一定要position到0,至关重要!否则会有很多奇妙的错误!将缓冲区的指针移动到头部,保证数据是从最开始处读取
220225 vertexBuffer. position(0 );
221226
@@ -254,17 +259,18 @@ class MyGLRenderer implements GLSurfaceView.Renderer {
254259 }
255260 public void onDrawFrame (GL10 unused ) {
256261 /* *********6.绘制************/
257- // 把颜色缓冲区设置为我们预设的颜色
262+ // 把颜色缓冲区设置为我们预设的颜色,绘图设计到多种缓冲区类型:颜色、深度和模板。这里只是向颜色缓冲区中绘制图形
258263 GLES30 . glClear(GLES30. GL_COLOR_BUFFER_BIT );
259264
260- // 绑定vertex坐标数据,告诉OpenGL可以在缓冲区vertextBuffer中获取数据
265+ // 0是上面着色器中写的vPosition的变量位置(location = 0)。意思就是绑定vertex坐标数据,然后将在vertextBuffer中的顶点数据传给vPosition变量。
266+ // 你肯定会想,如果我在着色器中不写呢?int vposition = glGetAttribLocation(program, "vPosition");就可以获得他的属性位置了
261267 GLES30 . glVertexAttribPointer(0 , 3 , GLES30. GL_FLOAT , false , 0 , vertexBuffer);
262- // 启用顶点位置句柄
268+ // 启用顶点变量,这个0也是vPosition在着色器变量中的位置,和上面一样,在着色器文件中的location=0声明的
263269 GLES30 . glEnableVertexAttribArray(0 );
264270
265271 // 准备颜色数据
266272 /**
267- * glVertexAttribPointer()方法的参数分别为 :
273+ * glVertexAttribPointer()方法的参数上面的也说过了,这里再按照这个场景说一下分别为 :
268274 * index:顶点属性的索引.(这里我们的顶点位置和颜色向量在着色器中分别为0和1)layout (location = 0) in vec4 vPosition; layout (location = 1) in vec4 aColor;
269275 * size: 指定每个通用顶点属性的元素个数。必须是1、2、3、4。此外,glvertexattribpointer接受符号常量gl_bgra。初始值为4(也就是涉及颜色的时候必为4)。
270276 * type:属性的元素类型。(上面都是Float所以使用GLES30.GL_FLOAT);
@@ -862,8 +868,7 @@ class TriangleRender implements GLSurfaceView.Renderer {
862868
863869
864870
865-
866- [ 上一篇: 4.GLTextureView实现] ( https://github.com/CharonChui/AndroidNote/blob/master/VideoDevelopment/OpenGL/4.GLTextureView%E5%AE%9E%E7%8E%B0.md )
871+ [ 上一篇: 4.GLTextureView实现] ( https://github.com/CharonChui/AndroidNote/blob/master/VideoDevelopment/OpenGL/4.GLTextureView%E5%AE%9E%E7%8E%B0.md )
867872[ 下一篇: 6.OpenGL ES绘制矩形及圆形] ( https://github.com/CharonChui/AndroidNote/blob/master/VideoDevelopment/OpenGL/6.OpenGL%20ES%E7%BB%98%E5%88%B6%E7%9F%A9%E5%BD%A2%E5%8F%8A%E5%9C%86%E5%BD%A2.md )
868873
869874---
0 commit comments