OpenGL ES

O Android inclui suporte a gráficos 2D e 3D de alto desempenho com a Open Graphics Library (OpenGL®), mais especificamente, a API OpenGL ES. OpenGL é uma API gráfica multiplataforma que especifica um e interface de software padrão para hardware de processamento gráfico 3D. O OpenGL ES é uma variação do OpenGL destinada a dispositivos incorporados. O Android oferece suporte a várias versões do OpenGL ES API:

  • OpenGL ES 2.0: esta especificação da API é compatível com o Android 2.2 (API de nível 8) e versões mais recentes.
  • OpenGL ES 3.0: essa especificação da API é compatível com o Android 4.3 (API de nível 18) e versões mais recentes.
  • OpenGL ES 3.1: essa especificação da API é compatível com o Android 5.0 (API de nível 21) e versões mais recentes.
  • OpenGL ES 3.2: essa especificação da API é compatível com o Android 7.0 (API de nível 24) e versões mais recentes.

Atenção: Independentemente da versão da plataforma Android, um dispositivo não pode oferecer suporte a API OpenGL ES 3.0, a menos que o fabricante do dispositivo forneça uma implementação desse pipeline de gráficos. Se você especificar no manifesto que O OpenGL ES 3.0 é obrigatório, pode ter certeza de que essa versão estará presente no dispositivo. Se você especificar que uma versão de nível inferior é necessária, mas quiser usar os recursos 3.0 se estiverem disponíveis, verifique no ambiente de execução para saber com qual versão do OpenGL o dispositivo é compatível. Para mais informações sobre como faça isso, consulte Verificar a versão do OpenGL ES.

Observação: O Android inclui suporte para OpenGL ES 1.0 e 1.1, mas essas versões da API foram descontinuados e não devem ser usados por aplicativos modernos.

Observação: A API específica fornecida pelo framework do Android é semelhante à API J2ME JSR239 OpenGL ES, mas não é idêntica. Se você conhece a especificação J2ME JSR239, tome cuidado com variações.

Consulte também

Noções básicas

O Android oferece suporte ao OpenGL tanto pela API do framework quanto pelo recurso de (NDK). Este tópico têm como foco as interfaces do framework do Android. Para mais informações sobre o NDK, consulte Android NDK.

Há duas classes básicas no framework do Android que permitem criar e manipular com a API OpenGL ES: GLSurfaceView e GLSurfaceView.Renderer. Se você quer usar o OpenGL no seu app Android, entender como implementar essas classes em uma atividade deve ser seu primeiro objetivo.

GLSurfaceView
Essa classe é um View em que é possível desenhar e manipular objetos usando as chamadas da API OpenGL e são semelhantes em função a uma SurfaceView. Você pode usar essa classe criando uma instância de GLSurfaceView e adicionando sua Renderer a ela. No entanto, se você quiser capturar eventos de tela de toque, estenda a classe GLSurfaceView para implementar os listeners de toque, como mostrado na aula de treinamento do OpenGL, Como responder a eventos de toque.
GLSurfaceView.Renderer
Esta interface define os métodos necessários para desenhar gráficos em uma GLSurfaceView. Você deve fornecer uma implementação dessa interface como um separada e anexe-a à sua instância GLSurfaceView usando GLSurfaceView.setRenderer().

A interface GLSurfaceView.Renderer exige que você implemente a seguintes métodos:

  • onSurfaceCreated(): o sistema chama isso uma vez ao criar o GLSurfaceView. Use esse método para realizar ações que precisam acontecer apenas uma vez, como configurar parâmetros de ambiente OpenGL ou inicializando objetos gráficos OpenGL.
  • onDrawFrame(): o sistema chama esse método em cada novo desenho de GLSurfaceView. Use este método como o ponto de execução principal para desenhar (e redesenhar) objetos gráficos.
  • onSurfaceChanged(): o sistema chama esse método quando a geometria do GLSurfaceView muda, incluindo mudanças no tamanho da GLSurfaceView ou na orientação da tela do dispositivo. Por exemplo, o sistema chama esse método quando o dispositivo muda da orientação retrato para paisagem. Use esse método para responder às mudanças no contêiner GLSurfaceView.

Pacotes do OpenGL ES

