Mobile Development 24 min read

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.

Ctrip Technology
Ctrip Technology
Ctrip Technology
Using OpenGL ES for Image Transition Effects in Mobile Video Editing

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.

AndroidGLSLOpenGLShaderVideoTransition
Ctrip Technology
Written by

Ctrip Technology

Official Ctrip Technology account, sharing and discussing growth.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.