OpenGL ES

Android, Open Graphics Library (OpenGL®) ile yüksek performanslı 2D ve 3D grafikleri, özellikle de OpenGL ES API'sını destekler. OpenGL, 3D grafik işleme donanımı için standart bir yazılım arayüzü belirten platformlar arası bir grafik API'sidir. OpenGL ES, yerleşik cihazlar için tasarlanan OpenGL spesifikasyonunun bir çeşididir. Android, OpenGL ES API'sinin çeşitli sürümlerini destekler:

  • OpenGL ES 2.0 - Bu API spesifikasyonu, Android 2.2 (API düzeyi 8) ve üstü tarafından desteklenir.
  • OpenGL ES 3.0 - Bu API spesifikasyonu, Android 4.3 (API düzeyi 18) ve üstü tarafından desteklenir.
  • OpenGL ES 3.1 - Bu API spesifikasyonu, Android 5.0 (API düzeyi 21) ve üstü tarafından desteklenir.
  • OpenGL ES 3.2 - Bu API spesifikasyonu, Android 7.0 (API düzeyi 24) ve üstü tarafından desteklenir.

Dikkat: Android platform sürümü ne olursa olsun, üreticisi bu grafik ardışık düzeninin bir uygulamasını sağlamadığı sürece cihaz OpenGL ES 3.0 API'yi destekleyemez. Manifest'te OpenGL ES 3.0'ın gerektiğini belirtirseniz bu sürümün cihazda mevcut olacağından emin olabilirsiniz. Daha düşük düzey bir sürümün gerekli olduğunu belirtirseniz ancak varsa 3.0 özelliklerini kullanmak isterseniz, cihazın hangi OpenGL sürümünü desteklediğini görmek için çalışma zamanında kontrol etmeniz gerekir. Bunun nasıl yapılacağı hakkında bilgi edinmek için OpenGL ES sürümünü kontrol etme bölümüne bakın.

Not: Android, OpenGL ES 1.0 ve 1.1 için destek içerir, ancak API'nin bu sürümleri kullanımdan kaldırılmıştır ve modern uygulamalar tarafından kullanılmamalıdır.

Not: Android çerçevesi tarafından sağlanan belirli API, J2ME JSR239 OpenGL ES API'sine benzer ancak aynı değildir. J2ME JSR239 spesifikasyonu hakkında bilginiz varsa varyasyonlara karşı dikkatli olun.

Ayrıca bakın:

Temel bilgiler

Android, hem çerçeve API'sı hem de Yerel Geliştirme Kiti (NDK) aracılığıyla OpenGL'i destekler. Bu konu, Android çerçeve arayüzlerine odaklanmaktadır. NDK hakkında daha fazla bilgi için Android NDK konusuna bakın.

Android çerçevesinde, OpenGL ES API ile grafikler oluşturup değiştirmenize olanak tanıyan iki temel sınıf vardır: GLSurfaceView ve GLSurfaceView.Renderer. Hedefiniz Android uygulamanızda OpenGL kullanmaksa, bu sınıfları bir etkinlikte nasıl uygulayacağınızı anlamak ilk hedefiniz olmalıdır.

GLSurfaceView
Bu sınıf, OpenGL API çağrılarını kullanarak nesneler çizebileceğiniz ve değiştirebileceğiniz bir View sınıfındadır ve işlevi SurfaceView ile benzerdir. GLSurfaceView örneği oluşturup Renderer öğenizi buna ekleyerek bu sınıfı kullanabilirsiniz. Bununla birlikte, dokunmatik ekran etkinliklerini yakalamak istiyorsanız Dokunma etkinliklerine yanıt verme başlıklı OpenGL eğitim dersinde gösterildiği gibi, dokunma işleyicileri uygulamak için GLSurfaceView sınıfını genişletmeniz gerekir.
GLSurfaceView.Renderer
Bu arayüzde, GLSurfaceView içinde grafik çizmek için gereken yöntemler tanımlanmaktadır. Bu arayüzün uygulamasını ayrı bir sınıf olarak sağlamalı ve GLSurfaceView.setRenderer() kullanarak GLSurfaceView örneğinize eklemelisiniz.

