OpenGL ES: nó là gì, kiến trúc và ứng dụng

Tác giả: IT Sectr Đã đăng: 2026-05-03 Thời gian đọc: 11 phút

OpenGL ES là một API đồ họa với đặc tả mở được thiết kế cho các hệ thống nhúng và di động. Nó cung cấp khả năng kết xuất đồ họa 2D và 3D được tăng tốc phần cứng thông qua pipeline shader có thể lập trình. Theo Khronos Group, 2025, OpenGL ES vẫn là API đồ họa phổ biến nhất trên các thiết bị di động, hỗ trợ hơn 10 tỷ cài đặt trên toàn thế giới. Thư viện được sử dụng trong trò chơi, dịch vụ bản đồ, ứng dụng AR và giao diện trên Android và iOS.

Những điểm chính

  • OpenGL ES là API đồ họa đa nền tảng cho thiết bị di động và nhúng, tiêu chuẩn thực tế trong ngành
  • Pipeline có thể lập trình bao gồm các shader đỉnh, mảnh và tính toán được viết bằng GLSL
  • Phiên bản OpenGL ES 2.0, 3.0 và 3.2 xác định tập hợp các tính năng khả dụng — mỗi phiên bản tiếp theo thêm các giai đoạn shader và cải thiện hiệu suất
  • EGL là lớp trung gian kết nối OpenGL ES với hệ thống cửa sổ của một nền tảng cụ thể (Android, iOS, Windows)
  • Metal và Vulkan là các giải pháp thay thế cấp thấp hơn, cung cấp ít chi phí hơn nhưng yêu cầu nhiều mã hơn để khởi tạo

OpenGL ES là gì?

OpenGL ES (Open Graphics Library for Embedded Systems) là một tập con của API OpenGL trên máy tính để bàn được điều chỉnh cho thiết bị di động, máy chơi game và hệ thống nhúng. Đặc tả được phát triển bởi tập đoàn Khronos Group và có sẵn miễn phí cho tất cả các nhà sản xuất. Không giống như OpenGL trên máy tính để bàn, OpenGL ES loại bỏ các tính năng kế thừa của pipeline cố định, chỉ giữ lại pipeline shader có thể lập trình — điều này giảm mức tiêu thụ điện năng và đơn giản hóa trình điều khiển.

Lĩnh vực ứng dụng chính của OpenGL ES là kết xuất đồ họa thời gian thực. API được sử dụng trong trò chơi di động (Unity, Unreal Engine), ứng dụng định vị, giải pháp AR dựa trên ARCore và ARKit, cũng như trong giao diện hệ thống Android và iOS. Theo StatCounter, 2026, tỷ lệ thiết bị hỗ trợ OpenGL ES 3.0+ vượt quá 92% trong số các điện thoại thông minh đang hoạt động.

Lợi thế chính của OpenGL ES là khả năng tương thích đa nền tảng. Cùng một ứng dụng viết bằng OpenGL ES có thể chạy trên Android, iOS, Linux và Windows với những thay đổi tối thiểu. Điều này làm cho API trở thành lựa chọn tối ưu cho các dự án nhắm đến nhiều nền tảng mà không cần viết lại engine đồ họa.

Pipeline cố định so với có thể lập trình

Các phiên bản đầu của OpenGL (trước 2.0) sử dụng pipeline cố định — một tập hợp các giai đoạn xử lý đỉnh và pixel được xác định trước. Nhà phát triển chỉ có thể cấu hình các tham số: vị trí nguồn sáng, thuộc tính vật liệu, ma trận biến đổi. Pipeline có thể lập trình, được giới thiệu trong OpenGL ES 2.0, đã thay thế các giai đoạn cố định bằng shader — các chương trình nhỏ thực thi trên GPU. Điều này cho phép nhà phát triển kiểm soát hoàn toàn việc kết xuất hình học.

Quá trình chuyển đổi sang pipeline có thể lập trình là một cuộc cách mạng cho đồ họa di động. Các nhà phát triển có khả năng triển khai các hiệu ứng phức tạp: PBR (Kết xuất dựa trên vật lý), bóng động, hậu xử lý và HDR. Pipeline cố định yêu cầu ít mã hơn nhưng không cho phép tạo ra phong cách hình ảnh độc đáo. Các trò chơi di động hiện đại hoạt động hoàn toàn trên pipeline có thể lập trình.

