Kamis, 17 November 2016

OpenGL, Karakteristik Model Pencahayaan

Pada kesempatan kali ini. Saya akan share praktikum 02 mata kuliah Grafika Lanjut. 

Pada praktikum 02 Grafika Lanjut mahasiswa dituntut agar mampu menjelaskan model cahaya dan karakteristik dari model-model cahaya tersebut. Selanjutnya bagaimana cara menerapkan model tersebut dengan OpenGL. 


Sebetulnya pemodelan cahaya ini bertujuan tidak hanya berkaitan dengan redup atau terangnya sebuah obyek. Tujuannya adalah membuat obyek terlihat lebih realistik seperti yang ada didunia maya dengan memanfaatkan model-model pencahayaan. Salah satu pemodelan cahaya yang biasa dipakai yaitu model cahaya phong. Dalam model cahaya phong dapat digolongkan kedalam tiga kategori :

·    Cahaya sekitar / ambient light
Cahaya sekitar tidak berasal dari arah yang spesifik. Obyek menerima cahaya tidak langsung dari sumber cahaya tetapi berupa hasil pantulan tidak langsung dari sumber cahaya. Karakteristik obyek yang dikenai cahaya sekitar yaitu akan terang di seluruh permukaan di segala arah.
·    Cahaya tersebar / diffuse light
Cahaya tersebar adalah hasil interaksi sumber cahaya dengan permukaan yang menyebarkan cahaya karena permukaannya tidak rata atau kasar.
·    Cahaya biasa / specular light
Cahaya biasa merupakan hasil dari interaksi sumber cahaya dari arah tertentu terhadap permukaan benda. Permukaan yang terpancar cahaya akan terang dan yang tidak terpancar akan gelap tergantung dari sudut pandang terhadap posisi sumber cahaya dan obyek.

Berikut ini contoh program model pencahayaan

// deklarasikan semua header disini

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <glut.h>

// inisialisasi variabel untuk transformasi seperti translasi, rotasi atau scaling
// gunakan bila perlu
float angle = 0.0f; 
float posX = 0.0f, rotX =  0.0f;
float posY = 0.0f, rotY =  0.0f;
float posZ = 5.0f, rotZ = -1.0f;

float objectAngle = 0.0f;
float objectPosX = 0.0f;
float objectPosY = 0.0f;
float objectPosZ = 0.0f;

// saklar untuk mematikan / menghidupkan pencahayaan
bool light0 = false;
bool light1 = false;
// material obyek
float matShininess[] = { 100.0 };
float matSurface[] = { 0.5, 0.5, 0.5, 0.0 };
float matSpecular[] = { 1.0, 1.0, 1.0, 0.0 };
// warna sumber cahaya
float lightColor0[] = { 0.0, 0.0, 1.0, 1.0 }; // biru
float lightColor1[] = { 0.0, 0.0, 0.0, 0.0 }; // hitam
//float lightColor2[] = { 0.0, 1.0, 0.0, 1.0 }; // hijau
// posisi sumber cahaya
float lightPosition0[] = { 10.0, -10.0, 10.0, 1.0 };
float lightPosition1[] = { -10.0, -10.0, 10.0, 1.0 };
//float lightPosition2[] = { 0.0, 10.0, 10.0, 1.0 };

// fungsi untuk menggambar obyek
void drawObject()
{
    // obyek bisa dimasukkan diantara glPushMatrix() dan glPopMatrix() 
    // fungsinya agar obyek tidak terpengaruh atau mempengaruhi obyek lain
    // saat diwarnai, ditransformasi dan sebagainya
    glPushMatrix();

    // operasi transformasi rotasi ke arah sumbu X (gunakan bila perlu)
    glRotatef(objectAngle, objectPosX, objectPosY, objectPosZ);

    // set warna obyek ke warna hijau (0, 1, 0)
    glColor3f(0.5f, 0.5f, 0.5f);
    // bila menggambar obyek harus diawali glBegin(tipe obyek) dan diakhiri dengan glEnd()
    // kecuali menggunakan fungsi yang sudah ada di GLUT-OpenGL seperti dibawah ini
    glutSolidSphere(1.0f, 50, 50);

    glPopMatrix();
}

