• Tidak ada hasil yang ditemukan

EC5130 Grafika Komputer dan Pemrograman GPU

N/A
N/A
Protected

Academic year: 2021

Membagikan "EC5130 Grafika Komputer dan Pemrograman GPU"

Copied!
117
0
0

Teks penuh

(1)

EC5130 – Grafika Komputer dan

Pemrograman GPU

Suplemen Diktat Kuliah

OpenGL Tutorial dengan GLUT:

Fixed Pipeline

Ary Setijadi Prihatmanto

Sekolah Teknik Elektro & Informatika

Institut Teknologi Bandung

(2)

Table of Content

Table of Content ... 1

Tutorial 01. “Hello World” dengan GLUT ... 2

Tutorial 02. OpenGL Primitives ... 5

Tutorial 03. 3D Vertex ... 10

Tutorial 04. Callback Reshape ... 11

Tutorial 04. Modeling & Transformasi Proyeksi ... 13

Transformasi Proyeksi ... 15

Transformasi Viewing ... 17

Transformasi Modeling ... 17

Tutorial 05. Urutan Transformasi ... 20

Tutorial 06. Texture Mapping & Blending ... 23

Tutorial 07. Transparency ... 32

Tutorial 08. Fog ... 35

Tutorial 09. Obyek Kompleks ... 41

Tutorial 10. Particle System ... 62

Tutorial 11. Lighting ... 69

(3)

Tutorial 01. “Hello World” dengan GLUT

Tujuan dari bagian ini adalah untuk membuat OpenGL-based window. Ada banyak cara

untuk membuat dan memperlihatkan suatu window dalam berbagai sistem window. Salah

satunya adalah dengan menggunakan OpenGL Utility Toolkit. OpenGL UtilityToolkit

(GLUT) menyediakan banyak fungsi yang dapat membuat window dengan cara yang

independen terhadap sistem operasinya. Hal ini berarti program yang dibuat dengan

GLUT dapat beroperasi pada sistem windowing yang berbeda tanpa merubah code secara

manual.

GLUT adalah API (Application Programming Interface) dengan binding ANSI C untuk

penulisan Sistem Windows program OpenGL. GLUT adalah buatan Mark J. Killgard

ketika bekerja di Silicon Graphics Inc. Walaupun dirancang untuk digunakan

bersama-sama dengan kode OpenGL, GLUT dapat digunakan dengan atau tanpa OpenGL. Toolkit

ini mendukung fungsionalitas sebagai berikut:

• Multiplewindows untuk rendering OpenGL.

• Callback driven event processing.

• Sophisticated input devices.

• An “idle” routine and timers.

• A simple, cascading pop-up menu facility.

• Utility routines to generate various solid and wire frame objects.

• Support for bitmap and stroke fonts.

• Miscellaneous window management functions, including managing overlays.

Walaupun secara fungsional mungkin jauh tertinggal dari multiplatform window system

yang lain seperti Qt, namun kesederhanaan penggunaan serta hubungannya dengan API

grafika komputer OpenGL membuat glut masih banyak digunakan terutama sebagai alat

bantu pendidikan Grafika Komputer.

GLUT library dapat didownload dari

http://www.glut.org

. Setelah library GLUT diinstall,

GLUT dapat digunakan dengan mengacu ke header file glut.h. File tersebut selain

mendefinisikan beberapa hal-hal yang terkait dengan GLUT, mengacu pada opengl.h dan

glu.h juga memberikan arahan kepada compiler untuk me-link secara automatis dengan

library-library yang dibutuhkan contohnya opengl.lib(opengl32.lib), glu.lib(glu32.lib)

dan glut.lib(glut32.lib). Selain itu, untuk aplikasi di atas sistem operasi windows

memerlukan glut32.dll dapat terlihat oleh aplikasi.

Struktur dari aplikasi berbasis GLUT akan terdiri atas beberapa langkah berikut, yaitu:

• Menetapkan konfigurasi windows, dan membuka windows

• Inisialisasi status OpenGL

• Registrasi callback functions (jika dibutuhkan)

o Render

o Resize

o Input

o Timer

(4)

o Idle

• Enter event processing loop. Gambar 1 mengilustrasikan loop tersebut.

Gambar 1. GLUT Event Processing Loop yang disederhanakan

Fraksi kode berikut adalah contoh bagian main() dari suatu program GLUT:

void main( int argc, char** argv )

{

// Konfigurasi dan Menampilkan Window

int mode = GLUT_RGB|GLUT_DOUBLE;

glutInitDisplayMode( mode );

glutCreateWindow( argv[0] );

// Fungsi untuk melakukan initialisasi

init();

// Registrasi Callback Function

glutDisplayFunc( display );

glutReshapeFunc( resize );

glutKeyboardFunc( key );

glutIdleFunc( idle );

// Event Processing Loop

glutMainLoop();

(5)

}

Pada kode diatas, status OpenGL diinisialisasi di fungsi init(), sedangkan kode-kode

yang mengandung fungsi-fungsi rendering OpenGL biasanya merupakan bagian dari

fungsi callback display.

Program 01. GLUT “Hello World” & Gambar Segiempat

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> void mydisplay(){

glClear(GL_COLOR_BUFFER_BIT); // Menghapus layar glBegin(GL_POLYGON); glVertex2f(-0.5, -0.5); glVertex2f(-0.5, 0.5); glVertex2f(0.5, 0.5); glVertex2f(0.5, -0.5); glEnd(); glFlush(); }

int main(int argc, char** argv) {

printf(“Hello World… this is 2D Rectangle”); glutCreateWindow("simple");

glutDisplayFunc(mydisplay); glutMainLoop();

}

mydisplay() diregistrasi oleh glutDisplayFunc() sebagai fungsi yang dilaksanakan saat

window digambar, yang biasanya adalah isi dari gambarnya.. Hasilnya akan tampak

seperti gambar berikut:

Coba periksa dimensi window seperti koordinat titik tengah, titik kiri atas, titik kiri

bawah, titik kanan atas dan titik kanan bawah dengan merubah-rubah parameter fungsi

glVertex2f().

Diperoleh Koordinat:

- Titik Tengah ( ___, ___)

- Titik Kiri Atas ( ___, ___), Titik Kiri Bawah ( ___, ___)

- Titik Kanan Atas ( ___, ___), Titik Kanan Bawah ( ___, ___)

(6)

Tutorial 02. OpenGL Primitives

Pada tutorial 01 telah diberikan contoh program untuk merepresentasikan model obyek

segiempat 2D. OpenGL memiliki beberapa komponen dasar untuk merepresentasikan

suatu obyek. Komponen dasar tersebut disebut OpenGL Geometric primitives. Gambar

2 menggambarkan semua OpenGL Geometric primitives yang mungkin.

Gambar 2. OpenGL Geometric Primitives

Setiap obyek harus dimodelkan sebagai kombinasi dari komponen-komponen dasar

tersebut. Sebagai contoh, obyek segiempat pada tutorial 01 tersebut dimodelkan dengan

menggunakan komponen dasar GL_POLYGON. Obyek tersebut dapat pula dimodelkan

dengan komponen dasar GL_TRIANGLES atau pun GL_QUAD.

Hingga saat ini kita belum menerangkan secara detil masing-masing fungsi OpenGL.

Secara umum perintah-perintah dalam OpenGL memenuhi aturan sebagai berikut:

G

GL

L_

_Q

QU

UA

AD

D_

_S

ST

TR

RI

IP

P

G

GL

L_

_P

PO

OL

LY

YG

GO

ON

N

G

GL

L_

_T

TR

RI

IA

AN

NG

GL

LE

E_

_S

ST

TR

RI

IP

P

G

GL

L_

_T

TR

RI

IA

AN

NG

GL

LE

E_

_F

FA

AN

N

G

GL

L_

_P

PO

OI

IN

NT

TS

S

G

GL

L_

_L

LI

IN

NE

ES

S

G

GL

L_

_L

LI

IN

NE

E_

_L

LO

OO

OP

P

G

GL

L_

_L

LI

IN

NE

E_

_S

ST

TR

RI

IP

P

G

GL

L_

_T

TR

RI

IA

AN

NG

GL

LE

ES

S

G

GL

L_

_Q

QU

UA

AD

DS

S

(7)

Dalam OpenGL, menggambar geometric primitives selalu dilakukan di antara fungsi

glBegin(PRIMITIVES)

//

Fungsi

Menggambar Primitives di sini

glEnd()

Setiap OpenGL geometric primitive dispesifikasi oleh urutan vertex-vertex-nya dalam

bentuk urutan koordinat homogenous. Koordinat homogenous adalah koordinat dalam

bentuk ( x, y, z, w ). Setiap primitive memiliki standar tentang bagaimana vertex-vertex

diorganisasikan. Program 02 dan Program 03 memberikan contoh bagaimana

memodelkan primitive segitiga dan segidelapan.

Program 02. Segitiga

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); glVertex2f(-0.5, -0.5); glVertex2f(-0.5, 0.5); glVertex2f(0.5, 0.5); glEnd(); glFlush(); }