GLSurfaceView.Renderer arayüzü aşağıdaki yöntemleri uygulamanızı gerektirir:

  • onSurfaceCreated(): GLSurfaceView oluşturulurken sistem bu yöntemi bir kez çağırır. OpenGL ortam parametrelerini ayarlama veya OpenGL grafik nesnelerini başlatma gibi yalnızca bir kez olması gereken işlemleri gerçekleştirmek için bu yöntemi kullanın.
  • onDrawFrame(): Sistem, GLSurfaceView öğesinin her yeniden çiziminde bu yöntemi çağırır. Bu yöntemi grafik nesneleri çizmek (ve yeniden çizmek) için birincil yürütme noktası olarak kullanın.
  • onSurfaceChanged(): GLSurfaceView geometrisi değiştiğinde sistem bu yöntemi çağırır. Buna GLSurfaceView boyutunun veya cihaz ekranının yönünün değişmesi de dahildir. Örneğin, cihaz dikey yönden yatay yöne geçtiğinde sistem bu yöntemi çağırır. GLSurfaceView kapsayıcısındaki değişikliklere yanıt vermek için bu yöntemi kullanın.

OpenGL ES paketleri

GLSurfaceView ve GLSurfaceView.Renderer kullanarak OpenGL ES için bir kapsayıcı görünümü oluşturduktan sonra, aşağıdaki sınıfları kullanarak OpenGL API'lerini çağırmaya başlayabilirsiniz:

  • OpenGL ES 2.0 API Sınıfı
    • android.opengl.GLES20 - Bu paket, OpenGL ES 2.0 için arayüz sağlar ve Android 2.2 (API düzeyi 8) sürümünden itibaren kullanılabilir.
  • OpenGL ES 3.0/3.1/3.2 API Paketleri
    • android.opengl - Bu paket, OpenGL ES 3.0/3.1 sınıfları için arayüz sağlar. Sürüm 3.0, Android 4.3 (API düzeyi 18) sürümünden itibaren kullanıma sunulmuştur. Sürüm 3.1, Android 5.0 (API düzeyi 21) ve sonraki sürümlerde kullanılabilir. Sürüm 3.2, Android 7.0 (API düzeyi 24) sürümünden itibaren kullanılabilir.

Hemen OpenGL ES ile bir uygulama oluşturmaya başlamak istiyorsanız OpenGL ES ile grafikleri görüntüleme sınıfını izleyin.

OpenGL gereksinimlerini bildirme

