Rabu, 28 Januari 2015

CG[LWJGL0018] || GL Texture (Texture-1)

Table of contents
Pada tutorial kali ini kita akan kembali membahas masalah Texture setelah sebelumnya pada kesempatan yang lalu kita telah membahas tentang Membuat Texture dengan bantuan library Slick Util.

Materi Dasar Citra Digital (Digital Image)
Sebuah citra (gambar) sebagaimana kita ketahui hanyalah berupa sebuah array warna yang dirender di dalam ruang dua dimensi. Mari kita simak contoh gambar sprite hati dan sprite setengah hati berikut ini:





sekarang, jika kita melakukan zoom-in (memperbesar view citra) menggunakan aplikasi image processor seperti Photoshop atau yang lainnya, Lihatlah bagaimana gambar tersebut dibangun dari piksel-piksel individual.











Ada banyak cara untuk menyimpan gambar sejenis ini menggunakan komputer. Salah satu teknik yang paring sering digunakan adalah RGBA with 8-bits per channel. RGBA mengacu pada chanel Red, Green, Blue dan Alpha (chanel transparansi). Berikut ini ada beberapa alternatif untuk menyimpan warna merah:

  • HEX alias RGB int; #ff0000 atau 0xff0000
  • RGBA byte: (255, 0, 0, 255) atau (R=255, G=0, B=0, A=255)
  • RGBA float: (1.0f, 0.0f, 0.0f, 1.0f) atau (R=1f, G=0f, B=0f, A=1f)


seperti yang kita lihat bahwa chanel RGBA ini mewakili satu piksel atau satu sel jadi sebenarnya sebuah citra 2D berwarna yang menggunakan chanel RGBA akan disimpan menggunakan array 3D. misalkan saja kita memikiki citra berwarna RGBA berukuran 100x100 px maka kita akan menyimpan datanya dalam array berukuran 100x100x4 (100 baris x 100 kolom x 4 layer). Karena ukuran array ini bisa menjadi sangat besar maka kita menggunakan kompresi file citra JPEG ataupun PNG sebelum meng-upload citra ke web, email, dll.

OpenGL Textures
Di dalam OpenGL kita menggunakan Texture untuk menyimpan data citra. OpenGL Texture tidak sekedar menyimpan data citra. Data Citra tersebut juga disederhanakan ke dalam array bertipe float yang kemudian disimpan ke GPU, yang sangat berguna untuk pemetaan shadow dan teknik lainnya.

Langkah-langkah dasar untuk membuat texture dari sebuah gambar adalah sebagai berikut:

  1. Decode citra ke tipe RGBA byte
  2. Mendapatkan ID Texture baru
  3. Bind(mengikat) texture
  4. Menetapkan parameter-parameter texture
  5. Upload RGBA byte ke OpenGL
Decode PNG ke RGBA byte
OpenGL tidak tahu menahu dan tidak mau tahu tentang PNG, GIF, JPG, dll. :) . OpenGL hanya mengerti byte dan float. Jadi kita harus mengkonversi PNG ke ByteBuffer. Ada banyak resourse java yang bisa kita gunakan untuk mengkonversi PNG ke ByteBuffer diantaranya seperti yang telah kita bahas sebelumnya menggunakan library Slick-Util ataupun menggunakan PNGDecoder, Matthias Mann's PNGDecoder, Matthias Mann's TextureLoader, dll.

untuk melakukan decode citra ke bytebuffer adalah sebagai berikut:


Membuat Texture
Meskipun OpenGL memungkinkan kita untuk melakukan bind Multiple Texture namun dalam pembahasan ini kita hanya akan membahas tentang Single Texture Unit (unit tekstur tunggal). Untuk mengatur parameter-parameter Texture atau untuk mengirim Byte RGBA ke OpenGL, pertama-tama kita perlu mengikat (bind) texture tersebut yaitu membuatnya menjadi currently active texture. Kita dapat menggunakan method glGenTextures untuk menperoleh identifikasi teksture yang unik (berupa "texture name" atau "texture handle") sehingga OpenGL mengetahui texture mana yang sedang kita bind.

