Aby wyświetlać grafikę przy użyciu OpenGL ES w aplikacji na Androida, musisz utworzyć dla niej kontener widoku. Jednym z prostych sposobów jest zaimplementowanie zarówno GLSurfaceView
, jak i GLSurfaceView.Renderer
. GLSurfaceView
to kontener widoku dla grafik rysowanych w trybie OpenGL, a GLSurfaceView.Renderer
określa, co ma być rysowane w tym widoku. Więcej informacji o tych klasach znajdziesz w przewodniku dla programistów OpenGL ES.
GLSurfaceView
to tylko jeden ze sposobów dodania do aplikacji grafiki OpenGL ES. Dobrym pomysłem jest wyświetlenie grafiki na pełnym ekranie lub prawie na pełnym ekranie.
Deweloperzy, którzy chcą wykorzystywać grafikę OpenGL ES w niewielkiej części układów, powinni zapoznać się z TextureView
. Rzeczywiście programiści samodzielnie też mogą utworzyć widok OpenGL ES za pomocą SurfaceView
, ale wymaga to napisania sporo dodatkowego kodu.
Z tej lekcji dowiesz się, jak przeprowadzić minimalnie wdrożenie GLSurfaceView
i GLSurfaceView.Renderer
w ramach prostego działania w aplikacji.
Zadeklaruj użycie OpenGL ES w pliku manifestu
Aby aplikacja używała interfejsu OpenGL ES 2.0 API, musisz dodać do pliku manifestu tę deklarację:
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
Jeśli aplikacja korzysta z kompresji tekstur, musisz też zadeklarować, które formaty kompresji obsługuje ona, aby aplikacja była instalowana tylko na zgodnych urządzeniach.
<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" /> <supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />
Więcej informacji na temat formatów kompresji tekstur znajdziesz w przewodniku dla programistów OpenGL.
Utwórz aktywność dla grafiki OpenGL ES
W aplikacjach na Androida, które używają OpenGL ES, działania są takie same jak w przypadku każdej innej aplikacji, która ma interfejs. Główną różnicą od innych aplikacji jest to, co umieszczasz w układzie
aktywności. W wielu aplikacjach możesz używać TextView
, Button
i ListView
, ale w aplikacji, która używa OpenGL ES, możesz też dodać GLSurfaceView
.
Ten przykładowy kod przedstawia minimalną implementację działania, w którym głównym widokiem jest GLSurfaceView
:
Kotlin
class OpenGLES20Activity : Activity() { private lateinit var gLView: GLSurfaceView public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Create a GLSurfaceView instance and set it // as the ContentView for this Activity. gLView = MyGLSurfaceView(this) setContentView(gLView) } }
Java
public class OpenGLES20Activity extends Activity { private GLSurfaceView gLView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a GLSurfaceView instance and set it // as the ContentView for this Activity. gLView = new MyGLSurfaceView(this); setContentView(gLView); } }
Uwaga: OpenGL ES 2.0 wymaga Androida 2.2 (poziom interfejsu API 8) lub nowszego, więc upewnij się, że projekt Androida jest kierowany na ten interfejs API lub nowszy.
Tworzenie obiektu GLSurfaceView
GLSurfaceView
to specjalny widok, w którym można wyświetlać grafikę OpenGL ES.
Sama w sobie nie robi wiele. Rzeczywiste rysowanie obiektów jest określane w elemencie GLSurfaceView.Renderer
ustawionym w tym widoku. W rzeczywistości kod tego obiektu jest tak cienki, że może Cię interesować, by pominąć jego rozszerzenie i utworzyć niezmodyfikowaną instancję GLSurfaceView
, ale nie rób tego. Musisz rozszerzyć te zajęcia, aby rejestrować zdarzenia kliknięcia. Zostało to omówione w lekcji Reagowanie na zdarzenia dotknięcia.
Podstawowy kod dla obiektu GLSurfaceView
jest minimalny, więc w celu szybkiej implementacji często tworzy się w aktywności, która z niej korzysta, po prostu utworzyć klasę wewnętrzną:
Kotlin
import android.content.Context import android.opengl.GLSurfaceView class MyGLSurfaceView(context: Context) : GLSurfaceView(context) { private val renderer: MyGLRenderer init { // Create an OpenGL ES 2.0 context setEGLContextClientVersion(2) renderer = MyGLRenderer() // Set the Renderer for drawing on the GLSurfaceView setRenderer(renderer) } }
Java
import android.content.Context; import android.opengl.GLSurfaceView; class MyGLSurfaceView extends GLSurfaceView { private final MyGLRenderer renderer; public MyGLSurfaceView(Context context){ super(context); // Create an OpenGL ES 2.0 context setEGLContextClientVersion(2); renderer = new MyGLRenderer(); // Set the Renderer for drawing on the GLSurfaceView setRenderer(renderer); } }
Innym opcjonalnym dodatkiem do implementacji GLSurfaceView
jest skonfigurowanie trybu renderowania w taki sposób, aby rysował widok tylko wtedy, gdy w danych rysowania zmienią się za pomocą ustawienia GLSurfaceView.RENDERMODE_WHEN_DIRTY
:
Kotlin
// Render the view only when there is a change in the drawing data renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
Java
// Render the view only when there is a change in the drawing data setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
To ustawienie uniemożliwia ponowne przerysowanie ramki GLSurfaceView
, dopóki nie wywołasz funkcji requestRender()
, co jest skuteczniejsze w przypadku tej przykładowej aplikacji.
Tworzenie klasy mechanizmu renderowania
Sprawa zaczyna się interesująć dzięki implementacji klasy (lub mechanizmu renderowania) GLSurfaceView.Renderer
w aplikacji korzystającej z platformy OpenGL ES. Ta klasa określa, co jest rysowane w elemencie GLSurfaceView
, z którym jest powiązana. W mechanizmie renderowania Android stosuje się 3 metody, które system Android wywołuje, aby ustalić, co i jak narysować na GLSurfaceView
:
onSurfaceCreated()
– wywołano raz w celu skonfigurowania środowiska OpenGL ES widoku.onDrawFrame()
– wywoływane przy każdym powiększeniu widoku.onSurfaceChanged()
– wywoływane, gdy zmieni się geometria widoku, na przykład gdy zmieni się orientacja ekranu urządzenia.
Oto bardzo podstawowa implementacja mechanizmu renderowania OpenGL ES, który nie robi nic więcej niż rysowanie czarnego tła w interfejsie GLSurfaceView
:
Kotlin
import javax.microedition.khronos.egl.EGLConfig import javax.microedition.khronos.opengles.GL10 import android.opengl.GLES20 import android.opengl.GLSurfaceView class MyGLRenderer : GLSurfaceView.Renderer { override fun onSurfaceCreated(unused: GL10, config: EGLConfig) { // Set the background frame color GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f) } override fun onDrawFrame(unused: GL10) { // Redraw background color GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) } override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) { GLES20.glViewport(0, 0, width, height) } }
Java
import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLES20; import android.opengl.GLSurfaceView; public class MyGLRenderer implements GLSurfaceView.Renderer { public void onSurfaceCreated(GL10 unused, EGLConfig config) { // Set the background frame color GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); } public void onDrawFrame(GL10 unused) { // Redraw background color GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); } public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); } }
To wszystko. Powyższe przykłady kodu tworzą prostą aplikację na Androida, która wyświetla czarny ekran za pomocą OpenGL. Chociaż ten kod nie robi nic interesującego, tworzenie tych klas da Ci podstawy do rozpoczęcia rysowania elementów graficznych w OpenGL.
Uwaga: być może zastanawiasz się, dlaczego te metody mają parametr GL10
, gdy korzystasz z interfejsów API OpengGL ES 2.0.
Te podpisy metod są po prostu używane ponownie w interfejsach API 2.0, aby uprościć kod platformy Androida.
Jeśli znasz interfejsy API OpenGL ES, możesz teraz skonfigurować w aplikacji środowisko OpenGL ES i zacząć rysować grafikę. Jeśli jednak potrzebujesz dodatkowej pomocy, przejdź do następnych lekcji.