Uygulamanız tüm cihazlarda bulunmayan OpenGL özellikleri kullanıyorsa bu gereksinimleri AndroidManifest.xml dosyanıza eklemeniz gerekir. En yaygın OpenGL manifest bildirimleri aşağıda verilmiştir:

  • OpenGL ES sürüm gereksinimleri - Uygulamanız için belirli bir OpenGL ES sürümü gerekiyorsa bu gereksinimi, aşağıda gösterildiği gibi manifest'inize aşağıdaki ayarları ekleyerek beyan etmeniz gerekir.

    OpenGL ES 2.0 için:

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

    Bu beyanı eklemek, Google Play'in, uygulamanızın OpenGL ES 2.0'ı desteklemeyen cihazlara yüklenmesini kısıtlamasına neden olur. Uygulamanız özel olarak OpenGL ES 3.0'ı destekleyen cihazlara yönelikse, bunu manifest dosyanızda da belirtebilirsiniz:

    OpenGL ES 3.0 için:

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

    OpenGL ES 3.1 için:

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

    OpenGL ES 3.2 için:

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

    Not: OpenGL ES 3.x API, 2.0 API ile geriye dönük uyumludur. Bu da uygulamanızda OpenGL ES'yi kullanırken daha esnek olabileceğiniz anlamına gelir. OpenGL ES 2.0 API'yi manifest dosyanızda bir gereklilik olarak belirterek bu API sürümünü varsayılan olarak kullanabilir, çalışma zamanında 3.x API'nin kullanılabilir olup olmadığını kontrol edebilir ve ardından cihaz destekliyorsa OpenGL ES 3.x özelliklerini kullanabilirsiniz. Cihazlar tarafından desteklenen OpenGL ES sürümünü kontrol etmeyle ilgili daha fazla bilgi için bkz. OpenGL ES sürümünü kontrol etme.

  • Doku sıkıştırma şartları: Uygulamanız doku sıkıştırma biçimleri kullanıyorsa uygulamanızın desteklediği biçimleri, <supports-gl-texture> kullanarak manifest dosyanızda belirtmeniz gerekir. Kullanılabilir doku sıkıştırma biçimleri hakkında daha fazla bilgi için Doku sıkıştırma desteği bölümüne bakın.

    Manifest'inizde doku sıkıştırma gereksinimleri beyan etmeniz, uygulamanızı, beyan ettiğiniz sıkıştırma türlerinden en az birini desteklemeyen cihazlara sahip kullanıcılardan gizler. Google Play filtrelemesinin doku sıkıştırmalarda nasıl çalıştığı hakkında daha fazla bilgi edinmek için <supports-gl-texture> dokümanlarının Google Play ve doku sıkıştırma filtrelemesi bölümüne bakın.

Çizilen nesnelerin koordinatlarını eşleme

Android cihazlarda grafikleri görüntülemeyle ilgili temel sorunlardan biri, ekranlarının boyut ve şekilde değişebilmesidir. OpenGL, kare, tek tip bir koordinat sistemi varsayar ve varsayılan olarak, bu koordinatları tipik olarak kare olmayan ekranınıza tam karemiş gibi çizer.

Şekil 1. Varsayılan OpenGL koordinat sistemi (sol), tipik bir Android cihaz ekranıyla (sağ) eşlenir.

Yukarıdaki çizimde, soldaki bir OpenGL çerçevesi için varsayılan tek tip koordinat sistemi ve bu koordinatların gerçekte yatay yöndeki tipik bir cihaz ekranıyla nasıl eşlendiği gösterilmektedir. Bu sorunu çözmek için, grafik nesnelerinizin tüm ekranlarda doğru oranlarda olması amacıyla koordinatları dönüştürmek amacıyla OpenGL projeksiyon modları ve kamera görünümleri uygulayabilirsiniz.

Projeksiyon ve kamera görünümlerini uygulamak için bir projeksiyon matrisi ile bir kamera görünümü matrisi oluşturup bunları OpenGL oluşturma ardışık düzenine uygularsınız. Projeksiyon matrisi, grafiklerinizin koordinatlarını yeniden hesaplar. Böylece, grafikler Android cihaz ekranlarıyla doğru şekilde eşleştirilir. Kamera görünümü matrisi, belirli bir göz konumundaki nesneleri oluşturan bir dönüşüm oluşturur.

OpenGL ES 2.0 ve sonraki sürümlerde projeksiyon ve kamera görünümü

