OpenGL ES

Android menyertakan dukungan untuk grafis 2D dan 3D berperforma tinggi dengan Open Graphics Library (OpenGL®), khususnya, OpenGL ES API. OpenGL adalah API grafis lintas platform yang menentukan antarmuka perangkat lunak standar untuk perangkat keras pemrosesan grafis 3D. OpenGL ES adalah ragam dari OpenGL spesifikasi yang ditujukan untuk perangkat tertanam. 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: Apa pun 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 yang lebih rendah diperlukan tetapi Anda ingin menggunakan fitur 3.0 jika tersedia, Anda harus memeriksa pada saat runtime untuk melihat versi OpenGL apa yang didukung perangkat. Untuk informasi tentang cara lakukan ini, 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, tapi tidak sama. Jika Anda mengenal spesifikasi J2ME JSR239, waspadai variasi.

Lihat juga

Dasar-dasar

Android mendukung OpenGL baik melalui API framework-nya maupun 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 Anda, memahami cara menerapkan kelas-kelas ini dalam suatu aktivitas harus menjadi tujuan pertama Anda.

GLSurfaceView
Class ini adalah View tempat Anda dapat menggambar dan memanipulasi objek menggunakan OpenGL API memanggil dan fungsinya mirip dengan SurfaceView. Anda dapat menggunakan class ini dengan membuat instance GLSurfaceView dan menambahkan Renderer ke kunci tersebut. Namun, jika ingin merekam peristiwa layar sentuh, Anda harus memperluas class GLSurfaceView ke mengimplementasikan pemroses sentuh, seperti yang terlihat dalam pelajaran 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 yang terpisah dan melampirkannya ke instance GLSurfaceView menggunakan GLSurfaceView.setRenderer().

Antarmuka GLSurfaceView.Renderer mengharuskan Anda mengimplementasikan metode berikut:

  • onSurfaceCreated(): Sistem memanggilnya sekali, 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 grafis.
  • onSurfaceChanged(): Sistem memanggil metode ini saat geometri GLSurfaceView berubah, termasuk perubahan ukuran GLSurfaceView atau orientasi layar perangkat. Misalnya, sistem memanggil metode ini ketika 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 memulai 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 dari Android 2.2 (API level 8).
  • Paket OpenGL ES 3.0/3.1/3.2 API
    • android.opengl - Paket ini menyediakan antarmuka ke OpenGL ES 3.0/3.1 Google Cloud Platform. Versi 3.0 tersedia mulai dari Android 4.3 (API level 18). Versi 3.1 telah tersedia dimulai dengan Android 5.0 (level API 21). Versi 3.2 tersedia mulai dari Android 7.0 (API tingkat 24).

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

Mendeklarasikan persyaratan OpenGL

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

  • Persyaratan versi OpenGL ES - Jika aplikasi Anda memerlukan versi OpenGL ES, Anda harus mendeklarasikan persyaratan tersebut dengan menambahkan setelan berikut ke manifes sebagai seperti yang ditampilkan 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 pada perangkat yang tidak mendukung OpenGL ES 2.0. Jika aplikasi Anda ditujukan khusus untuk perangkat yang mendukung OpenGL ES 3.0, Anda juga dapat menentukan ini 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 kompatibel dengan versi sebelumnya 2.0 API, yang berarti Anda bisa lebih fleksibel dengan implementasi OpenGL ES di aplikasi Anda. Dengan mendeklarasikan OpenGL, ES 2.0 API sebagai persyaratan dalam manifes, Anda bisa menggunakan versi API itu sebagai untuk ketersediaan 3.x API pada waktu proses dan kemudian gunakan fitur OpenGL ES 3.x jika perangkat Anda 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 tekstur format kompresi file, Anda harus mendeklarasikan format yang didukung aplikasi dalam file manifes menggunakan <supports-gl-texture>. Untuk informasi selengkapnya tentang 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 Anda deklarasikan. Untuk selengkapnya informasi 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 pada perangkat Android adalah layar perangkat dapat bervariasi dalam ukuran dan bentuk. OpenGL mengasumsikan sistem koordinat persegi yang seragam dan, secara default, dengan senang hati menggambar koordinat tersebut ke layar yang biasanya tidak berbentuk persegi seolah-olah persegi tersebut merupakan persegi sempurna.

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

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

