这里介绍一个最基本的着色器实现。
#version 100 // 版本号 对用 OpenGL ES 2.0
precision mediump float; // 浮点数精度默认使用中等
// uniform变量 每次绘制操作过程中不可变
uniform mat4 u_mvp;
// attribute变量 每个顶点数据各不相同
attribute vec3 a_pos;
attribute vec4 a_color;
// varying变量 每个定点数据各不相同 可以在顶点着色器与片段着色器间传递中间计算结果
// 并且在两个顶点中过度位置会自动计算插值
varying vec4 v_frag_color;
void main() { // 入口
// 使用u_mvp以及a_pos生成的齐次坐标 计算最终坐标
gl_Position = u_mvp * vec4(a_pos, 1);
// 直接使用a_color赋值v_frag_color 这里直接赋值因为仅作演示使用
v_frag_color = a_color;
}
#version 100 // 版本号 对用 OpenGL ES 2.0
precision mediump float; // 浮点数精度默认使用中等
// 由顶点着色器传递过来的值
varying vec4 v_frag_color;
void main() { // 入口
// 直接使用v_frag_color对gl_FragColor这个系统内置输出变量赋值
// 这里直接赋值因为仅作演示使用 所以不写额外逻辑
gl_FragColor = v_frag_color;
}
fun createAndCompileShader(type: Int, source: String): Int {
// 创建shader, type可选值为GL_VERTEX_SHADER、GL_FRAGMENT_SHADER
val id = GLES20.glCreateShader(type)
// 输入着色器源码
GLES20.glShaderSource(id, source)
// 编译
GLES20.glCompileShader(id)
return id
}
fun createAndLinkProgram(vs: Int, fs: Int = 0): Int {
// 创建着色器程序
val id = GLES20.glCreateProgram()
// 附加顶点着色器
GLES20.glAttachShader(id, vs)
// 附加可选片段着色器
if (fs != 0) {
GLES20.glAttachShader(id, fs)
}
// 链接
GLES20.glLinkProgram(id)
return id
}
// 初始化着色器
vsId = createAndCompileShader(GLES20.GL_VERTEX_SHADER, App.readAsset("simple_vs.glsl"))
fsId = createAndCompileShader(GLES20.GL_FRAGMENT_SHADER, App.readAsset("simple_fs.glsl"))
progId = createAndLinkProgram(vsId, fsId)
// 寻找uniform、attribute变量位置
mvpUniformId = GLES20.glGetUniformLocation(progId, "u_mvp")
posAttributeId = GLES20.glGetAttribLocation(progId, "a_pos")
colorAttributeId = GLES20.glGetAttribLocation(progId, "a_color")
// 启用以及传入attribute变量值
GLES20.glEnableVertexAttribArray(posAttributeId)
GLES20.glVertexAttribPointer(posAttributeId, 3, GLES20.GL_FLOAT, false, 0, pos)
GLES20.glEnableVertexAttribArray(colorAttributeId)
GLES20.glVertexAttribPointer(colorAttributeId, 4, GLES20.GL_FLOAT, false, 0, color)
// 传入uniform变量值
GLES20.glUniformMatrix4fv(mvpUniformId, 1, false, mvp, 0)
// 调用一次绘制操作
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3)