117
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 2007

EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

  • Upload
    vudung

  • View
    272

  • Download
    6

Embed Size (px)

Citation preview

Page 1: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

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 2007

Page 2: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

1/117

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 Tutorial 12.Vertex Animation ......................................................................................... 112

Page 3: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

2/117

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

Page 4: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

3/117

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();

Page 5: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

4/117

} 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 ( ___, ___)

Page 6: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

5/117

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:

GGLL__QQUUAADD__SSTTRRIIPP

GGLL__PPOOLLYYGGOONN

GGLL__TTRRIIAANNGGLLEE__SSTTRRIIPP GGLL__TTRRIIAANNGGLLEE__FFAANN

GGLL__PPOOIINNTTSS

GGLL__LLIINNEESS

GGLL__LLIINNEE__LLOOOOPPGGLL__LLIINNEE__SSTTRRIIPP

GGLL__TTRRIIAANNGGLLEESS

GGLL__QQUUAADDSS

Page 7: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

6/117

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();

ggllVVeerrtteexx33ffvv(( vv ))

NNuummbbeerr ooff ccoommppoonneennttss

22 -- ((xx,,yy)) 33 -- ((xx,,yy,,zz)) 44 -- ((xx,,yy,,zz,,ww))

DDaattaa TTyyppee

bb -- bbyyttee uubb -- uunnssiiggnneedd bbyyttee ss -- sshhoorrtt uuss -- uunnssiiggnneedd sshhoorrtt ii -- iinntt uuii -- uunnssiiggnneedd iinntt ff -- ffllooaatt dd -- ddoouubbllee

VVeeccttoorr

oommiitt ““vv”” ffoorr ssccaallaarr ffoorrmm

ggllVVeerrtteexx22ff(( xx,, yy ))

Page 8: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

7/117

} 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.

Page 9: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

8/117

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(); }

Hasilnya diilustrasikan pada gambar berikut:

Page 10: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

9/117

Page 11: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

10/117

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(); }

Page 12: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

11/117

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) { printf(“Hello World… this is 2D Rectangle”);

Page 13: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

12/117

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 penggunaannya.

Page 14: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

13/117

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

viewingvolume

Page 15: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

14/117

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.

Page 16: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

15/117

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

Page 17: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

16/117

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

side elevation view

Page 18: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

17/117

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 //

Page 19: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

18/117

#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 ); } void myTimeOut(int id)

Page 20: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

19/117

{ // 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 glutSwapBuffer().

Page 21: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

20/117

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) { glViewport(0, 0, width, height);

Page 22: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

21/117

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);

Page 23: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

22/117

// 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).

Page 24: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

23/117

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)

Page 25: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

24/117

• 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 TextureImage[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

rasterizer

Page 26: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

25/117

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 // - Function to load bitmap

Page 27: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

26/117

// - 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, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // Create Linear Filtered Texture

Page 28: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

27/117

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, TextureImage[0]->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 } void myKeyboard(unsigned char key,int x, int y)

Page 29: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

28/117

{ 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);

Page 30: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

29/117

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); glutInitWindowPosition(0,0);

Page 31: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

30/117

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

Page 32: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

31/117

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(); }

Page 33: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

32/117

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);

Page 34: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

33/117

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

Page 35: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

34/117

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 permukaan boks lainnya.

Page 36: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

35/117

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; // Status Indicator

Page 37: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

36/117

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, TextureImage[0]->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, TextureImage[0]->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 }

Page 38: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

37/117

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); } }

Page 39: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

38/117

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(); }

Page 40: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

39/117

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);

Page 41: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

40/117

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.

Page 42: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

41/117

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> #include <stdlib.h>

Page 43: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

42/117

#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 readstr(filein,oneline);

Page 44: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

43/117

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

Page 45: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

44/117

// 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, TextureImage[0]->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, TextureImage[0]->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) // Prevent A Divide By Zero By

Page 46: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

45/117

{ 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 } void myTimeOut(int id)

Page 47: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

46/117

{ // 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) {

Page 48: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

47/117

z-=0.02f; lookupdown-= 1.0f; } else if(key==GLUT_KEY_PAGE_DOWN) { z+=0.02f; lookupdown+= 1.0f; } } void mydisplay(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer glLoadIdentity(); // Reset The View GLfloat x_m, y_m, z_m, u_m, v_m; GLfloat xtrans = -xpos; GLfloat ztrans = -zpos; GLfloat ytrans = -walkbias-0.25f; GLfloat sceneroty = 360.0f - yrot; int numtriangles; glRotatef(lookupdown,1.0f,0,0); glRotatef(sceneroty,0,1.0f,0); glTranslatef(xtrans, ytrans, ztrans); glBindTexture(GL_TEXTURE_2D, texture[filter]); numtriangles = sector1.numtriangles; // Process Each Triangle for (int loop_m = 0; loop_m < numtriangles; loop_m++) { glBegin(GL_TRIANGLES); glNormal3f( 0.0f, 0.0f, 1.0f); x_m = sector1.triangle[loop_m].vertex[0].x; y_m = sector1.triangle[loop_m].vertex[0].y; z_m = sector1.triangle[loop_m].vertex[0].z; u_m = sector1.triangle[loop_m].vertex[0].u; v_m = sector1.triangle[loop_m].vertex[0].v; glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); x_m = sector1.triangle[loop_m].vertex[1].x; y_m = sector1.triangle[loop_m].vertex[1].y; z_m = sector1.triangle[loop_m].vertex[1].z; u_m = sector1.triangle[loop_m].vertex[1].u; v_m = sector1.triangle[loop_m].vertex[1].v; glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); x_m = sector1.triangle[loop_m].vertex[2].x; y_m = sector1.triangle[loop_m].vertex[2].y; z_m = sector1.triangle[loop_m].vertex[2].z; u_m = sector1.triangle[loop_m].vertex[2].u; v_m = sector1.triangle[loop_m].vertex[2].v;

Page 49: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

48/117

glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); glEnd(); } glFlush(); glutSwapBuffers(); } 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); glutSpecialFunc(mySpecialKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; } World.txt NUMPOLLIES 36 // Floor 1 -3.0 0.0 -3.0 0.0 6.0 -3.0 0.0 3.0 0.0 0.0 3.0 0.0 3.0 6.0 0.0 -3.0 0.0 -3.0 0.0 6.0 3.0 0.0 -3.0 6.0 6.0 3.0 0.0 3.0 6.0 0.0 // Ceiling 1 -3.0 1.0 -3.0 0.0 6.0 -3.0 1.0 3.0 0.0 0.0 3.0 1.0 3.0 6.0 0.0 -3.0 1.0 -3.0 0.0 6.0 3.0 1.0 -3.0 6.0 6.0 3.0 1.0 3.0 6.0 0.0 // A1

Page 50: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

49/117

-2.0 1.0 -2.0 0.0 1.0 -2.0 0.0 -2.0 0.0 0.0 -0.5 0.0 -2.0 1.5 0.0 -2.0 1.0 -2.0 0.0 1.0 -0.5 1.0 -2.0 1.5 1.0 -0.5 0.0 -2.0 1.5 0.0 // A2 2.0 1.0 -2.0 2.0 1.0 2.0 0.0 -2.0 2.0 0.0 0.5 0.0 -2.0 0.5 0.0 2.0 1.0 -2.0 2.0 1.0 0.5 1.0 -2.0 0.5 1.0 0.5 0.0 -2.0 0.5 0.0 // B1 -2.0 1.0 2.0 2.0 1.0 -2.0 0.0 2.0 2.0 0.0 -0.5 0.0 2.0 0.5 0.0 -2.0 1.0 2.0 2.0 1.0 -0.5 1.0 2.0 0.5 1.0 -0.5 0.0 2.0 0.5 0.0 // B2 2.0 1.0 2.0 2.0 1.0 2.0 0.0 2.0 2.0 0.0 0.5 0.0 2.0 0.5 0.0 2.0 1.0 2.0 2.0 1.0 0.5 1.0 2.0 0.5 1.0 0.5 0.0 2.0 0.5 0.0 // C1 -2.0 1.0 -2.0 0.0 1.0 -2.0 0.0 -2.0 0.0 0.0 -2.0 0.0 -0.5 1.5 0.0 -2.0 1.0 -2.0 0.0 1.0 -2.0 1.0 -0.5 1.5 1.0 -2.0 0.0 -0.5 1.5 0.0 // C2 -2.0 1.0 2.0 2.0 1.0 -2.0 0.0 2.0 2.0 0.0 -2.0 0.0 0.5 0.5 0.0 -2.0 1.0 2.0 2.0 1.0 -2.0 1.0 0.5 0.5 1.0 -2.0 0.0 0.5 0.5 0.0 // D1 2.0 1.0 -2.0 0.0 1.0 2.0 0.0 -2.0 0.0 0.0 2.0 0.0 -0.5 1.5 0.0

Page 51: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

50/117

2.0 1.0 -2.0 0.0 1.0 2.0 1.0 -0.5 1.5 1.0 2.0 0.0 -0.5 1.5 0.0 // D2 2.0 1.0 2.0 2.0 1.0 2.0 0.0 2.0 2.0 0.0 2.0 0.0 0.5 0.5 0.0 2.0 1.0 2.0 2.0 1.0 2.0 1.0 0.5 0.5 1.0 2.0 0.0 0.5 0.5 0.0 // Upper hallway - L -0.5 1.0 -3.0 0.0 1.0 -0.5 0.0 -3.0 0.0 0.0 -0.5 0.0 -2.0 1.0 0.0 -0.5 1.0 -3.0 0.0 1.0 -0.5 1.0 -2.0 1.0 1.0 -0.5 0.0 -2.0 1.0 0.0 // Upper hallway - R 0.5 1.0 -3.0 0.0 1.0 0.5 0.0 -3.0 0.0 0.0 0.5 0.0 -2.0 1.0 0.0 0.5 1.0 -3.0 0.0 1.0 0.5 1.0 -2.0 1.0 1.0 0.5 0.0 -2.0 1.0 0.0 // Lower hallway - L -0.5 1.0 3.0 0.0 1.0 -0.5 0.0 3.0 0.0 0.0 -0.5 0.0 2.0 1.0 0.0 -0.5 1.0 3.0 0.0 1.0 -0.5 1.0 2.0 1.0 1.0 -0.5 0.0 2.0 1.0 0.0 // Lower hallway - R 0.5 1.0 3.0 0.0 1.0 0.5 0.0 3.0 0.0 0.0 0.5 0.0 2.0 1.0 0.0 0.5 1.0 3.0 0.0 1.0 0.5 1.0 2.0 1.0 1.0 0.5 0.0 2.0 1.0 0.0 // Left hallway - Lw -3.0 1.0 0.5 1.0 1.0 -3.0 0.0 0.5 1.0 0.0 -2.0 0.0 0.5 0.0 0.0 -3.0 1.0 0.5 1.0 1.0 -2.0 1.0 0.5 0.0 1.0 -2.0 0.0 0.5 0.0 0.0 // Left hallway - Hi

Page 52: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

51/117

-3.0 1.0 -0.5 1.0 1.0 -3.0 0.0 -0.5 1.0 0.0 -2.0 0.0 -0.5 0.0 0.0 -3.0 1.0 -0.5 1.0 1.0 -2.0 1.0 -0.5 0.0 1.0 -2.0 0.0 -0.5 0.0 0.0 // Right hallway - Lw 3.0 1.0 0.5 1.0 1.0 3.0 0.0 0.5 1.0 0.0 2.0 0.0 0.5 0.0 0.0 3.0 1.0 0.5 1.0 1.0 2.0 1.0 0.5 0.0 1.0 2.0 0.0 0.5 0.0 0.0 // Right hallway - Hi 3.0 1.0 -0.5 1.0 1.0 3.0 0.0 -0.5 1.0 0.0 2.0 0.0 -0.5 0.0 0.0 3.0 1.0 -0.5 1.0 1.0 2.0 1.0 -0.5 0.0 1.0 2.0 0.0 -0.5 0.0 0.0 Perhatikan loop rendering yang terjadi pada void mydisplay() yang memperlihatkan bagaimana suatu model di render secara otomatis. TUGAS: Coba untuk merancang model 3D dengan membuat file dengan format di atas. Program 14 memberi ilustrasi tentang bagaimana suatu file .3ds dibaca dan dirender. Carilah model 3D dalam format .3ds lengkap dengan texture yang berkaitan. Perhatikan pula loop renderingnya. TUGAS: Dari membaca file 3dsloader.h dan 3dsloader.cpp, terangkan format dari file .3ds yang dapat dibaca oleh Program 14. Program 14. Tutorial4.h /********************************************************** * * TYPES DECLARATION * *********************************************************/ #define MAX_VERTICES 8000 // Max number of vertices (for each object) #define MAX_POLYGONS 8000 // Max number of polygons (for each object) // Our vertex type typedef struct{

Page 53: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

52/117

float x,y,z; }vertex_type; // The polygon (triangle), 3 numbers that aim 3 vertices typedef struct{ int a,b,c; }polygon_type; // The mapcoord type, 2 texture coordinates for each vertex typedef struct{ float u,v; }mapcoord_type; // The object type typedef struct { char name[20]; int vertices_qty; int polygons_qty; vertex_type vertex[MAX_VERTICES]; polygon_type polygon[MAX_POLYGONS]; mapcoord_type mapcoord[MAX_VERTICES]; int id_texture; } obj_type, *obj_type_ptr; Texture.h extern int num_texture; extern int LoadBitmap(char *filename); Texture.cpp #include <stdio.h> #include <windows.h> #include <GL/glut.h> #include "texture.h" /********************************************************** * * VARIABLES DECLARATION * *********************************************************/ int num_texture=-1; //Counter to keep track of the last loaded texture /********************************************************** * * FUNCTION LoadBitmap(char *) * * This function loads a bitmap file and return the OpenGL reference ID to use that texture

Page 54: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

53/117