Proses untuk membuat texture dan meng-upload RGBA byte diperlihatkan sebagai berikut:



Pemanggilan method glTexImage2D adalah penetapan texture ke OpenGL yang sebenarnya. Kita dapat kembali memanggil metode ini jika kita hendak mengubah width maupun height citra texture kita ataupun kita akan mengganti nilai RGBA piksel data citra kita. Jika kita hanya ingin mengubah sebagian dari RGBA piksel data kita, kita dapat menggunakan method glTexSubImage2D untuk modifikasi piksel per piksel. Namun kita akan lebih banyak menggunakan Fragment Shader untuk menangani hal ini dan InsyaAllah akan kita bahas dalam tutorial selanjutnya.

CATATAN: anda dapat membaca penggunaan GL_UNPACK_ALIGNMENT disini.

Parameter-Parameter Texture
Sebelum memanggil method glTexImage2D, sangatlah penting untuk menetapkan parameter texture dengan benar. Code untuk menetapkan parameter texture diperlihatkan sebagai berikut:



Filtering
Filter minification dan filter magnification mendefinisikan bagaimana sebuah gambar ditangani dalam operasi penskalaan. Untuk "pixel-art" berstyle game, umumnya GL_NEAREST cocok karena mengarah ke hard-tepi skala tanpa mengaburkan, sedangkan GL_LINEAR akan menggunakan skala bilinear untuk hasil halus, yang umumnya efektif untuk game 3D (misalnya 1024x1024 texture batu maupun rumput) tapi tidak begitu untuk cocok untuk game 2D:



Mode Wrap
Untuk menjelaskan tentang mode wrap ini kita memerlukan pemahaman tentang koordinat textur dan vertex-vertex. Mari kita ambil contoh gambar 2D seperti gambar batu bata berikut ini:



Untuk membuat objek di atas kita perlu memberikan empat vertex ke OpenGL. Setiap vertex akan memiliki sejumlah atribut temasuk di dalamnya Position(x,y) dan Texture Coordinates(s, t). Texture coordinates/koordinat tekstur di defenisikan dalam ruang tangen. Umumnya berada antara nilai 0.0f sampai 1.0f. Koordinat tekstur ini memberitahukan ke OpenGL tentang data sampel tekstur yang akan kita gunakan. Gambar berikut memperlihatkan nilai atribut-atribut vertex dalam kotak yang kita buat:


Kadang-kadang programmer dan modeller menggunakan UV dan ST secara begantian. UV-Mapping adalah cara lain untuk mendeskripsikan bagaimana tekstur-tekstur diterapkan pada Mesh 3D.

Pertanyaannya adalah apa yang terjadi jika kita menggunakan nilai koordinat tekstur lebih kecil dari 0.0f maupun lebih besar dari 1.0f? Disinilah Mode Wrap bekerja. Kita akan memberi tahu OpenGL bagaimana seharusnya nilai-nilai diluar koordinat tekstur ditangani. Ada dua mode yang paling umum yaitu GL_CLAMP_TO_EDGE yang melakukan penyederhanaan sampel ke warna tepi dan GL_REPEAT dengan melakukan pengulangan pola sampel texture. Gambar berikut ini memperlihatkan perbedaan penggunaan keduanya:


Max Texture Size
Bagaimanapun juga akhirnya implementasi imajinasi kita harus dibatasi oleh hardware :) :) :). berikut ini method yang dapat digunakan untuk mengetahui berapa ukuran resolusi maksimal tekstur yang diizinkan oleh hardware yang kita gunakan:

int maxSize = glGetInteger(GL_MAX_TEXTURE_SIZE);

Source Code Lengkap
Berikut ini source code lengkap untuk Simple Texture Wrapper kita:



----


Referensi:
- https://github.com/mattdesl/lwjgl-basics/wiki/Textures

Tidak ada komentar:

Posting Komentar

/*SYNTAX HIGHLIGHTER*/