OpenGL ES

Android menyertakan dukungan untuk grafis 2D dan 3D performa tinggi dengan Open Graphics Library (OpenGL®), khususnya, OpenGL ES API. OpenGL adalah API grafis lintas platform yang menentukan antarmuka software standar untuk hardware pemrosesan grafis 3D. OpenGL ES adalah ragam spesifikasi OpenGL yang dimaksudkan untuk perangkat tersemat. Android mendukung beberapa versi OpenGL ES API:

  • OpenGL ES 2.0 - Spesifikasi API ini didukung oleh Android 2.2 (API level 8) dan yang lebih tinggi.
  • OpenGL ES 3.0 - Spesifikasi API ini didukung oleh Android 4.3 (API level 18) dan yang lebih tinggi.
  • OpenGL ES 3.1 - Spesifikasi API ini didukung oleh Android 5.0 (API level 21) dan yang lebih tinggi.
  • OpenGL ES 3.2 - Spesifikasi API ini didukung oleh Android 7.0 (API level 24) dan yang lebih tinggi.

Perhatian: Terlepas dari versi platform Android, perangkat tidak dapat mendukung OpenGL ES 3.0 API kecuali jika produsen perangkat menyediakan implementasi pipeline grafis ini. Jika Anda menentukan dalam manifes bahwa OpenGL ES 3.0 diperlukan, Anda dapat memastikan bahwa versi tersebut akan ada di perangkat. Jika Anda menentukan bahwa versi tingkat rendah diperlukan tetapi Anda ingin menggunakan fitur 3.0 jika tersedia, Anda harus memeriksa pada waktu proses untuk melihat versi OpenGL yang didukung perangkat. Untuk informasi cara melakukannya, lihat Memeriksa versi OpenGL ES.

Catatan: Android menyertakan dukungan untuk OpenGL ES 1.0 dan 1.1, tetapi versi API ini tidak digunakan lagi dan tidak boleh digunakan oleh aplikasi modern.

Catatan: API spesifik yang disediakan oleh framework Android mirip dengan J2ME JSR239 OpenGL ES API, tetapi tidak identik. Jika Anda sudah terbiasa dengan spesifikasi J2ME JSR239, waspadai variasinya.

Lihat juga

Dasar-dasar

Android mendukung OpenGL melalui API framework-nya dan Native Development Kit (NDK). Topik ini berfokus pada antarmuka framework Android. Untuk informasi selengkapnya tentang NDK, lihat Android NDK.

Ada dua class dasar dalam framework Android yang memungkinkan Anda membuat dan memanipulasi grafis dengan OpenGL ES API: GLSurfaceView dan GLSurfaceView.Renderer. Jika tujuan Anda adalah menggunakan OpenGL di aplikasi Android, memahami cara mengimplementasikan class ini dalam aktivitas harus menjadi tujuan pertama Anda.

GLSurfaceView
Class ini adalah View tempat Anda dapat menggambar dan memanipulasi objek menggunakan panggilan OpenGL API, dan fungsinya serupa dengan SurfaceView. Anda dapat menggunakan class ini dengan membuat instance GLSurfaceView dan menambahkan Renderer ke instance tersebut. Namun, jika ingin merekam peristiwa layar sentuh, Anda harus memperluas class GLSurfaceView untuk mengimplementasikan pemroses sentuh, seperti yang ditunjukkan dalam tutorial pelatihan OpenGL, Merespons peristiwa sentuh.
GLSurfaceView.Renderer
Antarmuka ini menentukan metode yang diperlukan untuk menggambar grafis di GLSurfaceView. Anda harus menyediakan implementasi antarmuka ini sebagai class terpisah dan melampirkannya ke instance GLSurfaceView menggunakan GLSurfaceView.setRenderer().

Antarmuka GLSurfaceView.Renderer mengharuskan Anda menerapkan metode berikut:

  • onSurfaceCreated(): Sistem memanggil metode ini satu kali, saat membuat GLSurfaceView. Gunakan metode ini untuk melakukan tindakan yang perlu terjadi hanya sekali, seperti menyetel parameter lingkungan OpenGL atau menginisialisasi objek grafis OpenGL.
  • onDrawFrame(): Sistem memanggil metode ini di setiap penggambaran ulang GLSurfaceView. Gunakan metode ini sebagai titik eksekusi utama untuk menggambar (dan menggambar ulang) objek visual.
  • onSurfaceChanged(): Sistem memanggil metode ini saat geometri GLSurfaceView berubah, termasuk perubahan ukuran GLSurfaceView atau orientasi layar perangkat. Misalnya, sistem memanggil metode ini saat perangkat berubah dari orientasi potret ke lanskap. Gunakan metode ini untuk merespons perubahan di penampung GLSurfaceView.

Paket OpenGL ES

Setelah menetapkan tampilan penampung untuk OpenGL ES menggunakan GLSurfaceView dan GLSurfaceView.Renderer, Anda dapat mulai memanggil OpenGL API menggunakan class berikut:

  • Class OpenGL ES 2.0 API
    • android.opengl.GLES20 - Paket ini menyediakan antarmuka ke OpenGL ES 2.0 dan tersedia mulai Android 2.2 (API level 8).
  • Paket OpenGL ES 3.0/3.1/3.2 API

Jika Anda ingin segera mulai membuat aplikasi dengan OpenGL ES, ikuti class Menampilkan grafis dengan OpenGL ES.

Mendeklarasikan persyaratan OpenGL

Jika aplikasi Anda menggunakan fitur OpenGL yang hanya tersedia di perangkat tertentu, Anda harus menyertakan persyaratan ini dalam file AndroidManifest.xml. Berikut ini beberapa deklarasi manifes OpenGL yang paling umum:

  • Persyaratan versi OpenGL ES - Jika aplikasi memerlukan OpenGL ES versi tertentu, Anda harus mendeklarasikan persyaratan tersebut dengan menambahkan setelan berikut ke manifes, seperti yang ditunjukkan di bawah ini.

    Untuk OpenGL ES 2.0:

    <!-- Tell the system this app requires OpenGL ES 2.0. -->
    <uses-feature android:glEsVersion="0x00020000" android:required="true" />
    

    Menambahkan deklarasi ini menyebabkan Google Play membatasi aplikasi Anda agar tidak diinstal di perangkat yang tidak mendukung OpenGL ES 2.0. Jika aplikasi Anda ditujukan khusus untuk perangkat yang mendukung OpenGL ES 3.0, Anda juga dapat menentukannya dalam manifes:

    Untuk OpenGL ES 3.0:

    <!-- Tell the system this app requires OpenGL ES 3.0. -->
    <uses-feature android:glEsVersion="0x00030000" android:required="true" />
    

    Untuk OpenGL ES 3.1:

    <!-- Tell the system this app requires OpenGL ES 3.1. -->
    <uses-feature android:glEsVersion="0x00030001" android:required="true" />
    

    Untuk OpenGL ES 3.2:

    <!-- Tell the system this app requires OpenGL ES 3.2. -->
    <uses-feature android:glEsVersion="0x00030002" android:required="true" />
    

    Catatan: OpenGL ES 3.x API memiliki kompatibilitas mundur dengan 2.0 API, yang berarti Anda dapat lebih fleksibel dalam mengimplementasikan OpenGL ES dalam aplikasi. Dengan mendeklarasikan OpenGL ES 2.0 API sebagai persyaratan dalam manifes, Anda dapat menggunakan versi API tersebut sebagai default, memeriksa ketersediaan 3.x API saat runtime, kemudian menggunakan fitur OpenGL ES 3.x jika perangkat mendukungnya. Untuk informasi selengkapnya tentang memeriksa versi OpenGL ES yang didukung oleh perangkat, lihat Memeriksa versi OpenGL ES.

  • Persyaratan kompresi tekstur - Jika aplikasi Anda menggunakan format kompresi tekstur, Anda harus mendeklarasikan format yang didukung aplikasi Anda dalam file manifes menggunakan <supports-gl-texture>. Untuk mengetahui informasi selengkapnya tentang format kompresi tekstur yang tersedia, lihat Dukungan kompresi tekstur.

    Mendeklarasikan persyaratan kompresi tekstur dalam manifes akan menyembunyikan aplikasi Anda dari pengguna dengan perangkat yang tidak mendukung setidaknya salah satu jenis kompresi yang dideklarasikan. Untuk mengetahui informasi selengkapnya tentang cara kerja pemfilteran Google Play untuk kompresi tekstur, lihat bagian Pemfilteran kompresi tekstur dan Google Play dalam dokumentasi <supports-gl-texture>.