* *********************************************************/ int LoadBitmap(char *filename) { int i, j=0; //Index variables FILE *l_file; //File pointer unsigned char *l_texture; //The pointer to the memory zone in which we will load the texture // windows.h gives us these types to work with the Bitmap files BITMAPFILEHEADER fileheader; BITMAPINFOHEADER infoheader; RGBTRIPLE rgb; num_texture++; // The counter of the current texture is increased if( (l_file = fopen(filename, "rb"))==NULL) return (-1); // Open the file for reading fread(&fileheader, sizeof(fileheader), 1, l_file); // Read the fileheader fseek(l_file, sizeof(fileheader), SEEK_SET); // Jump the fileheader fread(&infoheader, sizeof(infoheader), 1, l_file); // and read the infoheader // Now we need to allocate the memory for our image (width * height * color deep) l_texture = (byte *) malloc(infoheader.biWidth * infoheader.biHeight * 4); // And fill it with zeros memset(l_texture, 0, infoheader.biWidth * infoheader.biHeight * 4); // At this point we can read every pixel of the image for (i=0; i < infoheader.biWidth*infoheader.biHeight; i++) { // We load an RGB value from the file fread(&rgb, sizeof(rgb), 1, l_file); // And store it l_texture[j+0] = rgb.rgbtRed; // Red component l_texture[j+1] = rgb.rgbtGreen; // Green component l_texture[j+2] = rgb.rgbtBlue; // Blue component l_texture[j+3] = 255; // Alpha value j += 4; // Go to the next position } fclose(l_file); // Closes the file stream glBindTexture(GL_TEXTURE_2D, num_texture); // Bind the ID texture specified by the 2nd parameter // The next commands sets the texture parameters glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image is repeated glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

Page 55: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

54/117

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // The magnification function ("linear" produces better results) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //The minifying function glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // We don't combine the color with the original surface color, use only the texture map. // Finally we define the 2d texture glTexImage2D(GL_TEXTURE_2D, 0, 4, infoheader.biWidth, infoheader.biHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, l_texture); // And create 2d mipmaps for the minifying function gluBuild2DMipmaps(GL_TEXTURE_2D, 4, infoheader.biWidth, infoheader.biHeight, GL_RGBA, GL_UNSIGNED_BYTE, l_texture); free(l_texture); // Free the memory we used to load the texture return (num_texture); // Returns the current texture OpenGL ID } 3dsloader.h /********************************************************** * * FUNCTION Load3DS (obj_type_ptr, char *) * * This function loads a mesh from a 3ds file. * Please note that we are loading only the vertices, polygons and mapping lists. * If you need to load meshes with advanced features as for example: * multi objects, materials, lights and so on, you must insert other chunk parsers. * *********************************************************/ extern char Load3DS (obj_type_ptr ogg, char *filename); 3dsloader.cpp #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <io.h> #include "tutorial4.h" #include "3dsloader.h" /********************************************************** * * FUNCTION Load3DS (obj_type_ptr, char *) * * This function loads a mesh from a 3ds file. * Please note that we are loading only the vertices, polygons and mapping lists.

Page 56: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

55/117

* If you need to load meshes with advanced features as for example: * multi objects, materials, lights and so on, you must insert other chunk parsers. * *********************************************************/ char Load3DS (obj_type_ptr p_object, char *p_filename) { int i; //Index variable FILE *l_file; //File pointer unsigned short l_chunk_id; //Chunk identifier unsigned int l_chunk_lenght; //Chunk lenght unsigned char l_char; //Char variable unsigned short l_qty; //Number of elements in each chunk unsigned short l_face_flags; //Flag that stores some face information if ((l_file=fopen (p_filename, "rb"))== NULL) return 0; //Open the file while (ftell (l_file) < filelength (fileno (l_file))) //Loop to scan the whole file { //getche(); //Insert this command for debug (to wait for keypress for each chuck reading) fread (&l_chunk_id, 2, 1, l_file); //Read the chunk header printf("ChunkID: %x\n",l_chunk_id); fread (&l_chunk_lenght, 4, 1, l_file); //Read the lenght of the chunk printf("ChunkLenght: %x\n",l_chunk_lenght); switch (l_chunk_id) { //----------------- MAIN3DS ----------------- // Description: Main chunk, contains all the other chunks // Chunk ID: 4d4d // Chunk Lenght: 0 + sub chunks //------------------------------------------- case 0x4d4d: break; //----------------- EDIT3DS ----------------- // Description: 3D Editor chunk, objects layout info // Chunk ID: 3d3d (hex) // Chunk Lenght: 0 + sub chunks //------------------------------------------- case 0x3d3d: break; //--------------- EDIT_OBJECT --------------- // Description: Object block, info for each object

Page 57: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

56/117

// Chunk ID: 4000 (hex) // Chunk Lenght: len(object name) + sub chunks //------------------------------------------- case 0x4000: i=0; do { fread (&l_char, 1, 1, l_file); p_object->name[i]=l_char; i++; }while(l_char != '\0' && i<20); break; //--------------- OBJ_TRIMESH --------------- // Description: Triangular mesh, contains chunks for 3d mesh info // Chunk ID: 4100 (hex) // Chunk Lenght: 0 + sub chunks //------------------------------------------- case 0x4100: break; //--------------- TRI_VERTEXL --------------- // Description: Vertices list // Chunk ID: 4110 (hex) // Chunk Lenght: 1 x unsigned short (number of vertices) // + 3 x float (vertex coordinates) x (number of vertices) // + sub chunks //------------------------------------------- case 0x4110: fread (&l_qty, sizeof (unsigned short), 1, l_file); p_object->vertices_qty = l_qty; printf("Number of vertices: %d\n",l_qty); for (i=0; i<l_qty; i++) { fread (&p_object->vertex[i].x, sizeof(float), 1, l_file); printf("Vertices list x: %f\n",p_object->vertex[i].x); fread (&p_object->vertex[i].y, sizeof(float), 1, l_file); printf("Vertices list y: %f\n",p_object->vertex[i].y); fread (&p_object->vertex[i].z, sizeof(float), 1, l_file); printf("Vertices list z: %f\n",p_object->vertex[i].z); } break; //--------------- TRI_FACEL1 ---------------- // Description: Polygons (faces) list // Chunk ID: 4120 (hex) // Chunk Lenght: 1 x unsigned short (number of

Page 58: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

57/117

polygons) // + 3 x unsigned short (polygon points) x (number of polygons) // + sub chunks //------------------------------------------- case 0x4120: fread (&l_qty, sizeof (unsigned short), 1, l_file); p_object->polygons_qty = l_qty; printf("Number of polygons: %d\n",l_qty); for (i=0; i<l_qty; i++) { fread (&p_object->polygon[i].a, sizeof (unsigned short), 1, l_file); printf("Polygon point a: %d\n",p_object->polygon[i].a); fread (&p_object->polygon[i].b, sizeof (unsigned short), 1, l_file); printf("Polygon point b: %d\n",p_object->polygon[i].b); fread (&p_object->polygon[i].c, sizeof (unsigned short), 1, l_file); printf("Polygon point c: %d\n",p_object->polygon[i].c); fread (&l_face_flags, sizeof (unsigned short), 1, l_file); printf("Face flags: %x\n",l_face_flags); } break; //------------- TRI_MAPPINGCOORS ------------ // Description: Vertices list // Chunk ID: 4140 (hex) // Chunk Lenght: 1 x unsigned short (number of mapping points) // + 2 x float (mapping coordinates) x (number of mapping points) // + sub chunks //------------------------------------------- case 0x4140: fread (&l_qty, sizeof (unsigned short), 1, l_file); for (i=0; i<l_qty; i++) { fread (&p_object->mapcoord[i].u, sizeof (float), 1, l_file); printf("Mapping list u: %f\n",p_object->mapcoord[i].u); fread (&p_object->mapcoord[i].v, sizeof (float), 1, l_file); printf("Mapping list v: %f\n",p_object->mapcoord[i].v); } break; //----------- Skip unknow chunks ------------ //We need to skip all the chunks that currently we

Page 59: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

58/117

don't use //We use the chunk lenght information to set the file pointer //to the same level next chunk //------------------------------------------- default: fseek(l_file, l_chunk_lenght-6, SEEK_CUR); } } fclose (l_file); // Closes the file stream return (1); // Returns ok } Main.h #define MAX_VERTICES 8000 // Max number of vertices (for each object) #define MAX_POLYGONS 8000 // Max number of polygons (for each object) // Our vertex type typedef struct{ float x,y,z; }vertex_type; // The polygon (triangle), 3 numbers that aim 3 vertices typedef struct{ int a,b,c; }polygon_type; // The mapcoord type, 2 texture coordinates for each vertex typedef struct{ float u,v; }mapcoord_type; // The object type typedef struct { char name[20]; int vertices_qty; int polygons_qty; vertex_type vertex[MAX_VERTICES]; polygon_type polygon[MAX_POLYGONS]; mapcoord_type mapcoord[MAX_VERTICES]; int id_texture; } obj_type, *obj_type_ptr; Main.cpp #include <windows.h> #include <GL/glut.h> #include "tutorial4.h" #include "texture.h" #include "3dsloader.h"

Page 60: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

59/117

// The width and height of your window, change them as you like int screen_width=640; int screen_height=480; // Absolute rotation values (0-359 degrees) and rotation increments for each frame double rotation_x=0, rotation_x_increment=0.1; double rotation_y=0, rotation_y_increment=0.05; double rotation_z=0, rotation_z_increment=0.03; // Flag for rendering as lines or filled polygons int filling=1; //0=OFF 1=ON //Now the object is generic, the cube has annoyed us a little bit, or not? obj_type object; void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); // This clear the background color to black glShadeModel(GL_SMOOTH); // Type of shading for the polygons // Viewport transformation glViewport(0,0,screen_width,screen_height); // Projection transformation glMatrixMode(GL_PROJECTION); // Specifies which matrix stack is the target for matrix operations glLoadIdentity(); // We initialize the projection matrix as identity gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,10.0f,10000.0f); // We define the "viewing volume" glEnable(GL_DEPTH_TEST); // We enable the depth test (also called z buffer) glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled) glEnable(GL_TEXTURE_2D); // This Enable the Texture mapping Load3DS (&object,"spaceship.3ds"); object.id_texture=LoadBitmap("spaceshiptexture.bmp"); // The Function LoadBitmap() return the current texture ID // If the last function returns -1 it means the file was not found so we exit from the program if (object.id_texture==-1) { MessageBox(NULL,"Image file: spaceshiptexture.bmp not found", "Zetadeck",MB_OK | MB_ICONERROR); exit (0); } } void resize (int width, int height)

Page 61: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

60/117

{ screen_width=width; // We obtain the new screen width values and store it screen_height=height; // Height value glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // We clear both the color and the depth buffer so to draw the next frame glViewport(0,0,screen_width,screen_height); // Viewport transformation glMatrixMode(GL_PROJECTION); // Projection transformation glLoadIdentity(); // We initialize the projection matrix as identity gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,10.0f,10000.0f); glutPostRedisplay (); // This command redraw the scene (it calls the same routine of glutDisplayFunc) } void keyboard (unsigned char key, int x, int y) { switch (key) { case ' ': rotation_x_increment=0; rotation_y_increment=0; rotation_z_increment=0; break; case 'r': case 'R': if (filling==0) { glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled) filling=1; } else { glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); // Polygon rasterization mode (polygon outlined) filling=0; } break; } } void keyboard_s (int key, int x, int y) { switch (key) { case GLUT_KEY_UP: rotation_x_increment = rotation_x_increment +0.005; break; case GLUT_KEY_DOWN:

Page 62: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

61/117

rotation_x_increment = rotation_x_increment -0.005; break; case GLUT_KEY_LEFT: rotation_y_increment = rotation_y_increment +0.005; break; case GLUT_KEY_RIGHT: rotation_y_increment = rotation_y_increment -0.005; break; } } void display(void) { int l_index; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); // Modeling transformation glLoadIdentity(); // Initialize the model matrix as identity glTranslatef(0.0,0.0,-300); // We move the object forward (the model matrix is multiplied by the translation matrix) rotation_x = rotation_x + rotation_x_increment; rotation_y = rotation_y + rotation_y_increment; rotation_z = rotation_z + rotation_z_increment; if (rotation_x > 359) rotation_x = 0; if (rotation_y > 359) rotation_y = 0; if (rotation_z > 359) rotation_z = 0; glRotatef(rotation_x,1.0,0.0,0.0); // Rotations of the object (the model matrix is multiplied by the rotation matrices) glRotatef(rotation_y,0.0,1.0,0.0); glRotatef(rotation_z,0.0,0.0,1.0); glBindTexture(GL_TEXTURE_2D, object.id_texture); // We set the active texture glBegin(GL_TRIANGLES); // glBegin and glEnd delimit the vertices that define a primitive (in our case triangles) for (l_index=0;l_index<object.polygons_qty;l_index++) { //----------------- FIRST VERTEX ----------------- // Texture coordinates of the first vertex glTexCoord2f( object.mapcoord[ object.polygon[l_index].a ].u, object.mapcoord[ object.polygon[l_index].a ].v); // Coordinates of the first vertex glVertex3f( object.vertex[ object.polygon[l_index].a ].x, object.vertex[ object.polygon[l_index].a ].y, object.vertex[ object.polygon[l_index].a ].z); //Vertex definition //----------------- SECOND VERTEX ----------------- // Texture coordinates of the second vertex glTexCoord2f( object.mapcoord[ object.polygon[l_index].b ].u, object.mapcoord[ object.polygon[l_index].b ].v); // Coordinates of the second vertex

Page 63: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

62/117

glVertex3f( object.vertex[ object.polygon[l_index].b ].x, object.vertex[ object.polygon[l_index].b ].y, object.vertex[ object.polygon[l_index].b ].z); //----------------- THIRD VERTEX ----------------- // Texture coordinates of the third vertex glTexCoord2f( object.mapcoord[ object.polygon[l_index].c ].u, object.mapcoord[ object.polygon[l_index].c ].v); // Coordinates of the Third vertex glVertex3f( object.vertex[ object.polygon[l_index].c ].x, object.vertex[ object.polygon[l_index].c ].y, object.vertex[ object.polygon[l_index].c ].z); } glEnd(); glFlush(); // This force the execution of OpenGL commands glutSwapBuffers(); // In double buffered mode we invert the positions of the visible buffer and the writing buffer } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(screen_width,screen_height); glutInitWindowPosition(0,0); glutCreateWindow("simple"); glutDisplayFunc(display); glutIdleFunc(display); glutReshapeFunc (resize); glutKeyboardFunc (keyboard); glutSpecialFunc (keyboard_s); init(); glutMainLoop(); return(0); }

