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 (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.
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.
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 pipeline | Mục đích | Có thể lập trình |
|---|---|---|
| Shader đỉnh | Biến đổi đỉnh, áp dụng ma trận mô hình-góc nhìn-phép chiếu | Có — GLSL |
| Tessellation | Phân chia hình học (chỉ ES 3.2) | Có — GLSL |
| Shader hình học | Tạo hình học mới từ các nguyên thủy | Có — GLSL |
| Rasterization | Chuyển đổi nguyên thủy thành mảnh (pixel) | Không — cố định |
| Shader mảnh | Tính màu của mỗi mảnh, tạo kết cấu, chiếu sáng | Có — GLSL |
| Thao tác trên mảnh | Kiểm tra độ sâu, kiểm tra stencil, hòa trộn, kiểm tra cắt | Cấ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.
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.
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ản | Năm | Khả năng chính | Tương thích (2026) |
|---|---|---|---|
| 1.x | 2003 | Pipeline cố định, chiếu sáng, kết cấu | Lỗi thời |
| 2.0 | 2007 | Pipeline có thể lập trình, GLSL ES | 99% thiết bị |
| 3.0 | 2012 | MRT, instancing, ETC2, phản hồi biến đổi | 92% thiết bị |
| 3.1 | 2014 | Shader tính toán, bộ đệm nguyên tử | 80% thiết bị |
| 3.2 | 2015 | Tessellation, shader hình học | 65% thiết bị |
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 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.
// 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 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.
// 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.
Để 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.
// 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.
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.
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ểm | OpenGL ES | Metal | Vulkan |
|---|---|---|---|
| Nền tảng | Android, iOS, Windows, Linux | Chỉ iOS, macOS | Android, Windows, Linux (không iOS) |
| Cấp độ API | Cao (máy trạng thái) | Trung bình | Thấp (rõ ràng) |
| Mã khởi tạo | 50–100 dòng | 100–200 dòng | 300–500 dòng |
| Kiểm soát bộ nhớ | Tự động | Bán tự động | Hoàn toàn thủ công |
| Hiệu suất | Cơ bản | +20–40% so với ES | +30–60% so với ES |
Các câu hỏi thường gặp
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.
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.
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ó, 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.
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
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.
Đọc thêm