ES 2.0 ve 3.0 API'larında, önce grafik nesnelerinizin köşe gölgelendiricilerine bir matris üyesi ekleyerek projeksiyon ve kamera görünümü uygularsınız. Bu matris üyesi eklendiğinde, projeksiyon ve kamera görüntüleme matrisleri oluşturup bunları nesnenize uygulayabilirsiniz.

  1. Matrisi tepe gölgelendiricilerine ekleme - Görünüm projeksiyon matrisi için bir değişken oluşturun ve bunu gölgelendiricinin konumunun çarpanı olarak ekleyin. Aşağıdaki örnekte köşe gölgelendirici kodunda, eklenen uMVPMatrix üyesi, bu gölgelendiriciyi kullanan nesnelerin koordinatlarına projeksiyon ve kamera görüntüleme matrislerini uygulamanıza olanak tanır.

    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";
    

    Not: Yukarıdaki örnekte, birleştirilmiş projeksiyon matrisi ve kamera görünümü matrisi uyguladığınız köşe gölgelendiricide tek bir dönüşüm matrisi üyesi tanımlanmaktadır. Uygulama gereksinimlerinize bağlı olarak, köşe gölgelendiricilerinizde ayrı projeksiyon matrisi ve kamera görüntüleme matrisi üyeleri tanımlamak ve bu üyeleri birbirinden bağımsız olarak değiştirmek isteyebilirsiniz.

  2. Gölgelendirici matrisine erişme - Projeksiyon ve kamera görünümünü uygulamak için köşe noktası gölgelendiricilerinizde bir kanca oluşturduktan sonra, projeksiyon ve kamera görüntüleme matrislerini uygulamak için bu değişkene erişebilirsiniz. Aşağıdaki kod, yukarıdaki köşe gölgelendiricide tanımlanan matris değişkenine erişmek için bir GLSurfaceView.Renderer uygulamasının onSurfaceCreated() yönteminin nasıl değiştirileceğini gösterir.

    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. Projeksiyon ve kamera görüntüleme matrisleri oluşturma - Grafik nesnelere uygulanacak projeksiyon ve görüntüleme matrislerini oluşturun. Aşağıdaki örnek kod, cihazın ekran en boy oranına göre kamera görüntüleme matrisi ve projeksiyon matrisi oluşturmak için GLSurfaceView.Renderer uygulaması için onSurfaceCreated() ve onSurfaceChanged() yöntemlerinin nasıl değiştirileceğini gösterir.

    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. Projeksiyon ve kamera görüntüleme matrislerini uygulama - Projeksiyon ve kamera görünümü dönüşümlerini uygulamak için matrisleri birbiriyle çarpın ve köşe gölgelendirmesine yerleştirin. Aşağıdaki örnek kod, yukarıdaki kodda oluşturulan projeksiyon matrisi ve kamera görünümünü birleştirmek için bir GLSurfaceView.Renderer uygulamasının onDrawFrame() yöntemini nasıl değiştireceğinizi ve ardından bunu OpenGL tarafından oluşturulacak grafik nesnelere nasıl uygulayacağınızı gösterir.

    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
        ...
    }
    

OpenGL ES 2.0 ile projeksiyon ve kamera görünümünün nasıl uygulanacağına ilişkin tam bir örnek için OpenGL ES ile grafikleri görüntüleme sınıfına bakın.

Yüz şekli ve sarma

OpenGL'de bir şeklin önü, üç boyutlu uzayda üç veya daha fazla noktayla tanımlanan bir yüzeydir. Üç veya daha fazla üç boyutlu nokta kümesinin (OpenGL'de köşeler olarak adlandırılır) bir ön yüzü ve bir arka yüzü vardır. Hangi yüzün ön, hangisinin arka olduğunu nasıl anlarsınız? Güzel soru. Yanıt, sarmalamayla veya bir şeklin noktalarını tanımladığınız yönle ilgilidir.

Üçgenin köşelerindeki
koordinatlar

Şekil 1. Saat yönünün tersine çevrilmiş bir koordinat listesi çizimi.

Bu örnekte, üçgenin noktaları saat yönünün tersine çizilecek şekilde bir sırada tanımlanmıştır. Bu koordinatların çizilme sırası, şeklin dolambaçlı yönünü tanımlar. Varsayılan olarak, OpenGL'de saat yönünün tersine çizilen yüz ön yüzdür. Şekil 1'de gösterilen üçgen, şeklin ön yüzüne (OpenGL tarafından yorumlandığı gibi), diğer taraf arka yüz olacak şekilde tanımlanmıştır.

Bir şeklin hangi yüzünün ön yüz olduğunu bilmek neden önemlidir? Bu sorunun cevabı, OpenGL'nin yüz soyutlama adı verilen yaygın olarak kullanılan bir özelliğiyle ilgili. Yüz toplama, oluşturma ardışık düzeninin bir şeklin arka yüzünü yoksaymasına (hesaplamamasına veya çizmesine) izin vererek zamandan, bellekten ve işleme döngülerinden tasarruf etmesini sağlayan, OpenGL ortamı için bir seçenektir:

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);

