Android obsługuje wysoką wydajność grafiki 2D i 3D dzięki Open Graphics Library. (OpenGL®), a w szczególności z interfejsu OpenGL ES API. OpenGL to wieloplatformowy interfejs API graficzny, który określa standardowy interfejs oprogramowania dla procesora graficznego 3D. OpenGL ES to rodzaj interfejsu OpenGL specyfikacja przeznaczona dla urządzeń umieszczonych na stronie. Android obsługuje kilka wersji OpenGL ES Interfejs API:
- OpenGL ES 2.0 – ta specyfikacja interfejsu API jest obsługiwana w systemie Android 2.2 (poziom API 8) i nowszym.
- OpenGL ES 3.0 – ta specyfikacja interfejsu API jest obsługiwana w Androidzie 4.3 (poziom API 18) i nowszym.
- OpenGL ES 3.1 – ta specyfikacja interfejsu API jest obsługiwana przez Androida 5.0 (poziom API 21) i nowsze wersje.
- OpenGL ES 3.2 – ta specyfikacja interfejsu API jest obsługiwana w Androidzie 7.0 (poziom API 24) i nowszych.
Uwaga: Urządzenie bez względu na wersję platformy Androida nie obsługuje interfejsu API OpenGL ES 3.0, chyba że producent urządzenia udostępnia wdrożenia tego potoku graficznego. Jeśli w pliku manifestu wskażesz, że Wymagany jest interfejs OpenGL ES 3.0 – możesz mieć pewność, że ta wersja będzie dostępna na urządzeniu. Jeśli określisz, że wymagana jest wersja niższego poziomu, ale Jeśli chcesz używać funkcji w wersji 3.0, jeśli są dostępne, sprawdź w czasie działania aby sprawdzić, jaką wersję OpenGL obsługuje urządzenie. Dowiedz się, jak jak to zrobić, zobacz Sprawdzanie wersji OpenGL ES.
Uwaga: Android obsługuje standard OpenGL ES 1.0 i 1.1, ale te wersje interfejsu API są wycofane i nie powinny być używane przez nowoczesne aplikacje.
Uwaga: Konkretny interfejs API udostępniany przez platformę Androida jest podobny do interfejsu J2ME JSR239 OpenGL ES API. ale nie jest identyczna. Jeśli znasz specyfikację J2ME JSR239, zwróć uwagę na odmian.
Patrz też
- Wyświetlanie grafiki przez OpenGL ES
- OpenGL ES
- Specyfikacja OpenGL ES 2.x
- Specyfikacja OpenGL ES 3.x
Podstawy
Android obsługuje OpenGL zarówno przez interfejs API platformy, jak i środowisko programistyczne Zestaw (NDK). Ta część koncentruje się na interfejsach platformy Android. Więcej informacji na temat NDK: zobacz pakiet Android NDK.
Na platformie Androida są 2 podstawowe klasy, które umożliwiają tworzenie i manipulowanie
grafika z interfejsem OpenGL ES API: GLSurfaceView
i
GLSurfaceView.Renderer
Jeśli chcesz używać trybu OpenGL w aplikacji na Androida,
Twoim pierwszym celem będzie zrozumienie, jak wdrożyć te zajęcia w ćwiczeniu.
GLSurfaceView
- Ta klasa to
View
, w której możesz rysować i manipulować obiektami za pomocą Interfejs OpenGL API wywołuje i działa podobnie doSurfaceView
. Za pomocą tę klasę, tworząc instancjęGLSurfaceView
i dodającRenderer
. Jeśli jednak chcesz przechwytywać zdarzeń na ekranie dotykowym, rozszerz klasęGLSurfaceView
na jak zaimplementować detektory dotykowe, jak pokazano na lekcji dotyczącej trenowania OpenGL, Reagowanie na zdarzenia dotknięcia GLSurfaceView.Renderer
- Ten interfejs definiuje metody wymagane do rysowania grafiki w
GLSurfaceView
. Należy zapewnić implementację tego interfejsu jako oddziel klasę i dołącz ją do instancjiGLSurfaceView
za pomocąGLSurfaceView.setRenderer()
Interfejs
GLSurfaceView.Renderer
wymaga zaimplementowania następujące metody:-
onSurfaceCreated()
: system nazywa to raz podczas tworzeniaGLSurfaceView
. Użyj tej metody, aby wykonać czynności, które trzeba wykonać tylko raz, takich jak ustawienie parametrów środowiska OpenGL lub inicjowanie obiektów graficznych OpenGL. -
onDrawFrame()
: system wywołuje tę metodę przy każdym ponownym odczytaniuGLSurfaceView
. Użyj tej metody jako głównego punktu wykonywania dla przez rysowanie (i ponowne rysowanie) obiektów graficznych. -
onSurfaceChanged()
: system wywołuje tę metodę, gdy zmieni się geometriaGLSurfaceView
, w tym rozmiarGLSurfaceView
lub orientację ekranu urządzenia. Na przykład wywołania systemowe tej metody, gdy orientacja urządzenia zmieni się z pionowej na poziomą. Użyj tej metody, aby: reagować na zmiany w kontenerzeGLSurfaceView
.
-
Pakiety OpenGL ES
Po utworzeniu widoku kontenera dla OpenGL ES za pomocą interfejsów GLSurfaceView
i GLSurfaceView.Renderer
można rozpocząć
interfejsów API OpenGL do wywoływania za pomocą tych klas:
- Klasa interfejsu API OpenGL ES 2.0
android.opengl.GLES20
– ten pakiet zawiera: interfejsu OpenGL ES 2.0 i jest dostępny od Androida 2.2 (poziom API 8).
- Pakiety interfejsów API OpenGL ES 3.0/3.1/3.2
android.opengl
– ten pakiet udostępnia interfejs OpenGL ES 3.0/3.1. zajęcia. Dostępna jest wersja 3.0 od Androida 4.3 (poziom API 18). Dostępna jest wersja 3.1 począwszy od Androida 5.0 (poziom interfejsu API 21). Dostępna jest wersja 3.2 od Androida 7.0 (interfejs API) na poziomie 24).
Jeśli chcesz od razu zacząć tworzyć aplikację z użyciem OpenGL ES, wykonaj Wyświetlanie grafiki przez OpenGL ES zajęcia.
Deklarowanie wymagań dotyczących OpenGL
Jeśli aplikacja korzysta z funkcji OpenGL, które nie są dostępne na wszystkich urządzeniach, musisz dodać parametr te wymagania w pliku AndroidManifest.xml . Oto najpopularniejsze deklaracje w pliku manifestu OpenGL:
- Wymagania dotyczące wersji OpenGL ES – jeśli aplikacja wymaga określonego
wersja
OpenGL ES, musisz zadeklarować to wymaganie, dodając do pliku manifestu następujące ustawienia jako:
poniżej.
OpenGL ES 2.0:
<!-- Tell the system this app requires OpenGL ES 2.0. --> <uses-feature android:glEsVersion="0x00020000" android:required="true" />
Jeśli dodasz tę deklarację, Google Play ograniczy możliwość instalowane na urządzeniach, które nie obsługują OpenGL ES 2.0. Jeśli aplikacja jest przeznaczona wyłącznie obsługujące OpenGL ES 3.0, możesz też określić to w pliku manifestu:
OpenGL ES 3.0:
<!-- Tell the system this app requires OpenGL ES 3.0. --> <uses-feature android:glEsVersion="0x00030000" android:required="true" />
OpenGL ES 3.1:
<!-- Tell the system this app requires OpenGL ES 3.1. --> <uses-feature android:glEsVersion="0x00030001" android:required="true" />
OpenGL ES 3.2:
<!-- Tell the system this app requires OpenGL ES 3.2. --> <uses-feature android:glEsVersion="0x00030002" android:required="true" />
Uwaga: Interfejs API OpenGL ES 3.x jest zgodny wstecznie z interfejsem API 2.0, co oznacza, że w sposób elastyczny podczas implementacji standardu OpenGL ES w aplikacji. Przez zadeklarowanie trybu OpenGL Interfejs ES 2.0 API jest wymagany w pliku manifestu. Możesz używać tej wersji interfejsu API jako domyślnego. Sprawdź , aby sprawdzić dostępność interfejsu API 3.x w czasie działania, a następnie użyj funkcji OpenGL ES 3.x, jeśli urządzenie ją obsługuje. Aby dowiedzieć się więcej o sprawdzaniu wersji OpenGL ES obsługiwanej przez urządzenia, zobacz Sprawdzanie wersji OpenGL ES.
- Wymagania dotyczące kompresji tekstur – jeśli aplikacja używa tekstury.
formatów kompresji, w pliku manifestu musisz zadeklarować formaty obsługiwane przez aplikację
za pomocą
<supports-gl-texture>
. Aby uzyskać więcej informacji o dostępnej kompresji tekstur formatów: patrz Obsługa kompresji tekstur.Zadeklarowanie w pliku manifestu wymagań dotyczących kompresji tekstur ukrywa aplikację przed użytkownikami z urządzeniami, które nie obsługują co najmniej jednego z zadeklarowanych przez Ciebie typów kompresji. Więcej o tym, jak działa filtrowanie w Google Play pod kątem kompresji tekstur, znajdziesz w Sekcja Google Play i filtrowanie kompresji tekstur w dokumentacji
<supports-gl-texture>
.
Mapowanie współrzędnych rysowanych obiektów
Jednym z podstawowych problemów z wyświetlaniem grafiki na urządzeniach z Androidem jest to, że mogą różnią się rozmiarem i kształtem. OpenGL zakłada kwadrat, jednolity układ współrzędnych i, domyślnie, rysuje te współrzędne na ekranie, który zazwyczaj nie jest kwadratowy, tak jakby był on idealnie kwadratowy.
Ilustracja powyżej przedstawia jednolity układ współrzędnych przyjęty dla klatki OpenGL na od lewej oraz jak te współrzędne mapują się na ekran typowego urządzenia w orientacji poziomej, po prawej. Aby rozwiązać ten problem, można zastosować tryby projekcji OpenGL i widoki kamery można przekształcić współrzędne tak, aby obiekty graficzne miały prawidłowe proporcje na każdym wyświetlaczu.
Aby zastosować projekcję i widoki z kamery, należy utworzyć macierz projekcji i widok z kamery i zastosować je w potoku renderowania OpenGL. Macierz projekcji ponownie oblicza współrzędne grafiki, aby były prawidłowo mapowane na ekrany urządzeń z systemem Android. Widok z kamery tworzy przekształcenie, które renderuje obiekty z określonej pozycji oka.
Projekcja i obraz z kamery w OpenGL ES 2.0 i nowszych
W interfejsach API ES 2.0 i 3.0 możesz zastosować projekcję i widok z kamery, najpierw dodając element matrycy. do cieniowania wierzchołków obiektów graficznych. Po dodaniu tego elementu macierzy generować i stosować macierze projekcji i obrazu z kamery do swoich obiektów.
- Dodaj macierz do cieniowania wierzchołków – utwórz zmienną do macierzy projekcji widoku.
i uwzględnić go jako mnożnik pozycji cieniowania. Moduł cieniowania wierzchołków poniżej
kod, dołączony użytkownik
uMVPMatrix
umożliwia korzystanie z funkcji projekcji i oglądania z kamery macierze ze współrzędnymi obiektów korzystających z tego cieniowania.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";
Uwaga: przykład powyżej definiuje jedną macierz przekształceń w cieniowaniu wierzchołków, do którego stosujesz połączoną matrycę projekcji i obraz z kamery. lub macierz. W zależności od wymagań aplikacji możesz zdefiniować osobną prognozę elementy macierzy i matrycy kamery w cieniowaniu wierzchołków, aby można je było zmieniać dzięki czemu mogą pracować niezależnie.
- Otwórz macierz cieniowania – po utworzeniu w maszynie cieniowania wierzchołków
za pomocą projekcji i widoku kamery, można uzyskać dostęp do tej zmiennej, aby zastosować projekcję.
i matryc obrazu. Ten kod pokazuje, jak zmodyfikować metodę
onSurfaceCreated()
implementacjiGLSurfaceView.Renderer
, aby uzyskać dostęp do macierzy zdefiniowaną powyżej w module cieniowania wierzchołków.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"); ... }
- Utwórz macierze obrazu i projekcji – wygeneruj projekcję i
macierze wyświetlania i zastosowania obiektów graficznych. Poniższy przykładowy kod pokazuje, jak zmodyfikować
onSurfaceCreated()
ionSurfaceChanged()
metod implementacjiGLSurfaceView.Renderer
do tworzenia macierzy obrazu z kamery oraz macierz projekcyjną opartą na współczynniku proporcji ekranu urządzenia.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); }
- Zastosuj projekcję i matryce obrazu – aby zastosować projekcję i
przekształceń widoku z kamery, pomnóż macierze przez siebie i umieść je w wierzchołku
program do cieniowania. Ten przykładowy kod pokazuje, jak można połączyć metodę
onDrawFrame()
implementacjiGLSurfaceView.Renderer
macierz projekcyjną i widok kamery utworzone w powyższym kodzie, a następnie zastosuj je do grafiki. obiektów do renderowania przez 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 ... }
Pełen przykład zastosowania projekcji i widoku z kamery w środowisku OpenGL ES 2.0 znajdziesz w artykule Wyświetlanie grafiki w interfejsie OpenGL ES. zajęcia.
Kształt twarzy i skrętów
W systemie OpenGL ściana kształtu to powierzchnia definiowana przez trzy lub więcej punktów w trójwymiarowym widoku kosmosu. Zestaw trzech lub więcej trójwymiarowych punktów (w interfejsie OpenGL nazywany wierzchołkami) ma przednią ścianę. i twarz z tyłu. Skąd wiadomo, która twarz jest z przodu, a która z tyłu? Dobre pytanie. odpowiedź dotyczy zawinięcia, czyli kierunku, w którym definiuje się punkty kształtu.
W tym przykładzie punkty na trójkącie zostały określone w takiej kolejności, aby zostały narysowane w lewo. Kolejność rysowania tych współrzędnych określa zwinięcie kierunek kształtu. Domyślnie w trybie OpenGL twarz rysowana w lewo jest przednią. Trójkąt widoczny na Rysunku 1 jest zdefiniowany tak, aby patrzeć na przednią stronę kształt (zinterpretowany przez OpenGL), a druga strona to tylna ściana.
Dlaczego ważne jest, aby wiedzieć, która ściana kształtu jest przednia? Odpowiedź dotyczy często używana funkcja OpenGL zwana zbieraniem twarzy. Strukcje twarzy są dostępne dla trybu OpenGL. które pozwala potokowi renderowania zignorować (a nie obliczyć ani narysować) tylnej strony kształt, oszczędzanie czasu, pamięci i cykle przetwarzania:
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);
Jeśli próbujesz użyć funkcji zaznaczania twarzy, nie wiedząc, po których stronach kształtów Jeśli przód i tył, i z tyłu są wyświetlane, grafika OpenGL będzie nieco cienka lub może w ogóle nie będzie widoczna. Zatem zawsze definiuj współrzędne kształtów OpenGL w kolejności rysowania w kierunku przeciwnym do ruchu wskazówek zegara.
Uwaga: można ustawić środowisko OpenGL w taki sposób, aby traktowało twarzy w kierunku zgodnym z ruchem wskazówek zegara, ale wymaga to więcej kodu i może dezorientować. programistów OpenGL, jeśli chcesz ich poprosić o pomoc. Dlatego nie rób tego.
Wersje OpenGL i zgodność urządzeń
Specyfikacje interfejsu API OpenGL ES 1.0 i 1.1 są obsługiwane od Androida 1.0. Programowanie graficzne przy użyciu interfejsu API OpenGL ES 1.0/1.1 znacznie się różni od interfejsu API 2.0 i wyższych. OpenGL ES 2.0 jest obsługiwany przez wszystkie urządzenia z Androidem 2.2 (poziom interfejsu API 8) i jest najwcześniejsza wersja zalecana dla nowych aplikacji tworzonych przy użyciu OpenGL ES. OpenGL ES 3.0 jest obsługiwany w systemie Android 4.3 (poziom interfejsu API 18) lub nowszym na urządzeniach, które zapewniają i wdrożyć interfejs API OpenGL ES 3.0. Informacje o względnej liczbie urządzeń z Androidem obsługujące daną wersję OpenGL ES, zapoznaj się z sekcją Panel wersji OpenGL ES.
Uważnie rozważ wymagania dotyczące grafiki i wybierz interfejs API która będzie najlepsza dla Twojej aplikacji. Więcej informacji: Wybór wersji interfejsu API OpenGL.
Interfejs OpenGL ES 3.0 API oferuje dodatkowe funkcje i zapewnia lepszą wydajność niż interfejs API 2.0. również zgodne wstecznie. Oznacza to, że można określić kierowanie na aplikację, standardu OpenGL ES 2.0 i warunkowo uwzględniaj funkcje graficzne OpenGL ES 3.0, jeśli są dostępne. Dla: więcej informacji na temat sprawdzania dostępności interfejsu API 3.0 znajdziesz w artykule Sprawdzanie wersji OpenGL ES
Obsługa kompresji tekstur
Kompresja tekstur może znacznie zwiększyć wydajność aplikacji OpenGL przez
zmniejsza wymagania dotyczące pamięci i efektywniej wykorzystuje przepustowość pamięci. Android
zapewnia obsługę formatu kompresji ETC1 jako standardowej funkcji,
klasy użytkowej ETC1Util
i narzędzie do kompresji etc1tool
(znajdujące się w
SDK dla Androida na stronie <sdk>/tools/
). Oto przykład aplikacji na Androida, która używa
kompresję tekstur, zobacz przykładowy kod CompressedTextureActivity
w pakiecie SDK na Androida
(<sdk>/samples/<version>/ApiDemos/src/com/example/android/apis/graphics/
).
Format ETC1 jest obsługiwany przez wszystkie urządzenia z Androidem, które obsługują standard OpenGL ES 2.0 lub nowszy.
Uwaga: format kompresji tekstur ETC1 nie obsługuje tekstur ze znakiem przezroczystość (kanał alfa). Jeśli Twoja aplikacja wymaga tekstur z przezroczystością, zbadania innych formatów kompresji tekstur dostępnych na urządzeniach docelowych. O Metodą renderowania tekstur kanału alfa przy użyciu ETC1 jest powiązanie dwóch obiektów tekstur ETC1: najpierw danymi o kolorze, drugi z danymi kanału alfa, a następnie połączyć wartości z obu możesz użyć funkcji cieniowania fragmentów.
Formaty kompresji tekstur ETC2/EAC będą dostępne podczas korzystania z interfejsu OpenGL ES 3.0 API. Ten format tekstur zapewnia znakomite współczynniki kompresji oraz wysoką jakość obrazu obsługuje też przezroczystość (kanał alfa).
Oprócz formatów ETC urządzenia z Androidem obsługują różne funkcje kompresji tekstur, oparte na chipsety GPU i implementacje OpenGL. Zalecamy sprawdzenie obsługi kompresji tekstur na na urządzenia, na które jest kierowana aplikacja, w celu określenia typów kompresji . Aby określić, które formaty tekstur są obsługiwane przez dane urządzenie, należy Wyślij zapytanie do urządzenia i sprawdź nazwy rozszerzeń OpenGL. określające formaty kompresji tekstur (oraz inne funkcje OpenGL) obsługiwane przez urządzenia. Oto niektóre powszechnie obsługiwane formaty kompresji tekstur:
- Adaptable Scalable Texture Compression (ASTC) – format kompresji tekstur.
która ma zastąpić wcześniejsze formaty. Większa elastyczność w porównaniu z wcześniejszymi formatami dzięki obsłudze różnych
bloki.
GL_KHR_texture_compression_astc_ldr
GL_KHR_texture_compression_astc_hdr
(wysoki zakres dynamiczny)
- S3TC (DXTn/DXTC) – kompresja tekstur S3 (S3TC) obejmuje kilka
(od DXT1 do DXT5) i jest mniej powszechnie dostępna. Format obsługuje tekstury RGB z
4- lub 8-bitowy kanał alfa. Te formaty są reprezentowane przez następujące rozszerzenie OpenGL
nazwa:
GL_EXT_texture_compression_s3tc
GL_EXT_texture_compression_dxt1
Poniższe formaty kompresji tekstur są uważane za formaty starszego typu i nie są zalecane do wykorzystania w nowych aplikacjach:
- ATITC (ATC) – kompresja tekstur ATI (ATITC lub ATC) jest dostępna
szeroki wybór urządzeń i obsługuje stałą szybkość kompresji tekstur RGB z i bez
kanału alfa. Ten format może być reprezentowany przez kilka nazw rozszerzeń OpenGL, na przykład:
GL_AMD_compressed_ATC_texture
GL_ATI_texture_compression_atitc
- PVRTC – kompresja tekstury PowerVR (PVRTC) jest dostępna w
różnych urządzeń oraz obsługuje tekstury 2-bitowe i 4-bitowe na piksel z kanałem alfa lub bez niego.
Jest on reprezentowany przez następującą nazwę rozszerzenia OpenGL:
GL_IMG_texture_compression_pvrtc
- 3DC – kompresja tekstury 3DC (3DC) to mniej powszechnie dostępny format,
obsługuje tekstury RGB z kanałem alfa. Format jest reprezentowany przez następujące tryby OpenGL
nazwa rozszerzenia:
GL_AMD_compressed_3DC_texture
Ostrzeżenie: te formaty kompresji tekstur nie są obsługiwane na wszystkich urządzeniach. Obsługa tych formatów może się różnić w zależności od producenta i urządzenia. Dla: jak określić formaty kompresji tekstur na danym urządzeniu, zobacz przejdź do następnej sekcji.
Uwaga: gdy już wybierzesz formaty kompresji tekstur aplikacji, upewnij się, że są one zadeklarowane w pliku manifestu za pomocą polecenia <supports-gl-texture> Użycie tej deklaracji umożliwia filtrowanie według usług zewnętrznych, takich jak Google Play, i pozwala aplikacja jest instalowana tylko na urządzeniach, które obsługują formaty wymagane przez aplikację. Więcej informacji: Deklaracje w pliku manifestu OpenGL.
Określanie rozszerzeń OpenGL
Implementacje standardu OpenGL różnią się w zależności od urządzenia z Androidem, jeśli chodzi o rozszerzenia interfejsu API OpenGL ES. które są obsługiwane. Te rozszerzenia obejmują kompresję tekstury, ale zwykle obejmują też inne do zestawu funkcji OpenGL.
Aby określić, które formaty kompresji tekstur i inne rozszerzenia OpenGL są obsługiwane w konkretne urządzenie:
- Uruchom poniższy kod na urządzeniach docelowych, aby określić stopień kompresji tekstur
obsługiwane formaty:
Kotlin
var extensions = gl.glGetString(GL10.GL_EXTENSIONS)
Java
String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
Ostrzeżenie: wyniki tego wywołania różnią się w zależności od modelu urządzenia. Ty należy uruchomić to wywołanie na kilku urządzeniach docelowych, aby określić typowe typy kompresji obsługiwane.
- Sprawdź wynik działania tej metody, aby określić, które rozszerzenia OpenGL są obsługiwane na urządzenia.
Pakiet rozszerzeń do Androida (AEP)
AEP zapewnia, że aplikacja obsługuje ustandaryzowany zestaw rozszerzeń OpenGL wymienionych powyżej i nie tylko zestawu podstawowego opisanego w specyfikacji OpenGL 3.1. Pakowanie tych rozszerzeń w jednym miejscu tworzy spójny zestaw funkcji na różnych urządzeniach, pozwalając jednocześnie programistom w pełni wykorzystać potencjał urządzeń mobilnych z GPU.
Poprawia również obsługę obrazów, buforów pamięci masowej cieniowania i liczników atomowych w cieniowanie fragmentów.
Aby aplikacja mogła korzystać z interfejsu AEP, jej plik manifestu musi zawierać deklarację, że jest ono wymagane. Dodatkowo musi go obsługiwać wersja platformy.
Wszystkie dodatkowe funkcje określone w narzędziu AEP są dostępne w podstawowej wersji OpenGL ES 3.2. specyfikacji. Jeśli aplikacja wymaga OpenGL ES 3.2, nie musisz wymagać AEP.
Zadeklaruj w pliku manifestu wymagania dotyczące AEP:
<uses-feature android:name="android.hardware.opengles.aep" android:required="true" />
Aby sprawdzić, czy wersja platformy obsługuje AEP, użyj
Metoda hasSystemFeature(String)
, przekazywanie danych
FEATURE_OPENGLES_EXTENSION_PACK
. Następujący fragment kodu:
Oto przykład:
Kotlin
var deviceSupportsAEP: Boolean = packageManager.hasSystemFeature(PackageManager.FEATURE_OPENGLES_EXTENSION_PACK)
Java
boolean deviceSupportsAEP = getPackageManager().hasSystemFeature (PackageManager.FEATURE_OPENGLES_EXTENSION_PACK);
Jeśli metoda zwraca wartość prawda, AEP jest obsługiwane.
Więcej informacji na temat programu AEP znajdziesz na jego stronie: Rejestr Khronos OpenGL ES.
Sprawdzam wersję OpenGL ES
Na urządzeniach z Androidem dostępnych jest kilka wersji OpenGL ES. Możesz określić minimalnej wersji interfejsu API wymaganej przez aplikację w pliku manifestu, ale możesz też jednocześnie korzystać z funkcji nowszych interfejsu API. Przykład: interfejs API OpenGL ES 3.0 jest zgodny wstecz z wersją 2.0, dlatego warto napisać aplikację w taki sposób, aby wykorzystywała funkcje OpenGL ES 3.0, ale wraca do interfejsu API 2.0, jeśli Interfejs API 3.0 jest niedostępny.
Przed użyciem funkcji OpenGL ES w wersji wyższej niż wymagana minimalna aplikacji manifestu, aplikacja powinna sprawdzić wersję interfejsu API dostępnego na urządzeniu. Możesz to zrobić na 2 sposoby:
- Spróbuj utworzyć kontekst OpenGL ES wyższego poziomu (
EGLContext
) oraz sprawdzić wynik. - Utwórz kontekst OpenGL ES obsługiwanego minimum i sprawdź wartość wersji.
Poniższy przykładowy kod pokazuje, jak sprawdzić dostępną wersję OpenGL ES przez utworzenie
EGLContext
i sprawdzam wynik. Ten przykład pokazuje, jak sprawdzić
Wersja 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; } }
Jeśli metoda createContext()
powyżej zwraca wartość null, kod powinien utworzyć OpenGL
ES 2.0 i przełącz się na używanie tylko tego interfejsu API.
Poniższy przykładowy kod pokazuje, jak sprawdzić wersję OpenGL ES przez utworzenie minimalnej wartości najpierw obsługiwany kontekst, a potem sprawdź ciąg znaków wersji:
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.
Przy tej metodzie, jeśli urządzenie obsługuje wyższe wersje interfejsu API, musi zniszczyć minimalny kontekst OpenGL ES i stworzyć nowy dostępnej wersji interfejsu API.
Wybór wersji interfejsu API OpenGL
Zarówno OpenGL ES w wersji 2.0, jak i 3.0 zapewniają wysokie interfejsów graficznych wydajności do tworzenia gier 3D, wizualizacji oraz interfejsów użytkownika. Grafika programowanie dla OpenGL ES 2.0 i 3.0 jest w dużym stopniu podobne, gdzie wersja 3.0 reprezentuje nadzbiór interfejsu API 2.0 z dodatkowymi funkcjami. Programowanie dla interfejsów API OpenGL ES 1.0/1.1 i OpenGL ES 2.0 i 3.0 znacznie się różnią i nie są zalecane w przypadku nowych aplikacji. Przed rozpoczęciem programowania deweloperzy powinni dokładnie wziąć pod uwagę poniższe czynniki. tych interfejsów API:
- Zgodność urządzeń – deweloperzy powinni wziąć pod uwagę typy urządzeń, Wersje Androida i wersje OpenGL ES dostępne dla klientów. Więcej informacji na temat konfiguracji zgodności z OpenGL na różnych urządzeniach, patrz wersje OpenGL urządzeń.
- Obsługa tekstur – interfejs API OpenGL ES 3.0 zapewnia najlepszą obsługę tekstur. kompresji, ponieważ gwarantuje ona dostępność formatu kompresji ETC2, który obsługuje i przejrzystością. Implementacje interfejsu API 2.0 obejmują obsługę ETC1, ale ten format tekstury nie obsługuje przezroczystości. Aby wdrożyć przezroczystość przy użyciu skompresowanego pliku dla tekstur należy użyć dwóch tekstur ETC1 (rozdzielonych na kolor i alfa) lub podać zasoby w innych formatach kompresji obsługiwanych przez urządzenia, na które kierujesz reklamy. Aby dowiedzieć się więcej, Więcej informacji znajdziesz w sekcji Obsługa kompresji tekstur.
Zgodność i obsługa tekstur może wpływać na decyzji, należy wybrać wersję interfejsu API OpenGL na podstawie tego, co uważasz za najlepsze. użytkowników.