Memetakan koordinat untuk objek yang digambar

Salah satu masalah dasar dalam menampilkan grafis di perangkat Android adalah ukuran dan bentuk layarnya dapat bervariasi. OpenGL mengasumsikan sistem koordinat persegi yang seragam dan, secara default, dengan mudah menggambar koordinat tersebut ke layar Anda yang biasanya bukan persegi seolah-olah berbentuk persegi sempurna.

Gambar 1. Sistem koordinat OpenGL default (kiri) dipetakan ke layar perangkat Android standar (kanan).

Ilustrasi di atas menunjukkan sistem koordinat seragam yang diasumsikan untuk frame OpenGL di sebelah kiri, dan bagaimana koordinat ini sebenarnya dipetakan ke layar perangkat standar dalam orientasi lanskap di sebelah kanan. Untuk mengatasi masalah ini, Anda dapat menerapkan mode proyeksi OpenGL dan tampilan kamera untuk mentransformasi koordinat sehingga objek grafis Anda memiliki proporsi yang benar di tampilan apa pun.

Untuk menerapkan proyeksi dan tampilan kamera, buat matriks proyeksi dan matriks tampilan kamera, lalu terapkan ke pipeline rendering OpenGL. Matriks proyeksi ini menghitung ulang koordinat grafis agar dapat dipetakan dengan benar ke layar perangkat Android. Matriks tampilan kamera membuat transformasi yang merender objek dari posisi mata tertentu.

Proyeksi dan tampilan kamera di OpenGL ES 2.0 dan yang lebih tinggi

