Senin, 26 Januari 2015

CG[LWJGL0017] || Shader Dasar

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

beri nama class TutorialLWJGL0017 kemudian klik finish
Add caption

 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


Tidak ada komentar:

Posting Komentar

/*SYNTAX HIGHLIGHTER*/