Şekillerinizin hangi kenarlarının ön ve arka olduğunu bilmeden yüz seçme özelliğini kullanmaya çalışırsanız, OpenGL grafikleriniz biraz ince görünür veya muhtemelen hiç görünmez. Bu nedenle, OpenGL şekillerinizin koordinatlarını her zaman saat yönünün tersine çizim sırasında tanımlayın.

Not: Saat yönü ön yüz olarak değerlendirilecek bir OpenGL ortamı oluşturmak mümkündür, ancak bunu yapmak daha fazla kod gerektirir ve yardım istediğinizde deneyimli OpenGL geliştiricilerinin kafasını karıştırabilir. Bunu yapmayın.

OpenGL sürümleri ve cihaz uyumluluğu

OpenGL ES 1.0 ve 1.1 API özellikleri, Android 1.0'dan beri desteklenmektedir. OpenGL ES 1.0/1.1 API ile grafik programlama, 2.0 ve üzeri sürümleri kullanmaktan önemli ölçüde farklıdır. OpenGL ES 2.0, Android 2.2 (API düzeyi 8) ile başlayan tüm Android cihazlarda desteklenir ve OpenGL ES ile geliştirilen yeni uygulamalar için önerilen en eski sürümdür. OpenGL ES 3.0, OpenGL ES 3.0 API'sinin bir uygulamasını sağlayan cihazlarda Android 4.3 (API düzeyi 18) ve sonraki sürümlerle desteklenir. Belirli bir OpenGL ES sürümünü destekleyen Android destekli cihazların göreli sayısı hakkında bilgi edinmek için OpenGL ES sürümü kontrol paneline bakın.

Grafik gereksinimlerini dikkatlice değerlendirmeniz ve uygulamanız için en uygun API sürümünü seçmeniz gerekir. Daha fazla bilgi için bkz. OpenGL API sürümü seçme.

OpenGL ES 3.0 API, 2.0 API'den ek özellikler ve daha iyi performans sağlar ve geriye dönük olarak da uyumludur. Diğer bir deyişle, uygulama hedefleme uygulamanızı OpenGL ES 2.0 yazabilir ve varsa, OpenGL ES 3.0 grafik özelliklerini koşullu olarak dahil edebilirsiniz. 3.0 API'nin kullanılabilirliğini kontrol etme hakkında daha fazla bilgi için bkz. OpenGL ES sürümünü kontrol etme

Doku sıkıştırma desteği