Di ES 2.0 dan 3.0 API, terapkan proyeksi dan tampilan kamera dengan terlebih dahulu menambahkan anggota matriks ke shader verteks objek grafis. Setelah anggota matriks ini ditambahkan, Anda dapat membuat dan menerapkan matriks proyeksi dan tampilan kamera ke objek Anda.

  1. Menambahkan matriks ke shader verteks - Buat variabel untuk matriks proyeksi tampilan dan sertakan sebagai pengganda posisi shader. Dalam contoh kode shader verteks berikut, anggota uMVPMatrix yang disertakan memungkinkan Anda menerapkan matriks proyeksi dan tampilan kamera ke koordinat objek yang menggunakan shader ini.

    Kotlin

    private val vertexShaderCode =
    
        // This matrix member variable provides a hook to manipulate
        // the coordinates of objects that use this vertex shader.
        "uniform mat4 uMVPMatrix;   \n" +
    
        "attribute vec4 vPosition;  \n" +
        "void main(){               \n" +
        // The matrix must be included as part of gl_Position
        // Note that the uMVPMatrix factor *must be first* in order
        // for the matrix multiplication product to be correct.
        " gl_Position = uMVPMatrix * vPosition; \n" +
    
        "}  \n"
    

    Java

    private final String vertexShaderCode =
    
        // This matrix member variable provides a hook to manipulate
        // the coordinates of objects that use this vertex shader.
        "uniform mat4 uMVPMatrix;   \n" +
    
        "attribute vec4 vPosition;  \n" +
        "void main(){               \n" +
        // The matrix must be included as part of gl_Position
        // Note that the uMVPMatrix factor *must be first* in order
        // for the matrix multiplication product to be correct.
        " gl_Position = uMVPMatrix * vPosition; \n" +
    
        "}  \n";
    

    Catatan: Contoh di atas menetapkan satu anggota matriks transformasi di shader verteks tempat Anda menerapkan gabungan matriks proyeksi dan matriks tampilan kamera. Bergantung pada persyaratan aplikasi, Anda dapat menentukan matriks proyeksi yang terpisah dan anggota matriks tampilan kamera di shader verteks sehingga Anda dapat mengubahnya secara independen.

  2. Mengakses matriks shader - Setelah membuat hook di shader verteks untuk menerapkan proyeksi dan tampilan kamera, Anda kemudian dapat mengakses variabel tersebut untuk menerapkan matriks proyeksi dan matriks tampilan kamera. Kode berikut menunjukkan cara memodifikasi metode onSurfaceCreated() dalam implementasi GLSurfaceView.Renderer untuk mengakses variabel matriks yang ditentukan dalam shader verteks di atas.

    Kotlin

    override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {
        ...
        muMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix")
        ...
    }
    

    Java

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        ...
        muMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix");
        ...
    }
    
  3. Membuat matriks proyeksi dan tampilan kamera - Buat matriks proyeksi dan tampilan untuk diterapkan ke objek grafis. Kode contoh berikut menunjukkan cara memodifikasi metode onSurfaceCreated() dan onSurfaceChanged() dari implementasi GLSurfaceView.Renderer untuk membuat matriks tampilan kamera dan matriks proyeksi berdasarkan rasio aspek layar perangkat.

    Kotlin

    override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {
        ...
        // Create a camera view matrix
        Matrix.setLookAtM(vMatrix, 0, 0f, 0f, -3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
    }
    
    override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)
    
        val ratio: Float = width.toFloat() / height.toFloat()
    
        // create a projection matrix from device screen geometry
        Matrix.frustumM(projMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
    }
    

    Java

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        ...
        // Create a camera view matrix
        Matrix.setLookAtM(vMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    }
    
    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    
        float ratio = (float) width / height;
    
        // create a projection matrix from device screen geometry
        Matrix.frustumM(projMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
    }
    
  4. Menerapkan matriks proyeksi dan tampilan kamera - Untuk menerapkan transformasi proyeksi dan tampilan kamera, kalikan kedua matriks tersebut, lalu setel ke dalam shader verteks. Kode contoh berikut menunjukkan cara memodifikasi metode onDrawFrame() dalam implementasi GLSurfaceView.Renderer untuk menggabungkan matriks proyeksi dan tampilan kamera yang dibuat dalam kode di atas, lalu menerapkannya ke objek grafis yang akan dirender oleh OpenGL.

    Kotlin

    override fun onDrawFrame(gl: GL10) {
        ...
        // Combine the projection and camera view matrices
        Matrix.multiplyMM(vPMatrix, 0, projMatrix, 0, vMatrix, 0)
    
        // Apply the combined projection and camera view transformations
        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, vPMatrix, 0)
    
        // Draw objects
        ...
    }
    

    Java

    public void onDrawFrame(GL10 unused) {
        ...
        // Combine the projection and camera view matrices
        Matrix.multiplyMM(vPMatrix, 0, projMatrix, 0, vMatrix, 0);
    
        // Apply the combined projection and camera view transformations
        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, vPMatrix, 0);
    
        // Draw objects
        ...
    }
    

Untuk contoh lengkap cara menerapkan proyeksi dan tampilan kamera dengan OpenGL ES 2.0, lihat kelas Menampilkan grafis dengan OpenGL ES.

Membentuk wajah dan lekukan

Dalam OpenGL, wajah dari suatu bentuk adalah permukaan yang ditentukan oleh tiga atau lebih titik dalam ruang tiga dimensi. Rangkaian titik tiga dimensi atau lebih (disebut verteks di OpenGL) memiliki wajah depan dan wajah belakang. Bagaimana cara menentukan wajah depan dan belakang? Pertanyaan yang bagus. Jawabannya berkaitan dengan pelilitan, atau arah tempat Anda menentukan titik-titik suatu bentuk.

Koordinat pada titik sudut
segitiga

Gambar 1. Ilustrasi daftar koordinat yang diterjemahkan menjadi urutan menggambar berlawanan arah jarum jam.

Dalam contoh ini, titik-titik segitiga ditentukan dalam urutan sedemikian rupa sehingga digambar dalam arah berlawanan arah jarum jam. Urutan penggambaran koordinat ini menentukan arah lilitan untuk bentuk. Secara default, di OpenGL, wajah yang digambar berlawanan arah jarum jam adalah wajah depan. Segitiga yang ditampilkan dalam Gambar 1 didefinisikan sehingga Anda melihat wajah depan bentuk tersebut (sebagaimana ditafsirkan oleh OpenGL) dan sisi lainnya adalah wajah belakang.

