Files
midi-android/moduleUtil/src/main/java/com/xscm/moduleutil/widget/ChannelSplitRenderer.kt
2025-08-26 19:34:44 +08:00

122 lines
3.8 KiB
Kotlin

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)
}
}