int main(int argc, char** argv){

glutCreateWindow("simple"); glutDisplayFunc(mydisplay); glutMainLoop();

g

g

l

l

V

V

e

e

r

r

t

t

e

e

x

x

3

3

f

f

v

v

(

(

v

v

)

)

N Nuummbbeerr ooff c coommppoonneennttss 2 2 -- ((xx,,yy)) 3 3 -- ((xx,,yy,,zz)) 4 4 -- ((xx,,yy,,zz,,ww)) D Daattaa TTyyppee b b -- bbyyttee u ubb -- uunnssiiggnneedd bbyyttee s s -- sshhoorrtt u uss -- uunnssiiggnneedd sshhoorrtt i i -- iinntt u uii -- uunnssiiggnneedd iinntt f f -- ffllooaatt d d -- ddoouubbllee V Veeccttoorr

o

om

mi

it

t

“v

v”

f

fo

or

r

s

sc

ca

al

la

ar

r

f

fo

or

rm

m

g

gl

lV

Ve

er

rt

te

ex

x2

2f

f(

(

x

x,

,

y

y

)

)

(8)

}

Program 03. Polygon Segi Delapan

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glColor3f(0, 1, 0); glVertex2f(-0.5, -0.5); glVertex2f(-0.75, 0); glVertex2f(-0.5, 0.5); glVertex2f(0, 0.75); glVertex2f(0.5, 0.5); glVertex2f(0.75, 0); glVertex2f(0.5, -0.5); glVertex2f(0,-0.75); glEnd(); glFlush(); }

int main(int argc, char** argv){

glutCreateWindow("simple"); glutDisplayFunc(mydisplay); glutMainLoop();

}

Perhatikan urutan dari vertex untuk setiap jenis OpenGL Geometric Primitive.

Tugas: Buat Program untuk menggambar jenis OpenGL Geometric Primitive yang

lain.

Bonus:

glColor3f()

adalah fungsi untuk menentukan warna yang berlaku hingga fungsi

berikutnya. Program 03 berikut adalah program yang sama dengan Program 02 hanya di

sini setiap vertex diberi warna yang berbeda.

(9)

Program 04. Polygon Segi Delapan dengan warna

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glColor3f(0, 1, 0); glVertex2f(-0.5, -0.5); glColor3f(0, 0, 1); glVertex2f(-0.75, 0); glColor3f(1, 0, 0); glVertex2f(-0.5, 0.5); glColor3f(0, 1, 0); glVertex2f(0, 0.75); glColor3f(0, 0, 1); glVertex2f(0.5, 0.5); glColor3f(1, 0, 0); glVertex2f(0.75, 0); glColor3f(0, 1, 0); glVertex2f(0.5, -0.5); glColor3f(0, 0, 1); glVertex2f(0,-0.75); glEnd(); glFlush(); }

int main(int argc, char** argv){

glutCreateWindow("simple"); glutDisplayFunc(mydisplay); glutMainLoop();

}

(10)
(11)

Tutorial 03. 3D Vertex

Semua vertex dari obyek yang dimodelkan di atas masih berada pada satu bidang z=0,

atau obyek yang dimodelkan masih berupa model 2D karena kita hanya memberikan

vertex properti koordinat x dan y dengan menggunakan fungsi glVertex2f().

Untuk memodelkan obyek dalam 3D kita perlu memberi properti koordinat z dengan

menggunakan fungsi glVertex3f(). Program 05 memberikan ilustrasi penggunaan fungsi

tersebut.

Program 05. 3 Dimensional Vertex

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glColor3f(0, 1, 0); glVertex3f(-0.5, -0.5, 1); glColor3f(0, 0, 1); glVertex3f(-0.75, 0, 1); glColor3f(1, 0, 0); glVertex3f(-0.5, 0.5, 1); glColor3f(0, 1, 0); glVertex3f(0, 0.75, 1); glColor3f(0, 0, 1); glVertex3f(0.5, 0.5, -1); glColor3f(1, 0, 0); glVertex3f(0.75, 0, -1); glColor3f(0, 1, 0); glVertex3f(0.5, -0.5, -1); glColor3f(0, 0, 1); glVertex3f(0,-0.75, -1); glEnd(); glFlush(); }