Untuk menerapkan proyeksi dan tampilan kamera, Anda membuat matriks proyeksi dan tampilan kamera dan menerapkannya ke pipeline rendering OpenGL. Matriks proyeksi menghitung ulang koordinat grafik Anda agar peta dipetakan ke layar perangkat Android dengan benar. 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, Anda menerapkan proyeksi dan tampilan kamera dengan menambahkan anggota matriks terlebih dahulu ke shader verteks objek grafis Anda. Dengan menambahkan anggota matriks ini, Anda kemudian 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 menyertakannya sebagai pengganda posisi shader. Pada contoh shader verteks berikut kode, anggota uMVPMatrix yang disertakan memungkinkan Anda menerapkan proyeksi dan tampilan kamera matriks 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 menentukan satu matriks transformasi anggota dalam shader verteks, tempat Anda menerapkan gabungan matriks proyeksi dan tampilan kamera yang dihasilkan. Bergantung pada persyaratan aplikasi Anda, Anda mungkin ingin menentukan proyeksi terpisah anggota matriks tampilan kamera dan matriks di shader verteks sehingga Anda dapat mengubahnya mereka dapat bekerja secara mandiri.

  2. Akses matriks shader - Setelah membuat hook di shader verteks untuk menerapkan proyeksi dan tampilan kamera, Anda kemudian dapat mengakses variabel untuk menerapkan proyeksi dan matriks penampil kamera. Kode berikut menunjukkan cara memodifikasi metode onSurfaceCreated() dalam implementasi GLSurfaceView.Renderer untuk mengakses 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 proyeksi dan melihat matriks untuk diterapkan pada objek grafis. Kode contoh berikut menunjukkan cara memodifikasi onSurfaceCreated() dan Metode 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 proyeksi dan transformasi tampilan kamera, kalikan matriks-matriks, lalu tetapkan ke dalam verteks shader. Kode contoh berikut menunjukkan cara memodifikasi metode onDrawFrame() dalam implementasi GLSurfaceView.Renderer untuk digabungkan matriks proyeksi dan tampilan kamera yang dibuat dalam kode di atas dan kemudian menerapkannya ke dalam grafik objek 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 Menampilkan grafis dengan OpenGL ES .

Membentuk wajah dan lekukan

Di OpenGL, wajah dari suatu bentuk adalah permukaan yang didefinisikan oleh tiga titik atau lebih dalam spasi. Sekumpulan tiga atau lebih titik tiga dimensi (disebut verteks di OpenGL) memiliki wajah depan dan tampilan belakang. Bagaimana cara menentukan wajah depan dan belakang? Pertanyaan yang bagus. Tujuan jawaban berkaitan dengan lilitan, atau, arah di mana Anda menentukan titik-titik suatu bentuk.

Koordinat di
titik sudut segitiga

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