// taruh semua obyek yang akan digambar di fungsi display()
void display()
{
    // bersihkan layar dan buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
GLfloat spotPosition0[] = {-1.0, 1.0, 0.0 }; 

    // set warna dan posisi sumber cahaya 
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition0);    // set posisi sumber cahaya 0
    glLightfv(GL_LIGHT1, GL_POSITION, lightPosition1);    // set posisi sumber cahaya 1
   // glLightfv(GL_LIGHT2, GL_POSITION, lightPosition2);    // set posisi sumber cahaya 2
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);    // set warna sumber cahaya 0
    glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1);    // set warna sumber cahaya 1
    //glLightfv(GL_LIGHT0, GL_AMBIENT, lightColor0);    // set warna sumber cahaya 0
    glLightfv(GL_LIGHT1, GL_AMBIENT, lightColor1);    // set warna sumber cahaya 1
    glLightfv(GL_LIGHT0, GL_SPECULAR, lightColor0);        // set warna sumber cahaya 0
    glLightfv(GL_LIGHT1, GL_SPECULAR, lightColor1);        // set warna sumber cahaya 1
    //glLightfv(GL_LIGHT2, GL_SPECULAR, lightColor2);    // set warna sumber cahaya 2
    //GLfloat spotPosition0[] = {-1.0, 1.0, 0.0 };            // arah lampu sorot
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotPosition0);    // set arah lampu sorot
    glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);                // set lebar sudut sorot
    glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 0.1);                // set intensitas lampu
    // perlakuan permukaan obyek
    glMaterialfv(GL_FRONT, GL_AMBIENT, matSurface);        // set material permukaan model ambient 
    glMaterialfv(GL_FRONT, GL_SPECULAR, matSpecular);    // set material permukaan model specular
    glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);    // set material permukaan mengkilat
    // matikan atau hidupkan sumber cahaya
    if (light0)
        glDisable(GL_LIGHT0);
    else
        glEnable(GL_LIGHT0);
    if (light1)
        glDisable(GL_LIGHT1);
    else
        glEnable(GL_LIGHT1);

    // posisikan kamera pandang
    // dalam hal ini sumbu Y ada diatas dan posisi kamera pandang di (posX, posY, posZ)
    gluLookAt(posX, posY, posZ, posX + rotX, posY + rotY, posZ + rotZ, 0.0f, 1.0f, 0.0f);

    // panggil fungsi untuk menggambar obyek
    drawObject();
    
    // tampilkan obyek ke layar
    // gunakan glFlush() bila memakai single buffer
    // gunakan glutSwapBuffers() bila memakai double buffer
    glutSwapBuffers();
}

// inisialisasi variabel, pencahayaan, tekstur dan pengaturan kamera pandang di fungsi init()
void init(void)
{
    // inisialisasi warna background layar
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glEnable(GL_DEPTH_TEST);                // mengaktifkan depth buffer
    glMatrixMode(GL_PROJECTION);        
    glLoadIdentity();
    gluPerspective(45.0, 1.0, 1.0, 100.0);    // set proyeksi ke perspektif
    glMatrixMode(GL_MODELVIEW);                
    glLoadIdentity();                        
    // set kamera pandang awal
    gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    // aktifkan pencahayaan dan warna material
    glEnable(GL_LIGHTING);    
    glEnable(GL_LIGHT0);    // sumber cahaya pertama (maksimal 8 sumber cahaya)
    glEnable(GL_LIGHT1);    // sumber cahaya kedua (maksimal 8 sumber cahaya)
    glEnable(GL_LIGHT2);    // sumber cahaya ketiga (maksimal 8 sumber cahaya)
    glEnable(GL_COLOR_MATERIAL); // aktifkan perlakuan ke permukaan
}

// fungsi ini digunakan bila layar akan diresize (default)
void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

// fungsi untuk mengatur masukan dari keyboard untuk arah kiri, kanan, atas, dan bawah
void keyboard(int key, int x, int y)
{
    float fraction = 0.1f;

    switch (key) 
    {
    case GLUT_KEY_F1:
        // masukkan perintah disini bila tombol F1 ditekan 
        light0 = !light0;        // matikan / hidupkan sumber cahaya 0
        glutPostRedisplay();
        break;
    case GLUT_KEY_F2:
        // masukkan perintah disini bila tombol F2 ditekan 
        light1 = !light1;        // matikan / hidupkan sumber cahaya 1
        glutPostRedisplay();
        break;
    case GLUT_KEY_LEFT:
        // masukkan perintah disini bila tombol kiri ditekan 
        // dalam hal ini perintah rotasi obyek ke kiri sebanyak 1 derajat 
        objectAngle -= 1.0f;
        objectPosX = 0.0f;
        objectPosY = 1.0f;
        objectPosZ = 0.0f;
        glutPostRedisplay();    // update obyek
        break;
    case GLUT_KEY_RIGHT:
        // masukkan perintah disini bila tombol kanan ditekan
        // dalam hal ini perintah rotasi obyek ke kanan sebanyak 1 derajat 
        objectAngle += 1.0f;
        objectPosX = 0.0f;
        objectPosY = 1.0f;
        objectPosZ = 0.0f;
        glutPostRedisplay();    // update obyek
        break;
    case GLUT_KEY_UP:
        // masukkan perintah disini bila tombol atas ditekan
        // dalam hal ini perintah rotasi obyek ke atas sebanyak 1 derajat 
        objectAngle -= 1.0f;
        objectPosX = 1.0f;
        objectPosY = 0.0f;
        objectPosZ = 0.0f;
        glutPostRedisplay();    // update obyek
        break;
    case GLUT_KEY_DOWN:
        // masukkan perintah disini bila tombol bawah ditekan
        // dalam hal ini perintah rotasi obyek ke bawah sebanyak 1 derajat 
        objectAngle += 1.0f;
        objectPosX = 1.0f;
        objectPosY = 0.0f;
        objectPosZ = 0.0f;
        glutPostRedisplay();    // update obyek
        break;
    // zoom in
    case GLUT_KEY_PAGE_UP:
        // masukkan perintah disini bila tombol PgUp ditekan
        posX += rotX * fraction;        
        posZ += rotZ * fraction;
        glutPostRedisplay();    // update obyek
        break;
    // zoom out
    case GLUT_KEY_PAGE_DOWN:
        // masukkan perintah disini bila tombol PgDn ditekan
        posX -= rotX * fraction;
        posZ -= rotZ * fraction;
        glutPostRedisplay();    // update obyek
        break;
    }
}

// timer untuk animasi (gunakan bila perlu)
void timer(int value)
{
    glutPostRedisplay();
    glutTimerFunc(55, timer, 0);
}

// program utama
int main(int argc, char** argv)
{
    // inisialisasi jendela OpenGL
    // GLUT_SINGLE berarti memakai single buffer
    // GLUT_DOUBLE berarti memakai double buffer
    // GLUT_RGB berarti mode tampilan yang dipakai RGB
    // GLUT_RGBA berarti mode tampilang yang dipakai RGBA
    // GLUT_DEPTH berarti memakai depth buffer
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

    // set ukuran jendela tampilan
    glutInitWindowSize(480, 480);        // besarnya jendela dalam piksel dalam hal ini 300x300
    glutInitWindowPosition(100, 100);    // posisi jendela dilayar komputer dalam piksel
    // judul jendela (wajib diubah dengan informasi NAMA / NIM - JUDUL PRAKTIKUM masing-masing)

glutCreateWindow("PRAKTIKUM 2 - IMAM MUAMAR KHARISMA - 1501318006");
printf("PRAKTIKUM 02\n "); 
printf("Imam Muamar Kharisma \n "); 
printf("\n "); 
printf("\n "); 
printf("\n "); 
printf("\n "); 
    
    // panggil fungsi init untuk inisialisasi awal
    init();

    // event handler untuk display, reshape dan keyboard
    glutDisplayFunc(display);   // display
    glutReshapeFunc(reshape);   // reshape
    glutSpecialFunc(keyboard);  // keyboard
    //glutTimerFunc(0, timer, 0); // aktifkan timer bila perlu

    // looping
    glutMainLoop();

    return 0;
}


Hasil :


Previous Post
Next Post

post written by:

0 komentar: