protectedfungetUniform(name: String): Int { if (programObjId < 1) throw IllegalArgumentException("Program ID=$programObjId is not valid. Make sure to call makeProgram() first.") return GLES20.glGetUniformLocation(programObjId, name) }
protectedfungetAttrib(name: String): Int { if (programObjId < 1) throw IllegalArgumentException("Program ID=$programObjId is not valid. Make sure to call makeProgram() first.") return GLES20.glGetAttribLocation(programObjId, name) } }
/** * 编译着色器程序 * @param type GLES20.GL_VERTEX_SHADER(0X8B31=35633) -> vertex shader * GLES20.GL_FRAGMENT_SHADER(0X8B30=35632) -> fragment shader * @param shaderCode 着色器程序代码 * * https://www.jianshu.com/p/a772bfc2276b */ funcompileShader(type: Int, shaderCode: String): Int { // Create a vertex shader type (GLES20.GL_VERTEX_SHADER) // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
// 1. 创建一个新的着色器对象 val shaderId = GLES20.glCreateShader(type)
// 6.验证编译状态 if (compileStatus[0] != GLES20.GL_TRUE) { // Failed LogContext.log.e(TAG, "Compilation of shader[$type] failed.", outputType = ILog.OUTPUT_TYPE_SYSTEM) // 如果编译失败,则删除创建的着色器对象 GLES20.glDeleteShader(shaderId)
// 7.返回着色器对象:失败,为0 return GLES20.GL_FALSE }
// 7. 返回着色器对象:成功,非0 return shaderId }
/** * @return OpenGL ES Program ID */ funlinkProgram(vertexShaderId: Int, fragmentShaderId: Int): Int { // 1. 创建一个 OpenGL ES 程序对象 // Create empty OpenGL ES Program val programObjId = GLES20.glCreateProgram() LogContext.log.i(TAG, "linkProgram() programObjId=$programObjId", outputType = ILog.OUTPUT_TYPE_SYSTEM)
// 2. 检查创建状态 checkGlError("glCreateProgram") // 返回值 0 代表着创建对象失败。 if (programObjId == GLES20.GL_FALSE) { // Failed LogContext.log.e(TAG, "Could not create new program.", outputType = ILog.OUTPUT_TYPE_SYSTEM) return GLES20.GL_FALSE }
// 3. 将顶点着色器依附到 OpenGL ES Program 对象 // Add the vertex shader to program GLES20.glAttachShader(programObjId, vertexShaderId) // 3. 将片段着色器依附到 OpenGL ES Program 对象 // Add the fragment shader to program GLES20.glAttachShader(programObjId, fragmentShaderId)
// Creates OpenGL ES program executables // 4. 将两个着色器链接到 OpenGL ES Program 对象 GLES20.glLinkProgram(programObjId)
// 5. 获取链接状态:OpenGL ES 将想要获取的值放入长度为1的数组的首位 val linkStatus = IntArray(1) GLES20.glGetProgramiv(programObjId, GLES20.GL_LINK_STATUS, linkStatus, 0)
// 6. 验证链接状态 if (linkStatus[0] != GLES20.GL_TRUE) { LogContext.log.e(TAG, "Could not link program: ${GLES20.glGetProgramInfoLog(programObjId)} linkStatus=${linkStatus[0]}", outputType = ILog.OUTPUT_TYPE_SYSTEM) // 链接失败则删除程序对象 GLES20.glDeleteProgram(programObjId)
// 7. 返回程序对象:失败,为0 return GLES20.GL_FALSE }
// 7. 返回程序对象:成功,非0 return programObjId }
/** * 检查 GL 操作是否有 error * @param op 当前检查前所做的操作 */ funcheckGlError(op: String): Int { var error: Int = GLES20.glGetError() while (error != GLES20.GL_NO_ERROR) { LogContext.log.e(TAG, "checkGlError. $op: glError $error", outputType = ILog.OUTPUT_TYPE_SYSTEM) error = GLES20.glGetError() } return error }
// Create a floating point buffer from the ByteBuffer .asFloatBuffer().apply { // Add the coordinates to the FloatBuffer put(array) // Set the buffer to read the first coordinate // position(0) rewind() } }
funcreateShortBuffer(array: ShortArray): ShortBuffer { return ByteBuffer.allocateDirect(array.size * Short.SIZE_BYTES) // Use the device hardware's native byte order .order(ByteOrder.nativeOrder())
// Create a short point buffer from the ByteBuffer .asShortBuffer().apply { // Add the coordinates to the FloatBuffer put(array) // Set the buffer to read the first coordinate // position(0) rewind() } }