Depois de estabelecer uma visualização de contêiner para o OpenGL ES usando GLSurfaceView e GLSurfaceView.Renderer, você pode começar chamando APIs OpenGL usando as seguintes classes:

  • Classe da API OpenGL ES 2.0
    • android.opengl.GLES20: este pacote oferece o para OpenGL ES 2.0 e está disponível a partir do Android 2.2 (API de nível 8).
  • Pacotes da API OpenGL ES 3.0/3.1/3.2
    • android.opengl: este pacote oferece a interface para o OpenGL ES 3.0/3.1. classes. A versão 3.0 está disponível a partir do Android 4.3 (API nível 18). A versão 3.1 está disponível a partir do Android 5.0 (nível 21 da API). A versão 3.2 está disponível a partir do Android 7.0 (API nível 24).

Se você quiser começar a criar um aplicativo com o OpenGL ES imediatamente, siga o Exibir gráficos com o OpenGL ES .

Declarar requisitos do OpenGL

Se seu aplicativo usa recursos do OpenGL que não estão disponíveis em todos os dispositivos, é necessário incluir esses requisitos no seu AndroidManifest.xml . Estas são as declarações mais comuns de manifesto do OpenGL:

  • Requisitos da versão do OpenGL ES: se o aplicativo exigir uma versão de OpenGL ES, é necessário declarar esse requisito adicionando as seguintes configurações ao manifesto como mostradas abaixo.

    Para o OpenGL ES 2.0:

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

    Adicionar essa declaração faz com que o Google Play restrinja o acesso do aplicativo instalado em dispositivos não compatíveis com o OpenGL ES 2.0. Caso seu aplicativo seja exclusivamente para compatíveis com OpenGL ES 3.0, também é possível especificar isto no manifesto:

    Para o OpenGL ES 3.0:

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

    Para o OpenGL ES 3.1:

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

    Para OpenGL ES 3.2:

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

    Observação: A API OpenGL ES 3.x é compatível com a API 2.0, o que significa que você pode ser mais flexível com a implementação do OpenGL ES no aplicativo. Ao declarar o OpenGL API ES 2.0 como requisito no manifesto, use essa versão da API como padrão. Verifique para a disponibilidade da API 3.x no tempo de execução e depois usar os recursos do OpenGL ES 3.x se o dispositivo oferece suporte para ela. Para mais informações sobre como verificar a versão do OpenGL ES compatível com um dispositivo, consulte Verificar a versão do OpenGL ES.

  • Requisitos de compactação de textura: caso seu aplicativo use textura formatos de compactação, você deve declarar no arquivo de manifesto os formatos com suporte do aplicativo usando <supports-gl-texture>. Para mais informações sobre compactação de textura disponível formatos, consulte Suporte à compactação de textura.

    Declarar requisitos de compactação de textura no manifesto oculta seu aplicativo dos usuários com dispositivos que não são compatíveis com pelo menos um dos tipos de compactação declarados. Para mais informações sobre como funciona a filtragem do Google Play para compactações de textura, consulte a Seção "Google Play e filtragem de compactação de textura" da documentação do <supports-gl-texture>.

Coordenadas de mapeamento para objetos desenhados

Um dos problemas básicos na exibição de gráficos em dispositivos Android é que as telas deles podem variam em tamanho e formato. O OpenGL presume que o sistema de coordenadas seja quadrado e uniforme e, por padrão, desenha essas coordenadas em uma tela normalmente não quadrada, como se ela fosse perfeitamente quadrada.

Figura 1. Sistema de coordenadas padrão do OpenGL (à esquerda) mapeado para uma interface típica do Android tela do dispositivo (à direita).

A ilustração acima mostra o sistema de coordenadas uniforme presumido para um frame OpenGL na esquerda e como essas coordenadas são mapeadas para uma tela típica de dispositivo na orientação paisagem à direita. Para resolver esse problema, você pode aplicar modos de projeção OpenGL e visualizações de câmera ao transformar as coordenadas para que os objetos gráficos tenham as proporções corretas em qualquer tela.