Apa perlunya mengetahui wajah mana yang merupakan wajah depan? Jawabannya ada hubungannya dengan fitur OpenGL yang umum digunakan, yang disebut face culling. Face culling adalah opsi untuk lingkungan OpenGL yang memungkinkan pipeline rendering mengabaikan (tidak menghitung atau menggambar) tampilan belakang bentuk, menghemat waktu, memori, dan siklus pemrosesan:

Kotlin

gl.apply {
    // enable face culling feature
    glEnable(GL10.GL_CULL_FACE)
    // specify which faces to not draw
    glCullFace(GL10.GL_BACK)
}

Java

// enable face culling feature
gl.glEnable(GL10.GL_CULL_FACE);
// specify which faces to not draw
gl.glCullFace(GL10.GL_BACK);

Jika Anda mencoba menggunakan fitur penghapusan wajah tanpa mengetahui sisi bentuk mana yang merupakan depan dan belakang, grafis OpenGL Anda akan terlihat sedikit lebih tipis, atau mungkin tidak muncul sama sekali. Jadi, selalu tentukan koordinat bentuk OpenGL dengan urutan menggambar berlawanan arah jarum jam.

Catatan: Anda dapat menyetel lingkungan OpenGL untuk memperlakukan wajah searah jarum jam sebagai tampilan depan, tetapi tindakan ini memerlukan lebih banyak kode dan cenderung membingungkan developer OpenGL berpengalaman saat Anda meminta bantuan mereka. Jadi, jangan lakukan itu.

Versi OpenGL dan kompatibilitas perangkat

Spesifikasi OpenGL ES 1.0 dan 1.1 API telah didukung sejak Android 1.0. Pemrograman grafis dengan OpenGL ES 1.0/1.1 API sangat berbeda dibandingkan menggunakan versi 2.0 dan yang lebih tinggi. OpenGL ES 2.0 didukung oleh semua perangkat Android mulai Android 2.2 (API level 8) dan merupakan versi paling awal yang direkomendasikan untuk aplikasi baru yang sedang dikembangkan dengan OpenGL ES. OpenGL ES 3.0 didukung dengan Android 4.3 (API level 18) dan yang lebih tinggi, di perangkat yang menyediakan implementasi OpenGL ES 3.0 API. Untuk informasi tentang jumlah relatif perangkat Android yang mendukung versi OpenGL ES tertentu, lihat Dasbor versi OpenGL ES.

Anda harus mempertimbangkan persyaratan grafis dengan cermat dan memilih versi API yang paling sesuai untuk aplikasi Anda. Untuk informasi selengkapnya, lihat Memilih versi OpenGL API.

OpenGL ES 3.0 API menyediakan fitur tambahan dan performa yang lebih baik daripada API 2.0 dan juga kompatibel dengan versi sebelumnya. Artinya, Anda berpotensi dapat menulis aplikasi yang menargetkan OpenGL ES 2.0 dan secara kondisional menyertakan fitur grafis OpenGL ES 3.0 jika tersedia. Untuk informasi selengkapnya tentang memeriksa ketersediaan API 3.0, lihat Memeriksa versi OpenGL ES

Dukungan kompresi tekstur

Kompresi tekstur dapat meningkatkan performa aplikasi OpenGL secara signifikan dengan mengurangi persyaratan memori dan memanfaatkan bandwidth memori secara lebih efisien. Framework Android memberikan dukungan untuk format kompresi ETC1 sebagai fitur standar, termasuk class utilitas ETC1Util dan alat kompresi etc1tool (terdapat di Android SDK di <sdk>/tools/). Untuk contoh aplikasi Android yang menggunakan kompresi tekstur, lihat contoh kode CompressedTextureActivity di Android SDK (<sdk>/samples/<version>/ApiDemos/src/com/example/android/apis/graphics/).

Format ETC1 didukung oleh semua perangkat Android yang mendukung OpenGL ES 2.0 atau yang lebih baru.

Catatan: Format kompresi tekstur ETC1 tidak mendukung tekstur dengan transparansi (saluran alfa). Jika aplikasi Anda memerlukan tekstur dengan transparansi, Anda harus menyelidiki format kompresi tekstur lain yang tersedia di perangkat target. Metode untuk merender tekstur saluran alfa menggunakan ETC1 adalah mengikat dua objek tekstur ETC1: yang pertama dengan data warna, yang kedua dengan data saluran alfa, lalu menggabungkan nilai dari kedua tekstur dalam shader fragmen.

