Using OpenGL ES for Image Transition Effects in Mobile Video Editing
This article introduces the role of OpenGL ES in mobile video editing, explains why it is preferred over Vulkan, details the rendering pipeline and GLSL shader programming, and provides step‑by‑step Android code for implementing image transition effects and combining multiple transitions.
With the rise of short‑video apps, audio‑video editing tools have become crucial, and rich transition effects can greatly improve user experience. This article first explains why OpenGL ES is chosen for mobile graphics processing, compares it with Vulkan, and outlines its advantages on Android and iOS.
Why use OpenGL ES – Mobile GPUs handle 3D graphics efficiently; OpenGL ES is supported on all Android versions and iOS, while Vulkan requires Android 7.0+. OpenGL ES is a streamlined subset of OpenGL, removing unnecessary features for embedded devices, making it easier to learn and integrate.
Basic concepts of OpenGL – OpenGL is a cross‑platform API for rendering 2D/3D graphics. It can be used for video processing, game engines, scientific visualization, AR/VR, etc. The rendering pipeline consists of vertex processing, optional geometry processing, primitive assembly, rasterization, fragment processing, and blending tests.
Rendering pipeline steps
Vertex data input
Vertex shader (coordinate transformation)
Geometry shader (optional)
Primitive assembly & rasterization
Fragment shader (pixel color calculation)
Blending & testing
Both Vertex Shader and Fragment Shader are programmable stages that run on the GPU. The vertex shader determines vertex positions, while the fragment shader computes final pixel colors.
GLSL (OpenGL Shading Language) – GLSL is a C‑like language used to write shaders. It provides built‑in types such as attribute , uniform , varying , and functions like mix , fract , step .
Vertex shader example
attribute vec4 Position; // vertex position
attribute vec2 TextureCoord; // texture coordinate
varying vec2 varyTextureCoord; // passed to fragment shader
void main() {
gl_Position = Position;
varyTextureCoord = TextureCoord;
}Fragment shader example
precision mediump float;
uniform sampler2D Texture;
uniform sampler2D Texture2;
varying vec2 varyTextureCoord;
const vec2 direction = vec2(0.0, 1.0);
void main() {
vec4 color = mix(texture2D(Texture, varyTextureCoord),
texture2D(Texture2, varyTextureCoord),
step(0.0, varyTextureCoord.y));
gl_FragColor = color;
}Drawing a simple image with OpenGL – The following Android renderer creates a program from the vertex and fragment shaders, loads two textures, and draws a full‑screen quad.
class SimpleImageRender(private val context: Context) : GLSurfaceView.Renderer {
private val vCoordinates = floatArrayOf(
-1f, -1f,
1f, -1f,
-1f, 1f,
1f, 1f
)
private val texCoordinates = floatArrayOf(
0f, 1f,
1f, 1f,
0f, 0f,
1f, 0f
)
var programId = 0
var vHandle = 0
var texHandle = 0
var textureId = 0
// buffers omitted for brevity
override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
programId = loadShaderWithResource(context, R.raw.simple_image_vs, R.raw.simple_image_fs)
vHandle = GLES20.glGetAttribLocation(programId, "a_position")
texHandle = GLES20.glGetAttribLocation(programId, "a_texCoord")
val ids = IntArray(1)
GLES20.glGenTextures(1, ids, 0)
textureId = ids[0]
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId)
// set parameters and load bitmap
}
override fun onDrawFrame(gl: GL10?) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
GLES20.glUseProgram(programId)
// enable attributes, set pointers, bind texture, draw
}
}Transition effects – A transition is achieved by blending two textures in the fragment shader. The GLTransitions project provides dozens of ready‑made GLSL transition shaders. To use one, add a uniform float progress (0‑1) and the two texture samplers, then output the blended color.
uniform vec2 direction;
uniform float progress;
uniform sampler2D u_texture0;
uniform sampler2D u_texture1;
varying vec2 v_texCoord;
vec4 transition(vec2 uv) {
vec2 p = uv + progress * sign(direction);
vec2 f = fract(p);
return mix(texture2D(u_texture1, f), texture2D(u_texture0, f),
step(0.0, p.y) * step(p.y, 1.0) * step(0.0, p.x) * step(p.x, 1.0));
}
void main() {
gl_FragColor = transition(v_texCoord);
}Combining multiple transitions – By defining an IDrawer interface and a ComposeRender that switches between different OpenGL programs after a fixed number of frames, developers can chain several transition effects to create richer visual experiences.
Conclusion – OpenGL ES offers high performance and broad compatibility for mobile graphics processing. Understanding the rendering pipeline and mastering GLSL shaders enables developers to implement custom image and video transition effects, and by leveraging open‑source resources such as GLTransitions, complex effects can be integrated quickly into Android or iOS applications.
Ctrip Technology
Official Ctrip Technology account, sharing and discussing growth.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.