Dalam contoh ini, titik-titik segitiga didefinisikan dalam urutan sedemikian rupa sehingga titik-titik tersebut digambar secara berlawanan arah jarum jam. Urutan penggambaran koordinat ini menentukan lilitan arah untuk bentuk. Secara default, di OpenGL, wajah yang digambar berlawanan arah jarum jam adalah wajah depan. Segitiga yang ditunjukkan pada Gambar 1 didefinisikan sehingga Anda melihat wajah depan bentuk (seperti yang 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 {i>face culling<i}. Face culling adalah opsi untuk OpenGL lingkungan yang memungkinkan pipeline rendering untuk 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 {i>face culling<i} tanpa mengetahui sisi mana dari bentuk Anda depan dan belakang, grafis OpenGL Anda akan terlihat sedikit 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 searah jarum jam sebagai wajah depan, tetapi melakukannya memerlukan lebih banyak kode dan cenderung pengembang OpenGL yang berpengalaman ketika 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 berbeda secara signifikan dibandingkan dengan menggunakan 2.0 dan versi yang lebih tinggi. OpenGL ES 2.0 didukung oleh semua perangkat Android mulai dari Android 2.2 (API level 8) dan versi paling awal yang direkomendasikan untuk aplikasi baru yang dikembangkan dengan OpenGL ES. OpenGL ES 3.0 didukung dengan Android 4.3 (API level 18) dan yang lebih tinggi, di perangkat yang menyediakan dan implementasi OpenGL ES 3.0 API. Untuk informasi tentang jumlah relatif perangkat yang didukung Android yang mendukung versi OpenGL ES tertentu, lihat Dasbor versi OpenGL ES.

Anda harus mempertimbangkan persyaratan grafis dengan cermat dan memilih 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 2.0 API serta dan kompatibel dengan teknologi lama. Ini berarti Anda berpotensi menulis penargetan aplikasi OpenGL ES 2.0 dan secara kondisional menyertakan fitur grafis OpenGL ES 3.0 jika tersedia. Sebagai informasi lebih lanjut mengenai cara memeriksa ketersediaan API 3.0, lihat Memeriksa versi OpenGL ES

Dukungan kompresi tekstur

Kompresi tekstur bisa meningkatkan performa aplikasi OpenGL secara signifikan dengan mengurangi kebutuhan memori dan membuat penggunaan {i>bandwidth<i} memori yang lebih efisien. 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/). Misalnya 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 tinggi.

Catatan: Format kompresi tekstur ETC1 tidak mendukung tekstur dengan elemen transparansi (saluran alfa). Jika aplikasi Anda memerlukan tekstur dengan transparansi, Anda harus selidiki format kompresi tekstur lain yang tersedia di perangkat target Anda. J untuk merender tekstur saluran alfa menggunakan ETC1 adalah dengan mengikat dua objek tekstur ETC1: pertama dengan data warna, yang kedua dengan data saluran alfa dan kemudian menggabungkan nilai dari keduanya 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 juga mendukung transparansi (saluran alfa).

Selain format ETC, perangkat Android memiliki dukungan yang bervariasi untuk kompresi tekstur berdasarkan {i>chipset<i} GPU dan implementasi OpenGL. Anda harus menyelidiki dukungan kompresi tekstur di perangkat yang Anda targetkan untuk menentukan jenis kompresi apa yang harus digunakan dukungan teknis IT. Untuk menentukan format tekstur apa yang didukung pada perangkat tertentu, Anda harus melakukan kueri perangkat dan meninjau nama ekstensi OpenGL, yang mengidentifikasi format kompresi tekstur (dan fitur OpenGL lainnya) yang didukung oleh perangkat seluler. Format kompresi tekstur yang umum didukung adalah sebagai berikut:

  • Adaptable Scalable Texture Compression (ASTC) - Format kompresi tekstur dirancang untuk menggantikan format sebelumnya. Lebih fleksibel daripada format sebelumnya karena 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 ekstensi OpenGL berikut nama:
    • 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 di aplikasi baru:

  • ATITC (ATC) - Kompresi tekstur ATI (ATITC atau ATC) tersedia di berbagai jenis perangkat dan mendukung kompresi kecepatan tetap untuk tekstur RGB dengan dan tanpa saluran alfa. Format ini mungkin diwakili oleh beberapa nama ekstensi OpenGL, misalnya:
    • GL_AMD_compressed_ATC_texture
    • GL_ATI_texture_compression_atitc
  • PVRTC - Kompresi tekstur PowerVR (PVRTC) tersedia dalam ruang berbagai perangkat dan mendukung tekstur 2-bit dan 4-bit per piksel dengan atau tanpa saluran alfa. Format ini diwakili oleh nama ekstensi OpenGL berikut:
    • GL_IMG_texture_compression_pvrtc
  • 3DC - Kompresi tekstur 3DC (3DC) adalah format yang ketersediaannya kurang luas yang mendukung tekstur RGB dengan saluran alfa. Format ini diwakili oleh OpenGL berikut nama ekstensi:
    • 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. Sebagai informasi tentang cara menentukan format kompresi tekstur yang ada di perangkat tertentu, lihat bagian berikutnya.