Para aplicar projeção e visualizações de câmera, crie uma matriz de projeção e uma visualização de câmera. e aplicá-las ao pipeline de renderização do OpenGL. A matriz de projeção recalcula coordenadas de seus gráficos para que eles sejam corretamente mapeados nas telas de dispositivos Android. Visualização da câmera cria uma transformação que renderiza objetos de uma posição de olho específica.

Projeção e visualização de câmera no OpenGL ES 2.0 e versões posteriores

Nas APIs ES 2.0 e 3.0, você aplica a projeção e a visualização de câmera adicionando primeiro um membro da matriz. aos sombreadores de vértice dos objetos gráficos. Com esse membro da matriz adicionado, é possível gerar e aplicar matrizes de projeção e visualização de câmera aos seus objetos.

  1. Adicionar matriz aos sombreadores de vértice: crie uma variável para a matriz de projeção de visualização. e incluí-lo como um multiplicador da posição do sombreador. No exemplo a seguir, o shader de vértice o membro uMVPMatrix incluído permite aplicar projeção e visualização de câmera. matrizes como coordenadas de objetos que usam esse sombreador.

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

    Observação: o exemplo acima define uma única matriz de transformação no shader de vértice em que você aplica uma matriz de projeção combinada e uma visualização de câmera matricial. Dependendo dos requisitos do seu aplicativo, você pode definir valores de projeção de matriz e de visualização da câmera nos sombreadores de vértice, para que seja possível mudá-los de forma independente.

  2. Acessar a matriz de sombreador: depois de criar um hook nos sombreadores de vértice, aplicar projeção e visualização de câmera, poderá acessar essa variável para aplicar a projeção e matrizes de visualização de câmeras. O código abaixo mostra como modificar o método onSurfaceCreated() de uma implementação GLSurfaceView.Renderer para acessar a matriz. variável definida no shader de vértice acima.

    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. Criar matrizes de projeção e de visualização de câmera: gere a projeção e matrizes de visualização sejam aplicadas aos objetos gráficos. O código de exemplo a seguir mostra como modificar os objetos onSurfaceCreated() e métodos onSurfaceChanged() de um implementação de GLSurfaceView.Renderer para criar a matriz de visualização da câmera e uma matriz de projeção baseada na proporção da tela do dispositivo.

    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. Aplicar matrizes de projeção e de visualização de câmera: para aplicar a projeção e o visualizações de câmera, multiplicar as matrizes e as definir no vértice sombreador. O código de exemplo abaixo mostra como modificar o método onDrawFrame() de uma implementação GLSurfaceView.Renderer para combinar a matriz de projeção e a visualização de câmera criadas no código acima e depois aplicá-las ao gráfico sejam renderizados pelo 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
        ...
    }
    

Para ver um exemplo completo de como aplicar projeção e visualização de câmera com o OpenGL ES 2.0, consulte Como exibir gráficos com o OpenGL ES .

Faces e enrolamento de formas

No OpenGL, a face de uma forma é uma superfície definida por três ou mais pontos em tridimensionais espaço. Um conjunto de três ou mais pontos tridimensionais (chamados de vértices no OpenGL) tem uma face frontal e de trás. Como saber qual é a face frontal e qual é a traseira? Boa pergunta. A tem a ver com o enrolamento, ou seja, a direção em que você define os pontos de uma forma.

Coordenadas em
vértices de um triângulo

Figura 1. Ilustração de uma lista de coordenadas que é convertida em uma no sentido anti-horário.

Neste exemplo, os pontos do triângulo são definidos em uma ordem de tal forma que sejam desenhados em uma sentido anti-horário. A ordem em que essas coordenadas são desenhadas define o enrolamento direção do polígono. Por padrão, no OpenGL, a face desenhada no sentido anti-horário é a face frontal. O triângulo mostrado na figura 1 está definido para que você olhe para a face frontal de a forma (conforme interpretado pelo OpenGL) e o outro lado é a face traseira.

Por que é importante saber qual face de uma forma é a frontal? A resposta tem a ver com um recurso comumente usado do OpenGL, chamado de seleção de face. A seleção de rostos é uma opção do OpenGL que permite ao pipeline de renderização ignorar (não calcular nem desenhar) a face traseira de um forma, economizando tempo, memória e ciclos de processamento:

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