Kiến trúc OpenGL ES: pipeline kết xuất

Pipeline đồ họa của OpenGL ES bao gồm nhiều giai đoạn tuần tự, mỗi giai đoạn biến đổi dữ liệu đầu vào trên đường từ đỉnh đến pixel trên màn hình. Hiểu kiến trúc pipeline là rất quan trọng để tối ưu hóa hiệu suất kết xuất trên các thiết bị di động với ngân sách năng lượng và nhiệt hạn chế.

Giai đoạn pipelineMục đíchCó thể lập trình
Shader đỉnhBiến đổi đỉnh, áp dụng ma trận mô hình-góc nhìn-phép chiếuCó — GLSL
TessellationPhân chia hình học (chỉ ES 3.2)Có — GLSL
Shader hình họcTạo hình học mới từ các nguyên thủyCó — GLSL
RasterizationChuyển đổi nguyên thủy thành mảnh (pixel)Không — cố định
Shader mảnhTính màu của mỗi mảnh, tạo kết cấu, chiếu sángCó — GLSL
Thao tác trên mảnhKiểm tra độ sâu, kiểm tra stencil, hòa trộn, kiểm tra cắtCấu hình tham số

Giai đoạn đầu tiên — shader đỉnh — xử lý mỗi đỉnh một cách độc lập. Ở giai đoạn này, các phép biến đổi được áp dụng: chuyển từ không gian cục bộ của mô hình sang không gian thế giới, sau đó sang không gian camera và cuối cùng sang không gian cắt (clip space). Biến đổi được thiết lập thông qua ma trận đồng nhất MVP (Mô hình-Góc nhìn-Phép chiếu), được cập nhật mỗi khung hình khi camera hoặc đối tượng di chuyển.

Sau khi lắp ráp nguyên thủy (điểm, đường, tam giác), quá trình rasterization được thực hiện — quá trình xác định pixel màn hình nào mà mỗi nguyên thủy bao phủ. Bộ rasterization tạo ra các mảnh — pixel tiềm năng với các thuộc tính được nội suy (màu sắc, pháp tuyến, tọa độ UV). Số lượng mảnh phụ thuộc trực tiếp vào độ phân giải màn hình và diện tích chiếu của nguyên thủy.

Shader mảnh được thực thi cho mỗi mảnh được tạo ra. Nó tính toán màu pixel cuối cùng có tính đến kết cấu, nguồn sáng và vật liệu. Đầu ra của shader mảnh đi qua một loạt kiểm tra trên mảnh: kiểm tra độ sâu xác định mảnh có hiển thị không; kiểm tra stencil hạn chế kết xuất theo mặt nạ; hòa trộn trộn màu mảnh với màu đã được ghi trong bộ đệm khung.

Trạng thái ngữ cảnh OpenGL ES

OpenGL ES hoạt động như một máy trạng thái: tất cả các cài đặt — shader hiện tại, kết cấu được liên kết, kiểm tra được kích hoạt — được lưu trữ trong trạng thái toàn cục của ngữ cảnh. Thay đổi trạng thái qua glEnable, glBindTexture hoặc glUseProgram ảnh hưởng đến tất cả các lệnh vẽ tiếp theo. Mỗi lần chuyển đổi trạng thái gây ra chi phí trong trình điều khiển, do đó nhóm các lệnh gọi vẽ theo trạng thái là kỹ thuật tối ưu hóa chính.

Các phiên bản OpenGL ES và khả năng của chúng

OpenGL ES 1.0 và 1.1 (phát hành năm 2003–2004) dựa trên pipeline cố định. Chúng hỗ trợ biến đổi, tạo kết cấu, chiếu sáng và hòa trộn, nhưng không cho phép lập trình shader. API được sử dụng trong các điện thoại di động đầu tiên và thiết bị dựa trên Symbian và Windows Mobile. Ngày nay các phiên bản này được coi là lỗi thời — các thiết bị hiện đại không hỗ trợ chúng.

OpenGL ES 2.0 (2007) đã giới thiệu pipeline có thể lập trình với shader đỉnh và mảnh bằng GLSL ES. Phiên bản này trở thành tiêu chuẩn cho Android 2.2+ và iOS 5+ và vẫn được đa số thiết bị hỗ trợ. OpenGL ES 2.0 là phiên bản tối thiểu cần thiết cho Unity, Unreal Engine và Cocos2d-x trên các nền tảng di động.

OpenGL ES 3.0 (2012) đã thêm một số khả năng quan trọng: nhiều mục tiêu kết xuất (MRT), phản hồi biến đổi, instancing, kết cấu định dạng tùy ý qua ETC2/EAC. Hiệu suất kết xuất tăng 30–50% so với phiên bản 2.0 nhờ giảm số lượng lệnh gọi vẽ. OpenGL ES 3.1 (2014) đã giới thiệu shader tính toán và thao tác bộ đệm nguyên tử — điều này cho phép thực thi trên GPU không chỉ các tác vụ đồ họa mà còn cả tính toán (hậu xử lý, mô phỏng vải, tính toán vật lý).

OpenGL ES 3.2 (2015) — phiên bản mới nhất của đặc tả — đã thêm shader tessellation và hình học, cùng với tập hợp mở rộng các kết cấu float và chế độ hòa trộn. Mặc dù Vulkan hiện đại hơn được phát hành vào năm 2016, OpenGL ES 3.2 vẫn là một API phù hợp nhờ cơ sở mã hiện có khổng lồ và dễ dàng chuyển ứng dụng giữa các nền tảng.

Phiên bảnNămKhả năng chínhTương thích (2026)
1.x2003Pipeline cố định, chiếu sáng, kết cấuLỗi thời
2.02007Pipeline có thể lập trình, GLSL ES99% thiết bị
3.02012MRT, instancing, ETC2, phản hồi biến đổi92% thiết bị
3.12014Shader tính toán, bộ đệm nguyên tử80% thiết bị
3.22015Tessellation, shader hình học65% thiết bị

Shader trong OpenGL ES: GLSL và pipeline có thể lập trình

GLSL ES (Ngôn ngữ tạo bóng OpenGL cho hệ thống nhúng) là ngôn ngữ lập trình shader dựa trên cú pháp C với các kiểu bổ sung để làm việc với vector và ma trận. Mỗi shader là một chương trình được biên dịch thành mã máy GPU ở giai đoạn khởi tạo ứng dụng. Không giống như mã CPU, shader được thực thi song song hàng loạt: hàng nghìn đỉnh hoặc mảnh được xử lý đồng thời.

Shader đỉnh

Shader đỉnh xử lý mỗi đỉnh của lưới. Nhiệm vụ chính của nó là tính toán vị trí đỉnh cuối cùng trong không gian cắt bằng cách nhân vị trí đầu vào với ma trận MVP. Ngoài ra, shader đỉnh có thể tính toán pháp tuyến, tọa độ UV, màu sắc và truyền chúng đến shader mảnh qua các biến varying. Mỗi lần gọi shader đỉnh hoạt động độc lập, cho phép GPU xử lý hàng triệu đỉnh mỗi khung hình.

glsl
// Simple vertex shader for OpenGL ES 3.0
#version 300 es
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_normal;
layout(location = 2) in vec2 a_texCoord;

uniform mat4 u_mvpMatrix;

out vec3 v_normal;
out vec2 v_texCoord;

void main() {
    gl_Position = u_mvpMatrix * a_position;
    v_normal = mat3(u_mvpMatrix) * a_normal;
    v_texCoord = a_texCoord;
}

Shader mảnh

Shader mảnh xác định màu của mỗi pixel trên màn hình. Nó nhận các giá trị varying được nội suy từ shader đỉnh, lấy mẫu texel từ các kết cấu được liên kết và áp dụng chiếu sáng. Để chiếu sáng chính xác, mô hình Phong hoặc Blinn-Phong được sử dụng với tính toán các thành phần khuếch tán, phản chiếu và môi trường. Mỗi lần gọi shader mảnh tương ứng với một pixel, do đó tổng số lần gọi bằng diện tích chiếu của đối tượng trên màn hình.

glsl
// Simple fragment shader with texture and lighting
#version 300 es
precision mediump float;

in vec3 v_normal;
in vec2 v_texCoord;

uniform sampler2D u_texture;
uniform vec3 u_lightDir;

out vec4 fragColor;

void main() {
    vec4 texel = texture(u_texture, v_texCoord);
    vec3 normal = normalize(v_normal);
    float diffuse = max(dot(normal, u_lightDir), 0.0);
    fragColor = vec4(texel.rgb * diffuse, texel.a);
}

Trong ví dụ trên, shader mảnh lấy mẫu texel từ kết cấu 2D theo tọa độ UV, tính toán chiếu sáng khuếch tán là tích vô hướng của pháp tuyến và hướng ánh sáng, và nhân màu texel với cường độ chiếu sáng. Mediump là độ chính xác được khuyến nghị cho shader mảnh trên GPU di động: nó cung cấp chất lượng đủ với mức tiêu thụ điện năng tối thiểu.

Cách bắt đầu làm việc với OpenGL ES trong các dự án di động

Để làm việc với OpenGL ES trên Android, bạn cần tạo một ngữ cảnh EGL — một bề mặt để kết xuất đồ họa. Trên iOS, lớp EAGL (tương tự EGL) do framework GLKit cung cấp được sử dụng. Trong cả hai trường hợp, quá trình khởi tạo bao gồm tạo bề mặt cửa sổ, cấu hình thuộc tính ngữ cảnh và liên kết với luồng kết xuất hiện tại.

kotlin
// OpenGL ES 3.0 initialization on Android
class MyGLRenderer : GLSurfaceView.Renderer {

    private val vertexShaderCode = "#version 300 es\n..."
    private val fragmentShaderCode = "#version 300 es\n..."

    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        GLES30.glClearColor(0.1f, 0.1f, 0.2f, 1.0f)
        GLES30.glEnable(GLES30.GL_DEPTH_TEST)
    }

    override fun onDrawFrame(gl: GL10?) {
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT or GLES30.GL_DEPTH_BUFFER_BIT)
        // bind VBO, set uniforms, draw elements
    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        GLES30.glViewport(0, 0, width, height)
    }
}

Sau khi tạo ngữ cảnh, nhà phát triển cần thiết lập bộ đệm: bộ đệm đỉnh (VBO) chứa tọa độ đỉnh, pháp tuyến và UV; bộ đệm chỉ mục (EBO) xác định thứ tự duyệt đỉnh để tạo thành tam giác. VAO (Đối tượng mảng đỉnh) kết hợp tất cả cấu hình thuộc tính vào một đối tượng, giảm số lượng lệnh gọi API khi chuyển đổi lưới.

Thiết lập ngữ cảnh EGL

EGL (Giao diện đồ họa nền tảng gốc) là lớp trung gian giữa OpenGL ES và hệ thống cửa sổ. Trên Android, EGL quản lý việc tạo bề mặt kết xuất, lựa chọn cấu hình bộ đệm khung (độ sâu màu, stencil, MSAA) và đồng bộ hóa với vsync. Một cấu hình điển hình yêu cầu RGBA8888 với bộ đệm độ sâu 24-bit và bộ đệm stencil 8-bit. Trên iOS, vai trò của EGL được thực hiện bởi EAGL kết hợp với CAEAGLLayer.

Tối ưu hóa hiệu suất OpenGL ES trên thiết bị di động bao gồm một số phương pháp chính. Sử dụng instancing (glDrawArraysInstanced) để kết xuất nhiều đối tượng giống hệt nhau — điều này giảm số lượng lệnh gọi vẽ. Áp dụng nhóm kết cấu và tránh chuyển đổi kết cấu giữa các lệnh gọi vẽ. Sắp xếp đối tượng theo shader, sau đó theo kết cấu, sau đó theo lưới — thứ tự này giảm thiểu chuyển đổi trạng thái ngữ cảnh.

OpenGL ES vs Metal vs Vulkan

Metal là API đồ họa cấp thấp của Apple, có sẵn trên iOS và macOS bắt đầu từ chip A7. Metal cung cấp quyền truy cập trực tiếp vào GPU với chi phí trình điều khiển tối thiểu, nhưng chỉ hoạt động trên các thiết bị Apple. Theo WWDC 2024, Metal cung cấp hiệu suất cao hơn tới 40% so với OpenGL ES trên cùng một phần cứng nhờ giảm kiểm tra trạng thái thời gian chạy.

Vulkan là sự kế thừa đa nền tảng của OpenGL ES, được phát triển bởi Khronos Group. Vulkan sử dụng quản lý tài nguyên rõ ràng: nhà phát triển cấp phát nhóm bộ nhớ, tạo bộ đệm lệnh và đồng bộ hóa quyền truy cập GPU. Điều này cho kiểm soát tối đa về hiệu suất, nhưng mã khởi tạo Vulkan dài gấp 3–4 lần so với OpenGL ES. Vulkan được khuyến nghị cho các trò chơi AAA và ứng dụng đồ họa yêu cầu cao trên Android 7+.

Sự lựa chọn giữa OpenGL ES, Metal và Vulkan phụ thuộc vào nền tảng mục tiêu và yêu cầu hiệu suất. OpenGL ES vẫn là lựa chọn tốt nhất cho các dự án đa nền tảng, nơi tốc độ phát triển quan trọng. Metal được ưa chuộng cho hệ sinh thái iOS/macOS với hiệu suất tối đa. Vulkan là lựa chọn cho các dự án nơi mỗi mili giây mỗi khung hình đều quan trọng và ngân sách phát triển cho phép đầu tư vào tối ưu hóa cấp thấp.

Đặc điểmOpenGL ESMetalVulkan
Nền tảngAndroid, iOS, Windows, LinuxChỉ iOS, macOSAndroid, Windows, Linux (không iOS)
Cấp độ APICao (máy trạng thái)Trung bìnhThấp (rõ ràng)
Mã khởi tạo50–100 dòng100–200 dòng300–500 dòng
Kiểm soát bộ nhớTự độngBán tự độngHoàn toàn thủ công
Hiệu suấtCơ bản+20–40% so với ES+30–60% so với ES

Các câu hỏi thường gặp

Sự khác biệt giữa OpenGL và OpenGL ES là gì?

OpenGL ES là một tập con của OpenGL trên máy tính để bàn, từ đó các tính năng kế thừa của pipeline cố định đã được loại bỏ. OpenGL ES có khối lượng đặc tả nhỏ hơn, hồ sơ độ chính xác đơn giản hơn và được tối ưu hóa cho mức tiêu thụ điện năng thấp của thiết bị di động.

Phiên bản OpenGL ES nào được hỗ trợ trên Android?

Android hỗ trợ OpenGL ES 2.0 trên tất cả thiết bị, 3.0 trên Android 4.3+, 3.1 trên Android 5.0+, 3.2 trên một số thiết bị chạy Android 7.0+. Mức hỗ trợ hiện tại có thể được kiểm tra qua EGL_CONFIG_CAVEAT.

Ngôn ngữ nào được sử dụng để viết shader OpenGL ES?

GLSL ES (Ngôn ngữ tạo bóng OpenGL cho hệ thống nhúng) là ngôn ngữ giống C với các kiểu vec2/vec3/vec4/mat4 và các hàm tích hợp texture, normalize, dot. Cho ES 3.0+, chỉ thị #version 300 es được sử dụng.

Có nên học OpenGL ES vào năm 2026 không?

Có, OpenGL ES vẫn phù hợp cho các dự án đa nền tảng, nơi tốc độ phát triển và hỗ trợ thiết bị rộng rãi là ưu tiên. Cho hệ sinh thái iOS, tốt hơn nên học Metal; cho các dự án mới với hiệu suất tối đa, hãy sử dụng Vulkan.

Làm thế nào để kiểm tra phiên bản OpenGL ES trên thiết bị?

Trên Android, gọi GLES30.glGetString(GLES30.GL_VERSION) sau khi tạo ngữ cảnh. Chuỗi chứa số phiên bản và thông tin nhà cung cấp. Trên iOS, sử dụng [EAGLContext currentContext] và thuộc tính API.

Tổng kết

  • OpenGL ES là API đồ họa chính cho thiết bị di động, được hỗ trợ trên hơn 10 tỷ cài đặt
  • Pipeline có thể lập trình với shader đỉnh và mảnh bằng GLSL ES cung cấp kiểm soát hoàn toàn việc kết xuất
  • Phiên bản 2.0, 3.0, 3.1, 3.2 khác nhau về tập hợp các giai đoạn shader và chức năng khả dụng
  • EGL kết nối OpenGL ES với hệ thống cửa sổ, quản lý bề mặt kết xuất và đồng bộ hóa
  • Metal và Vulkan là các giải pháp thay thế hiệu suất cao hơn nhưng yêu cầu nhiều mã hơn và dành riêng cho nền tảng
  • Tối ưu hóa bao gồm instancing, sắp xếp lệnh gọi vẽ theo trạng thái và nhóm kết cấu
  • Cho các dự án đa nền tảng OpenGL ES vẫn là lựa chọn tối ưu nhờ tính đơn giản và hệ sinh thái trưởng thành

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm