7.3 创建新着色器(Creating a New Set of Shaders)
在我们把纹理绘制到屏幕上之前,我们还需要创建一些着色器,这些着色器将会接收纹理图片数据然后把这些数据应用到将会绘制的片元上去;这些着色器与之前我们使用的着色器类似,为了支持纹理稍微变动了下而已。
7.3.1 创建顶点着色器(Creating the New Vertex Shader)
在目录/res/raw/ 下面创建文件texture_vertex_shader.glsl,并加入如下代码:
//AirHockeyTextured/res/raw/texture_vertex_shader.glsl
uniform mat4 u_Matrix;
attribute vec4 a_Position;
attribute vec2 a_TextureCoordinates;
varying vec2 v_TextureCoordinates;
void main() {
v_TextureCoordinates = a_TextureCoordinates;
gl_Position = u_Matrix * a_Position;
}
该着色器中的代码大部分都比较熟悉,定义了一个uniform类型的变量matrix以及对应当前位置的一个属性,用这两个值计算最终的gl_Position值;新属性a_TextureCoordinates对应于纹理坐标,它之所以被定义为二维的向量vec2,那是因为纹理坐标包含S坐标及T坐标两个部分;最后把该向量赋值给类型为varying的变量v_TextureCoordinates,该类型的变量最终会传递给片元着色器使用。
7.3.2 创建片元着色器(Creating the New Fragment Shader)
在相同目录下创建文件texture_fragment_shader.glsl,并添加如下着色器代码:
//AirHockeyTextured/res/raw/texture_fragment_shader.glsl
precision mediump float;
uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;
void main() {
gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
}
为了将纹理绘制到物体上面,OpenGL将会针对每个片元以纹理坐标v_TextureCoordinates为参数调用片元着色器,而片元着色器将会通过sampler2D类型的变量u_TextureUnit及传递过来的纹理坐标v_TextureCoordinates调用内置函数texture2D读取纹理数据。
插值产生的纹理坐标及纹理数据将会作为参数传递给内置函数texture2D(),该函数将读取纹理坐标处对应的纹理数据作为颜色值,最终通过设置内置变量gl_FragColor为刚刚读取的颜色值作为片元的颜色。
在接下来的章节将会创建一些新类来整合桌面顶点数据及着色器程序方便代码的复用(点击进入下一节)。