Tutorial 10. Particle System Salah satu teknik yang banyak digunakan dalam grafika komputer adalah sistem partikel. Banyak fenomena dapat dimodelkan dengan sistem partikel antara lain air, api, pasir dan lain-lain. Lebih jauh lagi, sistem partikel merupakan dasar dari teknik-teknik pemodelan yang disimulasikan dalam konsep simulasi mikro seperti SPH, DMS dan lain-lain. Sistem partikel, sesuai dengan namanya, adalah kumpulan obyek yang disebut partikel. Partikel di sini dapat divisualisasikan sebagai sekedar titik, bola, atau merupakan bagian dari obyek seperti triangle-soup dan lain-lain. Setiap partikel memiliki statusnya sendiri-sendiri, yaitu minimal memiliki nilai posisi. Sebagai kumpulan, dengan memodelkan interaksi antar partikel, kita dapat memodelkan berbagai macam fenomena seperti disebutkan di atas. Program 16 memberi ilustrasi tentang bagaimana sistem partikel bekerja. Pada Program 16, setiap partikel memiliki beberapa status yaitu posisi, kecepatan, warna, umur dan

Page 64: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

63/117

kecepatan penurunan umur serta indikator aktif (Particle.h). Setiap partikel memiliki prosedur pembuatan, inisialisasi dan prosedur evolusi selama hidupnya. Perhatikan bagaimana kumpulan partikel ini dirender pada void mydisplay(). Program 16 Particle.h #ifndef PARTICLE_H_ typedef struct { float lifetime; // total lifetime of the particle float decay; // decay speed of the particle float r,g,b; // color values of the particle float xpos,ypos,zpos; // position of the particle float xspeed,yspeed,zspeed; // speed of the particle boolean active; // is particle active or not? } PARTICLE; void CreateParticle(int i); void InitParticle(); void EvolveParticle(); #endif Particle.cpp #include <windows.h> #include <stdlib.h> #include <math.h> #include "particle.h" const maxparticle=2000; // set maximum number of particles PARTICLE particle[maxparticle]; void CreateParticle(int i) { particle[i].lifetime= (float)(500000*rand()/RAND_MAX)/500000.0; particle[i].decay=0.001; particle[i].r = 0.7; particle[i].g = 0.7; particle[i].b = 1.0; particle[i].xpos= 0.0; particle[i].ypos= 0.0; particle[i].zpos= 0.0; particle[i].xspeed = 10*(0.0005-(float)(100*rand()/RAND_MAX)/100000.0); particle[i].yspeed = 0.01-(float)(100*rand()/RAND_MAX)/100000.0; particle[i].zspeed = 0.0005-(float)(100*rand()/RAND_MAX)/100000.0; particle[i].active = true; } //---------------------------------------------------------------------------void InitParticle() {

Page 65: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

64/117

for(int i=0;i<=maxparticle;i++){ // initialize the particle parameters CreateParticle(i); particle[i].active = false; // set all particles inactive } } //---------------------------------------------------------------------------void EvolveParticle() { for(int i=0;i<=maxparticle;i++){ // evolve the particle parameters particle[i].lifetime-=particle[i].decay; particle[i].xpos+=particle[i].xspeed; particle[i].ypos+=particle[i].yspeed; particle[i].zpos+=particle[i].zspeed; particle[i].yspeed-=0.00010; } } Program.cpp // OpenGL // - 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" #include "particle.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[1]; // Storage For 3 Textures /* Particle System */ extern const maxparticle=2000; // set maximum number of particles extern PARTICLE particle[maxparticle]; int LoadGLTextures() // Load Bitmaps And Convert To Textures { int Status=FALSE; //

Page 66: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

65/117

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("particle.bmp")) { Status=TRUE; // Set The Status To TRUE glGenTextures(1, &texture[0]); // Create Three Textures // Create Nearest Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[0]); 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, TextureImage[0]->sizeY, 0, 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 } glEnable(GL_TEXTURE_2D); // Enable Texture Mapping 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, 0.0, 300.0); glMatrixMode(GL_PROJECTION); // the following operations affect the projection matrix glLoadIdentity(); // restore matrix to original state

Page 67: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

66/117

glOrtho( -0.60,0.60,-0.20,0.60,-0.60,0.60); // defines the viewing volume 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",filter); } } void mydisplay(void) { glClear(GL_COLOR_BUFFER_BIT); //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLoadIdentity(); glRotatef(50.0,1.0,0.0,0.0); // show scene from top front glBindTexture(GL_TEXTURE_2D,texture[0]); // choose particle texture for (int i=0;i<=maxparticle;i++){ if(particle[i].ypos<0.0) particle[i].lifetime=0.0; if((particle[i].active==true) && (particle[i].lifetime>0.0)){ glColor3f(particle[i].r,particle[i].g,particle[i].b); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(0.0,1.0); glVertex3f(particle[i].xpos+0.005, particle[i].ypos+0.005, particle[i].zpos+0.0); // top right glTexCoord2f(0.0,0.0); glVertex3f(particle[i].xpos-0.005, particle[i].ypos+0.005, particle[i].zpos+0.0); // top left glTexCoord2f(1.0,1.0); glVertex3f(particle[i].xpos+0.005, particle[i].ypos-0.005, particle[i].zpos+0.0); // bottom right glTexCoord2f(1.0,0.0); glVertex3f(particle[i].xpos-0.005, particle[i].ypos-0.005, particle[i].zpos+0.0); // bottom left glEnd();

Page 68: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

67/117

} else CreateParticle(i); } EvolveParticle(); glFlush(); glutSwapBuffers(); } void init() { glDisable(GL_DEPTH_TEST); // deactivate hidden surface removal glDisable(GL_CULL_FACE); // show backside of polygons glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black Background glColor4f(1.0f, 1.0f, 1.0f, 0.5); // Full Brightness. 50% Alpha if (!LoadGLTextures()) // Jump To Texture Loading Routine { return; // If Texture Didn't Load Return FALSE } InitParticle(); glMatrixMode(GL_MODELVIEW); return; } int main(int argc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode( GLUT_DOUBLE); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("simple"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }

Page 69: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

68/117

Page 70: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

69/117

Tutorial 11. Lighting Visualisasi tentu saja tidak akan terjadi bila tidak ada cahaya. Pencahayaan merupakan esensi dari visualisasi dan merupakan topik yang sangat kompleks. Hingga tahap ini lingkungan diberi pencahayaan default/standar dengan cahaya lingkungan (ambient) yang sama pada setiap titik. Kondisi default/standar dapat dicapai kapan saja dengan mematikan status Lighting menjadi disabled dengan glDisable(GL_LIGHT0). Dalam pencahayaan, ada dua hal yang menentukan tampilan suatu obyek, yaitu:

- Sumber cahaya dan pengaruh lingkungan terhadap cahaya o Lokasi sumber cahaya o Arah pencahayaan dari sumber cahaya (omni, spot) o Komponen pengaruh lingkungan terhadap cahaya (ambient, diffuse,

specular) - Material dari obyek, yang memodelkan bagaimana material bereaksi terhadap

sumber cahaya, yaitu: o Material reflektan terhadap komponen cahaya ambient o Material reflektan terhadap komponen cahaya diffuse o Material reflektan terhadap komponen cahaya specular o Material sebagai sumber cahaya (emitance)

Komponen ambient adalah cahaya yang arahnya tidak dapat ditentukan karena datang secara merata dari segala arah. Biasanya merupakan cahaya yang dihasilkan dari pemantulan berkali-kali sumber cahaya yang berarah. Poligon dalam openGL selalu diiluminasi secara seragam oleh komponen ambient tanpa memperdulikan orientasi dan posisinya. Komponen diffuse adalah cahaya yang bersumber dari satu arah dan mempengaruhi poligon secara uniform bergantung pada sudut datang terhadap permukaan poligon. Komponen specular adalah cahaya yang memantul dari obyek yang bergantung pada derajat inklinasi dari poligon terhadap cahaya dan posisi observer. Program 17 memberi contoh bagaimana efek sumber cahaya dan material dari obyek. Program 18 memberi contoh tentang posisi sumber cahaya. Pada setiap windows gunakan tombol klik kanan untuk mengakses menu. Program 17 Material .h float Brass[] = { 0.329412, 0.223529, 0.027451, 1.000000, 0.780392, 0.568627, 0.113725, 1.000000, 0.992157, 0.941176, 0.807843, 1.000000, 27.897400 }; float Bronze[] = { 0.212500, 0.127500, 0.054000, 1.000000,

Page 71: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

70/117

0.714000, 0.428400, 0.181440, 1.000000, 0.393548, 0.271906, 0.166721, 1.000000, 25.600000 }; float Polished_Bronze[] = { 0.250000, 0.148000, 0.064750, 1.000000, 0.400000, 0.236800, 0.103600, 1.000000, 0.774597, 0.458561, 0.200621, 1.000000, 76.800003 }; float Chrome[] = { 0.250000, 0.250000, 0.250000, 1.000000, 0.400000, 0.400000, 0.400000, 1.000000, 0.774597, 0.774597, 0.774597, 1.000000, 76.800003 }; float Copper[] = { 0.191250, 0.073500, 0.022500, 1.000000, 0.703800, 0.270480, 0.082800, 1.000000, 0.256777, 0.137622, 0.086014, 1.000000, 12.800000 }; float Polished_Copper[] = { 0.229500, 0.088250, 0.027500, 1.000000, 0.550800, 0.211800, 0.066000, 1.000000, 0.580594, 0.223257, 0.069570, 1.000000, 51.200001 }; float Gold[] = { 0.247250, 0.199500, 0.074500, 1.000000, 0.751640, 0.606480, 0.226480, 1.000000, 0.628281, 0.555802, 0.366065, 1.000000, 51.200001 }; float Polished_Gold[] = { 0.247250, 0.224500, 0.064500, 1.000000, 0.346150, 0.314300, 0.090300, 1.000000, 0.797357, 0.723991, 0.208006, 1.000000, 83.199997 }; float Pewter[] = { 0.105882, 0.058824, 0.113725, 1.000000, 0.427451, 0.470588, 0.541176, 1.000000, 0.333333, 0.333333, 0.521569, 1.000000, 9.846150 }; float Silver[] = { 0.192250, 0.192250, 0.192250, 1.000000, 0.507540, 0.507540, 0.507540, 1.000000,

Page 72: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

71/117

0.508273, 0.508273, 0.508273, 1.000000, 51.200001 }; float Polished_Silver[] = { 0.231250, 0.231250, 0.231250, 1.000000, 0.277500, 0.277500, 0.277500, 1.000000, 0.773911, 0.773911, 0.773911, 1.000000, 89.599998 }; float Emerald[] = { 0.021500, 0.174500, 0.021500, 0.550000, 0.075680, 0.614240, 0.075680, 0.550000, 0.633000, 0.727811, 0.633000, 0.550000, 76.800003 }; float Jade[] = { 0.135000, 0.222500, 0.157500, 0.950000, 0.540000, 0.890000, 0.630000, 0.950000, 0.316228, 0.316228, 0.316228, 0.950000, 12.800000 }; float Obsidian[] = { 0.053750, 0.050000, 0.066250, 0.820000, 0.182750, 0.170000, 0.225250, 0.820000, 0.332741, 0.328634, 0.346435, 0.820000, 38.400002 }; float Pearl[] = { 0.250000, 0.207250, 0.207250, 0.922000, 1.000000, 0.829000, 0.829000, 0.922000, 0.296648, 0.296648, 0.296648, 0.922000, 11.264000 }; float Ruby[] = { 0.174500, 0.011750, 0.011750, 0.550000, 0.614240, 0.041360, 0.041360, 0.550000, 0.727811, 0.626959, 0.626959, 0.550000, 76.800003 }; float Turquoise[] = { 0.100000, 0.187250, 0.174500, 0.800000, 0.396000, 0.741510, 0.691020, 0.800000, 0.297254, 0.308290, 0.306678, 0.800000, 12.800000 }; float Black_Plastic[] = { 0.000000, 0.000000, 0.000000, 1.000000, 0.010000, 0.010000, 0.010000, 1.000000, 0.500000, 0.500000, 0.500000, 1.000000,

Page 73: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

72/117

32.000000 }; float Black_Rubber[] = { 0.020000, 0.020000, 0.020000, 1.000000, 0.010000, 0.010000, 0.010000, 1.000000, 0.400000, 0.400000, 0.400000, 1.000000, 10.000000 }; Lighting.cpp /* lightmaterial.c Nate Robins, 1997 Tool for teaching about OpenGL lighting & material properties. */ #include <math.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <GL/glut.h> #include "glm.h" #include "materials.h" #pragma comment( linker, "/entry:\"mainCRTStartup\"" ) // set the entry point to be main() typedef struct _cell { int id; int x, y; float min, max; float value; float step; char* info; char* format; } cell; cell light_pos[4] = { { 1, 210, 30, -5.0, 5.0, -2.0, 0.01, "Specifies X coordinate of light vector.", "%.2f" }, { 2, 270, 30, -5.0, 5.0, 2.0, 0.01, "Specifies Y coordinate of light vector.", "%.2f" }, { 3, 330, 30, -5.0, 5.0, 2.0, 0.01, "Specifies Z coordinate of light vector.", "%.2f" }, { 4, 390, 30, 0.0, 1.0, 1.0, 1.0, "Specifies directional (0) or positional (1) light.", "%.2f" }, };

Page 74: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

73/117

cell light_Ka[4] = { { 5, 200, 60, 0.0, 1.0, 0.0, 0.01, "Specifies ambient red intensity of the light.", "%.2f" }, { 6, 260, 60, 0.0, 1.0, 0.0, 0.01, "Specifies ambient green intensity of the light.", "%.2f" }, { 7, 320, 60, 0.0, 1.0, 0.0, 0.01, "Specifies ambient blue intensity of the light.", "%.2f" }, { 8, 380, 60, 0.0, 1.0, 1.0, 0.01, "Specifies ambient alpha intensity of the light.", "%.2f" }, }; cell light_Kd[4] = { { 9, 200, 90, 0.0, 1.0, 1.0, 0.01, "Specifies diffuse red intensity of the light.", "%.2f" }, { 10, 260, 90, 0.0, 1.0, 1.0, 0.01, "Specifies diffuse green intensity of the light.", "%.2f" }, { 11, 320, 90, 0.0, 1.0, 1.0, 0.01, "Specifies diffuse blue intensity of the light.", "%.2f" }, { 12, 380, 90, 0.0, 1.0, 1.0, 0.01, "Specifies diffuse alpha intensity of the light.", "%.2f" }, }; cell light_Ks[4] = { { 13, 200, 120, 0.0, 1.0, 1.0, 0.01, "Specifies specular red intensity of the light.", "%.2f" }, { 14, 260, 120, 0.0, 1.0, 1.0, 0.01, "Specifies specular green intensity of the light.", "%.2f" }, { 15, 320, 120, 0.0, 1.0, 1.0, 0.01, "Specifies specular blue intensity of the light.", "%.2f" }, { 16, 380, 120, 0.0, 1.0, 1.0, 0.01, "Specifies specular alpha intensity of the light.", "%.2f" }, }; cell spot_direction[3] = { { 17, 250, 260, -1.0, 1.0, 1.0, 0.01, "Specifies X coordinate of spotlight direction vector.", "%.2f" }, { 18, 310, 260, -1.0, 1.0, -1.0, 0.01, "Specifies Y coordinate of spotlight direction vector.", "%.2f" }, { 19, 370, 260, -1.0, 1.0, -1.0, 0.01, "Specifies Z coordinate of spotlight direction vector.", "%.2f" }, }; cell spot_exponent = { 20, 210, 290, 0.0, 128.0, 30.0, 1.0, "Specifies intensity distribution of spotlight.", "%.0f" }; cell spot_cutoff = { 21, 410, 290, 0.0, 91.0, 91.0, 1.0, "Specifies maximum spread angle of spotlight (180 = off).", "%.0f" }; cell Kc = { 22, 120, 410, 0.0, 5.0, 1.0, 0.01, "Specifies constant attenuation factor.", "%.2f" }; cell Kl = { 23, 215, 410, 0.0, 5.0, 0.0, 0.01, "Specifies linear attenuation factor.", "%.2f" }; cell Kq = { 24, 315, 410, 0.0, 5.0, 0.0, 0.01, "Specifies quadratic attenuation factor.", "%.2f" }; cell material_Ka[4] = {

Page 75: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

74/117

{ 25, 220, 260, 0.0, 1.0, 0.2, 0.01, "Specifies ambient red reflectance of the material.", "%.2f" }, { 26, 280, 260, 0.0, 1.0, 0.2, 0.01, "Specifies ambient green reflectance of the material.", "%.2f" }, { 27, 340, 260, 0.0, 1.0, 0.2, 0.01, "Specifies ambient blue reflectance of the material.", "%.2f" }, { 28, 400, 260, 0.0, 1.0, 1.0, 0.01, "Specifies ambient alpha reflectance of the material.", "%.2f" }, }; cell material_Kd[4] = { { 29, 220, 290, 0.0, 1.0, 0.8, 0.01, "Specifies diffuse red reflectance of the material.", "%.2f" }, { 30, 280, 290, 0.0, 1.0, 0.8, 0.01, "Specifies diffuse green reflectance of the material.", "%.2f" }, { 31, 340, 290, 0.0, 1.0, 0.8, 0.01, "Specifies diffuse blue reflectance of the material.", "%.2f" }, { 32, 400, 290, 0.0, 1.0, 1.0, 0.01, "Specifies diffuse alpha reflectance of the material.", "%.2f" }, }; cell material_Ks[4] = { { 33, 220, 320, 0.0, 1.0, 1.0, 0.01, "Specifies specular red reflectance of the material.", "%.2f" }, { 34, 280, 320, 0.0, 1.0, 1.0, 0.01, "Specifies specular green reflectance of the material.", "%.2f" }, { 35, 340, 320, 0.0, 1.0, 1.0, 0.01, "Specifies specular blue reflectance of the material.", "%.2f" }, { 36, 400, 320, 0.0, 1.0, 1.0, 0.01, "Specifies specular alpha reflectance of the material.", "%.2f" }, }; cell material_Ke[4] = { { 37, 220, 350, 0.0, 1.0, 0.0, 0.01, "Specifies red emitted light intensity of the material.", "%.2f" }, { 38, 280, 350, 0.0, 1.0, 0.0, 0.01, "Specifies green emitted light intensity of the material.", "%.2f" }, { 39, 340, 350, 0.0, 1.0, 0.0, 0.01, "Specifies blue emitted light intensity of the material.", "%.2f" }, { 40, 400, 350, 0.0, 1.0, 1.0, 0.01, "Specifies alpha emitted light intensity of the material.", "%.2f" }, }; cell material_Se = { 41, 200, 380, 0.0, 128.0, 50.0, 1.0, "Specifies the specular exponent of the material.", "%.0f" }; cell lmodel_Ka[4] = { { 42, 220, 260, 0.0, 1.0, 0.2, 0.01, "Specifies ambient red intensity of the entire scene.", "%.2f" }, { 43, 280, 260, 0.0, 1.0, 0.2, 0.01, "Specifies ambient green intensity of the entire scene.", "%.2f" },

Page 76: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

75/117

{ 44, 340, 260, 0.0, 1.0, 0.2, 0.01, "Specifies ambient blue intensity of the entire scene.", "%.2f" }, { 45, 400, 260, 0.0, 1.0, 1.0, 0.01, "Specifies ambient alpha intensity of the entire scene.", "%.2f" }, }; cell local_viewer = { 46, 460, 340, 0.0, 1.0, 0.0, 1.0, "Specifies infinite (0.0) or local (1.0) light model.", "%.1f" }; cell two_side = { 47, 415, 390, 0.0, 1.0, 0.0, 1.0, "Specifies one (0.0) or two (1.0) sided lighting.", "%.1f" }; GLfloat eye[3] = { 0.0, 0.0, 3.0 }; GLfloat at[3] = { 0.0, 0.0, 0.0 }; GLfloat up[3] = { 0.0, 1.0, 0.0 }; GLboolean world_draw = GL_TRUE; GLMmodel* pmodel = NULL; GLint selection = 0; GLfloat spin_x = 0.0; GLfloat spin_y = 0.0; void redisplay_all(void); GLdouble projection[16], modelview[16], inverse[16]; GLuint window, world, screen, command; GLuint sub_width = 256, sub_height = 256; GLvoid *font_style = GLUT_BITMAP_TIMES_ROMAN_10; void setfont(char* name, int size) { font_style = GLUT_BITMAP_HELVETICA_10; if (strcmp(name, "helvetica") == 0) { if (size == 12) font_style = GLUT_BITMAP_HELVETICA_12; else if (size == 18) font_style = GLUT_BITMAP_HELVETICA_18; } else if (strcmp(name, "times roman") == 0) { font_style = GLUT_BITMAP_TIMES_ROMAN_10; if (size == 24) font_style = GLUT_BITMAP_TIMES_ROMAN_24; } else if (strcmp(name, "8x13") == 0) { font_style = GLUT_BITMAP_8_BY_13; } else if (strcmp(name, "9x15") == 0) { font_style = GLUT_BITMAP_9_BY_15; } } void drawstr(GLuint x, GLuint y, char* format, ...) { va_list args; char buffer[255], *s;

Page 77: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

76/117

va_start(args, format); vsprintf(buffer, format, args); va_end(args); glRasterPos2i(x, y); for (s = buffer; *s; s++) glutBitmapCharacter(font_style, *s); } void cell_draw(cell* cell) { glColor3ub(0, 255, 128); if (selection == cell->id) { glColor3ub(255, 255, 0); drawstr(10, 525, cell->info); glColor3ub(255, 0, 0); } if (cell->id == 21 && cell->value > 90.0) /* treat cutoff specially */ drawstr(cell->x, cell->y, cell->format, 180.0); else drawstr(cell->x, cell->y, cell->format, cell->value); } int cell_hit(cell* cell, int x, int y) { if (x > cell->x && x < cell->x+60 && y > cell->y-20 && y < cell->y+10) return cell->id; return 0; } void cell_update(cell* cell, int update) { if (selection != cell->id) return; cell->value += update * cell->step; if (cell->value < cell->min) cell->value = cell->min; else if (cell->value > cell->max) cell->value = cell->max; } void cell_vector(float* dst, cell* cell, int num) { while (--num >= 0) dst[num] = cell[num].value; }

Page 78: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

77/117

void drawmodel(void) { if (!pmodel) { pmodel = glmReadOBJ("data/soccerball.obj"); if (!pmodel) exit(0); glmUnitize(pmodel); glmFacetNormals(pmodel); glmVertexNormals(pmodel, 90.0); } glmDraw(pmodel, GLM_SMOOTH); } void drawaxes(void) { glColor3ub(255, 0, 0); glBegin(GL_LINE_STRIP); glVertex3f(0.0, 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glVertex3f(0.75, 0.25, 0.0); glVertex3f(0.75, -0.25, 0.0); glVertex3f(1.0, 0.0, 0.0); glVertex3f(0.75, 0.0, 0.25); glVertex3f(0.75, 0.0, -0.25); glVertex3f(1.0, 0.0, 0.0); glEnd(); glBegin(GL_LINE_STRIP); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glVertex3f(0.0, 0.75, 0.25); glVertex3f(0.0, 0.75, -0.25); glVertex3f(0.0, 1.0, 0.0); glVertex3f(0.25, 0.75, 0.0); glVertex3f(-0.25, 0.75, 0.0); glVertex3f(0.0, 1.0, 0.0); glEnd(); glBegin(GL_LINE_STRIP); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 1.0); glVertex3f(0.25, 0.0, 0.75); glVertex3f(-0.25, 0.0, 0.75); glVertex3f(0.0, 0.0, 1.0); glVertex3f(0.0, 0.25, 0.75); glVertex3f(0.0, -0.25, 0.75); glVertex3f(0.0, 0.0, 1.0); glEnd(); glColor3ub(255, 255, 0); glRasterPos3f(1.1, 0.0, 0.0); glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'x'); glRasterPos3f(0.0, 1.1, 0.0); glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'y'); glRasterPos3f(0.0, 0.0, 1.1); glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'z');