Doku sıkıştırma, bellek gereksinimlerini azaltarak ve bellek bant genişliğini daha verimli kullanarak OpenGL uygulamanızın performansını önemli ölçüde artırabilir. Android çerçevesi, ETC1Util yardımcı programı sınıfı ve etc1tool sıkıştırma aracı (<sdk>/tools/ adresindeki Android SDK'da bulunur) dahil, standart bir özellik olarak ETC1 sıkıştırma biçimini destekler. Doku sıkıştırma kullanan bir Android uygulaması örneği için Android SDK'daki (<sdk>/samples/<version>/ApiDemos/src/com/example/android/apis/graphics/) CompressedTextureActivity kod örneğine bakın.

ETC1 biçimi OpenGL ES 2.0 veya sonraki sürümleri destekleyen tüm Android cihazlar tarafından desteklenir.

Not: ETC1 doku sıkıştırma biçimi, şeffaflığa (alfa kanalı) sahip dokuları desteklemez. Uygulamanız şeffaf dokular gerektiriyorsa hedef cihazlarınızda kullanılabilen diğer doku sıkıştırma biçimlerini araştırmanız gerekir. ETC1 kullanarak alfa kanalı dokularının oluşturulmasına ilişkin bir yöntem, iki ETC1 doku nesnesini bağlamaktır: Birincisi renk verileriyle, ikincisi alfa kanalı verileriyle ve daha sonra, parça gölgelendiricide iki dokudan alınan değerleri birleştirmektir.

OpenGL ES3.0 API kullanılırken ETC2/EAC doku sıkıştırma biçimlerinin kullanılabilir olması garanti edilir. Bu doku biçimi, yüksek görsel kalitede mükemmel sıkıştırma oranları sunar. Ayrıca biçim, şeffaflığı da (alfa kanalı) destekler.

Android cihazlar, ETC biçimlerinin ötesinde GPU yonga setlerine ve OpenGL uygulamalarına bağlı olarak çeşitli doku sıkıştırma desteğine sahiptir. Uygulamanızın hangi sıkıştırma türlerini desteklemesi gerektiğini belirlemek için, hedeflediğiniz cihazlardaki doku sıkıştırma desteğini araştırmanız gerekir. Belirli bir cihazda hangi doku biçimlerinin desteklendiğini belirlemek için cihazı sorgulamanız ve cihazın hangi doku sıkıştırma biçimlerinin (ve diğer OpenGL özelliklerini) desteklediğini tanımlayan OpenGL uzantı adlarını incelemeniz gerekir. Yaygın olarak desteklenen bazı doku sıkıştırma biçimleri şunlardır:

  • Uyarlanabilir Ölçeklenebilir Doku Sıkıştırma (ASTC) - Önceki biçimlerin yerini alacak şekilde tasarlanmış bir doku sıkıştırma biçimi. Çeşitli blok boyutlarının desteklenmesi nedeniyle önceki biçimlerden daha esnektir.
    • GL_KHR_texture_compression_astc_ldr
    • GL_KHR_texture_compression_astc_hdr(yüksek dinamik aralık)
  • S3TC (DXTn/DXTC) - S3 doku sıkıştırma (S3TC) birkaç biçim varyasyonuna (DXT1'den DXT5'e) sahiptir ve daha az kullanılır. Biçim, 4 bit alfa veya 8 bit alfa kanallı RGB dokularını destekler. Bu biçimler, aşağıdaki OpenGL uzantı adıyla temsil edilir:
    • GL_EXT_texture_compression_s3tc
    Bazı cihazlar yalnızca DXT1 biçim varyasyonunu destekler; bu sınırlı destek aşağıdaki OpenGL uzantı adıyla temsil edilir:
    • GL_EXT_texture_compression_dxt1

Aşağıdaki doku sıkıştırma biçimleri, eski biçimler olarak kabul edilir ve yeni uygulamalarda kullanılmaları önerilmez:

  • ATITC (ATC): ATI doku sıkıştırma (ATITC veya ATC) çok çeşitli cihazlarda kullanılabilir ve alfa kanalı olan ve olmayan RGB dokuları için sabit hızlı sıkıştırmayı destekler. Bu biçim, çeşitli OpenGL uzantı adları ile temsil edilebilir, örneğin:
    • GL_AMD_compressed_ATC_texture
    • GL_ATI_texture_compression_atitc
  • PVRTC: PowerVR doku sıkıştırma (PVRTC) özelliği çok çeşitli cihazlarda kullanılabilir ve alfa kanalı olan veya olmayan piksel başına 2 bit ve 4 bit dokuları destekler. Bu biçim, aşağıdaki OpenGL uzantı adıyla temsil edilir:
    • GL_IMG_texture_compression_pvrtc
  • 3DC: 3DC doku sıkıştırma (3DC), bir alfa kanalıyla RGB dokularını destekleyen, daha az kullanılan bir biçimdir. Bu biçim, aşağıdaki OpenGL uzantısıyla temsil edilir:
    • GL_AMD_compressed_3DC_texture

Uyarı: Bu doku sıkıştırma biçimleri tüm cihazlarda desteklenmez. Bu biçimler için destek, üreticiye ve cihaza göre farklılık gösterebilir. Belirli bir cihazda hangi doku sıkıştırma biçimlerinin nasıl belirleneceğiyle ilgili bilgi için sonraki bölüme bakın.

Not: Uygulamanızın hangi doku sıkıştırma biçimlerini destekleyeceğini belirledikten sonra, bunları <supports-gl-texture> kullanarak manifest dosyanızda belirttiğinizden emin olun. Bu beyanı kullandığınızda, Google Play gibi harici hizmetlere göre filtreleme etkinleştirilir. Böylece uygulamanız yalnızca uygulamanızın gerektirdiği biçimleri destekleyen cihazlara yüklenir. Ayrıntılar için OpenGL manifest beyanları bölümüne bakın.

OpenGL uzantılarını belirleme

OpenGL uygulamaları, desteklenen OpenGL ES API uzantıları açısından Android cihaza göre değişir. Bu uzantılar, doku sıkıştırmaları içerir, ancak genellikle OpenGL özellik grubundaki başka uzantıları da içerir.

Belirli bir cihazda hangi doku sıkıştırma biçimlerinin ve diğer OpenGL uzantılarının desteklendiğini belirlemek için:

  1. Hangi doku sıkıştırma biçimlerinin desteklendiğini belirlemek için hedef cihazlarınızda aşağıdaki kodu çalıştırın:

    Kotlin

    var extensions = gl.glGetString(GL10.GL_EXTENSIONS)
    

    Java

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

    Uyarı: Bu çağrının sonuçları cihaz modeline göre değişir! Hangi sıkıştırma türlerinin yaygın olarak desteklendiğini belirlemek için bu çağrıyı birkaç hedef cihazda çalıştırmanız gerekir.

  2. Cihazda hangi OpenGL uzantılarının desteklendiğini belirlemek için bu yöntemin sonucunu inceleyin.

Android Uzantı Paketi (AEP)

AEP, uygulamanızın OpenGL 3.1 spesifikasyonunda açıklanan çekirdek kümenin üzerinde ve ötesinde standartlaştırılmış bir OpenGL uzantılarını desteklemesini sağlar. Bu uzantıların bir arada kullanılması, farklı cihazlarda tutarlı bir işlev kümesini teşvik ederken geliştiricilerin de en yeni mobil GPU cihazlarından tam olarak yararlanmasına olanak tanır.

AEP de parça gölgelendiricilerinde resim, gölgelendirici depolama arabellek ve atom sayaç desteğini iyileştirir.

Uygulamanızın AEP'yi kullanabilmesi için uygulamanın manifest dosyasında AEP'nin gerekli olduğu beyan edilmelidir. Ayrıca, platform sürümünün desteklemesi gerekir.

AEP'de belirtilen ek özelliklerin tümü, temel OpenGL ES 3.2 spesifikasyonuna dahildir. Uygulamanız OpenGL ES 3.2 gerektiriyorsa AEP'yi zorunlu kılmanıza gerek yoktur.

Manifest'teki AEP şartını aşağıdaki şekilde tanımlayın:

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

Platform sürümünün AEP'yi desteklediğini doğrulamak için FEATURE_OPENGLES_EXTENSION_PACK bağımsız değişken olarak geçirerek hasSystemFeature(String) yöntemini kullanın. Aşağıdaki kod snippet'inde bunun nasıl yapılacağına dair bir örnek gösterilmektedir:

Kotlin

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

Java

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

Yöntem true (doğru) değerini döndürürse AEP desteklenir.

AEP hakkında daha fazla bilgi için Khronos OpenGL ES Kayıt Defteri'ndeki sayfasını ziyaret edin.

OpenGL ES sürümünü kontrol etme

Android cihazlarda çeşitli OpenGL ES sürümleri mevcuttur. Uygulamanızın gerektirdiği minimum API sürümünü manifestinizde belirtebilirsiniz ancak aynı zamanda daha yeni bir API'nin özelliklerinden yararlanmak da isteyebilirsiniz. Örneğin, OpenGL ES 3.0 API'sı, API'nin 2.0 sürümüyle geriye dönük uyumludur. Bu nedenle uygulamanızı OpenGL ES 3.0 özelliklerini kullanacak ancak 3.0 API'sı kullanılamadığında 2.0 API'sını kullanacak şekilde yazmak isteyebilirsiniz.

Uygulama manifestinizde gereken minimumdan daha yüksek bir sürümdeki OpenGL ES özelliklerini kullanmadan önce, uygulamanızın cihazdaki API sürümünü kontrol etmesi gerekir. Bunu iki şekilde yapabilirsiniz:

  1. Daha üst düzey OpenGL ES bağlamını (EGLContext) oluşturmayı deneyin ve sonucu kontrol edin.
  2. Minimum desteklenen bir OpenGL ES bağlamı oluşturun ve sürüm değerini kontrol edin.

Aşağıdaki örnek kod, EGLContext oluşturup sonucu kontrol ederek kullanılabilir OpenGL ES sürümünün nasıl kontrol edileceğini gösterir. Aşağıdaki örnekte, OpenGL ES 3.0 sürümünün nasıl kontrol edileceği gösterilmektedir:

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;
  }
}

