Android est compatible avec les graphismes 2D et 3D hautes performances avec la bibliothèque Open Graphics (OpenGL®), et plus précisément avec l'API OpenGL ES. OpenGL est une API graphique multiplate-forme qui spécifie une interface logicielle standard pour le matériel de traitement graphique 3D. OpenGL ES est un type de spécification OpenGL destiné aux appareils embarqués. Android est compatible avec plusieurs versions de l'API OpenGL ES:
- OpenGL ES 2.0 : cette spécification d'API est compatible avec Android 2.2 (niveau d'API 8) ou version ultérieure.
- OpenGL ES 3.0 : cette spécification d'API est compatible avec Android 4.3 (niveau d'API 18) ou version ultérieure.
- OpenGL ES 3.1 : cette spécification d'API est compatible avec Android 5.0 (niveau d'API 21) ou version ultérieure.
- OpenGL ES 3.2 : cette spécification d'API est compatible avec Android 7.0 (niveau d'API 24) ou version ultérieure.
Attention:Quelle que soit la version de la plate-forme Android, un appareil ne peut pas prendre en charge l'API OpenGL ES 3.0, sauf si le fabricant de l'appareil fournit une implémentation de ce pipeline graphique. Si vous spécifiez dans le fichier manifeste qu'OpenGL ES 3.0 est requis, vous pouvez être sûr que cette version sera présente sur l'appareil. Si vous spécifiez qu'une version de niveau inférieur est requise, mais que vous souhaitez utiliser les fonctionnalités 3.0 si elles sont disponibles, vous devez vérifier au moment de l'exécution pour connaître la version d'OpenGL compatible avec l'appareil. Pour savoir comment procéder, consultez la section Vérifier la version d'OpenGL ES.
Remarque:Android est compatible avec OpenGL ES 1.0 et 1.1, mais ces versions de l'API sont obsolètes et ne doivent pas être utilisées par les applications modernes.
Remarque:L'API spécifique fournie par le framework Android est semblable à l'API OpenGL ES J2ME JSR239, mais elle n'est pas identique. Si vous connaissez bien la spécification JSR239, soyez à l'affût des variations.
Voir aussi
- Afficher des graphiques avec OpenGL ES
- OpenGL ES
- Spécifications OpenGL ES 2.x
- Spécifications OpenGL ES 3.x
Principes de base
Android est compatible avec OpenGL via son API de framework et le kit de développement natif (NDK). Cet article porte sur les interfaces du framework Android. Pour en savoir plus sur le NDK, consultez le NDK Android.
Le framework Android comporte deux classes de base qui vous permettent de créer et de manipuler des graphiques avec l'API OpenGL ES: GLSurfaceView
et GLSurfaceView.Renderer
. Si votre objectif est d'utiliser OpenGL dans votre application Android, votre objectif premier est de comprendre comment implémenter ces classes dans une activité.
GLSurfaceView
- Cette classe est une
View
dans laquelle vous pouvez dessiner et manipuler des objets à l'aide d'appels d'API OpenGL. Sa fonction est semblable à celle d'uneSurfaceView
. Pour utiliser cette classe, créez une instance deGLSurfaceView
et ajoutez-y votreRenderer
. Toutefois, si vous souhaitez capturer des événements d'écran tactile, vous devez étendre la classeGLSurfaceView
pour implémenter les écouteurs tactiles, comme indiqué dans la leçon d'entraînement OpenGL intitulée Répondre aux événements tactiles. GLSurfaceView.Renderer
- Cette interface définit les méthodes requises pour dessiner des graphiques dans un élément
GLSurfaceView
. Vous devez fournir une implémentation de cette interface en tant que classe distincte et l'associer à votre instanceGLSurfaceView
à l'aide deGLSurfaceView.setRenderer()
.L'interface
GLSurfaceView.Renderer
nécessite l'implémentation des méthodes suivantes:-
onSurfaceCreated()
: le système appelle cette méthode une fois lors de la création de l'GLSurfaceView
. Utilisez cette méthode pour effectuer des actions qui ne doivent être effectuées qu'une seule fois, telles que la définition des paramètres d'environnement OpenGL ou l'initialisation d'objets graphiques OpenGL. -
onDrawFrame()
: le système appelle cette méthode à chaque redessinage deGLSurfaceView
. Utilisez cette méthode comme point d'exécution principal pour dessiner (et redessiner) des objets graphiques. -
onSurfaceChanged()
: le système appelle cette méthode lorsque la géométrieGLSurfaceView
change, y compris en cas de changement de taille deGLSurfaceView
ou d'orientation de l'écran de l'appareil. Par exemple, le système appelle cette méthode lorsque l'appareil passe de l'orientation portrait à l'orientation paysage. Utilisez cette méthode pour répondre aux modifications apportées au conteneurGLSurfaceView
.
-
Packages OpenGL ES
Une fois que vous avez établi une vue du conteneur pour OpenGL ES à l'aide de GLSurfaceView
et GLSurfaceView.Renderer
, vous pouvez commencer à appeler les API OpenGL à l'aide des classes suivantes:
- Classe d'API OpenGL ES 2.0
android.opengl.GLES20
: ce package fournit l'interface à OpenGL ES 2.0 et est disponible à partir d'Android 2.2 (niveau d'API 8).
- Packages d'API OpenGL ES 3.0/3.1/3.2
android.opengl
: ce package fournit l'interface aux classes OpenGL ES 3.0/3.1. La version 3.0 est disponible à partir d'Android 4.3 (niveau d'API 18). La version 3.1 est disponible à partir d'Android 5.0 (niveau d'API 21). La version 3.2 est disponible à partir d'Android 7.0 (niveau d'API 24).
Si vous souhaitez commencer à créer une application avec OpenGL ES immédiatement, suivez la classe Afficher des graphiques avec OpenGL ES.
Déclarer des exigences OpenGL
Si votre application utilise des fonctionnalités OpenGL qui ne sont pas disponibles sur tous les appareils, vous devez inclure ces exigences dans votre fichier AndroidManifest.xml. Voici les déclarations de fichier manifeste OpenGL les plus courantes:
- Exigences relatives à la version OpenGL ES : si votre application nécessite une version spécifique d'OpenGL ES, vous devez déclarer cette exigence en ajoutant les paramètres suivants à votre fichier manifeste, comme indiqué ci-dessous.
Pour OpenGL ES 2.0:
<!-- Tell the system this app requires OpenGL ES 2.0. --> <uses-feature android:glEsVersion="0x00020000" android:required="true" />
L'ajout de cette déclaration empêche Google Play d'installer votre application sur les appareils non compatibles avec OpenGL ES 2.0. Si votre application est destinée exclusivement aux appareils compatibles avec OpenGL ES 3.0, vous pouvez également l'indiquer dans votre fichier manifeste:
Pour OpenGL ES 3.0:
<!-- Tell the system this app requires OpenGL ES 3.0. --> <uses-feature android:glEsVersion="0x00030000" android:required="true" />
Pour OpenGL ES 3.1:
<!-- Tell the system this app requires OpenGL ES 3.1. --> <uses-feature android:glEsVersion="0x00030001" android:required="true" />
Pour OpenGL ES 3.2:
<!-- Tell the system this app requires OpenGL ES 3.2. --> <uses-feature android:glEsVersion="0x00030002" android:required="true" />
Remarque:L'API OpenGL ES 3.x est rétrocompatible avec l'API 2.0, ce qui signifie que vous pouvez implémenter OpenGL ES de manière plus flexible dans votre application. En déclarant l'API OpenGL ES 2.0 comme exigence dans votre fichier manifeste, vous pouvez utiliser cette version d'API par défaut, vérifier la disponibilité de l'API 3.x au moment de l'exécution, puis utiliser les fonctionnalités OpenGL ES 3.x si l'appareil le permet. Pour savoir comment vérifier la version d'OpenGL ES compatible avec un appareil, consultez la section Vérifier la version d'OpenGL ES.
- Exigences concernant la compression de texture : si votre application utilise des formats de compression de texture, vous devez déclarer les formats compatibles avec votre fichier manifeste à l'aide de
<supports-gl-texture>
. Pour en savoir plus sur les formats de compression de texture disponibles, consultez la page Compatibilité avec la compression de texture.La déclaration d'exigences de compression de texture dans le fichier manifeste masque votre application aux utilisateurs dont les appareils ne sont pas compatibles avec au moins l'un des types de compression que vous avez déclarés. Pour en savoir plus sur le fonctionnement du filtrage Google Play pour les compressions de texture, consultez la section Google Play et filtrage par compression de texture de la documentation
<supports-gl-texture>
.
Cartographier des coordonnées pour les objets dessinés
L'un des problèmes de base lors de l'affichage des éléments graphiques sur les appareils Android est que la taille et la forme des écrans peuvent varier. OpenGL suppose un système de coordonnées uniformes carrés et, par défaut, dessine ces coordonnées sur votre écran généralement non carré comme si celui-ci était parfaitement carré.
![](https://developer.android.com/static/images/opengl/coordinates.png?authuser=6&hl=fr)
Figure 1 : Système de coordonnées OpenGL par défaut (à gauche) mappé sur un écran d'appareil Android standard (à droite).
L'illustration ci-dessus montre le système de coordonnées uniformes appliqué à une image OpenGL à gauche et la manière dont ces coordonnées sont mappées à un écran d'appareil classique en mode paysage à droite. Pour résoudre ce problème, vous pouvez appliquer des modes de projection OpenGL et des vues de caméra pour transformer les coordonnées afin que vos objets graphiques aient les proportions correctes sur n'importe quel écran.
Pour appliquer des vues de projection et de caméra, vous devez créer une matrice de projection et une matrice de vues de caméra, puis les appliquer au pipeline de rendu OpenGL. La matrice de projection recalcule les coordonnées de vos éléments graphiques pour les faire correspondre correctement aux écrans des appareils Android. La matrice de vue de la caméra crée une transformation qui affiche les objets à partir d'une position spécifique de l'œil.
Projection et vue de l'appareil photo dans OpenGL ES 2.0 ou version ultérieure
Dans les API ES 2.0 et 3.0, pour appliquer la projection et la vue de caméra, commencez par ajouter un membre matriciel aux nuanceurs de sommets de vos objets graphiques. Avec ce membre de matrice ajouté, vous pouvez ensuite générer et appliquer des matrices de projection et de vue de caméra à vos objets.
- Ajouter une matrice aux nuanceurs de sommets : créez une variable pour la matrice de projection de vues et incluez-la en tant que multiplicateur de la position du nuanceur. Dans l'exemple de code de nuanceur de sommets suivant, le membre
uMVPMatrix
inclus vous permet d'appliquer des matrices de projection et de visualisation de la caméra aux coordonnées des objets qui utilisent ce nuanceur.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";
Remarque:L'exemple ci-dessus définit un seul membre de la matrice de transformation dans le nuanceur de sommets, dans lequel vous appliquez une matrice de projection combinée à une matrice de vue de la caméra. En fonction des exigences de votre application, vous pouvez définir des membres distincts de la matrice de projection et de la matrice de visualisation des caméras dans vos nuanceurs de sommets, afin de pouvoir les modifier indépendamment.
- Accéder à la matrice de nuanceurs : après avoir créé un hook dans vos nuanceurs de sommets pour appliquer la projection et la vue de la caméra, vous pouvez accéder à cette variable pour appliquer des matrices de projection et d'affichage de la caméra. Le code suivant montre comment modifier la méthode
onSurfaceCreated()
d'une implémentationGLSurfaceView.Renderer
pour accéder à la variable matricielle définie dans le nuanceur de sommets ci-dessus.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"); ... }
- Créer des matrices de projection et d'affichage de caméra : générez les matrices de projection et de vue à appliquer aux objets graphiques. L'exemple de code suivant montre comment modifier les méthodes
onSurfaceCreated()
etonSurfaceChanged()
d'une implémentation deGLSurfaceView.Renderer
pour créer une matrice de vues de la caméra et une matrice de projection basée sur le format de l'écran de l'appareil.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); }
- Appliquer des matrices de projection et d'affichage de la caméra : pour appliquer les transformations de projection et de vue de la caméra, multipliez les matrices ensemble, puis définissez-les dans le nuanceur de sommets. L'exemple de code suivant montre comment modifier la méthode
onDrawFrame()
d'une implémentationGLSurfaceView.Renderer
pour combiner la matrice de projection et la vue de caméra créées dans le code ci-dessus, puis comment l'appliquer aux objets graphiques à afficher par 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 ... }
Pour obtenir un exemple complet d'application de la projection et de la vue de caméra avec OpenGL ES 2.0, consultez la classe Afficher des graphiques avec OpenGL ES.
Forme des faces et enroulement
Dans OpenGL, la face d'une forme est une surface définie par au moins trois points dans un espace tridimensionnel. Un ensemble de trois points en trois dimensions ou plus (appelés sommets dans OpenGL) a une face avant et une face arrière. Comment savoir quel visage est à l'avant et lequel est à l'arrière ? Bonne question. La réponse concerne le tracé, c'est-à-dire la direction dans laquelle vous définissez les points d'une forme.
![Les coordonnées au
sommet d'un triangle](https://developer.android.com/static/images/opengl/ccw-winding.png?authuser=6&hl=fr)
Figure 1 : Illustration d'une liste de coordonnées se traduisant dans un ordre de traçage dans le sens inverse des aiguilles d'une montre.
Dans cet exemple, les points du triangle sont définis dans l'ordre de façon à ce qu'ils soient dessinés dans le sens inverse des aiguilles d'une montre. L'ordre dans lequel ces coordonnées sont tracées définit la direction du tracé de la forme. Par défaut, dans OpenGL, la face avant est dessinée dans le sens inverse des aiguilles d'une montre. Le triangle de la figure 1 est défini de manière à regarder la face avant de la forme (interprétée par OpenGL), et l'autre côté est la face arrière.
Pourquoi est-il important de savoir quelle face d'une forme est la face avant ? La réponse porte sur une fonctionnalité couramment utilisée d'OpenGL : la sélection de visages. La sélection de visages est une option de l'environnement OpenGL qui permet au pipeline de rendu d'ignorer (et non de calculer ni de dessiner) la face arrière d'une forme, ce qui permet de gagner du temps, d'économiser de la mémoire et des cycles de traitement:
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);
Si vous essayez d'utiliser la fonctionnalité de sélection des visages sans savoir quels côtés de vos formes figurent à l'avant et à l'arrière, vos graphiques OpenGL seront un peu minces, voire ne s'afficheront pas du tout. Par conséquent, définissez toujours les coordonnées de vos formes OpenGL dans l'ordre inverse des aiguilles d'une montre.
Remarque:Il est possible de configurer un environnement OpenGL pour qu'il traite la clock face comme étant la face avant, mais cela nécessite plus de code et risque de perturber les développeurs OpenGL expérimentés lorsque vous leur demandez de l'aide. Alors ne le faites pas.
Versions d'OpenGL et compatibilité des appareils
Les spécifications de l'API OpenGL ES 1.0 et 1.1 sont compatibles depuis Android 1.0. La programmation graphique avec l'API OpenGL ES 1.0/1.1 est très différente de celle des versions 2.0 et ultérieures. OpenGL ES 2.0 est compatible avec tous les appareils Android à partir d'Android 2.2 (niveau d'API 8). Il s'agit de la première version recommandée pour les nouvelles applications développées avec OpenGL ES. OpenGL ES 3.0 est compatible avec Android 4.3 (niveau d'API 18) ou version ultérieure sur les appareils qui fournissent une implémentation de l'API OpenGL ES 3.0. Pour en savoir plus sur le nombre relatif d'appareils Android compatibles avec une version donnée d'OpenGL ES, consultez le tableau de bord des versions OpenGL ES.
Vous devez bien prendre en compte les exigences graphiques et choisir la version d'API la plus adaptée à votre application. Pour en savoir plus, consultez Choisir une version d'API OpenGL.
L'API OpenGL ES 3.0 offre des fonctionnalités supplémentaires et de meilleures performances que l'API 2.0. Elle est également rétrocompatible. Cela signifie que vous pouvez potentiellement écrire votre application ciblant OpenGL ES 2.0 et inclure sous conditions les fonctionnalités graphiques OpenGL ES 3.0 si elles sont disponibles. Pour en savoir plus sur la vérification de la disponibilité de l'API 3.0, consultez la section Vérifier la version d'OpenGL ES.
Prise en charge de la compression de texture
La compression de texture peut améliorer considérablement les performances de votre application OpenGL en réduisant les besoins en mémoire et en utilisant plus efficacement la bande passante mémoire. Le framework Android est compatible avec le format de compression ETC1 en tant que fonctionnalité standard, y compris une classe utilitaire ETC1Util
et l'outil de compression etc1tool
(situé dans le SDK Android sous <sdk>/tools/
). Pour obtenir un exemple d'application Android utilisant la compression de texture, consultez l'exemple de code CompressedTextureActivity
dans le SDK Android (<sdk>/samples/<version>/ApiDemos/src/com/example/android/apis/graphics/
).
Le format ETC1 est compatible avec tous les appareils Android compatibles avec OpenGL ES 2.0 ou version ultérieure.
Remarque:Le format de compression de texture ETC1 n'est pas compatible avec les textures avec une transparence (canal alpha). Si votre application nécessite des textures avec transparence, vous devez étudier d'autres formats de compression de texture disponibles sur vos appareils cibles. Une méthode d'affichage de textures de canaux alpha à l'aide d'ETC1 consiste à lier deux objets de texture ETC1: le premier avec des données de couleur, le second avec des données de canal alpha, puis à combiner les valeurs des deux textures dans le nuanceur de fragments.
La disponibilité des formats de compression de texture ETC2/EAC est garantie lorsque vous utilisez l'API OpenGL ES 3.0. Ce format de texture offre d'excellents taux de compression avec une haute qualité visuelle. Le format prend également en charge la transparence (canal alpha).
Au-delà des formats ETC, les appareils Android offrent une compatibilité différente pour la compression de texture en fonction de leurs chipsets GPU et de leurs implémentations OpenGL. Vous devez étudier la prise en charge de la compression de texture sur les appareils que vous ciblez pour déterminer les types de compression que votre application doit prendre en charge. Pour déterminer les formats de texture compatibles avec un appareil donné, vous devez interroger l'appareil et examiner les noms des extensions OpenGL, qui identifient les formats de compression de texture (et les autres fonctionnalités OpenGL) compatibles avec l'appareil. Voici quelques formats de compression de texture couramment acceptés:
- Adaptable Scalable Texture Compression (ASTC) : format de compression de texture conçu pour remplacer les formats précédents. Plus flexible que les formats précédents en raison de la prise en charge de différentes tailles de bloc.
GL_KHR_texture_compression_astc_ldr
GL_KHR_texture_compression_astc_hdr
(plage dynamique élevée)
- S3TC (DXTn/DXTC) : la compression de texture S3 (S3TC) présente plusieurs variantes de format (DXT1 à DXT5) et est moins largement disponible. Le format accepte les textures RVB avec des canaux alpha 4 bits ou 8 bits. Ces formats sont représentés par le nom d'extension OpenGL suivant :
GL_EXT_texture_compression_s3tc
GL_EXT_texture_compression_dxt1
Les formats de compression de texture suivants sont considérés comme d'anciens formats et ne sont pas recommandés pour de nouvelles applications:
- ATITC (ATC) : la compression de texture ATI (ATITC ou ATC) est disponible sur une grande variété d'appareils et est compatible avec la compression à taux fixe pour les textures RVB avec et sans canal alpha. Ce format peut être représenté par plusieurs noms d'extension OpenGL, par exemple :
GL_AMD_compressed_ATC_texture
GL_ATI_texture_compression_atitc
- PVRTC : la compression de texture PowerVR (PVRTC) est disponible sur une grande variété d'appareils et est compatible avec les textures 2 bits et 4 bits par pixel, avec ou sans canal alpha.
Ce format est représenté par le nom d'extension OpenGL suivant :
GL_IMG_texture_compression_pvrtc
- 3DC : la compression de texture 3DC (3DC) est un format moins largement disponible qui prend en charge les textures RVB avec un canal alpha. Ce format est représenté par le nom d'extension OpenGL suivant :
GL_AMD_compressed_3DC_texture
Avertissement:Ces formats de compression de texture ne sont pas compatibles avec tous les appareils. La prise en charge de ces formats peut varier selon le fabricant et l'appareil. Pour savoir comment déterminer les formats de compression de texture sur un appareil particulier, consultez la section suivante.
Remarque:Une fois que vous avez choisi les formats de compression de texture compatibles avec votre application, veillez à les déclarer dans votre fichier manifeste à l'aide de <supports-gl-texture> . L'utilisation de cette déclaration permet de filtrer par services externes tels que Google Play, afin que votre application ne soit installée que sur les appareils compatibles avec les formats requis. Pour en savoir plus, consultez la section Déclarations de fichier manifeste OpenGL.
Déterminer les extensions OpenGL
Les implémentations d'OpenGL varient selon l'appareil Android en termes d'extensions compatibles avec l'API OpenGL ES. Ces extensions incluent des compressions de texture, mais elles incluent généralement d'autres extensions à l'ensemble de fonctionnalités OpenGL.
Pour déterminer les formats de compression de texture et les autres extensions OpenGL compatibles avec un appareil particulier:
- Exécutez le code suivant sur vos appareils cibles pour déterminer les formats de compression de texture acceptés:
Kotlin
var extensions = gl.glGetString(GL10.GL_EXTENSIONS)
Java
String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
Avertissement:Les résultats de cet appel varient selon le modèle de l'appareil. Vous devez exécuter cet appel sur plusieurs appareils cibles pour déterminer les types de compression couramment acceptés.
- Examinez le résultat de cette méthode pour déterminer quelles extensions OpenGL sont compatibles avec l'appareil.
Pack d'extensions Android (AEP)
L'AEP garantit que votre application est compatible avec un ensemble standardisé d'extensions OpenGL, en plus de l'ensemble de base décrit dans la spécification OpenGL 3.1. Le packaging de ces extensions favorise un ensemble cohérent de fonctionnalités sur tous les appareils, tout en permettant aux développeurs de tirer pleinement parti de la dernière génération d'appareils mobiles GPU.
L'AEP améliore également la prise en charge des images, des tampons de stockage des nuanceurs et des compteurs atomiques dans les nuanceurs de fragments.
Pour que votre application puisse utiliser l'AEP, le fichier manifeste de l'application doit déclarer que l'AEP est obligatoire. De plus, la version de la plate-forme doit être compatible.
Toutes les fonctionnalités supplémentaires spécifiées dans l'AEP sont incluses dans la spécification OpenGL ES 3.2 de base. Si votre application nécessite OpenGL ES 3.2, vous n'avez pas besoin d'AEP.
Déclarez l'exigence AEP dans le fichier manifeste comme suit:
<uses-feature android:name="android.hardware.opengles.aep" android:required="true" />
Pour vérifier que la version de la plate-forme est compatible avec l'AEP, utilisez la méthode hasSystemFeature(String)
, en transmettant FEATURE_OPENGLES_EXTENSION_PACK
comme argument. L'extrait de code suivant montre comment procéder:
Kotlin
var deviceSupportsAEP: Boolean = packageManager.hasSystemFeature(PackageManager.FEATURE_OPENGLES_EXTENSION_PACK)
Java
boolean deviceSupportsAEP = getPackageManager().hasSystemFeature (PackageManager.FEATURE_OPENGLES_EXTENSION_PACK);
Si la méthode renvoie la valeur "true", AEP est pris en charge.
Pour en savoir plus sur l'AEP, consultez sa page dans le registre Khronos OpenGL ES.
Vérifier la version d'OpenGL ES
Plusieurs versions d'OpenGL ES sont disponibles sur les appareils Android. Vous pouvez spécifier la version minimale de l'API requise par votre application dans votre fichier manifeste, mais vous pouvez également profiter des fonctionnalités d'une API plus récente. Par exemple, l'API OpenGL ES 3.0 est rétrocompatible avec la version 2.0 de l'API. Vous pouvez donc écrire votre application de sorte qu'elle utilise les fonctionnalités OpenGL ES 3.0, mais qu'elle utilise l'API 2.0 si l'API 3.0 n'est pas disponible.
Avant d'utiliser les fonctionnalités d'OpenGL ES à partir d'une version supérieure à la version minimale requise dans le fichier manifeste de votre application, celle-ci doit vérifier la version de l'API disponible sur l'appareil. Pour cela, deux possibilités s'offrent à vous :
- Essayez de créer le contexte OpenGL ES de niveau supérieur (
EGLContext
) et vérifiez le résultat. - Créez un contexte OpenGL ES compatible avec la version minimale et vérifiez la valeur de la version.
L'exemple de code suivant montre comment vérifier la version d'OpenGL ES disponible en créant un EGLContext
et en vérifiant le résultat. Cet exemple montre comment vérifier la version d'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; } }
Si la méthode createContext()
ci-dessus renvoie la valeur "null", votre code doit créer un contexte OpenGL ES 2.0 et utiliser uniquement cette API.
L'exemple de code suivant montre comment vérifier la version d'OpenGL ES en créant d'abord un contexte minimal compatible, puis en vérifiant la chaîne de version:
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.
Avec cette approche, si vous découvrez que l'appareil est compatible avec une version d'API de niveau supérieur, vous devez détruire le contexte OpenGL ES minimal et créer un contexte avec la version d'API supérieure disponible.
Choisir une version d'API OpenGL
Les versions 2.0 et 3.0 d'OpenGL ES fournissent toutes deux des interfaces graphiques hautes performances pour la création de jeux, de visualisations et d'interfaces utilisateur en 3D. La programmation graphique pour OpenGL ES 2.0 et 3.0 est très similaire, la version 3.0 représentant un sur-ensemble de l'API 2.0 avec des fonctionnalités supplémentaires. La programmation de l'API OpenGL ES 1.0/1.1 et d'OpenGL ES 2.0 et 3.0 diffère considérablement et n'est pas recommandée pour les nouvelles applications. Les développeurs doivent prendre en compte les facteurs suivants avant de commencer le développement avec ces API:
- Compatibilité des appareils : les développeurs doivent prendre en compte les types d'appareils, les versions d'Android et les versions d'OpenGL ES disponibles pour leurs clients. Pour en savoir plus sur la compatibilité d'OpenGL entre les appareils, consultez la section Versions OpenGL et compatibilité des appareils.
- Prise en charge des textures : l'API OpenGL ES 3.0 offre la meilleure prise en charge de la compression de texture, car elle garantit la disponibilité du format de compression ETC2, qui prend en charge la transparence. Les implémentations de l'API 2.0 sont compatibles avec ETC1, mais ce format de texture n'est pas compatible avec la transparence. Pour implémenter la transparence avec des textures compressées, vous devez soit utiliser deux textures ETC1 (répartition entre couleur et alpha) ou fournir des ressources dans d'autres formats de compression compatibles avec les appareils que vous ciblez. Pour en savoir plus, consultez Compatibilité avec la compression de texture.
Bien que la compatibilité et la prise en charge des textures puissent influencer votre décision, vous devez choisir une version d'API OpenGL en fonction de ce qui, selon vous, offre la meilleure expérience à vos utilisateurs.