Format kompresi tekstur ETC2/EAC dijamin akan tersedia saat menggunakan OpenGL ES 3.0 API. Format tekstur ini menawarkan rasio kompresi yang sangat baik dengan kualitas visual yang tinggi dan formatnya juga mendukung transparansi (saluran alfa).

Selain format ETC, perangkat Android memiliki dukungan yang bervariasi untuk kompresi tekstur berdasarkan chipset GPU dan implementasi OpenGL-nya. Anda harus menyelidiki dukungan kompresi tekstur pada perangkat yang ditargetkan untuk menentukan jenis kompresi apa yang harus didukung aplikasi Anda. Untuk menentukan format tekstur yang didukung di perangkat tertentu, Anda harus membuat kueri perangkat dan meninjau nama ekstensi OpenGL, yang mengidentifikasi format kompresi tekstur (dan fitur OpenGL lainnya) yang didukung oleh perangkat. Format kompresi tekstur yang umum didukung adalah sebagai berikut:

  • Adaptable Scalable Texture Compression (ASTC) - Format kompresi tekstur yang dirancang untuk menggantikan format sebelumnya. Lebih fleksibel dari format sebelumnya karena adanya dukungan untuk berbagai ukuran blok.
    • GL_KHR_texture_compression_astc_ldr
    • GL_KHR_texture_compression_astc_hdr(rentang dinamis tinggi)
  • S3TC (DXTn/DXTC) - Kompresi tekstur S3 (S3TC) memiliki beberapa variasi format (DXT1 hingga DXT5) dan ketersediaannya tidak begitu luas. Format ini mendukung tekstur RGB dengan saluran alfa 4 bit atau 8 bit. Format ini diwakili oleh nama ekstensi OpenGL berikut:
    • GL_EXT_texture_compression_s3tc
    Beberapa perangkat hanya mendukung variasi format DXT1; dukungan terbatas ini diwakili oleh nama ekstensi OpenGL berikut:
    • GL_EXT_texture_compression_dxt1

Format kompresi tekstur berikut dianggap sebagai format lama dan tidak direkomendasikan untuk digunakan dalam aplikasi baru:

  • ATITC (ATC) - Kompresi tekstur ATI (ATITC atau ATC) tersedia di berbagai perangkat dan mendukung kompresi kecepatan tetap untuk tekstur RGB dengan dan tanpa saluran alfa. Format ini dapat diwakili oleh beberapa nama ekstensi OpenGL, misalnya:
    • GL_AMD_compressed_ATC_texture
    • GL_ATI_texture_compression_atitc
  • PVRTC - Kompresi tekstur PowerVR (PVRTC) tersedia di berbagai perangkat dan mendukung tekstur 2-bit dan 4-bit per piksel dengan atau tanpa saluran alfa. Format ini direpresentasikan oleh nama ekstensi OpenGL berikut:
    • GL_IMG_texture_compression_pvrtc
  • 3DC - Kompresi tekstur 3DC (3DC) adalah format yang ketersediaannya kurang luas dan mendukung tekstur RGB dengan saluran alfa. Format ini direpresentasikan oleh nama ekstensi OpenGL berikut:
    • GL_AMD_compressed_3DC_texture

Peringatan: Format kompresi tekstur ini tidak didukung di semua perangkat. Dukungan untuk format ini dapat bervariasi menurut produsen dan perangkat. Untuk mengetahui informasi cara menentukan format kompresi tekstur apa saja di perangkat tertentu, lihat bagian berikutnya.

Catatan: Setelah menentukan format kompresi tekstur yang akan didukung aplikasi, pastikan Anda mendeklarasikannya dalam manifes menggunakan <supports-gl-texture> . Menggunakan deklarasi ini memungkinkan pemfilteran oleh layanan eksternal seperti Google Play, sehingga aplikasi Anda hanya diinstal di perangkat yang mendukung format yang diperlukan aplikasi Anda. Untuk mengetahui detailnya, lihat Deklarasi manifes OpenGL.

Menentukan ekstensi OpenGL

Implementasi OpenGL bervariasi menurut perangkat Android dalam hal ekstensi ke OpenGL ES API yang didukung. Ekstensi ini mencakup kompresi tekstur, tetapi biasanya juga menyertakan ekstensi lain ke set fitur OpenGL.

