[OpenGL]Android OpenGL ES绘制三角形

192 阅读1分钟

先一发流程图:

OpenGL ES绘制三角形

重点流程

1、编译Shader代码

/**
 * 编译着色器
 */
private fun compileShader(type: Int, shaderSourceCode: String): Int {
    //1、创建Shader
    val shaderObjectId = glCreateShader(type)
    if (shaderObjectId == 0) {
        LOGE(msg = "create shader failed!")
        return 0
    }
    //2、shader和GDLS代码关联
    glShaderSource(shaderObjectId, shaderSourceCode)
    //3、编译shader
    glCompileShader(shaderObjectId)
    //4、验证编译结果
    val compileStatus = IntArray(1)
    //glGetShaderiv函数比较通用,在着色器阶段和 OpenGL 程序阶段都会通过它来验证结果。
    glGetShaderiv(shaderObjectId, GL_COMPILE_STATUS, compileStatus, 0)
    if ((compileStatus[0] == 0)) {
        // 失败则删除
        glDeleteShader(shaderObjectId)
        LOGE(msg = "compileShader failed!, type=$type")
        return 0
    }
    return shaderObjectId
}

2、链接着色器

/**
 * 创建 着色器 程序和着色器链接
 * @param vertexShaderId 通过[compileShader]创建的shader对象
 * @param fragmentShaderId 通过[compileShader]创建的shader对象
 */
fun linkProgram(vertexShaderId: Int, fragmentShaderId: Int): Int {
    //1、创建OpenGL程序
    val programObjectId = glCreateProgram()
    //2、链接shader
    glAttachShader(programObjectId, vertexShaderId)
    glAttachShader(programObjectId, fragmentShaderId)
    //3、链接OpenGL程序
    glLinkProgram(programObjectId)
    //4、验证链接结果
    val linkStatus = IntArray(1)
    glGetProgramiv(programObjectId, GL_LINK_STATUS, linkStatus, 0)

    if ((linkStatus[0] == 0)) {
        LOGI(
            msg =
            """
            Result of linking program:
            ${glGetProgramInfoLog(programObjectId)}
            """.trimIndent()
        )
        // 失败则删除
        glDeleteProgram(programObjectId)
        LOGE(msg = "link program failed!")
        return 0
    }
    return programObjectId
}

3、链接顶点属性

/**
 * 使顶点某个数据使能的
 * @param dataOffset
 * @param attributeLocation
 * @param componentCount
 * @param stride
 */
fun setVertexAttribPointer(
    dataOffset: Int,
    attributeLocation: Int,
    componentCount: Int,
    stride: Int
) {
    floatBuffer.position(dataOffset)
    GLES20.glVertexAttribPointer(
        attributeLocation,
        componentCount,
        GLES20.GL_FLOAT,
        false,
        stride,
        floatBuffer
    )
    GLES20.glEnableVertexAttribArray(attributeLocation)
    floatBuffer.position(0)
}
val floatBuffer: FloatBuffer = ByteBuffer
    .allocateDirect(vertexData.size * Constants.BYTES_PRE_FLOAT)
    .order(ByteOrder.nativeOrder())
    .asFloatBuffer()
    .put(vertexData)