Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK
Code

Cara Menggunakan OpenGL ES di Android Aplikasi

by
Difficulty:AdvancedLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Yanti Baddolo (you can also view the original English article)

Hampir setiap ponsel Android yang tersedia di pasaran saat ini memiliki unit pengolahan grafis, atau GPU untuk jangka pendek. Seperti namanya, ini adalah unit perangkat keras yang didedikasikan untuk menangani perhitungan yang biasanya terkait dengan grafis 3D. Sebagai pengembang aplikasi, anda dapat menggunakan GPU untuk membuat grafik dan animasi kompleks yang berjalan pada frame rate yang sangat tinggi.

Saat ini ada dua API berbeda yang dapat anda gunakan untuk berinteraksi dengan GPU perangkat Android: Vulkan dan OpenGLES. Sementara Vulkan hanya tersedia pada perangkat yang menjalankan Android 7.0 atau lebih tinggi, OpenGL ES didukung oleh semua versi Android.

Dalam tutorial ini, saya akan membantu anda memulai dengan menggunakan OpenGL ES 2.0 di aplikasi Android.

Prasyarat

Untuk dapat mengikuti tutorial ini, anda memerlukan:

  • versi terbaru dari Android Studio
  • perangkat Android yang mendukung OpenGL ES 2.0 atau lebih tinggi
  • versi terbaru dari Blender, atau perangkat lunak pemodelan 3D lainnya

1. Apa itu OpenGL ES?

OpenGL, yang merupakan singkatan dari Open Graphics Library, adalah platform-independent API yang memungkinkan anda membuat grafis 3D yang dipercepat dengan hardware.OpenGL ES, singkatan dari OpenGL untuk Embedded Systems, adalah bagian dari API.

OpenGL ES adalah API tingkat rendah. Dengan kata lain, ia tidak menawarkan metode apa pun yang memungkinkan anda membuat atau memanipulasi objek 3D  dengan cepat. Sebagai gantinya, saat bekerja dengannya, anda diharapkan mengelola kerjaan secara manual seperti membuat simpul individu dan wajah benda 3D, menghitung berbagai transformasi 3D, dan menciptakan berbagai jenis shader.

Perlu juga disebutkan bahwa android SDK dan NDK bersama-sama memungkinkan anda menulis kode terkait OpenGL ES di Java dan C.

2.   Setup Proyek

Karena API OpenGL ES adalah bagian dari kerangka kerja Android, anda tidak perlu menambahkan ketergantungan pada proyek anda untuk dapat menggunakannya.  Dalam tutorial ini, bagaimanapun, kita akan menggunakan perpustakaan Apache Commons IO untuk membaca isi beberapa file teks. Karena itu, tambahkan ia sebagai ketergantungan compile pada module's build.gradle file:

Dalam tutorial ini, bagaimanapun, kita akan menggunakan perpustakaan Apache Commons IO untuk membaca isi beberapa file teks. Karena itu, tambahkan ia sebagai ketergantungan compile pada module's build.gradle file:

3.   Buat kanvas

Kerangka Android menawarkan dua widget yang dapat berfungsi sebagai kanvas untuk grafis 3D anda:   GLSurfaceView dan TextureView.  Kebanyakan pengembang lebih suka menggunakan  GLSurfaceView, dan memilih TextureView  hanya ketika mereka berniat untuk overlay grafis 3D mereka yang lain view widget. Untuk aplikasi yang akan kita buat di tutorial ini, GLSurfaceView akan cukup.

Menambahkan GLSurfaceView widget ke file layout anda tidak berbeda dengan menambahkan widget lainnya.

Perhatikan bahwa kita telah membuat lebar widget kita sama dengan tingginya. Melakukan hal ini penting karena sistem koordinat OpenGL ES berbentuk persegi Jika anda harus menggunakan kanvas persegi panjang, ingatlah untuk menyertakan rasio aspeknya saat menghitung matriks proyeksi anda. Anda akan mempelajari matriks proyeksi di langkah selanjutnya.

Inisialisasi GLSurfaceView widget di dalam sebuah Aktivitas kelasnya sesederhana memanggil findViewById()metode dan melewati iduntuk itu.

Selain itu, kita harus memanggil metode setEGLContextClientVersion() untuk secara eksplisit menentukan versi OpenGL ES yang akan kita gunakan untuk menggambar di dalam widget.

4.   Buat Objek 3D

Meskipun dimungkinkan untuk membuat objek 3D di Java dengan mengkodekan kordinat X, Y, dan Z dari semua simpulnya, hal itu sangat rumit. Menggunakan alat pemodelan 3D malah jauh lebih mudah. Menggunakan alat pemodelan 3D malah jauh lebih mudah. Blender adalah salah satu alat tersebut. Ia bersifat open source, powerful, dan sangat mudah dipelajari.