int main(int argc, char** argv){

glutCreateWindow("simple"); glutDisplayFunc(mydisplay); glutMainLoop();

(12)

Tutorial 04. Callback Reshape

Ambil Program 01 yang menggambar bujur sangkat sebagai dasar. Jika kita drag ujung

windows sehingga window tidak lagi berupa bujursangkar, bujursangkar-nya juga

berubah bentuk. Gambar berikut mengilustrasikan situasinya.

Agar gambar tetap berada pada proporsi yang tepat, maka perlu digunakan callback

reshape yang dipanggil setiap kali window berubah ukuran. Untuk itu perlu lakukan dua

langkah berikut:

- membuat fungsi yang akan dipanggil saat rehape, di sini fungsinya adalah

void reshape(int width, int height)

- melakukan registrasi callback reshape dengan fungsi glutReshapeFunc(.)

Program 06. ReShape Callback Function

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> void mydisplay(){

glClear(GL_COLOR_BUFFER_BIT); // Menghapus layar glBegin(GL_POLYGON); glVertex2f(-0.5, -0.5); glVertex2f(-0.5, 0.5); glVertex2f(0.5, 0.5); glVertex2f(0.5, -0.5); glEnd(); glFlush(); }

void resize( int w, int h ) {

if (w >= h)

glViewport(0, 0, (GLsizei)h, (GLsizei)h) ; else

glViewport(0, 0, (GLsizei)w, (GLsizei)w) ; }

int main(int argc, char** argv) {

(13)

glutCreateWindow("simple"); glutDisplayFunc(mydisplay); glutReshapeFunc(reshape);

glutMainLoop(); }

Hasilnya diilustrasikan pada gambar berikut:

glViewport(x_left, x_top, x_right, y_right) bertanggung jawab untuk melakukan

setting viewport dari suatu window, yaitu bagian dari window yang digunakan untuk

menggambar.

Selain setting glViewport() biasanya Reshape callback function juga digunakan untuk

mengatur Transformasi Proyeksi. Tutorial berikut akan memberi gambaran

(14)

Tutorial 04. Modeling & Transformasi Proyeksi

Secara substansi, Grafika Komputer adalah proses transformasi dari model 3D obyek

berupa informasi geometri bentuk, informasi pose, warna, texture, dan pencahayaan

menjadi citra 2D (cf. Gambar 3).

Gambar 3. Grafika Komputer: Transformasi dari Model 3D Obyek menjadi Citra

Jika dilihat secara analogi, hal di atas mirip dengan cara kerja kamera dalam mengambil

foto dalam bidang fotografi (cf. Gambar 4). Model ini disebut model sintesis kamera.

Gambar 4. Analogi Pengambilan Gambar oleh Kamera

Model 3D Obyek

-

Bentuk

-

Pose (Posisi & Orientasi)

-

Warna

-

Texture

-

Pencahayaan

Citra 2D Obyek

T

camera

tripod

model

viewing

volume

(15)

Untuk menghasilkan gambar dari obyek dengan skenario tertentu kita harus melakukan

beberapa proses, yaitu:

- melakukan pengesetan kamera dalam bentuk setting lensa kamera

(Transformasi Proyeksi),

- mengarah kamera dengan mengatur letak tripod (Transformasi Viewing),

- mengatur letak obyek (Transformasi Modeling), dan

- mengatur skala dan layout dari foto (Transformasi Viewport)

Kita telah mempelajari Transformasi Viewport pada tutorial sebelumnya dengan

menggunakan perintah glViewport(). Pada tutorial ini, kita akan mempelajari

transformasi-transformasi lainnya.

(16)

Transformasi Proyeksi

Lensa kamera dan mata manusia memiliki daerah penglihatan (viewing volume) yang

berbentuk kerucut, namun karena bentuk display yang biasanya berbentuk segiempat

membuat OpenGL (dan hampir semua API grafika komputer lain) lebih efisien

memodelkan daerah penglihatan sebagai volume berbentuk piramida.

Tipe transformasi proyeksi ada dua macam, bergantung pada parameter dan bentuk

piramidanya. Dua tipe transformasi tersebut adalah Transformasi Ortogonal/Paralel

(Orthogonal Transformation) dan Transformasi Perspektif(Perspective Transformation)

(cf. Gambar 5).

Gambar 5. Transformasi Ortogonal dan Transformasi Proyektif.

Transformasi Ortogonal/Paralel

Transformasi Perspektif

Pada tutorial sebelumnya digunakan transformasi orthogonal dengan parameter default.

Transformasi ini membuat jarak benda relatif terhadap kamera tidak berpengaruh pada

(17)

citra benda tersebut. Biasanya transformasi ini digunakan pada aplikasi-aplikasi teknik

seperti gambar teknik (cf. Gambar 6). Untuk merubah parameter transformasi ortogonal

dapat menggunakan perintah glOrtho() dengan didahului proses merubah status OpenGL

ke mode proyeksi dengan perintah glMatrixMode(GL_PROJECTION).

Gambar 6. Contoh Transformasi Ortogonal/Paralel

Pada tutorial ini dan selanjutnya, kita akan memfokuskan diri pada transformasi yang

banyak digunakan yaitu transformasi perspektif. Pada transformasi jenis ini jarak benda

akan mempengaruhi gambar yang di buat. Parameter transformasi jenis ini dapat dirubah

dengan menggunakan gluPerspective()/glFrustum() , juga dengan didahului proses

merubah status OpenGL ke mode proyeksi dengan perintah

glMatrixMode(GL_PROJECTION).

glMatrixMode(GL_PROJECTION);

glLoadIdentity( );

gluPerspective(fovy, aspect, near, far);

A

Section AA

Front elevation view

(18)

fovy adalah sudut antara bidang bottom dan up.

Transformasi Viewing

Untuk menghasilkan gambar, kamera perlu diletakkan pada posisi yang tepat didepan

pemandangan yang diinginkan. Secara default, dalam OpenGL kemera akan berada pada

posisi (0,0,0) dengan menghadap ke arah z = -1 dengan sumbu y mengarah ke atas

kamera. Hal ini dapat dilakukan dengan menggunakan perintah gluLookAt() dengan

didahului proses merubah status OpenGL ke mode proyeksi dengan perintah

glMatrixMode(GL_MODELVIEW).

Transformasi Modeling

Selain posisi dan orientasi kamera yang dapat dirubah-rubah, secara natural obyek juga

dapat berpindah posisi dan orientasi relatif terhadap yang lain.Transformasi obyek dapat

direpresentasikan dengan dua cara, yaitu:

- menggunakan matriks transformasi (glLoadMatrix)

- menggunakan operasi transformasi (glRotate, glTranslate)

dengan didahului proses merubah status OpenGL ke mode proyeksi dengan perintah

glMatrixMode(GL_MODELVIEW).

Program dibawah memberi ilustrasi tentang bagaimana transformasi di atas

diimplementasikan. Sebagai tambahan juga diberikan tentang callback keyboard untuk

menangani input keyboard. Obyek ditranslasikan pada sumbu z dengan menggunakan

tombol keyboard “,” dan “.”.Callback timer digunakan untuk timer yang di sini

digunakan untuk animasi berputar.

Program 07. Proyeksi Perspektif

// - Viewing Volume of Perspective Projection // - Try the keyboard callback

// - Reshape callback // - Timer

(19)

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> float z_pos=0.0f; float rot=0.0f; void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0,0.0f,z_pos); glRotatef(rot, 0, 0, 1); glBegin(GL_POLYGON); glColor3f(0, 1, 0); glVertex3f(-0.5, -0.5, -5); glColor3f(0, 0, 1); glVertex3f(-0.75, 0, -5); glColor3f(1, 0, 0); glVertex3f(-0.5, 0.5, -5); glColor3f(0, 1, 0); glVertex3f(0, 0.75, -5); glColor3f(0, 0, 1); glVertex3f(0.5, 0.5, -5); glColor3f(1, 0, 0); glVertex3f(0.75, 0, -5); glColor3f(0, 1, 0); glVertex3f(0.5, -0.5, -5); glColor3f(0, 0, 1); glVertex3f(0,-0.75, -5); glEnd(); glFlush(); glutSwapBuffers(); }