Se você tentar usar o recurso de seleção de face sem saber quais lados das formas são na frente e na de trás, seus gráficos do OpenGL ficarão um pouco finos ou talvez nem apareçam. Portanto, sempre defina as coordenadas das formas do OpenGL em um sentido de desenho anti-horário.

Observação: é possível definir um ambiente OpenGL para tratar a A face no sentido horário é a face da frente, mas isso requer mais códigos e pode confundir desenvolvedores de OpenGL experientes quando pede ajuda a eles. Então, não faça isso.

Versões do OpenGL e compatibilidade com dispositivos

As especificações da API OpenGL ES 1.0 e 1.1 são compatíveis a partir do Android 1.0. A programação de gráficos com a API OpenGL ES 1.0/1.1 é significativamente diferente do uso da API 2.0 e versões mais recentes. O OpenGL ES 2.0 é compatível com todos os dispositivos Android a partir do Android 2.2 (API de nível 8) e a versão mais antiga recomendada para novos aplicativos em desenvolvimento com o OpenGL ES. O OpenGL ES 3.0 é compatível com o Android 4.3 (nível 18 da API) e versões mais recentes em dispositivos que oferecem uma implementação da API OpenGL ES 3.0. Para informações sobre o número relativo de dispositivos com tecnologia Android que oferecem suporte a uma determinada versão do OpenGL ES, consulte o Painel de versões do OpenGL ES.

Considere cuidadosamente os requisitos gráficos e escolha a API a versão mais adequada ao seu aplicativo. Para mais informações, consulte Como escolher uma versão da API OpenGL.

A API OpenGL ES 3.0 oferece mais recursos e desempenho melhor do que a API 2.0 e tem e também é compatível com versões anteriores. Isso significa que é possível programar seu aplicativo de destino OpenGL ES 2.0 e inclui condicionalmente recursos gráficos do OpenGL ES 3.0, se estiverem disponíveis. Para mais informações sobre como verificar a disponibilidade da API 3.0, consulte Verificar a versão do OpenGL ES

Compatibilidade com compactação de textura

A compactação de textura pode aumentar significativamente o desempenho do seu aplicativo OpenGL ao reduzindo os requisitos de memória e fazendo um uso mais eficiente da largura de banda de memória. O Android é compatível com o formato de compactação ETC1 como recurso padrão, incluindo uma A classe de utilitário ETC1Util e a ferramenta de compactação etc1tool (localizadas na SDK do Android em <sdk>/tools/). Para um exemplo de aplicativo Android que usa compactação de textura, consulte o exemplo de código CompressedTextureActivity no SDK do Android (<sdk>/samples/<version>/ApiDemos/src/com/example/android/apis/graphics/).

O formato ETC1 está disponível em todos os dispositivos Android compatíveis com OpenGL ES 2.0 ou mais recente.

Observação:o formato de compactação de textura ETC1 não é compatível com texturas com um transparência (Canal Alfa). Caso seu aplicativo exija texturas com transparência, você deve investigar outros formatos de compactação de textura disponíveis nos dispositivos de destino. Um de renderizar texturas do canal alfa usando ETC1 é vincular dois objetos de textura ETC1: o primeiro com dados de cores, a segunda com dados de canal alfa e depois combinar os valores dos dois texturas no sombreador de fragmento.

Os formatos de compactação de textura ETC2/EAC têm a garantia de estarem disponíveis ao usar o OpenGL ES 3.0. Este formato de textura oferece excelentes taxas de compactação com alta qualidade visual e o também é compatível com transparência (Canal Alfa).