Catatan: Setelah Anda memutuskan kompresi tekstur mana yang memformat didukung oleh 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 mencakup elemen ekstensi 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 jenis kompresi tekstur format 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 umum didukung.

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

Paket Ekstensi Android (AEP)

AEP memastikan aplikasi Anda mendukung serangkaian ekstensi OpenGL standar di atas dan seterusnya set inti yang dijelaskan dalam spesifikasi OpenGL 3.1. Mengemas ekstensi ini bersama-sama mendorong serangkaian fungsi yang konsisten di seluruh perangkat, sekaligus memungkinkan pengembang untuk memanfaatkan pemangkasan perangkat GPU seluler terbaru.

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 ditetapkan dalam AEP disertakan dalam OpenGL ES 3.2 dasar spesifikasi pendukung. 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 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 lamannya 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 Anda dalam manifes, tetapi sebaiknya Anda juga memanfaatkan fitur di API yang lebih baru di saat yang sama. Misalnya, OpenGL ES 3.0 API kompatibel dengan versi sebelumnya 2.0, jadi Anda mungkin ingin menulis aplikasi Anda sehingga menggunakan fitur OpenGL ES 3.0, namun 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 pada perangkat. Anda dapat melakukannya dengan salah satu dari dua cara berikut:

  1. Upayakan untuk membuat konteks OpenGL ES tingkat lebih tinggi (EGLContext) dan memeriksa 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 harus membuat OpenGL ES 2.0 sebagai gantinya dan kembali menggunakan API tersebut saja.

Contoh kode berikut menunjukkan cara memeriksa versi OpenGL ES dengan membuat konteks yang didukung terlebih dahulu, lalu periksa 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 itu mendukung versi API level yang lebih tinggi, Anda harus menghancurkan konteks OpenGL ES minimum dan membuat konteks baru dengan versi API yang tersedia.

Memilih versi OpenGL API

OpenGL ES versi 2.0, dan versi 3.0 keduanya memberikan grafis untuk membuat {i>game<i}, visualisasi, dan antarmuka pengguna 3D. {i>Graphics<i} Pemrograman untuk OpenGL ES 2.0 dan 3.0 sebagian besar mirip, dengan versi 3.0 mewakili superset 2.0 API dengan fitur tambahan. Pemrograman untuk OpenGL ES 1.0/1.1 API versus OpenGL ES 2.0 dan 3.0 berbeda secara signifikan, dan tidak direkomendasikan untuk aplikasi baru. Pengembang harus mempertimbangkan dengan cermat faktor-faktor berikut sebelum memulai pengembangan dengan API berikut:

  • Kompatibilitas Perangkat - Developer harus mempertimbangkan jenis perangkat, Versi Android dan versi OpenGL ES yang tersedia untuk pelanggan mereka. Untuk informasi lebih lanjut tentang kompatibilitas OpenGL di seluruh perangkat, lihat versi OpenGL dan kompatibilitas perangkat.
  • Dukungan Tekstur - OpenGL ES 3.0 API memiliki dukungan terbaik untuk tekstur kompresi standar 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 Anda harus menggunakan dua tekstur ETC1 (dibagi antara warna dan alfa) atau menyediakan dalam format kompresi lain yang didukung oleh perangkat yang Anda targetkan. Untuk informasi selengkapnya, lihat Dukungan kompresi tekstur.

Sementara kompatibilitas, dan dukungan tekstur dapat memengaruhi keputusannya, Anda harus memilih versi OpenGL API berdasarkan apa yang menurut Anda memberikan pengalaman terbaik ketersediaan tinggi dan latensi yang lebih rendah bagi pengguna Anda.