void init( void ) {

glClearColor( 1.0, 0.0, 0.0, 1.0 ); // A Background Clear Color

glMatrixMode(GL_PROJECTION); glLoadIdentity();

gluPerspective(45, (GLdouble)500.0/(GLdouble)500.0, 0, 100); glMatrixMode(GL_MODELVIEW);

}

void resize( int w, int h ) {

glViewport( 0, 0, (GLsizei) w, (GLsizei) h ); glMatrixMode( GL_PROJECTION );

glLoadIdentity();

gluPerspective(45, (GLdouble)w/(GLdouble)h, 0, 100); glMatrixMode( GL_MODELVIEW );

}

(20)

{

// called if timer event

// ...advance the state of animation incrementally...

rot+=10;

glutPostRedisplay(); // request redisplay

glutTimerFunc(100, myTimeOut, 0); // request next timer event

}

void myKeyboard(unsigned char key,int x, int y) {

if((key=='<')||(key==',')) z_pos-=0.1f;

if((key=='>')||(key=='.')) z_pos+=0.1f; }

int main(int argc, char** argv) { glutInit(&argc,argv); //glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("simple"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); }

Tambahan:

Konsep Double Buffer. Pada program di atas mode display menggunakan tipe

GLUT_DOUBLE yang diikuti oleh glutSwapBuffers(). Hal ini merupakan teknik yang

disebut Double Buffer untuk menghindari flicker. Untuk mengetahui apa itu flicker,

ubah mode display menjadi GLUT_SINGLE dan hapus/commented perintah

(21)

Tutorial 05. Urutan Transformasi

Transformasi dapat dilakukan pada level vertex, level surface, maupun level obyek

bergantung dimana transformasi diletakkan dalam program. Operasi transformasi

merupakan operasi yang tidak bersifat komutatif, artinya, urutan transformasi juga

sangat berpengaruh pada hasilnya. Gambar 7 memberi ilustrasi akibat urutan transformasi

yang berbeda, yaitu hasil operasi “rotasi kemudian di translasi” berbeda dengan operasi

“translasi baru dirotasi”.

Gambar 7. Pengaruh urutan transformasi

Program 08 di bawah ini mirip dengan Program 07, hanya sekarang obyeknya sudah

berupa obyek 3D berupa kubus. Perhatikan bagaimana kubus dibentuk dari vertex dan

surface. Selain dengan mendefinisikan obyeknya sendiri, GLUT telah menyediakan

beberapa fungsi untuk menggambar standard obyek, yaitu kubus, bola, dan poci teh.

Perhatikan apa yang terjadi bila glTranslate() dan glRotate() di fungsi mydisplay()

ditukar posisinya atau diletakkan didalam salah satu glBegin()..glEnd()

// OpenGL

// - Complex Object // - Notice:

// 1. There are surfaces that are not correctly rendered in order. // uncommented the GL_DEPTH

// 2. Flicker can be eliminated by using GL_DOUBLE //

// Rubah rendering algoritma dengan menggunakan data struktur // #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> float z_pos=-10.0f; float rot=0.0f;

void resize(int width, int height) {

(22)

glMatrixMode(GL_PROJECTION); glLoadIdentity();

gluPerspective(45.0, (float)width/(float)height, 1.0, 300.0); glMatrixMode(GL_MODELVIEW);

glLoadIdentity(); }

void myTimeOut(int id) {

// called if timer event

// ...advance the state of animation incrementally...

rot+=10;

glutPostRedisplay(); // request redisplay

glutTimerFunc(100, myTimeOut, 0); // request next timer event

}

void myKeyboard(unsigned char key,int x, int y) {

if((key=='<')||(key==',')) z_pos-=0.1f;

if((key=='>')||(key=='.')) z_pos+=0.1f; }

void mydisplay(void) { glClear(GL_COLOR_BUFFER_BIT ); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0,0.0f,z_pos); glRotatef(rot, 0, 1, 0); glBegin(GL_QUADS);

// Front Face, red

glColor3f(1.0,0.0,0.0); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);

// Back Face, green

glColor3f(0.0,1.0,0.0); glVertex3f( 1.0f, -1.0f, -1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);

// Top Face, blue

glColor3f(0.0,0.0,1.0); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);

// Bottom Face, yellow

glColor3f(1.0,1.0,0.0); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f);

// Right face, cyan

glColor3f(0.0,1.0,1.0); glVertex3f( 1.0f, -1.0f, -1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f);

(23)

// Left Face, magenta glColor3f(1.0,0.0,1.0); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); glFlush(); glutSwapBuffers(); } void init() { glEnable(GL_DEPTH_TEST);

glClearColor( 0.0, 0.0, 0.0, 1.0 ); // A Background Clear Color

glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45, (GLdouble)500.0/(GLdouble)500.0, 0, 100); glMatrixMode(GL_MODELVIEW); return; }

int main(int argc, char** argv) {

glutInit(&argc,argv);

//glutInitDisplayMode( GLUT_DOUBLE /*| GLUT_DEPTH*/ );

glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("simple"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }

Tambahan:

Konsep Depth Buffer. Mode display pada program di atas diberi tambahan mode

GLUT_DEPTH dan perintah glEnable(GL_DEPTH_TEST). Hal ini untuk memastikan

bahwa surface digambar sesuai dengan urutan penampakkan yang logis. Teknik ini

merupakan salah satu algoritma HIDDEN SURFACE REMOVAL. Untuk melihat apa

yang terjadi bila teknik ini tidak dilakukan, hapus/commented moda GLUT_DEPTH dan

glEnable(GL_DEPTH_TEST).

(24)

Tutorial 06. Texture Mapping & Blending

Hingga tahap ini, geometric primitive digambar dengan warna solid atau warna hasil

interpolasi warna-warna vertex-nya. Texture mapping memungkinkan untuk menaruh

gambar pada geometric primitive tersebut dan sekaligus mengikuti transformasi yang

diterapkan kepada polygon tersebut (cf. Gambar 8).

Gambar 8. Konsep Texture Mapping

Texture merupakan data segi-empat sederhana yang berada pada bidang texture. Bidang

texture diwakili oleh dua sumbu koordinat yaitu sumbu s dan sumbu t. Setiap texture

akan memenuhi bidang koordinat (0.0,0.0) sd. (1.0,1.0). Nilai individual dari array

texture biasanya dikenal dengan istilah texels (texture pixels).

Yang membuat texture mapping sedikit rumit adalah bagaimana proses pemetaan antara

bentuk segi-empat texture ke polygon menginngat secara umum bentuk poligon biasanya

non-rectangular.

Beberapa contoh penggunaan texture mapping antara lain:

• mensimulasikan aspek visual dari material seperti tampakan kayu, batu bata, atau

granit

• mengurangi kompleksitas (jumlah polygon yang dibutuhkan) dari suatu obyek

geometri.

• teknik pemrosesan citra seperti image warping dan rectification, rotation dan

scaling

s

t

x

y

z

image

geometry

screen

(0.0,1.0)

(1.0,0.0)

(0.0,0.0)

(25)

• mensimulasikan berbagai efek permukaan seperti efek reflektif seperti cermin

atau lantai yang telah digosok mengkilat, efek tonjolan dll.

Salah satu keuntungan dari texture mapping adalah bahwa detail visual itu berada di citra

bukan di geometri. Dan sekompleks apapun citra, selama tidak merubah ukuran citra,

tidak berpengaruh pada kinerja keseluruhan, yaitu kompleksitas cari citra tidak

berpengaruh kepada pipeline geometric (transformasi, clipping) dari OpenGL.

Texture ditambahkan saat rasterisasi ketika geometric pipeline dan pixel pipeline bertemu

seperti diilustrasikan pada Gambar berikut.

Secara konseptual ada tiga langkah dalam melakukan texture mapping, yaitu:

- Penentuan texture

o Baca image dari file

o Generate texture id untuk image tersebut glGenTextures(3, &texture[0])

- Pemberian koordinat texture ke vertex

- Penentuan parameter texture (wrapping / filtering)

Program 09 memberi ilustrasi tentang proses di atas. Perhatikan:

- baris T

extureImage[0]=LoadBMP("Crate.bmp").

Ubah sesuai file citra bmp

yang anda punya.

- prosedur int LoadGLTexture(). Perhatikan bagaimana menggunakan citra bmp

yang telah diload ke memory dalam bentuk struktur data

AUX_RGBImageRec* menjadi tiga buah texture dalam OpenGL dg metoda filter

pembesaran texture yang berbeda. Metoda itu adalah yaitu metoda Nearest Filtered Texture, metoda Linear Interpolation Texture dan metoda Mipmapped Texture. Perhatikan bedanya dengan merubah-rubah filternya menggunakan tombol keyboard “f”.

Filter pembesaran texture berpengaruh pada bagaimana OpenGL melakukan proses

rasterisasi texture saat texture ditampilkan pada jumlah pixel yang lebih besar atau lebih

kecil dari ukuran sebenarnya. Pada Nearest Filtered Texture, texture yang ditampilkan

merupakan hasil pemilihan nilai pixel pada posisi terdekat. Sedangkan dengan Linear

Interpolation Texture (LPT), texture yang ditampilkan merupakan hasil interpolasi

linear antara pixel-pixel disekitarnya. Pada Mipmapped Texture(MPT), interpolasi

linear dilakukan pada awal secara offline sehingga dihasilkan banyak texture dengan

ukuran dari yang kecil hingga yang besar. LPT dan MPT akan menghasilkan kira-kira

geometry pipeline

vertices

pixel pipeline

image

(26)

hasil yang sama dengan LPT akan sedikit lebih lambat dari MPT walaupun memori yang

digunakan jauh lebih kecil.

Program 09

Bmp.h

#include <GL/glaux.h>

AUX_RGBImageRec *LoadBMP(char *Filename);

Bmp.cpp

#include <windows.h>

#include <stdio.h> // Header File For Standard Input/Output

#include <gl\gl.h> // Header File For The OpenGL32 Library

#include <gl\glu.h> // Header File For The GLu32 Library

#include <gl\glaux.h> // Header File For The Glaux Library

#include "bmp.h"

AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image

{

FILE *File=NULL; //

File Handle

if (!Filename)

// Make Sure A Filename Was Given {

return NULL;

// If Not Return NULL }

File=fopen(Filename,"r"); //

Check To See If The File Exists

if (File)

// Does The File Exist? {

fclose(File);

// Close The Handle

return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer

}

return NULL;

// If Load Failed Return NULL }

Program.cpp

// OpenGL

(27)

// - Texture Mapping Magnification Filter // filter=0 --> Nearest Filtered Texture // filter=1 --> Linear Interpolation Texture // filter=2 --> Mipmapped Texture

#include <windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> #include "bmp.h" float z_pos=-5.0f; float rot=0.0f; GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f }; /* array to hold texture handles */

GLuint filter; // Which Filter To Use

GLuint texture[3]; // Storage For 3 Textures

int LoadGLTextures() //

Load Bitmaps And Convert To Textures {

int Status=FALSE; //

Status Indicator

AUX_RGBImageRec *TextureImage[1]; // Create

Storage Space For The Texture

memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL

// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit

if (TextureImage[0]=LoadBMP("Crate.bmp")) {

Status=TRUE; // Set The Status To TRUE

glGenTextures(3, &texture[0]); //

Create Three Textures

// Create Nearest Filtered Texture

glBindTexture(GL_TEXTURE_2D, texture[0]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, >sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

(28)

glBindTexture(GL_TEXTURE_2D, texture[1]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, >sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

// Create MipMapped Texture

glBindTexture(GL_TEXTURE_2D, texture[2]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_

NEAREST);

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); }

if (TextureImage[0]) //

If Texture Exists {

if (TextureImage[0]->data) //

If Texture Image Exists {

free(TextureImage[0]->data); // Free

The Texture Image Memory }

free(TextureImage[0]); //

Free The Image Structure }

return Status;

// Return The Status }

void resize(int width, int height) {

glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(45.0, (float)width/(float)height, 1.0, 300.0);

glMatrixMode(GL_MODELVIEW); glLoadIdentity();

}

void myTimeOut(int id) {

// called if timer event

// ...advance the state of animation incrementally... rot+=10;

glutPostRedisplay(); // request redisplay

glutTimerFunc(100, myTimeOut, 0); // request next timer event }

(29)

{

if((key=='<')||(key==',')) z_pos-=0.1f;

else if((key=='>')||(key=='.')) z_pos+=0.1f;

else if((key=='F')||(key='f')) { filter+=1; if (filter>2) { filter=0; } printf("filter: %i",filter); } }

void mydisplay(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLoadIdentity(); glTranslatef(0.0,0.0f,z_pos); glRotatef(rot, 0, 1, 0); glBindTexture(GL_TEXTURE_2D, texture[filter]); glBegin(GL_QUADS); // Front Face glColor3f(1.0,0.0,0.0); glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Back Face glNormal3f( 0.0f, 0.0f,-1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Face glNormal3f( 0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Bottom Face glNormal3f( 0.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Right face glNormal3f( 1.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);

(30)

glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Left Face glNormal3f(-1.0f, 0.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); glFlush(); glutSwapBuffers(); } void init() { if (!LoadGLTextures()) //

Jump To Texture Loading Routine {

return; //

If Texture Didn't Load Return FALSE }

glEnable(GL_TEXTURE_2D); //

Enable Texture Mapping

glShadeModel(GL_SMOOTH); //

Enable Smooth Shading

glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black

Background

glClearDepth(1.0f);

// Depth Buffer Setup

glEnable(GL_DEPTH_TEST); //

Enables Depth Testing

glDepthFunc(GL_LEQUAL); //

The Type Of Depth Testing To Do

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations

glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light

glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light

glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light

glEnable(GL_LIGHT1);

return; }

int main(int argc, char** argv) {

glutInit(&argc,argv);

glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize(500,500);

(31)

glutCreateWindow("simple"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }

Seringkali, efek yang diinginkan dapat diperoleh dengan mencampur lebih dari satu

texture. Proses pencampuran lebih dari satu texture disebut dengan istilah blending.

Salah satu efek blending yang paling sederhana adalah dengan memblending texture

dengan warna.

Fragment program 10 di bawah memperlihatkan perubahan yang terjadi pada void

mydisplay() jika kita ingin melakukan pencampuran antara texture dan warna.

Perhatikan fungsi glEnable(GL_BLEND). Di sini texture di blend dengan warna merah.

TUGAS: coba rubah codenya agar warna blending berbeda-beda pada setiap surface dari

box-nya.

Program 10.

void mydisplay(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLoadIdentity(); glTranslatef(0.0,0.0f,z_pos); glRotatef(rot, 0, 1, 0);

glEnable(GL_BLEND); // Turn Blending On glColor3f(1.0,0.0,0.0); // Blending Color glBindTexture(GL_TEXTURE_2D, texture[filter]); glBegin(GL_QUADS); // Front Face glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Back Face

(32)

glNormal3f( 0.0f, 0.0f,-1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Face glNormal3f( 0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Bottom Face glNormal3f( 0.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Right face glNormal3f( 1.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Left Face glNormal3f(-1.0f, 0.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); glFlush(); glutSwapBuffers(); }

(33)

Tutorial 07. Transparency

Salah satu efek yang dapat ditampilkan dari blending adalah transparency, yaitu

bagaimana membuat suatu permukaan tampak transparant. Hal ini dicapai dengan

menggunakan warna blending putih (full-brightness) dengan transparansi satu dengan

fungsi:

glColor4f(1.0f, 1.0f, 1.0f, 0.5);// Full Brightness. 50% Alpha glBlendFunc(GL_SRC_ALPHA,GL_ONE);

Program 11 menampilkan perubahan yang terjadi pada void init() dan void mydisplay()

pada Program 10 untuk menghasilkan suatu box tranparan. Coba untuk merubah

texturenya dengan citra yang lebih sesuai agar didapat nuansa boks dengan material kaca

dari pada boks “hantu”, seperti pada Gambar berikut:

Program 11

void mydisplay(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLoadIdentity(); glTranslatef(0.0,0.0f,z_pos); glRotatef(rot, 0, 1, 0); glBindTexture(GL_TEXTURE_2D, texture[filter]);

glEnable(GL_BLEND); // Turn Blending On

glDisable(GL_DEPTH_TEST); // Turn Depth Testing Off

glBegin(GL_QUADS); // Front Face glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);

(34)

glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Back Face glNormal3f( 0.0f, 0.0f,-1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Face glNormal3f( 0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Bottom Face glNormal3f( 0.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Right face glNormal3f( 1.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Left Face glNormal3f(-1.0f, 0.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); glFlush(); glutSwapBuffers(); } void init() { if (!LoadGLTextures())

// Jump To Texture Loading Routine

{

return;

// If Texture Didn't Load Return FALSE

}

glEnable(GL_TEXTURE_2D); //

Enable Texture Mapping

glShadeModel(GL_SMOOTH); //

Enable Smooth Shading

glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background

glClearDepth(1.0f);

// Depth Buffer Setup

glEnable(GL_DEPTH_TEST); //

Enables Depth Testing

glDepthFunc(GL_LEQUAL);

// The Type Of Depth Testing To Do

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations

(35)

glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light

glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light

glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light glEnable(GL_LIGHT1); glColor4f(1.0f, 1.0f, 1.0f, 0.5); // Full Brightness. 50% Alpha glBlendFunc(GL_SRC_ALPHA,GL_ONE); return; }

TUGAS: Pada Program 10 seluruh bagian dari boks bersifat transparan. Coba rubah agar

hanya satu bagian saja yang menjadi transparan dengan texture yang berbeda dari

(36)

Tutorial 08. Fog

Kabut/fog adalah salah satu fitur OpenGL lain yang sering digunakan pada banyak

kesempatan. Kabut digunakan dalam banyak kesempatan, antara lain:

- mensimulasikan efek kabut

- membatasi ruang pandang pengguna agar komputasi grafis yang diperlukan dapat

dibatasi. Hal ini terutama dilakukan pada era-era ketika algoritma grafis masih

dilakukan di CPU.

Program 12 memperlihatkan bagaimana menggunakan fungsi-fungsi OpenGL yang

terkait dengan fog.

Program 12.

// OpenGL

// - Fog Filter

// fogfilter=0 --> Nearest Filtered Texture // fogfilter=1 --> Linear Interpolation Texture // fogfilter=2 --> Mipmapped Texture

#include <windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> #include "bmp.h" float z_pos=-5.0f; float rot=0.0f; GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f }; /* array to hold texture handles */

GLuint filter; // Which Filter To Use

GLuint texture[3]; // Storage For 3 Textures // Fog

bool gp;

GLuint fogfilter;

GLuint fogMode[]={GL_EXP, GL_EXP2, GL_LINEAR}; GLfloat fogColor[4]={0.5f, 0.5f, 0.5f, 1.0f};

int LoadGLTextures() //

Load Bitmaps And Convert To Textures {

int Status=FALSE; //

(37)

AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture

memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL

// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit

if (TextureImage[0]=LoadBMP("glass.bmp")) {

Status=TRUE; // Set The Status To TRUE

glGenTextures(3, &texture[0]); //

Create Three Textures

// Create Nearest Filtered Texture

glBindTexture(GL_TEXTURE_2D, texture[0]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, >sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

// Create Linear Filtered Texture

glBindTexture(GL_TEXTURE_2D, texture[1]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, >sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

// Create MipMapped Texture

glBindTexture(GL_TEXTURE_2D, texture[2]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_

NEAREST);

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); }

if (TextureImage[0]) //

If Texture Exists {

if (TextureImage[0]->data) //

If Texture Image Exists {

free(TextureImage[0]->data); // Free

The Texture Image Memory }

free(TextureImage[0]); //

Free The Image Structure }

(38)

return Status; // Return The Status

}

void resize(int width, int height) {

glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(45.0, (float)width/(float)height, 1.0, 300.0);

glMatrixMode(GL_MODELVIEW); glLoadIdentity();

}

void myTimeOut(int id) {

// called if timer event

// ...advance the state of animation incrementally... rot+=1;

glutPostRedisplay(); // request redisplay

glutTimerFunc(100, myTimeOut, 0); // request next timer event }

void myKeyboard(unsigned char key,int x, int y) {

if((key=='<')||(key==',')) z_pos-=0.1f;

else if((key=='>')||(key=='.')) z_pos+=0.1f;

else if((key=='F')||(key='f')) { filter+=1; if (filter>2) { filter=0; } printf("filter: %i \n",filter); }

else if( (key=='G') || (key=='g')) {

if(gp==FALSE) {

gp=TRUE; fogfilter+=1;

if (fogfilter>2) // Is fogfilter Greater Than 2? {

fogfilter=0; // If So, Set fogfilter To Zero }

glFogi (GL_FOG_MODE, fogMode[fogfilter]); // Fog Mode } else { gp=FALSE; } printf("filter: %i \n",fogfilter); } }

(39)

void mydisplay(void) { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLoadIdentity(); glTranslatef(0.0,0.0f,z_pos); glRotatef(rot, 0, 1, 0); glBindTexture(GL_TEXTURE_2D, texture[filter]); glBegin(GL_QUADS); // Front Face glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Back Face glNormal3f( 0.0f, 0.0f,-1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Face glNormal3f( 0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Bottom Face glNormal3f( 0.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Right face glNormal3f( 1.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Left Face glNormal3f(-1.0f, 0.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); glFlush(); glutSwapBuffers(); }

(40)

void init() {

if (!LoadGLTextures()) //

Jump To Texture Loading Routine {

return; //

If Texture Didn't Load Return FALSE }

glEnable(GL_TEXTURE_2D); //

Enable Texture Mapping

glShadeModel(GL_SMOOTH); //

Enable Smooth Shading // FOG

glClearColor(0.5f,0.5f,0.5f,1.0f); // We'll Clear To The Color Of The Fog

glFogi(GL_FOG_MODE, fogMode[fogfilter]); // Fog Mode glFogfv(GL_FOG_COLOR, fogColor); // Set Fog Color

glFogf(GL_FOG_DENSITY, 0.35f); // How Dense Will The Fog Be glHint(GL_FOG_HINT, GL_DONT_CARE); // Fog Hint Value

glFogf(GL_FOG_START, 100.0f); // Fog Start Depth glFogf(GL_FOG_END, 1000.0f); // Fog End Depth glEnable(GL_FOG);

glClearDepth(1.0f);

// Depth Buffer Setup

glEnable(GL_DEPTH_TEST); //

Enables Depth Testing

glDepthFunc(GL_LEQUAL); //

The Type Of Depth Testing To Do

glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light

glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light

glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light

glEnable(GL_LIGHT1);

return; }

int main(int argc, char** argv) {

glutInit(&argc,argv);

glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("simple"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutTimerFunc(100, myTimeOut, 0);

(41)

glutReshapeFunc(resize); init();

glutMainLoop();

return 0; }

Variabel global dibuat agar kita bisa mencoba-coba tiga macam mode fog. Pada void

init() terdapat beberapa baris kode baru, yaitu:

- glEnable(GL_FOG) yang melakukan inisialisasi fog

- glFogi(GL_FOG_MODE, fogMode[fogfilter]); menentukan mode fog dengan

variabel array fogMode. Variabel fogMode diinisialisasi dengan tiga nilai, yaitu

GL_EXP, GL_EXP2, dan GL_LINEAR.:

o GL_EXP – fog standar yang dirender pada keseluruhan screen. Efek fognya

tidak terlalu terlihat namun jenis yang paling cepat dirender.

o GL_EXP2 – fog jenis ini juga mirip dengan GL_EXP, hanya akan memberikan

kesan dalam pada scene.

o GL_LINEAR – pada fog jenis ini, efek fog diinterpolasi secara linier

bergantung jarak dengan kamera sehingga didapat efek yang lebih baik.

- glFogfv(GL_FOG_COLOR, fogcolor); menentukan warna dari fog.

- glFogf(GL_FOG_DENSITY, 0.35f); menentukan seberapa padat kabutnya. Semakin

tinggi nilainy, semakin pekat kabut yang dihasilkan.

- The line glHint (GL_FOG_HINT, GL_DONT_CARE); memberikan informasi

kepada OpenGL tentang bagaimana proses rendering ingin dilakukan.

o gl_dont_care – terserah openGL

o gl_nicest – perhitungan fog dilakukan per-pixel.

o gl_fastest – perhitungan fog dilakukan per-vertex yang berarti lebih cepat tapi

lebih tidak akurat.

- glFogf(GL_FOG_START, 1.0f); menentukan jarak dari kamera ketika fog mulai.

- glFogf(GL_FOG_END, 5.0f); menentukan sejauh mana kabut masih berefek.

TUGAS: Rubah berbagai variabel di atas untuk memlihat apa pengaruhnya.

(42)

Tutorial 09. Obyek Kompleks

Hingga tahap ini obyek yang digunakan masih berangkat dari pemodelan manual

sehingga model yang dihasilkan masih sederhana. Kebutuhan untuk dapat menggunakan

model yang lebih kompleks sangat besar. Ada banyak aplikasi perangkat lunak yang

dapat digunakan untuk membuat model dengan lebih mudah. Contoh aplikasi untuk

pembuatan model 3D antara lain: 3DS Max, Blender, Maya, Milkshape dengan dibantu

aplikasi pemrosesan citra 2D seperti Photoshop, Corel dll. Format-format file standar

model 3D yang biasa digunakan antara lain .3ds, .obj, dll.

Persoalannya adalah bagaimana kita dapat menggunakan hasil dari aplikasi perangkat

lunak tersebut dalam program kita. Untuk itu kita membutuhkan kode untuk membaca

file tersebut dalam dan merepresentasikannya ke dalam program kita.

Tutorial 09 memberikan ilustrasi tentang bagaimana kita membaca file model 3D dan

menggunakannya dalam program berbasis openGL dan GLUT. Pertama file dalam

format .txt yang kita buat sendiri dan kemudian dengan format file .3ds. Model dengan

format 3DS sendiri awalnya merupakan file format pada versi-versi awal aplikasi 3D

Studio dari Autodesk Animation Ltd. sebelum berubah menjadi format file yang lebih

kompleks dengan aplikasinya menjadi 3D Studio Max. Format ini merupakan salah satu

format yang paling banyak dikenal.

Suatu set model 3D yang direpresentasikan oleh file .3ds biasanya ditemani oleh

beberapa file citra untuk texture dari model tersebut. Format file-nya disusun dengan

organisasi sebagai berikut:

Pada Program 13 kita membuat file model 3D dengan format kita sendiri. File format kita

adalah file .txt yang formatnya akan berupa aturan sebagai berikut:

- Kita dapat memasukkan baris kosong semau kita agar file lebih mudah dibaca

- Kita dapat memasukkan baris komentar dengan menambahkan “//” pada awal

baris

- Hanya terkait dengan satu file texture

- Primitif yang digunakan hanya GL_TRIANGLES

- Informasi awalnya akan berupa frasa NUMPOLLIES xx, dengan xx adalah

jumlah primitif

- Setelah itu kita harus memberi spesifikasi triangle-nya dengan menuliskan daftar

vertex perbaris dengan format baris sbb.

X

Y

Z S T

dengan X,Y, Z adalah posisi vertex sedangkan S, T adalah pixel texture yang

bersesuaian.

Contoh datanya juga diberikan pada bagian bawah dari Program 13.

Program 13

#include <windows.h>

#include <math.h> // Math Library Header File

#include <stdio.h>

(43)

#include <string.h>

#include <stdarg.h>

#include <GL/glut.h>

#include <GL/glaux.h>

const float piover180 = 0.0174532925f;

float heading;

float xpos;

float zpos;

GLfloat yrot; // Y Rotation GLfloat walkbias = 0;

GLfloat walkbiasangle = 0; GLfloat lookupdown = 0.0f;

GLfloat z=0.0f; // Depth Into The Screen

GLuint filter; // Which Filter To Use

GLuint texture[3]; // Storage For 3 Textures

typedef struct tagVERTEX {

float x, y, z;

float u, v; } VERTEX;

typedef struct tagTRIANGLE {

VERTEX vertex[3];

} TRIANGLE;

typedef struct tagSECTOR {

int numtriangles;

TRIANGLE* triangle; } SECTOR;

SECTOR sector1; // Our Model Goes Here:

void readstr(FILE *f,char *string) {

do

{

fgets(string, 255, f);

} while ((string[0] == '/') || (string[0] == '\n'));

return; } void SetupWorld() { float x, y, z, u, v; int numtriangles; FILE *filein; char oneline[255];

filein = fopen("data/world.txt", "rt"); // File To Load World Data From

(44)

sscanf(oneline, "NUMPOLLIES %d\n", &numtriangles); sector1.triangle = new TRIANGLE[numtriangles]; sector1.numtriangles = numtriangles;

for (int loop = 0; loop < numtriangles; loop++) {

for (int vert = 0; vert < 3; vert++) {

readstr(filein,oneline);

sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v); sector1.triangle[loop].vertex[vert].x = x; sector1.triangle[loop].vertex[vert].y = y; sector1.triangle[loop].vertex[vert].z = z; sector1.triangle[loop].vertex[vert].u = u; sector1.triangle[loop].vertex[vert].v = v; } } fclose(filein); return; }

AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image

{

FILE *File=NULL; // File Handle

if (!Filename) // Make Sure A Filename Was Given

{

return NULL; // If Not Return NULL }

File=fopen(Filename,"r"); // Check To See If The File Exists

if (File) // Does The File Exist?

{

fclose(File); // Close The Handle

return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer

}

return NULL; // If Load Failed Return NULL

}

int LoadGLTextures() // Load Bitmaps And Convert To Textures

{

int Status=FALSE; // Status Indicator

AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture

memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL

(45)

// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit

if (TextureImage[0]=LoadBMP("Data/Mud.bmp")) {

Status=TRUE; // Set The Status To TRUE

glGenTextures(3, &texture[0]); // Create Three Textures

// Create Nearest Filtered Texture

glBindTexture(GL_TEXTURE_2D, texture[0]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, >sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

// Create Linear Filtered Texture

glBindTexture(GL_TEXTURE_2D, texture[1]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, >sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

// Create MipMapped Texture

glBindTexture(GL_TEXTURE_2D, texture[2]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_

NEAREST);

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); }

if (TextureImage[0]) // If Texture Exists {

if (TextureImage[0]->data) // If Texture Image Exists

{

free(TextureImage[0]->data); // Free The Texture Image Memory

}

free(TextureImage[0]); // Free The Image Structure

}

return Status; // Return The Status }

void resize(int width, int height) // Resize And Initialize The GL Window

{

if (height==0)

(46)

{

height=1;

// Making Height Equal One }

glViewport(0,0,width,height); // Reset

The Current Viewport

glMatrixMode(GL_PROJECTION); // Select

The Projection Matrix

glLoadIdentity(); //

Reset The Projection Matrix

// Calculate The Aspect Ratio Of The Window

gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

glMatrixMode(GL_MODELVIEW); //

Select The Modelview Matrix

glLoadIdentity(); //

Reset The Modelview Matrix }

void init() // All

Setup For OpenGL Goes Here {

if (!LoadGLTextures()) //

Jump To Texture Loading Routine {

return; //

If Texture Didn't Load Return FALSE }

glEnable(GL_TEXTURE_2D); //

Enable Texture Mapping

glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set

The Blending Function For Translucency

glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This

Will Clear The Background Color To Black

glClearDepth(1.0); // Enables Clearing Of The Depth Buffer

glDepthFunc(GL_LESS); //

The Type Of Depth Test To Do

glEnable(GL_DEPTH_TEST); //

Enables Depth Testing

glShadeModel(GL_SMOOTH); //

Enables Smooth Color Shading

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations

SetupWorld();

return; //

Initialization Went OK }

(47)

{

// called if timer event

// ...advance the state of animation incrementally... //rot+=1;

glutPostRedisplay(); // request redisplay

glutTimerFunc(100, myTimeOut, 0); // request next timer event }

void myKeyboard(unsigned char key,int x, int y) {

}

void mySpecialKeyboard(int key,int x, int y) {

if(key==GLUT_KEY_UP) {

xpos -= (float)sin(heading*piover180) * 0.05f; zpos -= (float)cos(heading*piover180) * 0.05f;

if (walkbiasangle >= 359.0f) { walkbiasangle = 0.0f; } else { walkbiasangle+= 10; }

walkbias = (float)sin(walkbiasangle * piover180)/20.0f;

}

else if(key==GLUT_KEY_DOWN) {

xpos += (float)sin(heading*piover180) * 0.05f; zpos += (float)cos(heading*piover180) * 0.05f;

if (walkbiasangle <= 1.0f) { walkbiasangle = 359.0f; } else { walkbiasangle-= 10; }

walkbias = (float)sin(walkbiasangle * piover180)/20.0f;

} else if(key==GLUT_KEY_RIGHT) { heading -= 1.0f; yrot = heading; } else if(key==GLUT_KEY_LEFT) { heading += 1.0f; yrot = heading; } else if(key==GLUT_KEY_PAGE_UP) {

Gambar

Gambar 1. GLUT Event Processing Loop yang disederhanakan
Gambar 2. OpenGL Geometric Primitives
Gambar 3. Grafika Komputer: Transformasi dari Model 3D Obyek menjadi Citra
Gambar 5. Transformasi Ortogonal dan Transformasi Proyektif.
+3

Referensi

Garis besar

Dokumen terkait

Dengan harapan civil society menjalankan peran sebagai kelompok kepentingan dan kelompok penekan dalam konstalasi politik antara Eksekutif dan Legislatif, maka stabilitas

Set point suhu yang diberikan pada fire alarm system yang telah dibuat adalah lebih dari sama dengan 55.0 0 C sedangkan set point detektor asap adalah aktifnya detektor asap

BIDANG DATA, INFORMASI PELAYANAN UMUM, &amp; PENGADUAN DAN BIDANG PENGOLAHAN &amp; PENERBITAN PERIZINAN &amp; NON PERIZINAN NAMA SOP : Pelayanan Izin Gelanggang Bowling.. DASAR

P.21/MenLHK/Setjen/ KUM.1/10/2020 tanggal 2 November 2020 yaitu tentang Penilaian Kinerja Pengelolaan Hutan Produksi Lestari dan Verifikasi Legalitas Kayu Pada Pemegang Izin,

Pembelajaran Talking Stick adalah pembelajaran yang dipergunakan guru dalam mencapai tujuan pembelajaran yang diinginkan. Talking Stick sebagaimana dimaksudkan penelitian

Untuk lebih memudahkan, maka untuk setiap case baru yang diolah dalam VCIRS (seperti digambarkan pada gambar 1.18 di bawah), dibandingkan dengan rule-rule yang telah ada dalam KB

23 Dalam penelitian ini, akan dikaji tentang bagaimana politik penyusunan anggaran daerah, dengan memfokuskan pada variabel kontrol legislatif, kontrol administratif,

Terdapat pengaruh yang positif dan signifikan antara variabel-variabel bebas secara simultan terhadap variabel terikat, dengan tingkat pengaruh sedang, dan sumbangan