使用 GPUImage for Android 加载和应用自定义 GLSL 文件(例如你的 transition
文件)的方法如下:
1. 准备 GLSL 文件
确保你的 GLSL 文件已经调整为 GPUImage 的格式。对于你的自定义 GLSL 文件,GPUImage 期望包含以下结构:
-
顶点着色器:
GPUImage 默认使用标准顶点着色器,你无需更改。内容如下:attribute vec4 position; attribute vec4 inputTextureCoordinate;varying vec2 textureCoordinate;void main() {gl_Position = position;textureCoordinate = inputTextureCoordinate.xy; }
-
片段着色器:
调整你的 GLSL 文件以适配 GPUImage 的getFromColor
和getToColor
的实现。precision mediump float;varying vec2 textureCoordinate;uniform sampler2D inputImageTexture; // 当前纹理 uniform sampler2D inputImageTexture2; // 下一个纹理uniform float progress; // 过渡进度 uniform float dots; // 参数 dots uniform vec2 center; // 参数中心点const float SQRT_2 = 1.414213562373;vec4 getFromColor(vec2 uv) {return texture2D(inputImageTexture, uv); }vec4 getToColor(vec2 uv) {return texture2D(inputImageTexture2, uv); }vec4 transition(vec2 uv) {bool nextImage = distance(fract(uv * dots), vec2(0.5, 0.5)) < (progress / distance(uv, center));return nextImage ? getToColor(uv) : getFromColor(uv); }void main() {gl_FragColor = transition(textureCoordinate); }
将片段着色器保存为一个 .glsl
文件,例如:assets/shaders/transition.glsl
。
2. 在 GPUImage 中使用自定义着色器
2.1 添加 GPUImage 库
在项目的 build.gradle
文件中添加 GPUImage 的依赖:
implementation 'jp.co.cyberagent.android:gpuimage:2.1.0'
2.2 创建自定义滤镜
创建一个类来加载自定义片段着色器:
class CustomTransitionFilter(context: Context) : GPUImageFilter(NO_FILTER_VERTEX_SHADER, loadShaderFromAssets(context)) {private var progressLocation: Int = 0private var dotsLocation: Int = 0private var centerLocation: Int = 0override fun onInit() {super.onInit()// 获取 Uniform 参数的位置progressLocation = GLES20.glGetUniformLocation(program, "progress")dotsLocation = GLES20.glGetUniformLocation(program, "dots")centerLocation = GLES20.glGetUniformLocation(program, "center")}override fun onInitialized() {super.onInitialized()// 初始化 Uniform 参数setProgress(0f)setDots(20f)setCenter(floatArrayOf(0.5f, 0.5f))}fun setProgress(progress: Float) {setFloat(progressLocation, progress)}fun setDots(dots: Float) {setFloat(dotsLocation, dots)}fun setCenter(center: FloatArray) {setFloatVec2(centerLocation, center)}private fun loadShaderFromAssets(context: Context): String {return context.assets.open("shaders/transition.glsl").bufferedReader().use { it.readText() }}
}
2.3 应用滤镜并显示效果
将滤镜应用到 GPUImageView
或 GPUImage
上:
val gpuImageView = findViewById<GPUImageView>(R.id.gpuImageView)// 初始化 GPUImage 和自定义滤镜
val gpuImage = GPUImage(this)
val customFilter = CustomTransitionFilter(this)// 加载两张图片作为纹理
gpuImage.setImage(BitmapFactory.decodeResource(resources, R.drawable.image1))
customFilter.setProgress(0f) // 起始过渡进度// 应用自定义滤镜
gpuImage.setFilter(customFilter)// 动态更新过渡进度
val animator = ValueAnimator.ofFloat(0f, 1f).apply {duration = 2000addUpdateListener { animation ->val progress = animation.animatedValue as FloatcustomFilter.setProgress(progress)gpuImageView.requestRender() // 刷新视图}
}
animator.start()
3. 完整布局文件
确保你在 XML 文件中定义了 GPUImageView
:
<com.example.gpuimage.GPUImageViewandroid:id="@+id/gpuImageView"android:layout_width="match_parent"android:layout_height="match_parent" />
4. 动态参数设置
- 如果需要动态调整
dots
和center
参数,可以通过暴露方法setDots()
和setCenter()
实现。 - 例如:
customFilter.setDots(30f) customFilter.setCenter(floatArrayOf(0.3f, 0.7f))
总结
以上步骤说明了如何在 GPUImage 中加载并使用你的自定义 GLSL 文件。核心流程包括:
- 准备兼容的 GLSL 文件。
- 使用 GPUImage 创建自定义滤镜。
- 通过动画动态调整
progress
等 Uniform 参数,完成过渡效果。
如果需要进一步扩展或调试代码,请随时告诉我!