Além dos formatos ETC, os dispositivos Android oferecem suporte variado à compactação de textura, com base em os chipsets de GPU e as implementações do OpenGL. Pesquise o suporte à compactação de texturas os dispositivos que você está segmentando para determinar quais tipos de compactação seu aplicativo deve suporte. Para determinar quais formatos de textura são compatíveis com um determinado dispositivo, você deve consultar o dispositivo e analisar os nomes da extensão OpenGL; que identificam quais formatos de compactação de textura (e outros recursos do OpenGL) são suportados pelo dispositivo. Alguns dos formatos de compactação de textura mais comuns são:

  • Compactação de textura escalonável adaptável (ASTC, na sigla em inglês): um formato de compactação de textura projetado para substituir formatos anteriores. Mais flexível do que os formatos anteriores devido ao suporte a vários tamanhos de bloco.
    • GL_KHR_texture_compression_astc_ldr
    • GL_KHR_texture_compression_astc_hdr(alto intervalo dinâmico)
  • S3TC (DXTn/DXTC): a compactação de textura S3 (S3TC) tem diversas variações de formato (DXT1 a DXT5) e está disponível de forma menos ampla. O formato é compatível com texturas RGB com canais Alfa de 4 ou 8 bits. Esses formatos são representados pela seguinte extensão OpenGL nome:
    • GL_EXT_texture_compression_s3tc
    . Alguns dispositivos suportam apenas a variação de formato DXT1; esse suporte limitado é representado seguinte nome de extensão do OpenGL:
    • GL_EXT_texture_compression_dxt1

Os seguintes formatos de compactação de textura são considerados formatos legados e não são recomendados para uso em novos aplicativos:

  • ATITC (ATC): a compactação de textura ATI (ATITC ou ATC) está disponível em um para uma ampla variedade de dispositivos e oferece suporte à compactação de taxa fixa para texturas RGB, com e sem um canal alfa. Esse formato pode ser representado por vários nomes de extensão do OpenGL, por exemplo:
    • GL_AMD_compressed_ATC_texture
    • GL_ATI_texture_compression_atitc
  • PVRTC: a compactação de textura PowerVR (PVRTC) está disponível em um diversos dispositivos e suporta texturas de 2 bits e 4 bits por pixel com ou sem um canal alfa. Esse formato é representado pelo seguinte nome de extensão do OpenGL:
    • GL_IMG_texture_compression_pvrtc
  • 3DC: a compactação de textura 3DC é um formato menos disponível que oferece suporte a texturas RGB com um canal alfa. Esse formato é representado pelo seguinte Nome da extensão:
    • GL_AMD_compressed_3DC_texture

Aviso: esses formatos de compactação de textura não são compatível em todos os dispositivos. A compatibilidade com esses formatos pode variar de acordo com o fabricante e o dispositivo. Para informações sobre como determinar quais formatos de compactação de textura estão em um dispositivo específico, consulte na próxima seção.

Observação:depois de decidir quais formatos de compactação de textura aplicativo vai oferecer suporte, certifique-se de declará-los no manifesto usando <supports-gl-texture> . O uso dessa declaração permite filtrar por serviços externos, como o Google Play, para que Seu app é instalado somente em dispositivos que oferecem suporte aos formatos exigidos pelo app. Para mais detalhes, consulte Declarações de manifesto do OpenGL.

Determinar extensões do OpenGL

As implementações do OpenGL variam de acordo com o dispositivo Android em termos de extensões da API OpenGL ES com suporte. Essas extensões incluem compactações de textura, mas normalmente também incluem outras para o conjunto de recursos do OpenGL.

Para determinar quais formatos de compactação de textura e outras extensões OpenGL são suportados em um dispositivo específico:

  1. Execute o seguinte código nos dispositivos de destino para determinar qual compactação de textura são suportados:

    Kotlin

    var extensions = gl.glGetString(GL10.GL_EXTENSIONS)
    

    Java

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

    Alerta: os resultados dessa chamada variam de acordo com o modelo do dispositivo. Você deve executar essa chamada em vários dispositivos de destino para determinar quais tipos de compactação suporte.

  2. Confira a saída desse método para determinar quais extensões do OpenGL são compatíveis com a dispositivo.

Pacote de extensões para Android (AEP, na sigla em inglês)

O AEP garante que seu aplicativo ofereça suporte a um conjunto padronizado de extensões OpenGL acima e além ao conjunto principal descrito na especificação do OpenGL 3.1. Como empacotar essas extensões incentiva um conjunto consistente de funcionalidades em todos os dispositivos, ao mesmo tempo em que permite que os desenvolvedores aproveitem aproveitar a mais recente safra de dispositivos móveis de GPU.

O AEP também melhora o suporte a imagens, buffers de armazenamento de shader e contadores atômicos em sombreadores de fragmento.

Para que seu app possa usar o AEP, o manifesto precisa declarar que o AEP é necessário. Além disso, a versão da plataforma precisa ser compatível com o pacote.