Jalankan Blender dan tekan untuk menghapus default cube. Selanjutnya, tekan Shift-A dan pilih Mesh> Torus. Kita sekarang memiliki objek 3D yang cukup kompleks yang terdiri dari 576 titik.

Torus in Blender

Agar bisa menggunakan torus di aplikasi Android kita, kita harus mengekspornya sebagai file OBJ Wavefront. Karena itu, pergi ke File> Export> Wavefront (obj). Pada layar berikutnya, beri nama pada file OBJ, pastikan bahwa Triangulate Faces dan pilihan Keep Order Vertex dipilih, dan tekan tombol Ekspor OBJ .

Exporting 3D object as Wavefront OBJ file

Anda sekarang dapat menutup Blender dan pindahkan fileOBJ ke folder Assest proyek Android Studio anda.

5.   Parsing File OBJ

Jika anda belum menyadarinya, file OBJ yang kami buat di langkah sebelumnya adalah file teks, yang bisa dibuka menggunakan editor teks apapun.

OBJ file opened with a text editor

Dalam file, setiap baris yang dimulai dengan "v" mewakili satu titik. Demikian pula, setiap baris yang dimulai dengan "f" mewakili satu wajah segitiga tunggal. Sementara masing-masing garis verteks berisi koordinat X, Y, dan Z dari sebuah simpul, masing-masing garis wajah berisi indeks tiga simpul, yang membentuk wajah bersama. Itu saja yang perlu anda ketahui untuk mengurai file OBJ. 

Sebelum memulai, buat kelas Java baru yang disebut Torus dan tambahkan dua Daftar objek, satu untuk simpul dan satu untuk wajah, sebagai variabel anggotanya.

Cara termudah untuk membaca semua baris individu dari file OBJ adalah dengan menggunakan kelas Scanner dan metode nextLine(). Sementara perulangan melalui garis dan mengisi dua daftar, anda dapat menggunakan kelas String metode startsWith() untuk memeriksa apakah baris saat ini dimulai dengan "v" atau "f".

6. Buat Objek Buffer

Anda tidak dapat melewati daftar simpul dan wajah dengan metode yang tersedia di OpenGL ES API secara langsung. Anda harus terlebih dahulu mengubahnya menjadi objek penyangga. Untuk menyimpan data koordinat vertex, kita memerlukan objek FloatBuffer. Untuk data wajah, yang hanya terdiri dari indeks simpul, objek ShortBuffer sudah cukup.

Dengan demikian, tambahkan variabel anggota berikut ke kelas Torus:

Untuk menginisialisasi buffer, pertama kita harus membuat obyekByteBuffer menggunakan metode allocateDirect (). Untuk buffer simpul, alokasikan empat byte untuk setiap koordinat, dengan koordinat bilangan floating-point. Setelah objek ByteBuffer telah dibuat, anda bisa mengubahnya menjadi FloatBuffer dengan memanggil metode  asFloatBuffer ().

Demikian juga, buat objek ByteBuffer lain untuk penyangga wajah. Kali ini, alokasikan dua byte untuk setiap indeks vertex karena indeksnya  unsigned short literal.  Juga, pastikan anda menggunakan metode asShortBuffer()  untuk mengubah objek ByteBuffer ke ShortBuffer.

Mengisi simpul simpul melibatkan perulangan melalui konten verticesList, penggalian X, Y, dan Z koordinat dari setiap item, dan memanggil metode Put() untuk memasukkan data ke dalam buffer. Karena  verticesList hanya berisi string, kita harus menggunakan parseFloat() untuk mengubah koordinat dari string ke nilai float.

Perhatikan bahwa dalam kode di atas kita telah menggunakan metode position()untuk mereset posisi buffer.

Mengisi wajah penyangga sedikit berbeda. Anda harus menggunakan metode parseShort() untuk mengubah setiap indeks vertex menjadi nilai pendek. Selain itu, karena indeks dimulai dari satu dan bukan nol, anda harus ingat untuk mengurangi satu dari mereka sebelum memasukkannya ke dalam buffer.

7.   Buat Shader

Untuk bisa membuat objek 3D kita, kita harus membuat vertex shader dan shader fragmen untuknya. Untuk saat ini, anda bisa memikirkan shader sebagai program yang sangat sederhana yang ditulis dalam bahasa mirip C yang disebut OpenGL Shading Language, atau GLSL untuk jangka pendek.

Sebuah shader vertex, seperti yang anda duga, bertanggung jawab untuk menangani simpul objek 3D. Shader fragmen, juga disebut pixel shader, bertanggung jawab untuk mewarnai piksel objek 3D.

Langkah 1: Buat Vertex Shader

Buat file baru yang disebut vertex_shader.txt di dalam forlder res/raw projek anda.

Sebuah vertex shader harus memiliki sebuah atribut variabel global di dalamnya untuk menerima data posisi vertex dari kode Java anda. Selain itu, tambahkan uniform variabel global untuk menerima matriks proyeksi tampilan dari kode Java.

Di dalam Fungsi main() vertex shader, anda harusmengatur nilai gl_position, sebuah GLSL built-invariabel yang menentukan posisi akhir vertex. Untuk saat ini, anda cukup mengatur nilainya ke produk uniform dan atribut variabel global.

Dengan demikian, tambahkan kode berikut ke file:

Langkah 2: Buat Shader Fragmen

Buat file baru yang disebut fragment_shader.txt di dalam forlder res/raw projek anda.

Agar tutorial singkat ini, sekarang kita akan membuat shader fragmen yang sangat minimalis yang hanya memberi warna oranye ke semua piksel. Untuk menetapkan warna ke piksel, di dalam Fungsi main()shader fragmen, anda bisa menggunakan gl_FragColor built-in variable.

Dalam kode di atas, baris pertama yang menentukan ketepatan bilangan floating-point penting karena shader fragmen tidak memiliki ketepatan standar untuk keduanya.

Langkah 3: Kompilasi Shader

Kembali di kelas Torus, anda sekarang harus menambahkan kode untuk mengkompilasi dua shader yang anda buat. Sebelum melakukannya, anda harus mengubahnya dari sumber daya mentah menjadi string.  Kelas IOUtils yang merupakan bagian dari perpustakaanApache Commons IO, memiliki metode toString() untuk melakukan hal itu. Kode berikut menunjukkan cara menggunakannya:

Kode shader harus ditambahkan ke objek shader OpenGL ES. Untuk membuat objek shader baru, gunakan metode glCreateShader()dari kelas GLES20 Bergantung pada jenis objek shader yang ingin anda buat, anda bisa lewat GL_VERTEX_SHADER   atau   GL_FRAGMENT_SHADER  untuk itu. Metode mengembalikan bilangan bulat yang berfungsi sebagai referensi ke objek shader.  Objek shader yang baru dibuat tidak mengandung kode apapun. Untuk menambahkan kode shader ke objek shader, anda harus menggunakan metode glShaderSource().

Kode berikut membuat objek shader untuk shader vertex dan shader fragmen:

Kita sekarang bisa melewati objek shader ke metode  glCompileShader() untuk mengkompilasi kode yang dikandungnya.

8. Buat sebuah Program

Saat merender objek 3D, anda tidak menggunakan shader secara langsung. Sebagai gantinya, anda memasangnya ke program dan menggunakan program. Oleh karena itu, tambahkan variabel anggota ke kelas Torus untuk menyimpan referensi ke program ES OpenGL.

Untuk membuat program baru, gunakan metode glCreateProgram () . Untuk memasang objek shader simpul dan fragmen ke objek tersebut, gunakan metode glAttachShader ().

Pada titik ini, anda dapat menghubungkan program dan mulai menggunakannya. Untuk melakukannya, gunakan metode glLinkProgram() dan glUseProgram().

9. Gambar Objek 3D

Dengan shader dan buffer siap, kita memiliki semua yang kita butuhkan untuk menarik torus kita. Tambahkan metode baru ke kelas Torus yang disebut draw:

Pada langkah awal, di dalam vertex shader, kita mendefinisikan position variabel untuk menerima data posisi vertex dari kode Java. Sekarang saatnya mengirim data posisi simpul ke sana. Untuk melakukannya, kita harus terlebih dahulu mendapatkan pegangan ke position variabel dalam kode Java kita menggunakan metode glGetAttribLocation(). Selain itu, pegangan harus diaktifkan dengan menggunakan metode glEnableVertexAttribArray().

Dengan demikian, tambahkan kode berikut di dalam metode seri():

Untuk menunjuk posisi Pegang buffer simpul kita, kita harus menggunakan metode glVertexAttribPointer(). Selain simpul simpul itu sendiri, metode ini mengharapkan jumlah koordinat per simpul, jenis koordinat, dan offset byte untuk setiap simpul. Karena kita memiliki tiga koordinat per simpul dan setiap koordinat adalah float, byte offset harus 3*4.

Shader verteks kami juga mengharapkan matrik proyeksi tampilan. Meskipun matriks semacam itu tidak selalu diperlukan, dengan menggunakan satu memungkinkan anda memiliki kontrol yang lebih baik mengenai bagaimana objek 3D anda diberikan.

Matriks proyeksi tampilan hanyalah produk dari matriks tampilan dan proyeksi. Matriks tampilan memungkinkan anda menentukan lokasi kamera dan titik yang dilihatnya. Matriks proyeksi, di sisi lain, memungkinkan Anda untuk tidak hanya memetakan sistem koordinat persegi OpenGL ES ke layar segi empat dari perangkat Android, namun juga menentukan bidang dekat dan jauh dari melihat frustum.

Untuk membuat matriks, anda bisa membuat tiga array float ukuran 16:

Untuk menginisialisasi matriks proyeksi, anda bisa menggunakan metode frustumM() dari kelas Matriks. Ia mengharapkan lokasi dari plane kiri, kanan, bawah, atas, dekat, dan jauh.  Karena kanvas kita sudah persegi, anda bisa menggunakan nilainya -1 dan 1 untuk bagian kiri dan kanan, dan bagian bawah dan puncak pesawat. Untuk plane jepret yang dekat dan jauh, silakan bereksperimen dengan nilai yang berbeda.

Untuk menginisialisasi matriks tampilan, gunakan metode setLookAtM(). Ia mengharapkan posisi kamera dan titik yang dilihatnya. Anda bebas bereksperimen dengan nilai yang berbeda. 

Akhirnya, untuk menghitung matriks produk, gunakan metode multiplyMM().

Untuk melewatkan matriks produk ke vertex shader, anda harusmendapatkan pegangannya  matriks variabel menggunakan metode glGetUniformLocation (). Begitu anda memiliki pegangan, anda bisa mengarahkannya ke matriks produk menggunakan metode glUniformMatrix ().

Anda pasti sudah memperhatikan bahwa kita masih belum menggunakan penyangga wajah. Itu berarti kita masih belum memberi tahu OpenGL ES bagaimana menghubungkan simpul untuk membentuk segitiga, yang akan berfungsi sebagai wajah objek 3D kita

Metode glDrawElements() memungkinkan anda menggunakan wajah penyangga untuk membuat segitiga. Sebagai argumennya, ia mengharapkan jumlah indeks simpul, jenis masing-masing indeks, dan buffer wajah.

Terakhir, jangan lupa untuk menonaktifkannya atribut handler yang anda aktifkan sebelumnya untuk melewatkan data vertex ke vertex shader

10. Buat Renderer

Widget GLSurfaceView kita membutuhkan objek GLSurfaceView.Renderer untuk bisa membuat grafis 3D. Anda bisa menggunakan setRenderer() untuk mengaitkan penyaji dengan itu.

Di dalam Metode onSurfaceCreated() penyaji, anda harus menentukan seberapa sering grafik 3D harus diberikan. Untuk saat ini, mari kita membuat hanya ketika perubahan grafis 3D. Untuk melakukannya, lewatkan RENDERMODE_WHEN_DIRTY konstan untuk metode setRenderMode(). Selain itu, inisialisasi sebuah instance baru dari obyek Torus.

Di dalam Metode onSurfaceChanged() penyaji, anda dapat menentukan lebar dan tinggi area pandang anda dengan menggunakan metode glViewport().

Di dalam metode onDrawFrame() renderer, tambahkan panggilan ke metode draw() dari kelas Torus untuk benar-benar menarik torus.

Pada titik ini, anda dapat menjalankan aplikasi anda untuk melihat torus oranye.

App displaying torus

Kesimpulan

Sekarang anda tahu cara menggunakan OpenGL ES di aplikasi Android. Dalam tutorial ini, anda juga belajar cara mengurai file OBJ Wavefront dan mengekstrak simpul dan data wajah darinya. Saya sarankan anda menghasilkan beberapa objek 3D lagi menggunakan Blender dan mencoba merendernya di aplikasi.

Meskipun kita hanya berfokus pada OpenGL ES 2.0, ketahuilah bahwa OpenGL ES 3.x kompatibel dengan OpenGL ES 2.0. Itu berarti bahwa jika anda lebih memilih menggunakan OpenGL ES 3.x di aplikasi anda, anda cukup mengganti kelas GLES20 dengan kelas GLES30 atau GLES31.

Untuk mempelajari lebih lanjut tentang OpenGL ES, anda bisa merujuknya halaman referensi. Dan untuk mempelajari lebih lanjut tentang pengembangan aplikasi Android, pastikan untuk melihat beberapa tutorial kami yang lain di sini di Envato Tuts+!


Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.