Yukarıdaki createContext() yöntemi null değerini döndürürse kodunuz bunun yerine bir OpenGL ES 2.0 bağlamı oluşturmalı ve yalnızca bu API'yi kullanmaya devam etmelidir.

Aşağıdaki kod örneğinde, önce desteklenen minimum bir bağlam oluşturup ardından sürüm dizesini kontrol ederek OpenGL ES sürümünün nasıl kontrol edileceği gösterilmektedir:

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.

Bu yaklaşımda, cihazın daha üst düzey bir API sürümünü desteklediğini keşfederseniz minimum OpenGL ES bağlamını kaldırmanız ve daha yüksek düzeyde kullanılabilen API sürümüyle yeni bir bağlam oluşturmanız gerekir.

OpenGL API sürümü seçme

OpenGL ES sürüm 2.0 ve sürüm 3.0; 3D oyunlar, görselleştirmeler ve kullanıcı arayüzleri oluşturmak için yüksek performanslı grafik arayüzleri sağlar. OpenGL ES 2.0 ve 3.0 için grafik programlama büyük ölçüde benzerdir. 3.0 sürümü, ek özelliklere sahip 2.0 API'sinin bir üst kümesini temsil eder. OpenGL ES 1.0/1.1 API'sı ile OpenGL ES 2.0 ve 3.0 için yapılan programlama arasında önemli farklar vardır ve yeni uygulamalar için önerilmez. Geliştiriciler, bu API'lerle geliştirmeye başlamadan önce aşağıdaki faktörleri dikkatlice değerlendirmelidir:

  • Cihaz Uyumluluğu - Geliştiriciler, müşterilerine sunulan cihaz türlerini, Android sürümlerini ve OpenGL ES sürümlerini dikkate almalıdır. Cihazlar arasında OpenGL uyumluluğu hakkında daha fazla bilgi için OpenGL sürümleri ve cihaz uyumluluğu bölümüne bakın.
  • Doku Desteği - OpenGL ES 3.0 API, şeffaflığı destekleyen ETC2 sıkıştırma biçiminin kullanılabilirliğini garanti ettiği için doku sıkıştırma için en iyi desteği sunar. 2.0 API uygulamaları, ETC1 desteğini içerir ancak bu doku biçimi, şeffaflığı desteklemez. Sıkıştırılmış dokularla şeffaflığı uygulamak için iki ETC1 dokusu (renk ve alfa arasında bölünmüş) kullanmanız veya hedeflediğiniz cihazlar tarafından desteklenen diğer sıkıştırma biçimlerinde kaynaklar sağlamanız gerekir. Daha fazla bilgi için Doku sıkıştırma desteği bölümüne bakın.

Uyumluluk ve doku desteği kararınızı etkileyebilir, ancak kullanıcılarınız için en iyi deneyimi sağlayacağını düşündüğünüz özelliklere göre bir OpenGL API sürümü seçmeniz gerekir.