Todos os recursos adicionais especificados no AEP estão incluídos na versão básica do OpenGL ES 3.2 especificação. Se seu aplicativo exige o OpenGL ES 3.2, não é necessário solicitar o AEP.

Declare o requisito de AEP no manifesto da seguinte forma:

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

Para verificar se a versão da plataforma é compatível com o AEP, use o hasSystemFeature(String), transmitindo FEATURE_OPENGLES_EXTENSION_PACK como argumento. O snippet de código a seguir mostra um exemplo de como fazer isso:

Kotlin

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

Java

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

Se o método retornar verdadeiro, o AEP será compatível.

Para mais informações sobre a AEP, acesse a página na registro do Khronos OpenGL ES (em inglês).

Verificar a versão do OpenGL ES

Existem várias versões do OpenGL ES disponíveis em dispositivos Android. É possível especificar versão mínima da API que seu aplicativo requer em seu manifesto, mas você também pode querer aproveitar os recursos de uma API mais recente ao mesmo tempo. Por exemplo: a API OpenGL ES 3.0 é compatível com a versão 2.0 da API, então você pode escrever seu aplicativo para que ele use os recursos do OpenGL ES 3.0, mas recorre à API 2.0 se o A API 3.0 não está disponível.

Antes de usar os recursos do OpenGL ES em uma versão mais recente que a mínima exigida no manifesto do aplicativo, o aplicativo deve verificar a versão da API disponível no dispositivo. Isso pode ser feito de duas maneiras:

  1. Tente criar o contexto do OpenGL ES de nível superior (EGLContext) e conferir o resultado.
  2. Crie um contexto do OpenGL ES mínimo compatível e verifique o valor da versão.

O código de exemplo a seguir demonstra como verificar a versão do OpenGL ES disponível criando uma EGLContext e verificando o resultado. Este exemplo mostra como verificar Versão do 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;
  }
}

Se o método createContext() mostrado acima retornar nulo, seu código precisará criar um OpenGL ES 2.0 e voltar a usar apenas essa API.

O exemplo de código a seguir demonstra como verificar a versão do OpenGL ES criando uma o contexto suportado primeiro e, em seguida, verificando a string da versão:

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.

Com essa abordagem, se você descobrir que o dispositivo é compatível com uma versão de nível superior da API, precisa destruir o contexto mínimo do OpenGL ES e criar um novo contexto com a versão disponível da API.

Escolher uma versão da API OpenGL

As versões 2.0 e 3.0 do OpenGL ES oferecem alto interfaces gráficas de desempenho para criar jogos em 3D, visualizações e interfaces do usuário. Gráficos a programação para OpenGL ES 2.0 e 3.0 é muito semelhante, com a versão 3.0 representando um superconjunto da API 2.0 com recursos adicionais. Programação para a API OpenGL ES 1.0/1.1 versus OpenGL ES As versões 2.0 e 3.0 têm diferenças significativas e não são recomendadas para novos aplicativos. Os desenvolvedores devem considerar cuidadosamente os fatores a seguir antes de iniciar o desenvolvimento com estas APIs:

  • Compatibilidade do dispositivo: os desenvolvedores precisam considerar os tipos de dispositivo, Versões do Android e do OpenGL ES disponíveis para os clientes. Para mais informações sobre a compatibilidade com OpenGL em vários dispositivos, consulte as versões do OpenGL e seção "Compatibilidade do dispositivo".
  • Suporte a texturas: a API OpenGL ES 3.0 oferece a melhor compatibilidade com texturas. porque garante a disponibilidade do formato de compactação ETC2, que oferece suporte transparência As implementações da API 2.0 incluem suporte para ETC1. No entanto, esse formato de textura não tem suporte para transparência. Para implementar transparência com imagens texturas, você deve usar duas texturas ETC1 (divididas entre cor e alfa) ou fornecer recursos em outros formatos de compactação compatíveis com os dispositivos de destino. Para mais informações, consulte Suporte à compactação de textura.

Embora a compatibilidade e a compatibilidade com a textura possam influenciar escolha uma versão da API OpenGL com base no que você acha que oferece a melhor experiência para seus usuários.