Page 79: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

78/117

} void identity(GLdouble m[16]) { m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0; m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0; m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0; m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1; } GLboolean invert(GLdouble src[16], GLdouble inverse[16]) { double t; int i, j, k, swap; GLdouble tmp[4][4]; identity(inverse); for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { tmp[i][j] = src[i*4+j]; } } for (i = 0; i < 4; i++) { /* look for largest element in column. */ swap = i; for (j = i + 1; j < 4; j++) { if (fabs(tmp[j][i]) > fabs(tmp[i][i])) { swap = j; } } if (swap != i) { /* swap rows. */ for (k = 0; k < 4; k++) { t = tmp[i][k]; tmp[i][k] = tmp[swap][k]; tmp[swap][k] = t; t = inverse[i*4+k]; inverse[i*4+k] = inverse[swap*4+k]; inverse[swap*4+k] = t; } } if (tmp[i][i] == 0) { /* no non-zero pivot. the matrix is singular, which shouldn't happen. This means the user gave us a bad matrix. */ return GL_FALSE; } t = tmp[i][i]; for (k = 0; k < 4; k++) {

Page 80: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

79/117

tmp[i][k] /= t; inverse[i*4+k] /= t; } for (j = 0; j < 4; j++) { if (j != i) { t = tmp[j][i]; for (k = 0; k < 4; k++) { tmp[j][k] -= tmp[i][k]*t; inverse[j*4+k] -= inverse[i*4+k]*t; } } } } return GL_TRUE; } float normalize(float* v) { float length; length = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); v[0] /= length; v[1] /= length; v[2] /= length; return length; } void main_reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, width, height, 0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); #define GAP 25 /* gap between subwindows */ sub_width = (width-GAP*3)/3; sub_height = (height-GAP*3)/2; glutSetWindow(screen); glutPositionWindow(GAP, GAP); glutReshapeWindow(sub_width, sub_height); glutSetWindow(world); glutPositionWindow(GAP, GAP+sub_height+GAP); glutReshapeWindow(sub_width, sub_height); glutSetWindow(command); glutPositionWindow(GAP+sub_width+GAP, GAP); glutReshapeWindow(sub_width*2, sub_height*2+GAP); } void main_display(void) {

Page 81: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

80/117

glClearColor(0.8, 0.8, 0.8, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3ub(0, 0, 0); setfont("helvetica", 12); drawstr(GAP, GAP-5, "Screen-space view"); drawstr(GAP+sub_width+GAP, GAP-5, "Command manipulation window"); drawstr(GAP, GAP+sub_height+GAP-5, "World-space view"); glutSwapBuffers(); } void world_reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)width/height, 0.01, 256.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -6.0); glRotatef(-45.0, 0.0, 1.0, 0.0); glClearColor(0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glEnable(GL_LIGHT0); } void world_display(void) { double length; float l[3]; GLfloat pos[4], lKa[4], lKd[4], lKs[4]; GLfloat dir[3], mKa[4], mKd[4], mKs[4], mKe[4]; GLfloat lmKa[4]; cell_vector(pos, light_pos, 4); cell_vector(lKa, light_Ka, 4); cell_vector(lKd, light_Kd, 4); cell_vector(lKs, light_Ks, 4); cell_vector(dir, spot_direction, 3); cell_vector(mKa, material_Ka, 4); cell_vector(mKd, material_Kd, 4); cell_vector(mKs, material_Ks, 4); cell_vector(mKe, material_Ke, 4); cell_vector(lmKa, lmodel_Ka, 4); glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, local_viewer.value); glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, two_side.value); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmKa); glMaterialfv(GL_FRONT, GL_AMBIENT, mKa); glMaterialfv(GL_FRONT, GL_DIFFUSE, mKd); glMaterialfv(GL_FRONT, GL_SPECULAR, mKs); glMaterialfv(GL_FRONT, GL_EMISSION, mKe); glMaterialf(GL_FRONT, GL_SHININESS, material_Se.value);