Untuk menentukan format kompresi tekstur, dan ekstensi OpenGL lainnya, yang didukung di perangkat tertentu:

  1. Jalankan kode berikut di perangkat target untuk menentukan format kompresi tekstur yang didukung:

    Kotlin

    var extensions = gl.glGetString(GL10.GL_EXTENSIONS)
    

    Java

    String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
    

    Peringatan: Hasil dari panggilan ini bervariasi menurut model perangkat. Anda harus menjalankan panggilan ini di beberapa perangkat target untuk menentukan jenis kompresi yang biasanya didukung.

  2. Tinjau output metode ini untuk menentukan ekstensi OpenGL apa yang didukung di perangkat.

Paket Ekstensi Android (AEP)

AEP memastikan bahwa aplikasi Anda mendukung serangkaian ekstensi OpenGL standar di atas dan di luar set inti yang dijelaskan dalam spesifikasi OpenGL 3.1. Mengemas ekstensi ini bersama-sama mendorong serangkaian fungsi yang konsisten di seluruh perangkat, sekaligus memungkinkan developer mendapatkan manfaat penuh dari versi terbaru perangkat GPU seluler.

AEP juga meningkatkan dukungan untuk gambar, buffer penyimpanan shader, dan penghitung atomik di shader fragmen.

Agar aplikasi Anda dapat menggunakan AEP, manifes aplikasi harus mendeklarasikan bahwa AEP diperlukan. Selain itu, versi platform harus mendukungnya.

Semua fitur tambahan yang ditentukan dalam AEP disertakan dalam spesifikasi OpenGL ES 3.2 dasar. Jika aplikasi Anda memerlukan OpenGL ES 3.2, Anda tidak perlu mewajibkan AEP.

Deklarasikan persyaratan AEP dalam manifes sebagai berikut:

<uses-feature android:name="android.hardware.opengles.aep"
              android:required="true" />

Untuk memverifikasi bahwa versi platform mendukung AEP, gunakan metode hasSystemFeature(String), dengan meneruskan FEATURE_OPENGLES_EXTENSION_PACK sebagai argumen. Cuplikan kode berikut menunjukkan contoh cara melakukannya:

Kotlin

var deviceSupportsAEP: Boolean =
        packageManager.hasSystemFeature(PackageManager.FEATURE_OPENGLES_EXTENSION_PACK)

Java

boolean deviceSupportsAEP = getPackageManager().hasSystemFeature
     (PackageManager.FEATURE_OPENGLES_EXTENSION_PACK);

Jika metode ini menampilkan nilai true, berarti AEP didukung.

Untuk informasi selengkapnya tentang AEP, kunjungi halamannya di Registry OpenGL ES Khronos.

Memeriksa versi OpenGL ES

Ada beberapa versi OpenGL ES yang tersedia di perangkat Android. Anda dapat menentukan versi minimum API yang diperlukan aplikasi dalam manifes, tetapi secara bersamaan, Anda juga dapat memanfaatkan fitur-fitur di API yang lebih baru. Misalnya, OpenGL ES 3.0 API memiliki kompatibilitas mundur dengan versi 2.0 API, jadi Anda mungkin ingin menulis aplikasi agar menggunakan fitur OpenGL ES 3.0, tetapi kembali ke 2.0 API jika 3.0 API tidak tersedia.

Sebelum menggunakan fitur OpenGL ES dari versi yang lebih tinggi dari versi minimum yang diperlukan dalam manifes aplikasi, aplikasi Anda harus memeriksa versi API yang tersedia di perangkat. Anda dapat melakukannya dengan salah satu dari dua cara berikut:

  1. Coba buat konteks OpenGL ES tingkat lebih tinggi (EGLContext) dan periksa hasilnya.
  2. Buat konteks OpenGL ES minimum yang didukung dan periksa nilai versinya.

Kode contoh berikut menunjukkan cara memeriksa versi OpenGL ES yang tersedia dengan membuat EGLContext dan memeriksa hasilnya. Contoh ini menunjukkan cara memeriksa versi OpenGL ES 3.0:

Kotlin

private const val EGL_CONTEXT_CLIENT_VERSION = 0x3098
private const val glVersion = 3.0
private class ContextFactory : GLSurfaceView.EGLContextFactory {

    override fun createContext(egl: EGL10, display: EGLDisplay, eglConfig: EGLConfig): EGLContext {

        Log.w(TAG, "creating OpenGL ES $glVersion context")
        return egl.eglCreateContext(
                display,
                eglConfig,
                EGL10.EGL_NO_CONTEXT,
                intArrayOf(EGL_CONTEXT_CLIENT_VERSION, glVersion.toInt(), EGL10.EGL_NONE)
        ) // returns null if 3.0 is not supported
    }
}

Java

private static double glVersion = 3.0;

private static class ContextFactory implements GLSurfaceView.EGLContextFactory {

  private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;

  public EGLContext createContext(
          EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {

      Log.w(TAG, "creating OpenGL ES " + glVersion + " context");
      int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, (int) glVersion,
              EGL10.EGL_NONE };
      // attempt to create a OpenGL ES 3.0 context
      EGLContext context = egl.eglCreateContext(
              display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
      return context; // returns null if 3.0 is not supported;
  }
}

Jika metode createContext() yang ditampilkan di atas menampilkan null, kode Anda harus membuat konteks OpenGL ES 2.0 dan kembali menggunakan API tersebut saja.

Contoh kode berikut menunjukkan cara memeriksa versi OpenGL ES dengan membuat konteks minimum yang didukung terlebih dahulu, lalu memeriksa string versi:

Kotlin

// Create a minimum supported OpenGL ES context, then check:
gl.glGetString(GL10.GL_VERSION).also {
    Log.w(TAG, "Version: $it")
}
 // The version format is displayed as: "OpenGL ES <major>.<minor>"
 // followed by optional content provided by the implementation.

Java

// Create a minimum supported OpenGL ES context, then check:
String version = gl.glGetString(GL10.GL_VERSION);
Log.w(TAG, "Version: " + version );
// The version format is displayed as: "OpenGL ES <major>.<minor>"
// followed by optional content provided by the implementation.

Dengan pendekatan ini, jika Anda menemukan bahwa perangkat mendukung versi API level lebih tinggi, Anda harus menghancurkan konteks OpenGL ES minimum dan membuat konteks baru dengan versi API yang lebih tinggi yang tersedia.

Memilih versi OpenGL API

OpenGL ES versi 2.0, dan versi 3.0 menyediakan antarmuka grafis berperforma tinggi untuk membuat game, visualisasi, dan antarmuka pengguna 3D. Pemrograman grafis untuk OpenGL ES 2.0 dan 3.0 sebagian besar mirip, dengan versi 3.0 mewakili superset dari 2.0 API dengan fitur tambahan. Pemrograman untuk OpenGL ES 1.0/1.1 API versus OpenGL ES 2.0 dan 3.0 sangat berbeda, dan tidak direkomendasikan untuk aplikasi baru. Developer harus mempertimbangkan faktor-faktor berikut dengan cermat sebelum memulai pengembangan dengan API ini:

  • Kompatibilitas Perangkat - Developer harus mempertimbangkan jenis perangkat, versi Android, dan versi OpenGL ES yang tersedia bagi pelanggan mereka. Untuk informasi selengkapnya tentang kompatibilitas OpenGL di seluruh perangkat, lihat bagian Versi OpenGL dan kompatibilitas perangkat.
  • Dukungan Tekstur - OpenGL ES 3.0 API memiliki dukungan terbaik untuk kompresi tekstur karena menjamin ketersediaan format kompresi ETC2, yang mendukung transparansi. Implementasi API 2.0 menyertakan dukungan untuk ETC1, tetapi format tekstur ini tidak mendukung transparansi. Untuk menerapkan transparansi dengan tekstur terkompresi, Anda harus menggunakan dua tekstur ETC1 (dipisah antara warna dan alfa) atau menyediakan resource dalam format kompresi lain yang didukung oleh perangkat yang Anda targetkan. Untuk mengetahui informasi selengkapnya, lihat Dukungan kompresi tekstur.

Meskipun kompatibilitas, dan dukungan tekstur dapat memengaruhi keputusan, Anda harus memilih versi OpenGL API berdasarkan apa yang menurut Anda memberikan pengalaman terbaik bagi pengguna.