package com.xscm.moduleutil.widget import android.graphics.SurfaceTexture import android.opengl.GLES20 import android.opengl.Matrix class ChannelSplitRenderer { private val vertexShaderCode = """ attribute vec4 aPosition; attribute vec2 aTexCoord; varying vec2 vTexCoord; void main() { gl_Position = aPosition; vTexCoord = aTexCoord; } """ private val fragmentShaderCode = """ precision mediump float; uniform sampler2D uTexture; varying vec2 vTexCoord; void main() { // 只使用左半部分作为最终颜色 vec2 leftCoord = vec2(vTexCoord.x * 0.5, vTexCoord.y); vec4 color = texture2D(uTexture, leftCoord); // 设置 alpha 为 1.0 表示完全不透明,或根据需求设为 0.0 表示全透明 gl_FragColor = vec4(color.rgb, 0.0); // 左通道颜色 + 不透明 }""" private var program = 0 private var positionHandle = 0 private var texCoordHandle = 0 private var textureHandle = 0 private val projectionMatrix = FloatArray(16) private val modelMatrix = FloatArray(16) fun onSurfaceCreated(surface: SurfaceTexture, width: Int, height: Int) { // 初始化着色器 val vertexShader = ShaderUtils.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode) val fragmentShader = ShaderUtils.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode) program = GLES20.glCreateProgram().also { GLES20.glAttachShader(it, vertexShader) GLES20.glAttachShader(it, fragmentShader) GLES20.glLinkProgram(it) } positionHandle = GLES20.glGetAttribLocation(program, "aPosition") texCoordHandle = GLES20.glGetAttribLocation(program, "aTexCoord") textureHandle = GLES20.glGetUniformLocation(program, "uTexture") // 初始化矩阵 Matrix.setIdentityM(projectionMatrix, 0) Matrix.setIdentityM(modelMatrix, 0) GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f) GLES20.glEnable(GLES20.GL_BLEND) GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA) } fun onSurfaceChanged(width: Int, height: Int) { GLES20.glViewport(0, 0, width, height) } fun onDrawFrame(textureId: Int) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) GLES20.glUseProgram(program) // 定义顶点坐标(全屏) val vertices = floatArrayOf( -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f ) // 修改纹理坐标,只映射左半部分视频内容到左侧屏幕 val texCoords = floatArrayOf( 0.0f, 1.0f, // 左下角 0.5f, 1.0f, // 右下角(对应视频中间) 0.0f, 0.0f, // 左上角 0.5f, 0.0f // 右上角 ) val vertexBuffer = ShaderUtils.createFloatBuffer(vertices) val texBuffer = ShaderUtils.createFloatBuffer(texCoords) GLES20.glEnableVertexAttribArray(positionHandle) GLES20.glVertexAttribPointer( positionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer ) GLES20.glEnableVertexAttribArray(texCoordHandle) GLES20.glVertexAttribPointer( texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, texBuffer ) // 绑定纹理 GLES20.glActiveTexture(GLES20.GL_TEXTURE0) GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId) GLES20.glUniform1i(textureHandle, 0) // 绘制 GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4) // 清理 GLES20.glDisableVertexAttribArray(positionHandle) GLES20.glDisableVertexAttribArray(texCoordHandle) } fun release() { GLES20.glDeleteProgram(program) } }