Page 82: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

81/117

glLightfv(GL_LIGHT0, GL_AMBIENT, lKa); glLightfv(GL_LIGHT0, GL_DIFFUSE, lKd); glLightfv(GL_LIGHT0, GL_SPECULAR, lKs); glLighti(GL_LIGHT0, GL_SPOT_EXPONENT, (int)spot_exponent.value); if (spot_cutoff.value > 90) glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, 180); else glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, (int)spot_cutoff.value); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, Kc.value); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, Kl.value); glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, Kq.value); l[0] = at[0] - eye[0]; l[1] = at[1] - eye[1]; l[2] = at[2] - eye[2]; invert(modelview, inverse); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glMultMatrixd(inverse); glTranslatef(l[0], l[1], l[2]); glColor3fv(lKd); glBegin(GL_LINE_STRIP); if (spot_cutoff.value > 90) glVertex3f(0, 0, 0); else glVertex3f(pos[0]+spot_direction[0].value, pos[1]+spot_direction[1].value, pos[2]+spot_direction[2].value); if (pos[3] == 0) /* 10.0 = 'infinite' light */ glVertex3f(pos[0]*10.0,pos[1]*10.0,pos[2]*10.0); else glVertex3f(pos[0], pos[1], pos[2]); glEnd(); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir); glLightfv(GL_LIGHT0, GL_POSITION, pos); glPopMatrix(); length = normalize(l); if (world_draw) { glEnable(GL_LIGHTING); if (pmodel) drawmodel(); else glutSolidTorus(0.25, 0.75, 28, 28); glDisable(GL_LIGHTING); } #if 0 #define TESS 20 glNormal3f(0.0, 1.0, 0.0); for (i = 0; i < TESS; i++) { glBegin(GL_TRIANGLE_STRIP);

Page 83: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

82/117

for (j = 0; j <= TESS; j++) { glVertex3f(-1+(float)i/TESS*2, -1.0, -1+(float)j/TESS*2); glVertex3f(-1+(float)(i+1)/TESS*2, -1.0, -1+(float)j/TESS*2); } glEnd(); } #endif glPushMatrix(); glMultMatrixd(inverse); /* draw the axis and eye vector */ glPushMatrix(); glColor3ub(0, 0, 255); glBegin(GL_LINE_STRIP); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 0.0, -1.0*length); glVertex3f(0.1, 0.0, -0.9*length); glVertex3f(-0.1, 0.0, -0.9*length); glVertex3f(0.0, 0.0, -1.0*length); glVertex3f(0.0, 0.1, -0.9*length); glVertex3f(0.0, -0.1, -0.9*length); glVertex3f(0.0, 0.0, -1.0*length); glEnd(); glColor3ub(255, 255, 0); glRasterPos3f(0.0, 0.0, -1.1*length); glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'e'); glColor3ub(255, 0, 0); glScalef(0.4, 0.4, 0.4); drawaxes(); glPopMatrix(); invert(projection, inverse); glMultMatrixd(inverse); /* draw the viewing frustum */ glColor3f(0.2, 0.2, 0.2); glBegin(GL_QUADS); glVertex3i(1, 1, 1); glVertex3i(-1, 1, 1); glVertex3i(-1, -1, 1); glVertex3i(1, -1, 1); glEnd(); glColor3ub(128, 196, 128); glBegin(GL_LINES); glVertex3i(1, 1, -1); glVertex3i(1, 1, 1); glVertex3i(-1, 1, -1); glVertex3i(-1, 1, 1); glVertex3i(-1, -1, -1); glVertex3i(-1, -1, 1); glVertex3i(1, -1, -1); glVertex3i(1, -1, 1); glEnd();

Page 84: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

83/117

glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.2, 0.2, 0.4, 0.5); glBegin(GL_QUADS); glVertex3i(1, 1, -1); glVertex3i(-1, 1, -1); glVertex3i(-1, -1, -1); glVertex3i(1, -1, -1); glEnd(); glDisable(GL_BLEND); glPopMatrix(); glutSwapBuffers(); } void new_material(float* material) { material_Ka[0].value = material[0]; material_Ka[1].value = material[1]; material_Ka[2].value = material[2]; material_Ka[3].value = material[3]; material_Kd[0].value = material[4]; material_Kd[1].value = material[5]; material_Kd[2].value = material[6]; material_Kd[3].value = material[7]; material_Ks[0].value = material[8]; material_Ks[1].value = material[9]; material_Ks[2].value = material[10]; material_Ks[3].value = material[11]; material_Ke[0].value = 0; material_Ke[1].value = 0; material_Ke[2].value = 0; material_Ke[3].value = 0; material_Se.value = material[12]; } void world_menu(int value) { switch (value) { case 1: new_material(Brass); break; case 2: new_material(Bronze); break; case 3: new_material(Polished_Bronze); break; case 4: new_material(Chrome); break; case 5: new_material(Copper); break; case 6:

Page 85: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

84/117

new_material(Polished_Copper); break; case 7: new_material(Gold); break; case 8: new_material(Polished_Gold); break; case 9: new_material(Pewter); break; case 10: new_material(Silver); break; case 11: new_material(Polished_Silver); break; case 12: new_material(Emerald); break; case 13: new_material(Jade); break; case 14: new_material(Obsidian); break; case 15: new_material(Pearl); break; case 16: new_material(Ruby); break; case 17: new_material(Turquoise); break; case 18: new_material(Black_Plastic); break; case 19: new_material(Black_Rubber); break; } redisplay_all(); } void screen_reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (float)width/height, 0.5, 8.0); glGetDoublev(GL_PROJECTION_MATRIX, projection); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(eye[0], eye[1], eye[2], at[0], at[1], at[2], up[0],

Page 86: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

85/117

up[1],up[2]); glClearColor(0.2, 0.2, 0.2, 1.0); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } void screen_display(void) { GLfloat pos[4], lKa[4], lKd[4], lKs[4]; GLfloat dir[3], mKa[4], mKd[4], mKs[4], mKe[4]; GLfloat lmKa[4]; cell_vector(pos, light_pos, 4); cell_vector(lKa, light_Ka, 4); cell_vector(lKd, light_Kd, 4); cell_vector(lKs, light_Ks, 4); cell_vector(dir, spot_direction, 3); cell_vector(mKa, material_Ka, 4); cell_vector(mKd, material_Kd, 4); cell_vector(mKs, material_Ks, 4); cell_vector(mKe, material_Ke, 4); cell_vector(lmKa, lmodel_Ka, 4); glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, local_viewer.value); glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, two_side.value); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmKa); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, lKa); glLightfv(GL_LIGHT0, GL_DIFFUSE, lKd); glLightfv(GL_LIGHT0, GL_SPECULAR, lKs); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir); glLighti(GL_LIGHT0, GL_SPOT_EXPONENT, (int)spot_exponent.value); if (spot_cutoff.value > 90) glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, 180); else glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, (int)spot_cutoff.value); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, Kc.value); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, Kl.value); glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, Kq.value); glMaterialfv(GL_FRONT, GL_AMBIENT, mKa); glMaterialfv(GL_FRONT, GL_DIFFUSE, mKd); glMaterialfv(GL_FRONT, GL_SPECULAR, mKs); glMaterialfv(GL_FRONT, GL_EMISSION, mKe); glMaterialf(GL_FRONT, GL_SHININESS, material_Se.value); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(spin_y, 1.0, 0.0, 0.0); glRotatef(spin_x, 0.0, 1.0, 0.0); glGetDoublev(GL_MODELVIEW_MATRIX, modelview); if (pmodel) drawmodel(); else

Page 87: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

86/117

glutSolidTorus(0.25, 0.75, 28, 28); glPopMatrix(); #if 0 #define TESS 20 glNormal3f(0.0, 1.0, 0.0); for (i = 0; i < TESS; i++) { glBegin(GL_TRIANGLE_STRIP); for (j = 0; j <= TESS; j++) { glVertex3f(-1+(float)i/TESS*2, -1.0, -1+(float)j/TESS*2); glVertex3f(-1+(float)(i+1)/TESS*2, -1.0, -1+(float)j/TESS*2); } glEnd(); } #endif glutSwapBuffers(); } void screen_menu(int value) { char* name = 0; switch (value) { case 'a': name = "data/al.obj"; break; case 's': name = "data/soccerball.obj"; break; case 'd': name = "data/dolphins.obj"; break; case 'f': name = "data/flowers.obj"; break; case 'j': name = "data/f-16.obj"; break; case 'p': name = "data/porsche.obj"; break; case 'r': name = "data/rose+vase.obj"; break; case 'n': if (pmodel) glmDelete(pmodel); pmodel = NULL; redisplay_all(); return; } if (name) { if (pmodel) glmDelete(pmodel); pmodel = glmReadOBJ(name);

Page 88: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

87/117

if (!pmodel) exit(0); glmUnitize(pmodel); glmFacetNormals(pmodel); glmVertexNormals(pmodel, 90.0); } redisplay_all(); } int old_x, old_y; void screen_mouse(int button, int state, int x, int y) { old_x = x; old_y = y; redisplay_all(); } void screen_motion(int x, int y) { spin_x = x - old_x; spin_y = y - old_y; redisplay_all(); } void command_reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, width, height, 0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0.0, 0.0, 0.0, 0.0); } void lighting_display(void) { setfont("helvetica", 18); drawstr(10, light_pos[0].y, "GLfloat light_pos[ ] = {"); drawstr(10, light_Ka[0].y, "GLfloat light_Ka[ ] = {"); drawstr(10, light_Kd[0].y, "GLfloat light_Kd[ ] = {"); drawstr(10, light_Ks[0].y, "GLfloat light_Ks[ ] = {"); drawstr(light_pos[0].x+50, light_pos[0].y, ","); drawstr(light_pos[1].x+50, light_pos[1].y, ","); drawstr(light_pos[2].x+50, light_pos[2].y, ","); drawstr(light_pos[3].x+50, light_pos[3].y, "};"); drawstr(light_Ka[0].x+50, light_Ka[0].y, ","); drawstr(light_Ka[1].x+50, light_Ka[1].y, ","); drawstr(light_Ka[2].x+50, light_Ka[2].y, ","); drawstr(light_Ka[3].x+50, light_Ka[3].y, "};");

Page 89: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

88/117

drawstr(light_Kd[0].x+50, light_Kd[0].y, ","); drawstr(light_Kd[1].x+50, light_Kd[1].y, ","); drawstr(light_Kd[2].x+50, light_Kd[2].y, ","); drawstr(light_Kd[3].x+50, light_Kd[3].y, "};"); drawstr(light_Ks[0].x+50, light_Ks[0].y, ","); drawstr(light_Ks[1].x+50, light_Ks[1].y, ","); drawstr(light_Ks[2].x+50, light_Ks[2].y, ","); drawstr(light_Ks[3].x+50, light_Ks[3].y, "};"); setfont("helvetica", 12); drawstr(10, light_Ks[0].y+30, "glLightfv(GL_LIGHT0, GL_POSITION, light_pos);"); drawstr(10, light_Ks[1].y+50, "glLightfv(GL_LIGHT0, GL_AMBIENT, light_Ka);"); drawstr(10, light_Ks[2].y+70, "glLightfv(GL_LIGHT0, GL_DIFFUSE, light_Kd);"); drawstr(10, light_Ks[3].y+90, "glLightfv(GL_LIGHT0, GL_SPECULAR, light_Ks);"); setfont("helvetica", 18); cell_draw(&light_pos[0]); cell_draw(&light_pos[1]); cell_draw(&light_pos[2]); cell_draw(&light_pos[3]); cell_draw(&light_Ka[0]); cell_draw(&light_Ka[1]); cell_draw(&light_Ka[2]); cell_draw(&light_Ka[3]); cell_draw(&light_Kd[0]); cell_draw(&light_Kd[1]); cell_draw(&light_Kd[2]); cell_draw(&light_Kd[3]); cell_draw(&light_Ks[0]); cell_draw(&light_Ks[1]); cell_draw(&light_Ks[2]); cell_draw(&light_Ks[3]); glColor3ub(255, 255, 255); } void spotlight_display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3ub(255, 255, 255); lighting_display(); setfont("helvetica", 18); drawstr(10, spot_direction[0].y, "GLfloat spot_direction[ ] = {"); drawstr(10, spot_exponent.y, "GLint spot_exponent = "

Page 90: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

89/117

"spot_cutoff = "); drawstr(spot_direction[0].x+50, spot_direction[0].y, ","); drawstr(spot_direction[1].x+50, spot_direction[1].y, ","); drawstr(spot_direction[2].x+50, spot_direction[2].y, "};"); drawstr(spot_exponent.x+40, spot_cutoff.y, ","); drawstr(spot_cutoff.x+40, spot_cutoff.y, ";"); setfont("helvetica", 12); drawstr(10, spot_cutoff.y+30, "glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);"); drawstr(10, spot_cutoff.y+50, "glLighti(GL_LIGHT0, GL_SPOT_EXPONENT, spot_exponent);"); drawstr(10, spot_cutoff.y+70, "glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, spot_cutoff);"); setfont("helvetica", 18); drawstr(10, Kc.y, "GLfloat Kc = , Kl = , Kq = ;"); setfont("helvetica", 12); drawstr(10, Kq.y+30, "glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, Kc);"); drawstr(10, Kq.y+50, "glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, Kl);"); drawstr(10, Kq.y+70, "glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, Kq);"); setfont("helvetica", 18); cell_draw(&spot_direction[0]); cell_draw(&spot_direction[1]); cell_draw(&spot_direction[2]); cell_draw(&spot_exponent); cell_draw(&spot_cutoff); cell_draw(&Kc); cell_draw(&Kl); cell_draw(&Kq); if (!selection) { glColor3ub(255, 255, 0); drawstr(10, 525, "Click on the arguments and move the mouse to modify values."); } glutSwapBuffers(); } void material_display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3ub(255, 255, 255); lighting_display();

Page 91: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

90/117

setfont("helvetica", 18); drawstr(10, material_Ka[0].y, "GLfloat material_Ka[ ] = {"); drawstr(10, material_Kd[0].y, "GLfloat material_Kd[ ] = {"); drawstr(10, material_Ks[0].y, "GLfloat material_Ks[ ] = {"); drawstr(10, material_Ke[0].y, "GLfloat material_Ke[ ] = {"); drawstr(10, material_Se.y, "GLfloat material_Se = ;"); drawstr(material_Ka[0].x+50, material_Ka[0].y, ","); drawstr(material_Ka[1].x+50, material_Ka[1].y, ","); drawstr(material_Ka[2].x+50, material_Ka[2].y, ","); drawstr(material_Ka[3].x+50, material_Ka[3].y, "};"); drawstr(material_Kd[0].x+50, material_Kd[0].y, ","); drawstr(material_Kd[1].x+50, material_Kd[1].y, ","); drawstr(material_Kd[2].x+50, material_Kd[2].y, ","); drawstr(material_Kd[3].x+50, material_Kd[3].y, "};"); drawstr(material_Ks[0].x+50, material_Ks[0].y, ","); drawstr(material_Ks[1].x+50, material_Ks[1].y, ","); drawstr(material_Ks[2].x+50, material_Ks[2].y, ","); drawstr(material_Ks[3].x+50, material_Ks[3].y, "};"); drawstr(material_Ke[0].x+50, material_Ke[0].y, ","); drawstr(material_Ke[1].x+50, material_Ke[1].y, ","); drawstr(material_Ke[2].x+50, material_Ke[2].y, ","); drawstr(material_Ke[3].x+50, material_Ke[3].y, "};"); setfont("helvetica", 12); drawstr(10, material_Se.y+30, "glMaterialfv(GL_FRONT, GL_AMBIENT, material_Ka);"); drawstr(10, material_Se.y+50, "glMaterialfv(GL_FRONT, GL_DIFFUSE, material_Kd);"); drawstr(10, material_Se.y+70, "glMaterialfv(GL_FRONT, GL_SPECULAR, material_Ks);"); drawstr(10, material_Se.y+90, "glMaterialfv(GL_FRONT, GL_EMISSION, material_Ke);"); drawstr(10, material_Se.y+110, "glMaterialfv(GL_FRONT, GL_SHININESS, material_Se);"); setfont("helvetica", 18); cell_draw(&material_Ka[0]); cell_draw(&material_Ka[1]); cell_draw(&material_Ka[2]); cell_draw(&material_Ka[3]); cell_draw(&material_Kd[0]); cell_draw(&material_Kd[1]); cell_draw(&material_Kd[2]); cell_draw(&material_Kd[3]); cell_draw(&material_Ks[0]); cell_draw(&material_Ks[1]); cell_draw(&material_Ks[2]); cell_draw(&material_Ks[3]); cell_draw(&material_Ke[0]); cell_draw(&material_Ke[1]); cell_draw(&material_Ke[2]); cell_draw(&material_Ke[3]);

Page 92: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

91/117

cell_draw(&material_Se); if (!selection) { glColor3ub(255, 255, 0); drawstr(10, 525, "Click on the arguments and move the mouse to modify values."); } glutSwapBuffers(); } void lmodel_display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3ub(255, 255, 255); lighting_display(); setfont("helvetica", 18); drawstr(10, lmodel_Ka[0].y, "GLfloat lmodel_Ka[ ] = {"); drawstr(lmodel_Ka[0].x+50, lmodel_Ka[0].y, ","); drawstr(lmodel_Ka[1].x+50, lmodel_Ka[1].y, ","); drawstr(lmodel_Ka[2].x+50, lmodel_Ka[2].y, ","); drawstr(lmodel_Ka[3].x+50, lmodel_Ka[3].y, "};"); setfont("helvetica", 12); drawstr(10, lmodel_Ka[3].y+30, "glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_Ka);"); setfont("helvetica", 18); drawstr(10, local_viewer.y, "glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, "); drawstr(local_viewer.x+35, local_viewer.y, ");"); drawstr(10, two_side.y, "glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, "); drawstr(two_side.x+35, two_side.y, ");"); cell_draw(&lmodel_Ka[0]); cell_draw(&lmodel_Ka[1]); cell_draw(&lmodel_Ka[2]); cell_draw(&lmodel_Ka[3]); cell_draw(&local_viewer); cell_draw(&two_side); if (!selection) { glColor3ub(255, 255, 0); drawstr(10, 525, "Click on the arguments and move the mouse to modify values."); } glutSwapBuffers();

Page 93: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

92/117

} void lighting_mouse(int x, int y) { /* mouse should only hit _one_ of the cells, so adding up all the hits just propagates a single hit. */ selection += cell_hit(&light_pos[0], x, y); selection += cell_hit(&light_pos[1], x, y); selection += cell_hit(&light_pos[2], x, y); selection += cell_hit(&light_pos[3], x, y); selection += cell_hit(&light_Ka[0], x, y); selection += cell_hit(&light_Ka[1], x, y); selection += cell_hit(&light_Ka[2], x, y); selection += cell_hit(&light_Ka[3], x, y); selection += cell_hit(&light_Kd[0], x, y); selection += cell_hit(&light_Kd[1], x, y); selection += cell_hit(&light_Kd[2], x, y); selection += cell_hit(&light_Kd[3], x, y); selection += cell_hit(&light_Ks[0], x, y); selection += cell_hit(&light_Ks[1], x, y); selection += cell_hit(&light_Ks[2], x, y); selection += cell_hit(&light_Ks[3], x, y); } void material_mouse(int button, int state, int x, int y) { selection = 0; if (state == GLUT_DOWN) { lighting_mouse(x, y); /* mouse should only hit _one_ of the cells, so adding up all the hits just propagates a single hit. */ selection += cell_hit(&material_Ka[0], x, y); selection += cell_hit(&material_Ka[1], x, y); selection += cell_hit(&material_Ka[2], x, y); selection += cell_hit(&material_Ka[3], x, y); selection += cell_hit(&material_Kd[0], x, y); selection += cell_hit(&material_Kd[1], x, y); selection += cell_hit(&material_Kd[2], x, y); selection += cell_hit(&material_Kd[3], x, y); selection += cell_hit(&material_Ks[0], x, y); selection += cell_hit(&material_Ks[1], x, y); selection += cell_hit(&material_Ks[2], x, y); selection += cell_hit(&material_Ks[3], x, y); selection += cell_hit(&material_Ke[0], x, y); selection += cell_hit(&material_Ke[1], x, y); selection += cell_hit(&material_Ke[2], x, y); selection += cell_hit(&material_Ke[3], x, y); selection += cell_hit(&material_Se, x, y); } old_y = y; redisplay_all(); }

Page 94: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

93/117

void spotlight_mouse(int button, int state, int x, int y) { selection = 0; if (state == GLUT_DOWN) { lighting_mouse(x, y); /* mouse should only hit _one_ of the cells, so adding up all the hits just propagates a single hit. */ selection += cell_hit(&spot_direction[0], x, y); selection += cell_hit(&spot_direction[1], x, y); selection += cell_hit(&spot_direction[2], x, y); selection += cell_hit(&spot_exponent, x, y); selection += cell_hit(&spot_cutoff, x, y); selection += cell_hit(&Kc, x, y); selection += cell_hit(&Kl, x, y); selection += cell_hit(&Kq, x, y); } old_y = y; redisplay_all(); } void lmodel_mouse(int button, int state, int x, int y) { selection = 0; if (state == GLUT_DOWN) { lighting_mouse(x, y); /* mouse should only hit _one_ of the cells, so adding up all the hits just propagates a single hit. */ selection += cell_hit(&lmodel_Ka[0], x, y); selection += cell_hit(&lmodel_Ka[1], x, y); selection += cell_hit(&lmodel_Ka[2], x, y); selection += cell_hit(&lmodel_Ka[3], x, y); selection += cell_hit(&local_viewer, x, y); selection += cell_hit(&two_side, x, y); } old_y = y; redisplay_all(); } void command_motion(int x, int y) { cell_update(&light_pos[0], old_y-y); cell_update(&light_pos[1], old_y-y); cell_update(&light_pos[2], old_y-y); cell_update(&light_pos[3], old_y-y); cell_update(&light_Ka[0], old_y-y); cell_update(&light_Ka[1], old_y-y); cell_update(&light_Ka[2], old_y-y);

Page 95: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

94/117

cell_update(&light_Ka[3], old_y-y); cell_update(&light_Kd[0], old_y-y); cell_update(&light_Kd[1], old_y-y); cell_update(&light_Kd[2], old_y-y); cell_update(&light_Kd[3], old_y-y); cell_update(&light_Ks[0], old_y-y); cell_update(&light_Ks[1], old_y-y); cell_update(&light_Ks[2], old_y-y); cell_update(&light_Ks[3], old_y-y); cell_update(&spot_direction[0], old_y-y); cell_update(&spot_direction[1], old_y-y); cell_update(&spot_direction[2], old_y-y); cell_update(&spot_exponent, old_y-y); cell_update(&spot_cutoff, old_y-y); cell_update(&Kc, old_y-y); cell_update(&Kl, old_y-y); cell_update(&Kq, old_y-y); cell_update(&material_Ka[0], old_y-y); cell_update(&material_Ka[1], old_y-y); cell_update(&material_Ka[2], old_y-y); cell_update(&material_Ka[3], old_y-y); cell_update(&material_Kd[0], old_y-y); cell_update(&material_Kd[1], old_y-y); cell_update(&material_Kd[2], old_y-y); cell_update(&material_Kd[3], old_y-y); cell_update(&material_Ks[0], old_y-y); cell_update(&material_Ks[1], old_y-y); cell_update(&material_Ks[2], old_y-y); cell_update(&material_Ks[3], old_y-y); cell_update(&material_Ke[0], old_y-y); cell_update(&material_Ke[1], old_y-y); cell_update(&material_Ke[2], old_y-y); cell_update(&material_Ke[3], old_y-y); cell_update(&material_Se, old_y-y); cell_update(&lmodel_Ka[0], old_y-y); cell_update(&lmodel_Ka[1], old_y-y); cell_update(&lmodel_Ka[2], old_y-y); cell_update(&lmodel_Ka[3], old_y-y); cell_update(&local_viewer, old_y-y); cell_update(&two_side, old_y-y); old_y = y; redisplay_all(); } void redisplay_all(void) { glutSetWindow(command); glutPostRedisplay(); glutSetWindow(world); world_reshape(sub_width, sub_height); glutPostRedisplay(); glutSetWindow(screen); screen_reshape(sub_width, sub_height); glutPostRedisplay();

Page 96: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

95/117

} void main_keyboard(unsigned char key, int x, int y) { switch (key) { case 'r': light_pos[0].value = -2.0; light_pos[1].value = 2.0; light_pos[2].value = 2.0; light_pos[3].value = 1.0; light_Ka[0].value = 0; light_Ka[1].value = 0; light_Ka[2].value = 0; light_Ka[3].value = 1; light_Kd[0].value = 1; light_Kd[1].value = 1; light_Kd[2].value = 1; light_Kd[3].value = 1; light_Ks[0].value = 1; light_Ks[1].value = 1; light_Ks[2].value = 1; light_Ks[3].value = 1; spot_direction[0].value = 1.0; spot_direction[1].value = -1.0; spot_direction[2].value = -1.0; spot_exponent.value = 30.0; spot_cutoff.value = 91.0; Kc.value = 1.0; Kl.value = 0.0; Kq.value = 0.0; new_material(Pewter); lmodel_Ka[0].value = 0.2; lmodel_Ka[1].value = 0.2; lmodel_Ka[2].value = 0.2; lmodel_Ka[3].value = 1.0; local_viewer.value = 0; two_side.value = 0; break; case 'm': glutSetWindow(command); glutMouseFunc(material_mouse); glutDisplayFunc(material_display); break; case 's': glutSetWindow(command); glutMouseFunc(spotlight_mouse); glutDisplayFunc(spotlight_display); break; case 'l': glutSetWindow(command); glutMouseFunc(lmodel_mouse); glutDisplayFunc(lmodel_display); break; case 27: exit(0); }

Page 97: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

96/117

redisplay_all(); } void command_menu(int value) { main_keyboard((unsigned char)value, 0, 0); } int main(int argc, char** argv) { glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize((512+GAP*3)*3/2, 512+GAP*3); glutInitWindowPosition(50, 50); glutInit(&argc, argv); window = glutCreateWindow("Light & Material"); glutReshapeFunc(main_reshape); glutDisplayFunc(main_display); glutKeyboardFunc(main_keyboard); world = glutCreateSubWindow(window, GAP, GAP, 256, 256); glutReshapeFunc(world_reshape); glutDisplayFunc(world_display); glutKeyboardFunc(main_keyboard); glutCreateMenu(world_menu); glutAddMenuEntry("Materials", 0); glutAddMenuEntry("", 0); glutAddMenuEntry("Brass", 1); glutAddMenuEntry("Bronze", 2); glutAddMenuEntry("Polished_Bronze", 3); glutAddMenuEntry("Chrome", 4); glutAddMenuEntry("Copper", 5); glutAddMenuEntry("Polished_Copper", 6); glutAddMenuEntry("Gold", 7); glutAddMenuEntry("Polished_Gold", 8); glutAddMenuEntry("Pewter", 9); glutAddMenuEntry("Silver", 10); glutAddMenuEntry("Polished_Silver", 11); glutAddMenuEntry("Emerald", 12); glutAddMenuEntry("Jade", 13); glutAddMenuEntry("Obsidian", 14); glutAddMenuEntry("Pearl", 15); glutAddMenuEntry("Ruby", 16); glutAddMenuEntry("Turquoise", 17); glutAddMenuEntry("Black_Plastic", 18); glutAddMenuEntry("Black_Rubber", 19); glutAttachMenu(GLUT_RIGHT_BUTTON); screen = glutCreateSubWindow(window, GAP+256+GAP, GAP, 256, 256); glutReshapeFunc(screen_reshape); glutDisplayFunc(screen_display); glutKeyboardFunc(main_keyboard); glutMotionFunc(screen_motion); glutMouseFunc(screen_mouse);

Page 98: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

97/117

glutCreateMenu(screen_menu); glutAddMenuEntry("Models", 0); glutAddMenuEntry("", 0); glutAddMenuEntry("Torus", 'n'); glutAddMenuEntry("Flat plane", 'l'); glutAddMenuEntry("Soccerball", 's'); glutAddMenuEntry("Al Capone", 'a'); glutAddMenuEntry("F-16 Jet", 'j'); glutAddMenuEntry("Dolphins", 'd'); glutAddMenuEntry("Flowers", 'f'); glutAddMenuEntry("Porsche", 'p'); glutAddMenuEntry("Rose", 'r'); glutAttachMenu(GLUT_RIGHT_BUTTON); command = glutCreateSubWindow(window, GAP+256+GAP, GAP+256+GAP, 256, 256); glutReshapeFunc(command_reshape); glutDisplayFunc(material_display); glutMotionFunc(command_motion); glutMouseFunc(material_mouse); glutKeyboardFunc(main_keyboard); glutCreateMenu(command_menu); glutAddMenuEntry("Light & Material", 0); glutAddMenuEntry("", 0); glutAddMenuEntry("Material parameters", 'm'); glutAddMenuEntry("Light model parameters", 'l'); glutAddMenuEntry("Spotlight & attenuation", 's'); glutAddMenuEntry("Reset parameters (r)", 'r'); glutAddMenuEntry("", 0); glutAddMenuEntry("Quit", 27); glutAttachMenu(GLUT_RIGHT_BUTTON); new_material(Pewter); redisplay_all(); glutMainLoop(); return 0; } Program 18 /* lightposition.c Nate Robins, 1997 Tool for teaching about OpenGL light positioning. */ #include <math.h> #include <stdio.h> #include <stdlib.h>

Page 99: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

98/117

#include <stdarg.h> #include <string.h> #include <GL/glut.h> #include "glm.h" #pragma comment( linker, "/entry:\"mainCRTStartup\"" ) // set the entry point to be main() typedef struct _cell { int id; int x, y; float min, max; float value; float step; char* info; char* format; } cell; cell lookat[9] = { { 1, 180, 120, -5.0, 5.0, 0.0, 0.1, "Specifies the X position of the eye point.", "%.2f" }, { 2, 240, 120, -5.0, 5.0, 0.0, 0.1, "Specifies the Y position of the eye point.", "%.2f" }, { 3, 300, 120, -5.0, 5.0, 2.0, 0.1, "Specifies the Z position of the eye point.", "%.2f" }, { 4, 180, 160, -5.0, 5.0, 0.0, 0.1, "Specifies the X position of the reference point.", "%.2f" }, { 5, 240, 160, -5.0, 5.0, 0.0, 0.1, "Specifies the Y position of the reference point.", "%.2f" }, { 6, 300, 160, -5.0, 5.0, 0.0, 0.1, "Specifies the Z position of the reference point.", "%.2f" }, { 7, 180, 200, -2.0, 2.0, 0.0, 0.1, "Specifies the X direction of the up vector.", "%.2f" }, { 8, 240, 200, -2.0, 2.0, 1.0, 0.1, "Specifies the Y direction of the up vector.", "%.2f" }, { 9, 300, 200, -2.0, 2.0, 0.0, 0.1, "Specifies the Z direction of the up vector.", "%.2f" }, }; cell light[4] = { { 10, 180, 40, -5.0, 5.0, 1.5, 0.1, "Specifies X coordinate of light vector.", "%.2f" }, { 11, 240, 40, -5.0, 5.0, 1.0, 0.1, "Specifies Y coordinate of light vector.", "%.2f" }, { 12, 300, 40, -5.0, 5.0, 1.0, 0.1, "Specifies Z coordinate of light vector.", "%.2f" }, { 13, 360, 40, 0.0, 1.0, 0.0, 1.0, "Specifies directional (0) or positional (1) light.", "%.2f" } }; GLboolean swapped = GL_FALSE; GLboolean world_draw = GL_TRUE; GLMmodel* pmodel = NULL; GLint selection = 0;

Page 100: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

99/117

void redisplay_all(void); GLdouble projection[16], modelview[16], inverse[16]; GLuint window, world, screen, command; GLuint sub_width = 256, sub_height = 256; GLvoid *font_style = GLUT_BITMAP_TIMES_ROMAN_10; void setfont(char* name, int size) { font_style = GLUT_BITMAP_HELVETICA_10; if (strcmp(name, "helvetica") == 0) { if (size == 12) font_style = GLUT_BITMAP_HELVETICA_12; else if (size == 18) font_style = GLUT_BITMAP_HELVETICA_18; } else if (strcmp(name, "times roman") == 0) { font_style = GLUT_BITMAP_TIMES_ROMAN_10; if (size == 24) font_style = GLUT_BITMAP_TIMES_ROMAN_24; } else if (strcmp(name, "8x13") == 0) { font_style = GLUT_BITMAP_8_BY_13; } else if (strcmp(name, "9x15") == 0) { font_style = GLUT_BITMAP_9_BY_15; } } void drawstr(GLuint x, GLuint y, char* format, ...) { va_list args; char buffer[255], *s; va_start(args, format); vsprintf(buffer, format, args); va_end(args); glRasterPos2i(x, y); for (s = buffer; *s; s++) glutBitmapCharacter(font_style, *s); } void cell_draw(cell* cell) { glColor3ub(0, 255, 128); if (selection == cell->id) { glColor3ub(255, 255, 0); drawstr(10, 240, cell->info); glColor3ub(255, 0, 0); } drawstr(cell->x, cell->y, cell->format, cell->value); }

Page 101: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

100/117

int cell_hit(cell* cell, int x, int y) { if (x > cell->x && x < cell->x + 60 && y > cell->y-30 && y < cell->y+10) return cell->id; return 0; } void cell_update(cell* cell, int update) { if (selection != cell->id) return; cell->value += update * cell->step; if (cell->value < cell->min) cell->value = cell->min; else if (cell->value > cell->max) cell->value = cell->max; } void cell_vector(float* dst, cell* cell, int num) { while (--num >= 0) dst[num] = cell[num].value; } void drawmodel(void) { if (!pmodel) { pmodel = glmReadOBJ("data/soccerball.obj"); if (!pmodel) exit(0); glmUnitize(pmodel); glmFacetNormals(pmodel); glmVertexNormals(pmodel, 90.0); } glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL); } void drawaxes(void) { glColor3ub(255, 0, 0); glBegin(GL_LINE_STRIP); glVertex3f(0.0, 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glVertex3f(0.75, 0.25, 0.0); glVertex3f(0.75, -0.25, 0.0); glVertex3f(1.0, 0.0, 0.0); glVertex3f(0.75, 0.0, 0.25); glVertex3f(0.75, 0.0, -0.25);

Page 102: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

101/117

glVertex3f(1.0, 0.0, 0.0); glEnd(); glBegin(GL_LINE_STRIP); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glVertex3f(0.0, 0.75, 0.25); glVertex3f(0.0, 0.75, -0.25); glVertex3f(0.0, 1.0, 0.0); glVertex3f(0.25, 0.75, 0.0); glVertex3f(-0.25, 0.75, 0.0); glVertex3f(0.0, 1.0, 0.0); glEnd(); glBegin(GL_LINE_STRIP); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 1.0); glVertex3f(0.25, 0.0, 0.75); glVertex3f(-0.25, 0.0, 0.75); glVertex3f(0.0, 0.0, 1.0); glVertex3f(0.0, 0.25, 0.75); glVertex3f(0.0, -0.25, 0.75); glVertex3f(0.0, 0.0, 1.0); glEnd(); glColor3ub(255, 255, 0); glRasterPos3f(1.1, 0.0, 0.0); glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'x'); glRasterPos3f(0.0, 1.1, 0.0); glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'y'); glRasterPos3f(0.0, 0.0, 1.1); glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'z'); } void identity(GLdouble m[16]) { m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0; m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0; m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0; m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1; } GLboolean invert(GLdouble src[16], GLdouble inverse[16]) { double t; int i, j, k, swap; GLdouble tmp[4][4]; identity(inverse); for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { tmp[i][j] = src[i*4+j]; } } for (i = 0; i < 4; i++) {

Page 103: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

102/117

/* look for largest element in column. */ swap = i; for (j = i + 1; j < 4; j++) { if (fabs(tmp[j][i]) > fabs(tmp[i][i])) { swap = j; } } if (swap != i) { /* swap rows. */ for (k = 0; k < 4; k++) { t = tmp[i][k]; tmp[i][k] = tmp[swap][k]; tmp[swap][k] = t; t = inverse[i*4+k]; inverse[i*4+k] = inverse[swap*4+k]; inverse[swap*4+k] = t; } } if (tmp[i][i] == 0) { /* no non-zero pivot. the matrix is singular, which shouldn't happen. This means the user gave us a bad matrix. */ return GL_FALSE; } t = tmp[i][i]; for (k = 0; k < 4; k++) { tmp[i][k] /= t; inverse[i*4+k] /= t; } for (j = 0; j < 4; j++) { if (j != i) { t = tmp[j][i]; for (k = 0; k < 4; k++) { tmp[j][k] -= tmp[i][k]*t; inverse[j*4+k] -= inverse[i*4+k]*t; } } } } return GL_TRUE; } float normalize(float* v) { float length; length = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); v[0] /= length; v[1] /= length; v[2] /= length; return length;

Page 104: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

103/117

} void main_reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, width, height, 0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); #define GAP 25 /* gap between subwindows */ sub_width = (width-GAP*3)/2.0; sub_height = (height-GAP*3)/2.0; glutSetWindow(world); glutPositionWindow(GAP, GAP); glutReshapeWindow(sub_width, sub_height); glutSetWindow(screen); glutPositionWindow(GAP+sub_width+GAP, GAP); glutReshapeWindow(sub_width, sub_height); glutSetWindow(command); glutPositionWindow(GAP, GAP+sub_height+GAP); glutReshapeWindow(sub_width+GAP+sub_width, sub_height); } void main_display(void) { glClearColor(0.8, 0.8, 0.8, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3ub(0, 0, 0); setfont("helvetica", 12); drawstr(GAP, GAP-5, "World-space view"); drawstr(GAP+sub_width+GAP, GAP-5, "Screen-space view"); drawstr(GAP, GAP+sub_height+GAP-5, "Command manipulation window"); glutSwapBuffers(); } void main_keyboard(unsigned char key, int x, int y) { switch (key) { case 's': swapped = !swapped; break; case 'r': light[0].value = 1.5; light[1].value = 1.0; light[2].value = 1.0; light[3].value = 0.0; lookat[0].value = 0.0; lookat[1].value = 0.0; lookat[2].value = 2.0; lookat[3].value = 0.0; lookat[4].value = 0.0;

Page 105: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

104/117

lookat[5].value = 0.0; lookat[6].value = 0.0; lookat[7].value = 1.0; lookat[8].value = 0.0; break; case 27: exit(0); } redisplay_all(); } void world_reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)width/height, 0.01, 256.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -5.0); glRotatef(-45.0, 0.0, 1.0, 0.0); glClearColor(0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); } void world_display(void) { GLfloat pos[4]; double length; float l[3]; cell_vector(pos, light, 4); l[0] = lookat[3].value - lookat[0].value; l[1] = lookat[4].value - lookat[1].value; l[2] = lookat[5].value - lookat[2].value; invert(modelview, inverse); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (swapped) { glPushMatrix(); glTranslatef(l[0], l[1], l[2]); glMultMatrixd(inverse); glColor3ub(255, 255, 255); glBegin(GL_LINE_STRIP); glVertex3f(0.0, 0.0, 0.0); if (pos[3] == 0) /* 10.0 = 'infinite' light */ glVertex3f(pos[0]*10.0,pos[1]*10.0,pos[2]*10.0); else glVertex3f(pos[0], pos[1], pos[2]); glEnd(); glLightfv(GL_LIGHT0, GL_POSITION, pos);

Page 106: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

105/117

glPopMatrix(); } else { glColor3ub(255, 255, 255); glBegin(GL_LINE_STRIP); glVertex3f(0.0, 0.0, 0.0); if (pos[3] == 0) /* 10.0 = 'infinite' light */ glVertex3f(pos[0]*10.0,pos[1]*10.0,pos[2]*10.0); else glVertex3f(pos[0], pos[1], pos[2]); glEnd(); glLightfv(GL_LIGHT0, GL_POSITION, pos); } length = normalize(l); if (world_draw) { glEnable(GL_LIGHTING); drawmodel(); glDisable(GL_LIGHTING); } glPushMatrix(); glMultMatrixd(inverse); /* draw the axes and eye vector */ glPushMatrix(); glColor3ub(0, 0, 255); glBegin(GL_LINE_STRIP); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 0.0, -1.0*length); glVertex3f(0.1, 0.0, -0.9*length); glVertex3f(-0.1, 0.0, -0.9*length); glVertex3f(0.0, 0.0, -1.0*length); glVertex3f(0.0, 0.1, -0.9*length); glVertex3f(0.0, -0.1, -0.9*length); glVertex3f(0.0, 0.0, -1.0*length); glEnd(); glColor3ub(255, 255, 0); glRasterPos3f(0.0, 0.0, -1.1*length); glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'e'); glColor3ub(255, 0, 0); glScalef(0.4, 0.4, 0.4); drawaxes(); glPopMatrix(); invert(projection, inverse); glMultMatrixd(inverse); /* draw the viewing frustum */ glColor3f(0.2, 0.2, 0.2); glBegin(GL_QUADS); glVertex3i(1, 1, 1); glVertex3i(-1, 1, 1); glVertex3i(-1, -1, 1); glVertex3i(1, -1, 1); glEnd();

Page 107: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

106/117

glColor3ub(128, 196, 128); glBegin(GL_LINES); glVertex3i(1, 1, -1); glVertex3i(1, 1, 1); glVertex3i(-1, 1, -1); glVertex3i(-1, 1, 1); glVertex3i(-1, -1, -1); glVertex3i(-1, -1, 1); glVertex3i(1, -1, -1); glVertex3i(1, -1, 1); glEnd(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.2, 0.2, 0.4, 0.5); glBegin(GL_QUADS); glVertex3i(1, 1, -1); glVertex3i(-1, 1, -1); glVertex3i(-1, -1, -1); glVertex3i(1, -1, -1); glEnd(); glDisable(GL_BLEND); glPopMatrix(); glutSwapBuffers(); } void world_menu(int value) { switch (value) { case 'm': world_draw = !world_draw; break; } redisplay_all(); } void screen_reshape(int width, int height) { GLfloat pos[4]; cell_vector(pos, light, 4); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (float)width/height, 0.5, 8.0); glGetDoublev(GL_PROJECTION_MATRIX, projection); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (swapped) { glLightfv(GL_LIGHT0, GL_POSITION, pos); gluLookAt(lookat[0].value, lookat[1].value, lookat[2].value, lookat[3].value, lookat[4].value, lookat[5].value, lookat[6].value, lookat[7].value, lookat[8].value); } else {

Page 108: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

107/117

gluLookAt(lookat[0].value, lookat[1].value, lookat[2].value, lookat[3].value, lookat[4].value, lookat[5].value, lookat[6].value, lookat[7].value, lookat[8].value); glLightfv(GL_LIGHT0, GL_POSITION, pos); } glGetDoublev(GL_MODELVIEW_MATRIX, modelview); glClearColor(0.2, 0.2, 0.2, 0.0); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } void screen_display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); drawmodel(); glutSwapBuffers(); } void screen_menu(int value) { char* name = 0; switch (value) { case 'a': name = "data/al.obj"; break; case 's': name = "data/soccerball.obj"; break; case 'd': name = "data/dolphins.obj"; break; case 'f': name = "data/flowers.obj"; break; case 'j': name = "data/f-16.obj"; break; case 'p': name = "data/porsche.obj"; break; case 'r': name = "data/rose+vase.obj"; break; } if (name) { pmodel = glmReadOBJ(name); if (!pmodel) exit(0); glmUnitize(pmodel); glmFacetNormals(pmodel); glmVertexNormals(pmodel, 90.0); }

Page 109: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

108/117

redisplay_all(); } void command_reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, width, height, 0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0.0, 0.0, 0.0, 0.0); } void command_display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3ub(255, 255, 255); setfont("helvetica", 18); if (swapped) { lookat[0].y = 120; lookat[1].y = 120; lookat[2].y = 120; lookat[3].y = 120+40; lookat[4].y = 120+40; lookat[5].y = 120+40; lookat[6].y = 120+80; lookat[7].y = 120+80; lookat[8].y = 120+80; } else { lookat[0].y = 80; lookat[1].y = 80; lookat[2].y = 80; lookat[3].y = 80+40; lookat[4].y = 80+40; lookat[5].y = 80+40; lookat[6].y = 80+80; lookat[7].y = 80+80; lookat[8].y = 80+80; } drawstr(30, light[0].y, "GLfloat pos[4] = {"); drawstr(230, light[0].y, ","); drawstr(290, light[0].y, ","); drawstr(350, light[0].y, ","); drawstr(410, light[0].y, "};"); if (swapped) drawstr(30, 80, "glLightfv(GL_LIGHT0, GL_POSITION, pos);"); else drawstr(30, 200, "glLightfv(GL_LIGHT0, GL_POSITION, pos);"); drawstr(78, lookat[0].y, "gluLookAt("); drawstr(230, lookat[0].y, ","); drawstr(290, lookat[0].y, ",");

Page 110: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

109/117

drawstr(350, lookat[0].y, ","); drawstr(380, lookat[0].y, "<- eye"); drawstr(230, lookat[3].y, ","); drawstr(290, lookat[3].y, ","); drawstr(350, lookat[3].y, ","); drawstr(380, lookat[3].y, "<- center"); drawstr(230, lookat[6].y, ","); drawstr(290, lookat[6].y, ","); drawstr(350, lookat[6].y, ");"); drawstr(380, lookat[6].y, "<- up"); cell_draw(&light[0]); cell_draw(&light[1]); cell_draw(&light[2]); cell_draw(&light[3]); cell_draw(&lookat[0]); cell_draw(&lookat[1]); cell_draw(&lookat[2]); cell_draw(&lookat[3]); cell_draw(&lookat[4]); cell_draw(&lookat[5]); cell_draw(&lookat[6]); cell_draw(&lookat[7]); cell_draw(&lookat[8]); if (!selection) { glColor3ub(255, 255, 0); drawstr(10, 240, "Click on the arguments and move the mouse to modify values."); } glutSwapBuffers(); } int old_y; void command_mouse(int button, int state, int x, int y) { selection = 0; if (state == GLUT_DOWN) { /* mouse should only hit _one_ of the cells, so adding up all the hits just propagates a single hit. */ selection += cell_hit(&light[0], x, y); selection += cell_hit(&light[1], x, y); selection += cell_hit(&light[2], x, y); selection += cell_hit(&light[3], x, y); selection += cell_hit(&lookat[0], x, y); selection += cell_hit(&lookat[1], x, y); selection += cell_hit(&lookat[2], x, y); selection += cell_hit(&lookat[3], x, y); selection += cell_hit(&lookat[4], x, y); selection += cell_hit(&lookat[5], x, y); selection += cell_hit(&lookat[6], x, y);

Page 111: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

110/117

selection += cell_hit(&lookat[7], x, y); selection += cell_hit(&lookat[8], x, y); } old_y = y; redisplay_all(); } void command_motion(int x, int y) { cell_update(&light[0], old_y-y); cell_update(&light[1], old_y-y); cell_update(&light[2], old_y-y); cell_update(&light[3], old_y-y); cell_update(&lookat[0], old_y-y); cell_update(&lookat[1], old_y-y); cell_update(&lookat[2], old_y-y); cell_update(&lookat[3], old_y-y); cell_update(&lookat[4], old_y-y); cell_update(&lookat[5], old_y-y); cell_update(&lookat[6], old_y-y); cell_update(&lookat[7], old_y-y); cell_update(&lookat[8], old_y-y); old_y = y; redisplay_all(); } void command_menu(int value) { main_keyboard((unsigned char)value, 0, 0); } void redisplay_all(void) { glutSetWindow(command); glutPostRedisplay(); glutSetWindow(world); world_reshape(sub_width, sub_height); glutPostRedisplay(); glutSetWindow(screen); screen_reshape(sub_width, sub_height); glutPostRedisplay(); } int main(int argc, char** argv) { glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize(512+GAP*3, 512+GAP*3); glutInitWindowPosition(50, 50); glutInit(&argc, argv);

Page 112: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

111/117

window = glutCreateWindow("Light Positioning"); glutReshapeFunc(main_reshape); glutDisplayFunc(main_display); glutKeyboardFunc(main_keyboard); world = glutCreateSubWindow(window, GAP, GAP, 256, 256); glutReshapeFunc(world_reshape); glutDisplayFunc(world_display); glutKeyboardFunc(main_keyboard); glutCreateMenu(world_menu); glutAddMenuEntry("Toggle model", 'm'); glutAttachMenu(GLUT_RIGHT_BUTTON); screen = glutCreateSubWindow(window, GAP+256+GAP, GAP, 256, 256); glutReshapeFunc(screen_reshape); glutDisplayFunc(screen_display); glutKeyboardFunc(main_keyboard); glutCreateMenu(screen_menu); glutAddMenuEntry("Models", 0); glutAddMenuEntry("", 0); glutAddMenuEntry("Soccerball", 's'); glutAddMenuEntry("Al Capone", 'a'); glutAddMenuEntry("F-16 Jet", 'j'); glutAddMenuEntry("Dolphins", 'd'); glutAddMenuEntry("Flowers", 'f'); glutAddMenuEntry("Porsche", 'p'); glutAddMenuEntry("Rose", 'r'); glutAttachMenu(GLUT_RIGHT_BUTTON); command = glutCreateSubWindow(window, GAP+256+GAP, GAP+256+GAP, 256, 256); glutReshapeFunc(command_reshape); glutDisplayFunc(command_display); glutMotionFunc(command_motion); glutMouseFunc(command_mouse); glutKeyboardFunc(main_keyboard); glutCreateMenu(command_menu); glutAddMenuEntry("Light Positioning", 0); glutAddMenuEntry("", 0); glutAddMenuEntry("[s] Swap lookat/position calls", 's'); glutAddMenuEntry("[r] Reset parameters", 'r'); glutAddMenuEntry("", 0); glutAddMenuEntry("Quit", 27); glutAttachMenu(GLUT_RIGHT_BUTTON); redisplay_all(); glutMainLoop(); return 0; }

Page 113: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

112/117

Tutorial 12.Vertex Animation Banyak obyek sebetulnya bukan benda rigid. Sebagai contoh adalah bendera atau selembar kertas. Program 19 memberi ilustrasi tentang bagaimana membuat suatu bendera berkibar. Program 19 melakukan ilusi berkibar dengan merubah posisi relatif suatu vertex terhadap koordinat bendanya. Cara yang lebih canggih mencakup proses pemodelan dinamika benderanya. TUGAS: Terangkan bagaimana cara bekerjanya animasi bendera tersebut. Program 19 #include <windows.h> #include <math.h> // Math Library Header File #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> #include <GL/glaux.h> float points[45][45][3]; // The Array For The Points On The Grid Of Our "Wave" int wiggle_count = 0; // Counter Used To Control How Fast Flag Waves GLfloat xrot; // X Rotation ( NEW ) GLfloat yrot; // Y Rotation ( NEW ) GLfloat zrot; // Z Rotation ( NEW ) GLfloat hold; // Temporarily Holds A Floating Point Value GLuint texture[1]; // Storage For One Texture ( NEW ) 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;

Page 114: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

113/117

// 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 // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit if (TextureImage[0]=LoadBMP("Data/Tim.bmp")) { Status=TRUE; // Set The Status To TRUE glGenTextures(1, &texture[0]); // Create The Texture // Typical Texture Generation Using Data From The Bitmap glBindTexture(GL_TEXTURE_2D, texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); } 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(GLsizei width, GLsizei height) // Resize And Initialize The GL Window { if (height==0) // Prevent A Divide By Zero By { height=1; // Making Height Equal One } glViewport(0,0,width,height); // Reset The Current Viewport

Page 115: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

114/117

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 } int init(GLvoid) // All Setup For OpenGL Goes Here { if (!LoadGLTextures()) // Jump To Texture Loading Routine ( NEW ) { return FALSE; // If Texture Didn't Load Return FALSE } glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW ) 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 glPolygonMode( GL_BACK, GL_FILL ); // Back Face Is Solid glPolygonMode( GL_FRONT, GL_LINE ); // Front Face Is Made Of Lines for(int x=0; x<45; x++) { for(int y=0; y<45; y++) { points[x][y][0]=float((x/5.0f)-4.5f); points[x][y][1]=float((y/5.0f)-4.5f); points[x][y][2]=float(sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f)); } } return TRUE; // Initialization Went OK } void mydisplay(GLvoid) // Here's Where We Do All The Drawing { int x, y; float float_x, float_y, float_xb, float_yb;

Page 116: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

115/117

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer glLoadIdentity(); // Reset The View glTranslatef(0.0f,0.0f,-12.0f); glRotatef(xrot,1.0f,0.0f,0.0f); glRotatef(yrot,0.0f,1.0f,0.0f); glRotatef(zrot,0.0f,0.0f,1.0f); glBindTexture(GL_TEXTURE_2D, texture[0]); glBegin(GL_QUADS); for( x = 0; x < 44; x++ ) { for( y = 0; y < 44; y++ ) { float_x = float(x)/44.0f; float_y = float(y)/44.0f; float_xb = float(x+1)/44.0f; float_yb = float(y+1)/44.0f; glTexCoord2f( float_x, float_y); glVertex3f( points[x][y][0], points[x][y][1], points[x][y][2] ); glTexCoord2f( float_x, float_yb ); glVertex3f( points[x][y+1][0], points[x][y+1][1], points[x][y+1][2] ); glTexCoord2f( float_xb, float_yb ); glVertex3f( points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2] ); glTexCoord2f( float_xb, float_y ); glVertex3f( points[x+1][y][0], points[x+1][y][1], points[x+1][y][2] ); } } glEnd(); if( wiggle_count == 2 ) { for( y = 0; y < 45; y++ ) { hold=points[0][y][2]; for( x = 0; x < 44; x++) { points[x][y][2] = points[x+1][y][2]; } points[44][y][2]=hold; } wiggle_count = 0; } wiggle_count++; xrot+=0.3f; yrot+=0.2f; zrot+=0.4f;

Page 117: EC5130 – Grafika Komputer dan Pemrograman GPU · PDF fileTujuan dari bagian ini adalah untuk membuat OpenGL-based window. ... Gambar 2. OpenGL Geometric ... Analogi Pengambilan Gambar

116/117

glFlush(); glutSwapBuffers(); } void myTimeOut(int id) { // called if timer event // ...advance the state of animation incrementally... //rot+=1; glutPostRedisplay(); // request redisplay glutTimerFunc(10, myTimeOut, 0); // request next timer event } void myKeyboard(unsigned char key,int x, int y) { } void mySpecialKeyboard(int key,int x, int y) { } int main(int argc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode( GLUT_RGB |GLUT_DOUBLE| GLUT_DEPTH ); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("simple"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutSpecialFunc(mySpecialKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }