自定义View
代码
class MyGLSurfaceView(context: Context, attrs: AttributeSet) : GLSurfaceView(context, attrs) {
init {
setEGLContextClientVersion(3)
setRenderer(MyRenderer())
renderMode = RENDERMODE_WHEN_DIRTY
}
}
自定义Renderer
渲染代码
class MyRenderer : GLSurfaceView.Renderer {
private var mProgram = 0
private var vbo = IntArray(2)
override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
GLES30.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
initializeBuffers()
mProgram = initializeShaders()
}
override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
GLES30.glViewport(0, 0, width, height)
}
override fun onDrawFrame(gl: GL10?) {
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT or GLES30.GL_DEPTH_BUFFER_BIT)
drawSomething(mProgram)
}
private fun initializeBuffers() {
val vertices = floatArrayOf(
0.0f, 0.5f, 0.0f,
-0.5f, 0.0f, 0.0f,
0.5f, 0.0f, 0.0f
)
val colors = floatArrayOf(
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f
)
val vertexBuffer = ByteBuffer.allocateDirect(vertices.size * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(vertices)
.position(0)
val colorBuffer = ByteBuffer.allocateDirect(colors.size * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(colors)
.position(0)
GLES30.glGenBuffers(2, vbo, 0)
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbo[0])
GLES30.glBufferData(
GLES30.GL_ARRAY_BUFFER,
vertices.size * 4,
vertexBuffer,
GLES30.GL_STATIC_DRAW
)
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbo[1])
GLES30.glBufferData(
GLES30.GL_ARRAY_BUFFER,
colors.size * 4,
colorBuffer,
GLES30.GL_STATIC_DRAW
)
}
private fun initializeShaders(): Int {
val vertexShaderCode = """#version 300 es
layout (location = 0) in vec4 aPosition;
layout (location = 1) in vec4 aColor;
out vec4 vColor;
void main() {
gl_Position = aPosition;
vColor = aColor;
}""".trimIndent()
val fragmentShaderCode = """#version 300 es
precision mediump float;
in vec4 vColor;
out vec4 fragColor;
void main() {
fragColor = vColor;
}""".trimIndent()
val vertexShader = GLES30.glCreateShader(GLES30.GL_VERTEX_SHADER)
GLES30.glShaderSource(vertexShader, vertexShaderCode)
GLES30.glCompileShader(vertexShader)
val fragmentShader = GLES30.glCreateShader(GLES30.GL_FRAGMENT_SHADER)
GLES30.glShaderSource(fragmentShader, fragmentShaderCode)
GLES30.glCompileShader(fragmentShader)
val program = GLES30.glCreateProgram()
GLES30.glAttachShader(program, vertexShader)
GLES30.glAttachShader(program, fragmentShader)
GLES30.glLinkProgram(program)
return program
}
fun drawSomething(program: Int) {
GLES30.glUseProgram(program)
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbo[0])
val positionHandle = GLES30.glGetAttribLocation(program, "aPosition")
GLES30.glEnableVertexAttribArray(positionHandle)
GLES30.glVertexAttribPointer(positionHandle, 3, GLES30.GL_FLOAT, false, 0, 0)
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbo[1])
val colorHandle = GLES30.glGetAttribLocation(program, "aColor")
GLES30.glEnableVertexAttribArray(colorHandle)
GLES30.glVertexAttribPointer(colorHandle, 3, GLES30.GL_FLOAT, false, 0, 0)
GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 3)
GLES30.glDisableVertexAttribArray(positionHandle)
GLES30.glDisableVertexAttribArray(colorHandle)
}
}
效果图
