OpenGL (Open Graphics Library) adalah pustaka grafis yang
banyak digunakan untuk membuat aplikasi 3D interaktif. Salah satu framework
yang sering digunakan untuk mempermudah pembuatan aplikasi grafis berbasis
OpenGL adalah GLUT (OpenGL Utility Toolkit). Artikel ini akan membahas sebuah
contoh aplikasi yang menggunakan OpenGL dan GLUT untuk membuat tampilan grafis
3D dengan beberapa objek yang berputar.
1. Pendahuluan
Program yang akan kita bahas ini menampilkan tiga jenis
objek 3D, yaitu bola, kerucut, dan torus, dengan rotasi pada setiap objek
tersebut. Program ini memungkinkan pengguna untuk mengubah jumlah
"slices" dan "stacks" yang digunakan pada objek-objek
tersebut dengan menekan tombol + atau -. Selain itu, program ini
juga menggunakan pencahayaan untuk memberikan efek yang lebih realistis pada
objek-objek tersebut.
/*
* GLUT Shapes Demo
*
* Written by Nigel
Stewart November 2003
*
* This program is
test harness for the sphere, cone
* and torus shapes in
GLUT.
*
* Spinning wireframe
and smooth shaded shapes are
* displayed until the
ESC or q key is pressed. The
* number of geometry
stacks and slices can be adjusted
* using the + and -
keys.
*/
#include <windows.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <stdlib.h>
static int slices = 16;
static int stacks = 16;
/* GLUT callback Handlers */
static void resize(int width, int height)
{
const float ar =
(float) width / (float) height;
glViewport(0, 0,
width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar,
-1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
}
static void display(void)
{
const double t =
glutGet(GLUT_ELAPSED_TIME) / 1000.0;
const double a =
t*90.0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3d(1,0,0);
glPushMatrix();
glTranslated(-2.4,1.2,-6);
glRotated(60,1,0,0);
glRotated(a,0,0,1);
glutSolidSphere(1,slices,stacks);
glPopMatrix();
glPushMatrix();
glTranslated(0,1.2,-6);
glRotated(60,1,0,0);
glRotated(a,0,0,1);
glutSolidCone(1,1,slices,stacks);
glPopMatrix();
glPushMatrix();
glTranslated(2.4,1.2,-6);
glRotated(60,1,0,0);
glRotated(a,0,0,1);
glutSolidTorus(0.2,0.8,slices,stacks);
glPopMatrix();
glPushMatrix();
glTranslated(-2.4,-1.2,-6);
glRotated(60,1,0,0);
glRotated(a,0,0,1);
glutWireSphere(1,slices,stacks);
glPopMatrix();
glPushMatrix();
glTranslated(0,-1.2,-6);
glRotated(60,1,0,0);
glRotated(a,0,0,1);
glutWireCone(1,1,slices,stacks);
glPopMatrix();
glPushMatrix();
glTranslated(2.4,-1.2,-6);
glRotated(60,1,0,0);
glRotated(a,0,0,1);
glutWireTorus(0.2,0.8,slices,stacks);
glPopMatrix();
glutSwapBuffers();
}
static void key(unsigned char key, int x, int y)
{
switch (key)
{
case 27 :
case 'q':
exit(0);
break;
case '+':
slices++;
stacks++;
break;
case '-':
if
(slices>3 && stacks>3)
{
slices--;
stacks--;
}
break;
}
glutPostRedisplay();
}
static void idle(void)
{
glutPostRedisplay();
}
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };
/* Program entry point */
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("GLUT Shapes");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutIdleFunc(idle);
glClearColor(1,1,1,1);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_AMBIENT,
light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE,
light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_AMBIENT,
mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE,
mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR,
mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
glutMainLoop();
return
EXIT_SUCCESS;
}
2. Mengatur Tampilan Jendela
Salah satu aspek penting dalam pemrograman grafis adalah
pengaturan tampilan jendela dan proyeksi. Program ini menggunakan fungsi glFrustum untuk
menetapkan proyeksi perspektif, yang memberikan kesan kedalaman pada
objek-objek 3D. Fungsi glViewport digunakan untuk mengatur area
jendela tempat objek-objek akan digambar.
static void resize(int width, int height)
{
const float ar =
(float) width / (float) height;
glViewport(0, 0,
width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar,
-1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
3. Menambahkan Objek 3D
Program ini menampilkan beberapa objek 3D, termasuk glutSolidSphere, glutSolidCone,
dan glutSolidTorus untuk objek padat, serta glutWireSphere, glutWireCone,
dan glutWireTorus untuk objek berbentuk wireframe (kerangka). Setiap
objek diputar pada sumbu Z dengan kecepatan yang bergantung pada waktu yang
telah berlalu.
Contoh kode untuk menggambar bola 3D:
glPushMatrix();
glTranslated(-2.4,
1.2, -6);
glRotated(60, 1,
0, 0);
glRotated(a, 0, 0,
1);
glutSolidSphere(1,
slices, stacks);
glPopMatrix();
4. Menambahkan Pencahayaan
Pencahayaan
memainkan peran penting dalam memberikan kesan tiga dimensi dan meningkatkan
realisme objek. Program ini mengaktifkan pencahayaan dengan
menggunakan glEnable(GL_LIGHT0) dan mengonfigurasi sumber cahaya
dengan beberapa parameter, seperti ambient, diffuse, dan specular.
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
5. Interaktivitas dengan Pengguna
Program ini juga menyediakan interaktivitas dengan pengguna
menggunakan input dari keyboard. Pengguna dapat menekan tombol + untuk
menambah jumlah slices dan stacks pada objek, atau tombol - untuk
menguranginya. Fungsi key() mengatur interaksi ini.
static void key(unsigned char key, int x, int y)
{
switch (key)
{
case 27 :
case 'q':
exit(0);
break;
case '+':
slices++;
stacks++;
break;
case '-':
if (slices
> 3 && stacks > 3)
{
slices--;
stacks--;
}
break;
}
glutPostRedisplay();
}
6. Kesimpulan
Dengan menggunakan OpenGL dan GLUT, kita dapat membuat
tampilan grafis 3D yang interaktif dengan pencahayaan dan rotasi objek. Program
ini memberikan dasar yang kuat bagi pengembangan aplikasi grafis lebih lanjut
yang lebih kompleks. Menggunakan fungsi-fungsi seperti glutSolidSphere, glutWireTorus,
serta pencahayaan yang disesuaikan memungkinkan kita untuk menghasilkan efek
visual yang menarik dan realistis.
Program ini adalah contoh sederhana dari potensi besar OpenGL dalam membuat aplikasi grafis yang dapat berinteraksi dengan pengguna dan menampilkan objek 3D secara dinamis.
Komentar
Posting Komentar