Table of contents
GLSL adalah singkatan dari OpenGL Shading Language. Shader adalah script yang memungkinkan kita berinteraksi lebih dekat dengan processor grafis (GPU). Shader merupakan aspek penting dalam pemrograman grafis dan dapat digunakan untuk mengembangkan berbagai efek visual 2D dan 3D. Penggunaan shader semakin penting di masa depan, jadi lebih baik memulai langsung dengan shader walaupun lebih kompleks. Jangan kaget jika code yang diperlukan cukup panjang. OpenGL sifatnya dekat dengan hardware, powerful, cepat tetapi sayangnya jadi kompleks (pengantar shader).
Proses untuk menampilkan gambar di layar melibatkan berbagai tahapan yang ada di rendering pipeline. Misalnya untuk menentukan suatu objek berada di posisi mana dan warnya apa (untuk memberikan efek 3D warna dapat berubah tergantung posisi dan posisi cahaya). Sejalan dengan semakin majunya GPU, pipeline ini dapat diprogram. Mulai dari versi 3.1 (core profile), shader wajib digunakan.
Program shader pada dasarnya adalah code yang dijalankan langsung oleh GPU pada rendering pipeline. Dengan shader, programmer memiliki fleksibilitas lebih tinggi dalam memanfaatkan GPU. Minimal ada dua program shader yang harus digunakan, pertama vertex shader dan fragment shader. Vertex shader bisa sederhana, sekeder mengcopy data (seperti pada contoh di posting ini) atau yang lebih kompleks seperti mengatur posisi vertex. Fragment shader mengatur warna pada layar, termasuk memberikan tekstur (texture) dan efek kedalaman (depth).
Selanjutnya kita akan membuat source code penggunaan shader. Sumber source code ini diambil dari: indonesiaberkicau.com, schabby.de dan wiki.LWJGL.
STEP 1:
Buatlah sebuah project eclipse baru dengan memilih menu file --> new --> Java Project
STEP 2:
Beri nama project misalnya ProjectLWJGL0003
STEP 3:
copy folder library lwjgl (penulis menggunakan lwjgl-2.9.2)
kemudian paste folder library lwjgl (penulis menggunakan lwjgl-2.9.2) ke project yang baru dibuat.
STEP 4:
Lakukan pengaturan built path dengan cara klik kanan pada project yang baru dibuat --> pilih menu Built Path --> Configure Built Path...
selanjutnya kotak dialog Java Built Path akan terbuka
STEP 5:
Klik tombol "Add JARs" lalu pilih file library LWJGL yang dibutuhkan: lwjgl_util.jar, lwjgl-debug.jar dan lwjgl.jar
kemudian klik OK
selanjutnya klik tombol expand pada lwjgl-debug.jar sehingga tampak seperti gambar berikut:
kemudian klik "Native library location:"
klick tombol workspace
masuk ke direktori native dan pilih nama OS yang digunakan.
STEP 6:
Buatlah sebuah package (paket) baru di dalam ProjectLWJGL0003 dengan melakukan klik kanan pada nama projectnya kemudian pilih menu New --> Package
kemudian beri nama package misalnya: "latihanShader00"
STEP 7:
Buatlah sebuah class baru di dalam package latihanShader00
selanjutnya akan tampil source class TutorialLWJGL0017 berikut
STEP 8:
Tambahkan code berikut ke dalam class TutorialLWJGL0017
STEP 9:
Buatlah class ShaderProgram yang berfungsi untuk me-load dan meng-compile file shader sebagai berikut:
STEP 10:
selanjutnya kita akan membuat file shader yang terdiri dari file vertex shader (dalam contoh ini diberi nama: "dasar.vert") dan file fragment shader(dalam contoh ini diberi nama: "dasar.frag"). Kedua file ini berisi code GLSL (OpenGL Shading Language) yang mirip dengan bahasa C. Penjelasan tentang Vertex shader dan Fragment shader ini akan dibahas pada tutorial selanjutnya InsyaAllah...
berikut ini cara membuat file dasar.vert: klik kanan pada package latihanShader00 --> New --> File lalu beri file name: dasar.vert lalu klik finish. kemudian copy-paste code dasar.vert berikut:
lakukan langkah yang sama untuk file dasar.frag lalu copy-paste code dasar.frag berikut:
STEP 11:
Langkah terakhir adalah melengkapi class TutorialLWJGL0017.
- Tambahkan lima atribut berikut ke dalam class TutorialLWJGL0017:
String windowTitle = "CG[LWJGL0017] || Shader Dasar";
public boolean closeRequested = false;
ShaderProgram shader;
private int vaoId = 0;
private int vboId = 0;
- Edit method inisilaisasi window OpenGL menjadi seperti berikut ini:
private void createWindow(){
// menggunakan OpenGL versi 4 dan tidak
// menggunakan deprecated function
PixelFormat pixelFormat = new PixelFormat();
ContextAttribs contextAtrributes = new ContextAttribs(4, 0);
contextAtrributes.withForwardCompatible(true);
contextAtrributes.withProfileCore(true);
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setVSyncEnabled(true);
Display.setTitle(windowTitle);
Display.create(pixelFormat, contextAtrributes);
} catch (LWJGLException e) {
Sys.alert("Error", "Initialization failed!\n\n" + e.getMessage());
System.exit(0);
}
}
- Edit method inisialisasi GL menjadi seperti berikut ini:
private void initializeGL(){
int width = Display.getDisplayMode().getWidth();
int height = Display.getDisplayMode().getHeight();
GL11.glViewport(0, 0, width, height);
GL11.glClearColor(0.20392156862f, 0.59607843137f, 0.85882352941f, 0.0f);
}
- edit method input key-esc untuk melakukan exit program seperti berikut ini:
public void pollInput(){
// scroll through key events
while (Keyboard.next()){
if (Keyboard.getEventKeyState()){
if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE)
closeRequested = true;
}
}
if (Display.isCloseRequested()){
closeRequested = true;
}
}
- Edit method renderGL untuk menggambar array vertex menjadi seperti berikut ini:
private void renderGL(){
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// tell OpenGL to use the shader
GL20.glUseProgram(shader.getProgramId());
// bind vertex, bukan untuk alokasi tapi untuk mengaktifkan
GL30.glBindVertexArray(vaoId);
GL20.glEnableVertexAttribArray(0);
// draw VAO
// mulai dari 0, sebanyak 3 point
GL11.glDrawArrays(GL11.GL_POINTS, 0, 3);
// check for errors
if( glGetError() != GL_NO_ERROR ){
throw new RuntimeException("OpenGL error: "+GLU.gluErrorString(glGetError()));
}
}
- Tambahkan method untuk mengkonstruksi objek array vertex seperti berikut ini:
private void constructVertexArrayObject(){
// create vertex data
// koordinat 3 titik, masing2 direprsentasikan
// dengan tiga nilai: x,y,z
float[] vertices = new float[] {
0f, 0f, 0f,
0.5f, 0f, 0f,
0f, 0.5f, 0f
};
// pindahkan array ke buffer
//kalau di contoh C++ kebanyakan menggunakan array
//lwjgl menggunakan buffer agar lebih cepat
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices);
verticesBuffer.flip();
// Buat Vertex Array Object (VAO) dan pilih (bind)
// Satu VAO dapat memiliki 16 atribut (VBO)
//GLGen untuk alokasi nama
//GLBind untuk alokasi memori
vaoId = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoId);
// Buat vertex buffer object dan pilih (VBO)
// VBO berisi vector, pada program ini akan diisi oleh lokasi vertex
// VBO dikelola oleh vertex array object (VAO)
vboId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
//transfer vertexdata ke buffer object yang dipilih
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
//parameter 1: Letakkan VBO pada attributes list di index 0
// ini terkait dengan vertex shader
// 0 --> layout(location = 0) di simple.vertex
//parameter 2: ukuran tiap vertex, yaitu 3 (x,y,z)
//paramter 4 : false --> koordinat tidak dibatasi -1, 1
//paramter 5 : 0 --> data contiguous (tidak loncat2)
//paramter 6 : 0 --> data mulai dari posisi 0
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
//ukuran point, default 1 pixel yang tidak terlihat
//jadi diperbesar jadi 5 pixel
GL11.glPointSize(5);
//Deselect (bind to 0) the VBO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
// Deselect (bind to 0) the VAO
GL30.glBindVertexArray(0);
}
- Terakhir, edit method run menjadi seperti berikut ini:
public void run(){
//Inisialisasi
createWindow();
initializeGL();
//instansiasi objek shader
shader = new ShaderProgram();
// loading, compiling, linking vertex shader dan fragment shader
shader.init("src/latihanShader00/dasar.vert", "src/latihanShader00/dasar.frag");
//mempersiapkan VAO dan VBO
//outpuntya: voaId sudah siap
constructVertexArrayObject();
//Looping
while(!closeRequested){
pollInput();
updateLogic();
renderGL();
Display.update();
Display.sync(60);
}
//Terminate
cleanup();
}
Berikut ini source code lengkap untuk class TutorialLWJGL0017:
Preview program:
SELAMAT MENCOBA
Referensi:
- http://indonesiaberkicau.com/opengl-bagian-2-pengantar-shader/
- http://schabby.de/opengl-shader-example/
- https://bitbucket.org/ra4king/lwjgl-shader-tutorials
- http://relativity.net.au/gaming/java/SimpleSquareShader.html
- http://www.java-gaming.org/index.php?topic=28048.0
- https://www.opengl.org/discussion_boards/showthread.php/178963-Simple-working-VBO-in-LWJGL
- http://goharsha.com/lwjgl-tutorial-series/the-first-triangle/
- http://lwjgl.blogspot.com/
- http://www.wenda.io/questions/1902892/lwjgl-vertex-shader-gl-pointsize-not-working.html
GLSL adalah singkatan dari OpenGL Shading Language. Shader adalah script yang memungkinkan kita berinteraksi lebih dekat dengan processor grafis (GPU). Shader merupakan aspek penting dalam pemrograman grafis dan dapat digunakan untuk mengembangkan berbagai efek visual 2D dan 3D. Penggunaan shader semakin penting di masa depan, jadi lebih baik memulai langsung dengan shader walaupun lebih kompleks. Jangan kaget jika code yang diperlukan cukup panjang. OpenGL sifatnya dekat dengan hardware, powerful, cepat tetapi sayangnya jadi kompleks (pengantar shader).
Proses untuk menampilkan gambar di layar melibatkan berbagai tahapan yang ada di rendering pipeline. Misalnya untuk menentukan suatu objek berada di posisi mana dan warnya apa (untuk memberikan efek 3D warna dapat berubah tergantung posisi dan posisi cahaya). Sejalan dengan semakin majunya GPU, pipeline ini dapat diprogram. Mulai dari versi 3.1 (core profile), shader wajib digunakan.
Program shader pada dasarnya adalah code yang dijalankan langsung oleh GPU pada rendering pipeline. Dengan shader, programmer memiliki fleksibilitas lebih tinggi dalam memanfaatkan GPU. Minimal ada dua program shader yang harus digunakan, pertama vertex shader dan fragment shader. Vertex shader bisa sederhana, sekeder mengcopy data (seperti pada contoh di posting ini) atau yang lebih kompleks seperti mengatur posisi vertex. Fragment shader mengatur warna pada layar, termasuk memberikan tekstur (texture) dan efek kedalaman (depth).
Selanjutnya kita akan membuat source code penggunaan shader. Sumber source code ini diambil dari: indonesiaberkicau.com, schabby.de dan wiki.LWJGL.
STEP 1:
Buatlah sebuah project eclipse baru dengan memilih menu file --> new --> Java Project
STEP 2:
Beri nama project misalnya ProjectLWJGL0003
STEP 3:
copy folder library lwjgl (penulis menggunakan lwjgl-2.9.2)
kemudian paste folder library lwjgl (penulis menggunakan lwjgl-2.9.2) ke project yang baru dibuat.
STEP 4:
Lakukan pengaturan built path dengan cara klik kanan pada project yang baru dibuat --> pilih menu Built Path --> Configure Built Path...
selanjutnya kotak dialog Java Built Path akan terbuka
STEP 5:
Klik tombol "Add JARs" lalu pilih file library LWJGL yang dibutuhkan: lwjgl_util.jar, lwjgl-debug.jar dan lwjgl.jar
kemudian klik OK
selanjutnya klik tombol expand pada lwjgl-debug.jar sehingga tampak seperti gambar berikut:
kemudian klik "Native library location:"
klick tombol workspace
masuk ke direktori native dan pilih nama OS yang digunakan.
STEP 6:
Buatlah sebuah package (paket) baru di dalam ProjectLWJGL0003 dengan melakukan klik kanan pada nama projectnya kemudian pilih menu New --> Package
kemudian beri nama package misalnya: "latihanShader00"
STEP 7:
Buatlah sebuah class baru di dalam package latihanShader00
beri nama class TutorialLWJGL0017 kemudian klik finish
Add caption |
STEP 8:
Tambahkan code berikut ke dalam class TutorialLWJGL0017
STEP 9:
Buatlah class ShaderProgram yang berfungsi untuk me-load dan meng-compile file shader sebagai berikut:
STEP 10:
selanjutnya kita akan membuat file shader yang terdiri dari file vertex shader (dalam contoh ini diberi nama: "dasar.vert") dan file fragment shader(dalam contoh ini diberi nama: "dasar.frag"). Kedua file ini berisi code GLSL (OpenGL Shading Language) yang mirip dengan bahasa C. Penjelasan tentang Vertex shader dan Fragment shader ini akan dibahas pada tutorial selanjutnya InsyaAllah...
berikut ini cara membuat file dasar.vert: klik kanan pada package latihanShader00 --> New --> File lalu beri file name: dasar.vert lalu klik finish. kemudian copy-paste code dasar.vert berikut:
lakukan langkah yang sama untuk file dasar.frag lalu copy-paste code dasar.frag berikut:
STEP 11:
Langkah terakhir adalah melengkapi class TutorialLWJGL0017.
- Tambahkan lima atribut berikut ke dalam class TutorialLWJGL0017:
String windowTitle = "CG[LWJGL0017] || Shader Dasar";
public boolean closeRequested = false;
ShaderProgram shader;
private int vaoId = 0;
private int vboId = 0;
- Edit method inisilaisasi window OpenGL menjadi seperti berikut ini:
private void createWindow(){
// menggunakan OpenGL versi 4 dan tidak
// menggunakan deprecated function
PixelFormat pixelFormat = new PixelFormat();
ContextAttribs contextAtrributes = new ContextAttribs(4, 0);
contextAtrributes.withForwardCompatible(true);
contextAtrributes.withProfileCore(true);
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setVSyncEnabled(true);
Display.setTitle(windowTitle);
Display.create(pixelFormat, contextAtrributes);
} catch (LWJGLException e) {
Sys.alert("Error", "Initialization failed!\n\n" + e.getMessage());
System.exit(0);
}
}
- Edit method inisialisasi GL menjadi seperti berikut ini:
private void initializeGL(){
int width = Display.getDisplayMode().getWidth();
int height = Display.getDisplayMode().getHeight();
GL11.glViewport(0, 0, width, height);
GL11.glClearColor(0.20392156862f, 0.59607843137f, 0.85882352941f, 0.0f);
}
- edit method input key-esc untuk melakukan exit program seperti berikut ini:
public void pollInput(){
// scroll through key events
while (Keyboard.next()){
if (Keyboard.getEventKeyState()){
if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE)
closeRequested = true;
}
}
if (Display.isCloseRequested()){
closeRequested = true;
}
}
- Edit method renderGL untuk menggambar array vertex menjadi seperti berikut ini:
private void renderGL(){
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// tell OpenGL to use the shader
GL20.glUseProgram(shader.getProgramId());
// bind vertex, bukan untuk alokasi tapi untuk mengaktifkan
GL30.glBindVertexArray(vaoId);
GL20.glEnableVertexAttribArray(0);
// draw VAO
// mulai dari 0, sebanyak 3 point
GL11.glDrawArrays(GL11.GL_POINTS, 0, 3);
// check for errors
if( glGetError() != GL_NO_ERROR ){
throw new RuntimeException("OpenGL error: "+GLU.gluErrorString(glGetError()));
}
}
- Tambahkan method untuk mengkonstruksi objek array vertex seperti berikut ini:
private void constructVertexArrayObject(){
// create vertex data
// koordinat 3 titik, masing2 direprsentasikan
// dengan tiga nilai: x,y,z
float[] vertices = new float[] {
0f, 0f, 0f,
0.5f, 0f, 0f,
0f, 0.5f, 0f
};
// pindahkan array ke buffer
//kalau di contoh C++ kebanyakan menggunakan array
//lwjgl menggunakan buffer agar lebih cepat
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices);
verticesBuffer.flip();
// Buat Vertex Array Object (VAO) dan pilih (bind)
// Satu VAO dapat memiliki 16 atribut (VBO)
//GLGen untuk alokasi nama
//GLBind untuk alokasi memori
vaoId = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoId);
// Buat vertex buffer object dan pilih (VBO)
// VBO berisi vector, pada program ini akan diisi oleh lokasi vertex
// VBO dikelola oleh vertex array object (VAO)
vboId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
//transfer vertexdata ke buffer object yang dipilih
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
//parameter 1: Letakkan VBO pada attributes list di index 0
// ini terkait dengan vertex shader
// 0 --> layout(location = 0) di simple.vertex
//parameter 2: ukuran tiap vertex, yaitu 3 (x,y,z)
//paramter 4 : false --> koordinat tidak dibatasi -1, 1
//paramter 5 : 0 --> data contiguous (tidak loncat2)
//paramter 6 : 0 --> data mulai dari posisi 0
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
//ukuran point, default 1 pixel yang tidak terlihat
//jadi diperbesar jadi 5 pixel
GL11.glPointSize(5);
//Deselect (bind to 0) the VBO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
// Deselect (bind to 0) the VAO
GL30.glBindVertexArray(0);
}
- Terakhir, edit method run menjadi seperti berikut ini:
public void run(){
//Inisialisasi
createWindow();
initializeGL();
//instansiasi objek shader
shader = new ShaderProgram();
// loading, compiling, linking vertex shader dan fragment shader
shader.init("src/latihanShader00/dasar.vert", "src/latihanShader00/dasar.frag");
//mempersiapkan VAO dan VBO
//outpuntya: voaId sudah siap
constructVertexArrayObject();
//Looping
while(!closeRequested){
pollInput();
updateLogic();
renderGL();
Display.update();
Display.sync(60);
}
//Terminate
cleanup();
}
Berikut ini source code lengkap untuk class TutorialLWJGL0017:
Preview program:
SELAMAT MENCOBA
- http://indonesiaberkicau.com/opengl-bagian-2-pengantar-shader/
- http://schabby.de/opengl-shader-example/
- https://bitbucket.org/ra4king/lwjgl-shader-tutorials
- http://relativity.net.au/gaming/java/SimpleSquareShader.html
- http://www.java-gaming.org/index.php?topic=28048.0
- https://www.opengl.org/discussion_boards/showthread.php/178963-Simple-working-VBO-in-LWJGL
- http://goharsha.com/lwjgl-tutorial-series/the-first-triangle/
- http://lwjgl.blogspot.com/
- http://www.wenda.io/questions/1902892/lwjgl-vertex-shader-gl-pointsize-not-working.html
Tidak ada komentar:
Posting Komentar