基本着色器

这里介绍一个最基本的着色器实现。

Code

顶点着色器

Code

#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;
}

片段着色器

Code

#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;
}

着色器创建

Code

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
}

着色器使用

Code

// 初始化着色器
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)