EC5130 Grafika Komputer dan Pemrograman GPU
|
|
|
- Suhendra Sudirman
- 9 tahun lalu
- Tontonan:
Transkripsi
1 EC5130 Grafika Komputer dan Pemrograman GPU Suplemen Diktat Kuliah OpenGL Tutorial dengan GLUT: Fixed Pipeline Ary Setijadi Prihatmanto Sekolah Teknik Elektro & Informatika Institut Teknologi Bandung 2007
2 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 Tutorial 04. Callback Reshape Tutorial 04. Modeling & Transformasi Proyeksi Transformasi Proyeksi Transformasi Viewing Transformasi Modeling Tutorial 05. Urutan Transformasi Tutorial 06. Texture Mapping & Blending Tutorial 07. Transparency Tutorial 08. Fog Tutorial 09. Obyek Kompleks Tutorial 10. Particle System Tutorial 11. Lighting Tutorial 12.Vertex Animation
3 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 bersamasama 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 Setelah library GLUT diinstall, GLUT dapat digunakan dengan mengacu ke header file glut.h. File tersebut selain mendefinisikan beberapa hal-hal yang terkait dengan GLUT, mengacu pada opengl.h dan glu.h juga memberikan arahan kepada compiler untuk me-link secara automatis dengan library-library yang dibutuhkan contohnya opengl.lib(opengl32.lib), glu.lib(glu32.lib) dan glut.lib(glut32.lib). Selain itu, untuk aplikasi di atas sistem operasi windows memerlukan glut32.dll dapat terlihat oleh aplikasi. Struktur dari aplikasi berbasis GLUT akan terdiri atas beberapa langkah berikut, yaitu: Menetapkan konfigurasi windows, dan membuka windows Inisialisasi status OpenGL Registrasi callback functions (jika dibutuhkan) o Render o Resize o Input o Timer
4 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();
5 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 (, )
6 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 GL_POINTS GL_LINES GL_LINE_STRIP GL_LINE_LOOP GL_POLYGON GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN GL_QUADS GL_QUAD_STRIP 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:
7 6/117 glvertex3fv( v ) Number of components 2 - (x,y) 3 - (x,y,z) 4 - (x,y,z,w) Data Type b - byte ub - unsigned byte s - short us - unsigned short i - int ui - unsigned int f - float d - double Vector omit v for scalar form glvertex2f( x, y ) 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();
8 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.
9 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:
10 9/117
11 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 Dimensional Vertex #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> void mydisplay() glclear(gl_color_buffer_bit); glbegin(gl_polygon); glcolor3f(0, 1, 0); glvertex3f(-0.5, -0.5, 1); glcolor3f(0, 0, 1); glvertex3f(-0.75, 0, 1); glcolor3f(1, 0, 0); glvertex3f(-0.5, 0.5, 1); glcolor3f(0, 1, 0); glvertex3f(0, 0.75, 1); glcolor3f(0, 0, 1); glvertex3f(0.5, 0.5, -1); glcolor3f(1, 0, 0); glvertex3f(0.75, 0, -1); glcolor3f(0, 1, 0); glvertex3f(0.5, -0.5, -1); glcolor3f(0, 0, 1); glvertex3f(0,-0.75, -1); glend(); glflush(); int main(int argc, char** argv) glutcreatewindow("simple"); glutdisplayfunc(mydisplay); glutmainloop();
12 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 );
13 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.
14 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 Model 3D Obyek - Bentuk - Pose (Posisi & Orientasi) - Warna - Texture - Pencahayaan T Citra 2D Obyek 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. camera Gambar 4. Analogi Pengambilan Gambar oleh Kamera viewing volume tripod model
15 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.
16 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
17 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 Section AA A side elevation view Front elevation view 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);
18 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 //
19 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)
20 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().
21 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);
22 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);
23 22/117 glend(); // 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); glflush(); glutswapbuffers(); void init() glenable(gl_depth_test); glclearcolor( 0.0, 0.0, 0.0, 1.0 ); // A Background Clear Color glmatrixmode(gl_projection); glloadidentity(); gluperspective(45, (GLdouble)500.0/(GLdouble)500.0, 0, 100); glmatrixmode(gl_modelview); return; int main(int argc, char** argv) glutinit(&argc,argv); //glutinitdisplaymode( GLUT_DOUBLE /* GLUT_DEPTH*/ ); glutinitdisplaymode( GLUT_DOUBLE GLUT_DEPTH ); glutinitwindowsize(500,500); glutinitwindowposition(0,0); glutcreatewindow("simple"); // callbacks glutdisplayfunc(mydisplay); glutkeyboardfunc(mykeyboard); gluttimerfunc(100, mytimeout, 0); glutreshapefunc(resize); init(); glutmainloop(); return 0; Tambahan: Konsep Depth Buffer. Mode display pada program di atas diberi tambahan mode GLUT_DEPTH dan perintah glenable(gl_depth_test). Hal ini untuk memastikan bahwa surface digambar sesuai dengan urutan penampakkan yang logis. Teknik ini merupakan salah satu algoritma HIDDEN SURFACE REMOVAL. Untuk melihat apa yang terjadi bila teknik ini tidak dilakukan, hapus/commented moda GLUT_DEPTH dan glenable(gl_depth_test).
24 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 y z x geometry screen (0.0,1.0) t image (0.0,0.0) s (1.0,0.0) 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
25 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. vertices geometry pipeline rasterizer image pixel pipeline 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
26 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> Input/Output #include <gl\gl.h> #include <gl\glu.h> #include <gl\glaux.h> #include "bmp.h" // Header File For Standard // Header File For The OpenGL32 Library // Header File For The GLu32 Library // Header File For The Glaux Library 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); The Bitmap And Return A Pointer // Load return NULL; // If Load Failed Return NULL Program.cpp // OpenGL // - Function to load bitmap
27 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]; Storage Space For The Texture memset(textureimage,0,sizeof(void *)*1); Pointer To NULL // Set The // Create // 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
28 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 The Texture Image Memory free(textureimage[0]->data); // Free 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)
29 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);
30 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); Ambient Light gllightfv(gl_light1, GL_DIFFUSE, LightDiffuse); Diffuse Light gllightfv(gl_light1, GL_POSITION,LightPosition); Light glenable(gl_light1); // Setup The // Setup The // Position The return; int main(int argc, char** argv) glutinit(&argc,argv); glutinitdisplaymode( GLUT_DOUBLE GLUT_DEPTH ); glutinitwindowsize(500,500); glutinitwindowposition(0,0);
31 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); glcolor3f(1.0,0.0,0.0); // Turn Blending On // Blending Color glbindtexture(gl_texture_2d, texture[filter]); glbegin(gl_quads); // Front Face glnormal3f( 0.0f, 0.0f, 1.0f); gltexcoord2f(0.0f, 0.0f); glvertex3f(-1.0f, -1.0f, 1.0f); gltexcoord2f(1.0f, 0.0f); glvertex3f( 1.0f, -1.0f, 1.0f); gltexcoord2f(1.0f, 1.0f); glvertex3f( 1.0f, 1.0f, 1.0f); gltexcoord2f(0.0f, 1.0f); glvertex3f(-1.0f, 1.0f, 1.0f); // Back Face
32 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();
33 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); gldisable(gl_depth_test); // Turn Blending On // Turn Depth Testing Off glbegin(gl_quads); // Front Face glnormal3f( 0.0f, 0.0f, 1.0f); gltexcoord2f(0.0f, 0.0f); glvertex3f(-1.0f, -1.0f, 1.0f); gltexcoord2f(1.0f, 0.0f); glvertex3f( 1.0f, -1.0f, 1.0f); gltexcoord2f(1.0f, 1.0f); glvertex3f( 1.0f, 1.0f, 1.0f);
34 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
35 34/117 gllightfv(gl_light1, GL_AMBIENT, LightAmbient); Ambient Light gllightfv(gl_light1, GL_DIFFUSE, LightDiffuse); Diffuse Light gllightfv(gl_light1, GL_POSITION,LightPosition); Light glenable(gl_light1); glcolor4f(1.0f, 1.0f, 1.0f, 0.5); Brightness. 50% Alpha glblendfunc(gl_src_alpha,gl_one); // Setup The // Setup The // Position The // Full 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.
36 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
37 36/117 AUX_RGBImageRec *TextureImage[1]; Storage Space For The Texture memset(textureimage,0,sizeof(void *)*1); Pointer To NULL // Set The // Create // 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 The Texture Image Memory free(textureimage[0]->data); // Free free(textureimage[0]); // Free The Image Structure
38 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);
39 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();
40 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 // FOG glclearcolor(0.5f,0.5f,0.5f,1.0f); // We'll Clear To The Color Of The 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, f); // 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); Ambient Light gllightfv(gl_light1, GL_DIFFUSE, LightDiffuse); Diffuse Light gllightfv(gl_light1, GL_POSITION,LightPosition); Light glenable(gl_light1); // Setup The // Setup The // Position The return; int main(int argc, char** argv) glutinit(&argc,argv); glutinitdisplaymode( GLUT_DOUBLE GLUT_DEPTH ); glutinitwindowsize(500,500); glutinitwindowposition(0,0); glutcreatewindow("simple"); // callbacks glutdisplayfunc(mydisplay); glutkeyboardfunc(mykeyboard); gluttimerfunc(100, mytimeout, 0);
41 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.
42 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> #include <stdio.h> #include <stdlib.h> // Math Library Header File
43 42/117 #include <string.h> #include <stdarg.h> #include <GL/glut.h> #include <GL/glaux.h> const float piover180 = f; 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"); To Load World Data From // File readstr(filein,oneline);
44 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) Image FILE *File=NULL; if (!Filename) Filename Was Given return NULL; File=fopen(Filename,"r"); The File Exists if (File) Exist? fclose(file); return auxdibimageload(filename); Return A Pointer return NULL; Return NULL int LoadGLTextures() Convert To Textures int Status=FALSE; AUX_RGBImageRec *TextureImage[1]; Space For The Texture // Loads A Bitmap // File Handle // Make Sure A // If Not Return NULL // Check To See If // Does The File // Close The Handle // Load The Bitmap And // If Load Failed // Load Bitmaps And // Status Indicator // Create Storage NULL memset(textureimage,0,sizeof(void *)*1); // Set The Pointer To
45 44/117 TRUE // 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 Textures glgentextures(3, &texture[0]); // Create Three // 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 Structure free(textureimage[0]); // Free The Image return Status; // Return The Status void resize(int width, int height) Window if (height==0) // Prevent A Divide By Zero By // Resize And Initialize The GL
46 45/117 height=1; // Making Height Equal One glviewport(0,0,width,height); The Current Viewport // Reset 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)
47 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)
48 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;
49 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 // Ceiling // A1
50 49/ // A // B // B // C // C // D
51 50/ // D // Upper hallway - L // Upper hallway - R // Lower hallway - L // Lower hallway - R // Left hallway - Lw // Left hallway - Hi
52 51/ // Right hallway - Lw // Right hallway - Hi 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
53 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
54 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);
55 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.
56 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 file if ((l_file=fopen (p_filename, "rb"))== NULL) return 0; //Open the 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) the chunk 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 printf("chunklenght: %x\n",l_chunk_lenght); chunks switch (l_chunk_id) // MAIN3DS // Description: Main chunk, contains all the other // 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
57 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; 3d mesh info // OBJ_TRIMESH // Description: Triangular mesh, contains chunks for // 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_FACEL // Description: Polygons (faces) list // Chunk ID: 4120 (hex) // Chunk Lenght: 1 x unsigned short (number of
58 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
59 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"
60 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, f); // 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)
61 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, f); 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 ; break; case GLUT_KEY_DOWN:
62 61/117 rotation_x_increment = rotation_x_increment ; break; case GLUT_KEY_LEFT: rotation_y_increment = rotation_y_increment ; break; case GLUT_KEY_RIGHT: rotation_y_increment = rotation_y_increment ; 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
63 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 sendirisendiri, 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
64 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; float decay; float r,g,b; float xpos,ypos,zpos; float xspeed,yspeed,zspeed; boolean active; PARTICLE; // total lifetime of the particle // decay speed of the particle // color values of the particle // position of the particle // speed of the particle // is particle active or not? 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; PARTICLE particle[maxparticle]; // set maximum number of particles void CreateParticle(int i) particle[i].lifetime= (float)(500000*rand()/rand_max)/ ; 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*( (float)(100*rand()/RAND_MAX)/ ); particle[i].yspeed = 0.01-(float)(100*rand()/RAND_MAX)/ ; particle[i].zspeed = (float)(100*rand()/RAND_MAX)/ ; particle[i].active = true; // void InitParticle()
65 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-= ; 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; particles extern PARTICLE particle[maxparticle]; // set maximum number of int LoadGLTextures() // Load Bitmaps And Convert To Textures int Status=FALSE; //
66 65/117 Status Indicator AUX_RGBImageRec *TextureImage[1]; Storage Space For The Texture memset(textureimage,0,sizeof(void *)*1); Pointer To NULL // Set The // Create // 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]) Texture Exists if (TextureImage[0]->data) Texture Image Exists free(textureimage[0]->data); Texture Image Memory // If // If // Free The 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); projection matrix glloadidentity(); // the following operations affect the // restore matrix to original state
67 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();
68 67/117 else CreateParticle(i); EvolveParticle(); glflush(); glutswapbuffers(); void init() gldisable(gl_depth_test); gldisable(gl_cull_face); // deactivate hidden surface removal // show backside of polygons glclearcolor(0.0f, 0.0f, 0.0f, 1.0f); Background glcolor4f(1.0f, 1.0f, 1.0f, 0.5); Brightness. 50% Alpha // Black // Full 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;
69 68/117
70 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[] = , , , , , , , , , , , , ; float Bronze[] = , , , ,
71 70/117 ; , , , , , , , , float Polished_Bronze[] = , , , , , , , , , , , , ; float Chrome[] = , , , , , , , , , , , , ; float Copper[] = , , , , , , , , , , , , ; float Polished_Copper[] = , , , , , , , , , , , , ; float Gold[] = , , , , , , , , , , , , ; float Polished_Gold[] = , , , , , , , , , , , , ; float Pewter[] = , , , , , , , , , , , , ; float Silver[] = , , , , , , , ,
72 71/117 ; , , , , float Polished_Silver[] = , , , , , , , , , , , , ; float Emerald[] = , , , , , , , , , , , , ; float Jade[] = , , , , , , , , , , , , ; float Obsidian[] = , , , , , , , , , , , , ; float Pearl[] = , , , , , , , , , , , , ; float Ruby[] = , , , , , , , , , , , , ; float Turquoise[] = , , , , , , , , , , , , ; float Black_Plastic[] = , , , , , , , , , , , ,
73 72/117 ; float Black_Rubber[] = , , , , , , , , , , , , ; 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", ;
74 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] =
75 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",
76 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;
77 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;
78 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');
79 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++)
80 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)
81 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);
82 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);
83 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();
84 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:
85 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],
86 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
87 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);
88 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, ";");
89 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 =
90 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();
91 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]);
92 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();
93 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();
94 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);
95 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();
96 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);
97 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);
98 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>
99 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;
100 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);
101 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);
102 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++)
103 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;
104 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;
105 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);
106 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();
107 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
108 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);
109 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 = ; lookat[4].y = ; lookat[5].y = ; lookat[6].y = ; lookat[7].y = ; lookat[8].y = ; 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, ",");
110 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);
111 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);
112 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;
113 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> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> #include <GL/glaux.h> // Math Library Header File float points[45][45][3]; "Wave" int wiggle_count = 0; // The Array For The Points On The Grid Of Our // 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) Bitmap Image FILE *File=NULL; // File Handle // Loads A 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); Bitmap And Return A Pointer // Load The return NULL;
114 113/117 // If Load Failed Return NULL int LoadGLTextures() // Load Bitmaps And Convert To Textures int Status=FALSE; // Status Indicator AUX_RGBImageRec *TextureImage[1]; Storage Space For The Texture memset(textureimage,0,sizeof(void *)*1); To NULL // Create // Set The Pointer // 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) The GL Window if (height==0) // Prevent A Divide By Zero By height=1; // Making Height Equal One // Resize And Initialize glviewport(0,0,width,height); // Reset The Current Viewport
115 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)* *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;
116 115/117 glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); And The Depth Buffer glloadidentity(); // Reset The View // Clear The Screen 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; points[x][y][2] ); gltexcoord2f( float_x, float_y); glvertex3f( points[x][y][0], points[x][y][1], 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;
117 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;
Tutorial 04 Modeling & Transformasi Proyeksi
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
Tutorial 08. Fog. mensimulasikan efek kabut membatasi ruang pandang pengguna agar komputasi grafis yang diperlukan dapat dibatasi.
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
Tutorial 06. Texture Mapping & Blending
Tutorial 06. Texture Mapping & Blending Hingga tahap ini, geometric primitive digambar dengan warna solid atau warna hasil interpolasi warnawarna vertex-nya. Texture mapping memungkinkan untuk menaruh
/*Bismillahirrohmanirrohim _Fatimah_Rombel 2_Projek_Akhir_Komgraf*/ #include <stdio.h> #include <stdlib.h> #include <string.
/*Bismillahirrohmanirrohim.. 5302413025_Fatimah_Rombel 2_Projek_Akhir_Komgraf*/ #include #include #include #include "SOIL.h" #include float z_pos = -5.0f; float
FAKULTAS TEKNIK UNIVERSITAS NEGERI YOGYAKARTA LAB. SHEET PRAKTIKUM GRAFIKA KOMPUTER
No. : ST/EKA/PTI223/06 Revisi : 02 Senin 010509 Hal. 1 dari 9 hal. Pengantar Fog adalah pengaruh atmospheric yang ditambahkan objek, sehingga akan terjadi kekaburan pada obyek yang tergantung seberapa
FAKULTAS TEKNIK UNIVERSITAS NEGERI YOGYAKARTA LAB. SHEET PRAKTIKUM GRAFIKA KOMPUTER
No. : ST/EKA/PTI275/05 Revisi : 02 1 P a g e A. Pendahuluan OpenGL akan melakukan komputasi warna setiap pixel di display akhir, ditampilkan adegan itu dilakukan di frame buffer. Bagian dari komputasi
Tabel 1 Perintah-perintah OpenGL yang telah dipraktekan
A. Pendahuluan Review Praktikum sebelumnya Sebelum ke modul selanjutnya, perhatikan sintak dibawah ini Tabel 1 Perintah-perintah OpenGL yang telah dipraktekan Perintah Arti Keterangan glvertex2i(x,y);
FAKULTAS TEKNIK UNIVERSITAS NEGERI YOGYAKARTA LAB. SHEET PRAKTIKUM GRAFIKA KOMPUTER
No. : ST/EKA/PTI223/05 Revisi : 02 Senin 010409 Hal. 1 dari 8 hal. A. Pendahuluan OpenGL akan melakukan komputasi warna setiap pixel di display akhir, ditampilkan adegan itu dilakukan di frame buffer.
BAB II LINGKUNGAN PEMROGRAMAN GRAFIK DENGAN OPEN GL
BAB II LINGKUNGAN PEMROGRAMAN GRAFIK DENGAN OPEN GL Pemrograman Grafis Pemrograman grafis adalah pemrograman yang digunakan untuk menghasilkan gambar pada komputer menggunakan library yang ada. Teknik-teknik
Tutorial 09. Lighting
Tutorial 09. 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
BAB IV IMPLEMENTASI DAN PENGUJIAN
BAB IV IMPLEMENTASI DAN PENGUJIAN 4.1 Implementasi Tahapan implementasi bertujuan untuk memastikan apakah aplikasi yang dibuat dapat bekerja secara efektif dan efisien sesuai dengan yang diharapkan. Sebelum
Tabel 1 Perintah-perintah OpenGL yang telah dipraktekan
No. : ST/EKA/PTI223/04 Revisi : 02 Senin 010210 Hal. 1 dari 8 hal. A. Pendahuluan Review Praktikum sebelumnya Sebelum ke modul selanjutnya, perhatikan sintak dibawah ini Tabel 1 Perintah-perintah OpenGL
Topik bahasan: 1. Membuat objek mudah dan kompleks dengan jaring poligon 2. Merender jaring poligon sebagai wireframe dan atau pejal dengan OpenGL
Grafika-5 Pemodelan 3D dengan Jaring Poligon Tujuan Materi: Setelah mempelajari bab ini, Anda diharapkan dapat menjelaskan secara ringkas bagaimana membentuk objek 3D dengan jaring poligon (polygon meshes)
Pengenalan OpenGL. Sintax Perintah OpenGL. Library yang Berhubungan dengan OpenGL
Pengenalan OpenGL OpenGL adalah suatu graphic library yang sebagian bersifat open source, dipakai pada banyak platform (windows, linux) dan dapat digunakan pada berbagai jenis compiler seperti C++ atau
Program 1 /* Menampilkan Bayangan sebuah obyek sumber file */
No. : ST/EKA/PTI223/10 Revisi : 01 Senin 010509 Hal. 1 dari 5 hal. Pengantar Untuk menghasilkan gambar yang realistik perlu memodelkan pencerminan dan pembiasan maupun memunculkan bayangan karena pengaruh
Pengenalan OpenGL. Sintax Perintah OpenGL. Library yang Berhubungan dengan OpenGL
Pengenalan OpenGL OpenGL adalah suatu graphic library yang sebagian bersifat open source, dipakai pada banyak platform (windows, linux) dan dapat digunakan pada berbagai jenis compiler seperti C++ atau
Gambar 1. Viewport pada layar
No. : ST/EKA/PTI223/03 Revisi : 02 Hal. 1 dari 9 hal. A. Pendahuluan Transformasi adalah memindahkan objek tanpa merusak bentuk. Contoh transformasi adalah transisi, penskalaan, putaran/rotasi, balikan,
Gambar 1. Viewport pada layar
No. : ST/EKA/PTI223/03 Revisi : 03 Senin 010210 Hal. 1 dari 5 hal. A. Pendahuluan Transformasi adalah memindahkan objek tanpa merusak bentuk. Contoh transformasi adalah transisi, penskalaan, putaran/rotasi,
PETEMUAN KE-3 PRIMITIVE DRAWING 2
PETEMUAN KE-3 PRIMITIVE DRAWING 2 A.Tujuan 1. Dapat mengaplikasikan objek primitif dalam bentuk yang lain B. Dasar Teori Dalam praktikum sebelumnya anda diminta membuat titik garis, dan sebagainya. Dalam
BAB IV IMPLEMENTASI DAN PENGUJIAN SISTEM
BAB IV IMPLEMENTASI DAN PENGUJIAN SISTEM Pada bab ini akan dibahas implementasi bertujuan memastikan apakah aplikasi yang dibuat berjalan sesuai yang penulis harapakan. Sebelum program diimplementasikan
Grafika Komputer. Evangs Mailoa
Grafika Komputer Evangs Mailoa Kumpulan polygon atau permukaan yang secara bersama-sama membentuk kulit dari suatu obyek. Dinyatakan dengan daftar poligon-poligon yang disertai dengan arah dari permukaan
apa yang terjadi?. Kemudian lakukan pengantian beberapa bagian seperti sintak
No. : ST/EKA/PTI223/02 Revisi : 02 Senin 010210 Hal. 1 dari 8 hal. A. Pendahuluan Dalam praktikum sebelumnya anda diminta membuat titik garis, dan sebagainya. Dalam praktikum hari ini lakukan penambahan
PETEMUAN KE-5 TRANSFORMASI-PANDANGAN (Viewing)
PETEMUAN KE-5 TRANSFORMASI-PANDANGAN (Viewing) A.Tujuan 1. Dapat menggambar objek 3D 2. Dapat mentransformasikan objek 3D 3. Dapat menggunkan glviewport,glmodelview, glprojection, glfrustum B. Dasar Teori
DIAN PRATIWI. ST, MTI
DIAN PRATIWI. ST, MTI PEMROGRAMAN GRAFIKA KOMPUTER BERBASIS OPENGL Diterbitkan melalui Nida Dwi Karya Publishing PEMROGRAMAN GRAFIKA KOMPUTER BERBASIS OPENGL Oleh: Dian Pratiwi, ST, MTI Copyright 2015
LAMPIRAN SOURCE CODE
DAFTAR PUSTAKA Anonim. www.opengl.org (diakses pada tanggal 01 Juli 2015). Fadlisyah, et al. 2007. Pengantar Grafika Komputer. Yogyakarta: Andi. Haemel, Nicholas, et al. 2011. OpenGL super bible : comprehensive
Gambar 1. Contoh tekstur makrostruktur
No. : ST/EKA/PTI223/08 Revisi : 02 Senin 010510 Hal. 1 dari 14 hal. Pengantar Tekstur adalah tampilan permukaan (corak) dari suatu benda yang dapat dinilai dengan cara dilihat atau diraba. Pada prakteknya,
DAFTAR PUSTAKA. (diakses 1 maret 2016)
DAFTAR PUSTAKA [1] http://www.surakarta.go.id/konten/bus-tingkat-werkudara# (diakses 28 februari 2016) [2] Anonim. www.opengl.org (diakses 1 maret 2016) [3] Haemel, Nicholas, et al. 2011. OpenGL super
PENGANTAR GRAFIKA KOMPUTER
PENGANTAR GRAFIKA KOMPUTER Achmad Basuki Nana Ramadijanti Achmad Basuki, Nana Ramadijanti - Laboratorium Computer Vision Politeknik Elektronika Negeri Surabaya (PENS-ITS) Materi Pengenalan grafika komputer
OPENGL DALAM MICROSOFT VISUAL STUDIO EXPRESS Created by: Gideon
OPENGL DALAM MICROSOFT VISUAL STUDIO EXPRESS 2012 Created by: Gideon Tutorial Open GL untuk membuat garis dengan program Microsoft Visual Studio Express 2012 OpenGL dengan Microsoft Visual Express 2012
Praktikum Komputer Grafik [MODUL] Genap 2012/2013. Laboratorium Multimedia 1/35
Praktikum Komputer Grafik [MODUL] Genap 2012/2013 1/35 KONTRAK PRAKTIKUM Nama Mata Kuliah : Praktikum Komputer Grafik Kode Mata Praktikum : TIF121 SKS : 1 Mata Kuliah Prasyarat : - Dosen Penanggung Jawab
Pewarnaan dan Perputaran Polygon Untuk Objek Gambar Segi Tiga dan Segi Empat Menggunakan Program OPENGL 32
Pewarnaan dan Perputaran Polygon Untuk Objek Gambar Segi Tiga dan Segi Empat Menggunakan Program OPENGL 32 Aqwam Rosadi Kardian, Bheta Agus Wardijono STMIK JAKARTA STI&K [email protected], [email protected]
FAKULTAS TEKNIK UNIVERSITAS NEGERI YOGYAKARTA LAB. SHEET PRAKTIKUM GRAFIKA KOMPUTER
A. Pendahuluan Objek 3D pada open GL merupakan objek yang lebih hidup dibandingkan objek 2D. Namun permukaan objek 3D yang polos membuat 3D cenderung kurang menarik dan kaku. Untuk membuat objek yang lebih
ALGORITMA PERPOTONGAN OBJEK
ALGORITMA PERPOTONGAN OBJEK Ina Agustina, Fauziah Jurusan Sistem Informasi, Fakultas Teknologi Komunikasi dan Informatika, Universitas Nasional Jl. Sawo Manila, Pejaten Pasar Minggu No.61, Jakarta 12520
BAB 3 PERANCANGAN DAN PEMBUATAN. Engine akan dirancang agar memenuhi syarat maintainability, reusability dan
13 BAB 3 PERANCANGAN DAN PEMBUATAN 3.1 Perancangan Engine Engine akan dirancang agar memenuhi syarat maintainability, reusability dan usability. Maintainability berarti kode program engine harus mudah
TRANSFORMASI. Tujuan transfomasi adalah:
TRANSFORMASI Grafika komputer merupakan bidang yang menarik minat banyak orang. Salah sub bagian dari grafika komputer adalah pemodelan objek (object modelling). Dalam pemodelan objek dua dimensi (2D),didapati
Bab 1 Pengenalan GLUT
Bab 1 Pengenalan GLUT A. KOMPETENSI DASAR Memahami GLUT. Memahami dasar pemrograman GLUT. Memahami dasar menampilkan windows GLUT. B. ALOKASI WAKTU 4 js (4x50 menit) C. PETUNJUK Awali setiap aktivitas
MODUL 9 Material Texture
MODUL 9 Material Texture A. KOMPETENSI DASAR Memahami Inisialisasi Material Texture Memahami Texture Mapping. Memahami dasar menampilkan susunan obyek yang dilengkapi dengan texture mapping. B. ALOKASI
Praktikum Komputer Grafik [MODUL] Genap 2013/2014. Laboratorium Multimedia 1/47
Praktikum Komputer Grafik [MODUL] Genap 2013/2014 1/47 KONTRAK PRAKTIKUM Nama Mata Kuliah : Praktikum Komputer Grafik Kode Mata Praktikum : TIF121 SKS : 1 Mata Kuliah Prasyarat : - Dosen Penanggung Jawab
Grafik Komputer : Konsep 3 Dimensi
Grafik Komputer : Konsep 3 Dimensi Universitas Gunadarma 2006 Grafik Komputer : Konsep 3D 1/10 Alur Proses Grafik Komputer 3D (1/2) Penetapan ruang model. Transformasi model adalah menempatkan model pada
Modul 1 Primitif Drawing
Modul 1 Primitif Drawing I. Tugas Pendahuluan 1. Jelaskan tentang OpenGL! 2. Jelaskan tenteng ouput primitif dalam grafika computer! II. Tujuan Mahasiswa mampu membuat dan memanfaatkan output primitif
Laboratorium Teknologi Informasi & Aplikasi. Praktikum Komputer Grafik [MODUL] Genap 2014/2015. Lab TIA 1/58
Laboratorium Teknologi Informasi & Aplikasi Praktikum Komputer Grafik [MODUL] Genap 2014/2015 1/58 KONTRAK PRAKTIKUM Nama Mata Kuliah : Praktikum Komputer Grafik Kode Mata Praktikum : TIF121 SKS : 1 Mata
BAB 2 TEORI PENUNJANG
BAB 2 TEORI PENUNJANG Pada tinjauan pustaka ini akan dibahas tentang teori teori penunjang dalam menyelesaikan proyek akhir ini. Beberapa teori penunjang pada proyek akhir ini adalah sebagai berikut :
PRIMITIVE DRAWING. Achmad Basuki Nana Ramadijanti
PRIMITIVE DRAWING Achmad Basuki Nana Ramadijanti Materi Program Dasar dengan OpenGL Menggambar Titik Menggambar Garis Menggambar Polyline Menggambar Polygon Pewarnaan Struktur Dasar Program Grafik Dengan
TUGAS PENGANTAR GRAFIK KOMPUTER DAN OLAH CITRA
TUGAS PENGANTAR GRAFIK KOMPUTER DAN OLAH CITRA NAMA : HERU SANJAYA NPM : 39110387 KELAS : 2DB23 Gambar dibawah ini adalah tampilan awal Code Blocks. Setelah itu, pilih menu Settings Compiler and Debugger.
Laboratorium Teknologi Informasi & Aplikasi. Praktikum Komputer Grafik [MODUL] Genap 2015/2016. Lab TIA 1/59
Laboratorium Teknologi Informasi & Aplikasi Praktikum Komputer Grafik [MODUL] Genap 2015/2016 1/59 KONTRAK PRAKTIKUM Nama Mata Kuliah : Praktikum Komputer Grafik Kode Mata Praktikum : TIF121 SKS : 1 Mata
Modul 2 Primitive Objects
Modul 2 Primitive Objects A. KOMPETENSI DASAR Memahami jenis-jenis primitive objects. Memahami dan dapat membuat objek primitif. Memahami penerapan Objek primitif menjadi bangun 2 dimensi dasar. Memahami
Modul 6 Interaksi dengan Keyboard dan Mouse
Modul 6 Interaksi dengan Keyboard dan Mouse A. KOMPETENSI DASAR Memahami prinsip-prinsip deteksi input berupa interaksi dari keyboard. Membuat objek 2D yang dikendalikan dengan keyboard. Memahami prinsip-prinsip
PEMBENTUKAN TRANSFORMASI OBJEK 2 DIMENSI DENGAN OPENGL
PEMBENTUKAN TRANSFORMASI OBJEK 2 DIMENSI DENGAN OPENGL Ina Agustina, Fauziah Jurusan Sistem Informasi Universitas Nasional Jl. Sawo Manila No.61 Pasar Minggu E-Mail : [email protected], [email protected]
Viewing 3D. Tujuan: memberi kesan pada viewer bahwa ia melihat foto 3D dengan cara yg sama saat kita memotret obyek 3D ke film 2D.
Komputer Grafik 1 Viewing 3D Tujuan: memberi kesan pada viewer bahwa ia melihat foto 3D dengan cara yg sama saat kita memotret obyek 3D ke film 2D. memproyeksikan obyek 3D ke bidang 2D 2 Pinhole Camera
GRAFIK KOMPUTER & PENGOLAHAN CITRA
GRAFIK KOMPUTER & PENGOLAHAN CITRA MEMBUAT GARIS MENGGUNAKAN OPENGL NAMA : ADRY FITRA AZHAR SIREGAR NPM : 10114361 KELAS : 3KA26 UNIVERSITAS GUNADARMA SISTEM INFORMASI PTA 2016 / 2017 PENGENALAN OPENGL
Praktikum Komputer Grafik [MODUL] Ganjil 2012/2013. Laboratorium Multimedia 1/41
Praktikum Komputer Grafik [MODUL] Ganjil 2012/2013 1/41 KONTRAK PRAKTIKUM Nama Mata Kuliah : Praktikum Komputer Grafik Kode Mata Praktikum : TKC 111 SKS : 1 Mata Kuliah Prasyarat : - Dosen Penanggung Jawab
IMPLEMENTASI OPEN GL32 UNTUK MEMANIPULASI GAMBAR SEGITIGA DAN SEGIEMPAT
IMPLEMENTASI OPEN GL32 UNTUK MEMANIPULASI GAMBAR SEGITIGA DAN SEGIEMPAT Agung Slamet Riyadi, Universitas Gunadarma, Jl. Margonda Raya No. 100 Pondok Cina Depok Jawa Barat e-mail [email protected]
Drawing, Viewport, dan Transformasi. Pertemuan - 02
Drawing, Viewport, dan Transformasi Pertemuan - 02 Ruang Lingkup Definisi Drawing Viewport Transfomasi Definisi Bagian dari grafik komputer meliputi: 1. Citra (Imaging) : mempelajari cara pengambilan dan
BAB 2 DASAR TEORI. Pada bagian ini akan dibahas tentang teori dasar dari grafika komputer, yang
BAB 2 DASAR TEORI 2.1 Teori Dasar Grafika Komputer Pada bagian ini akan dibahas tentang teori dasar dari grafika komputer, yang akan digunakan dalam pembahasan teknik environment mapping. 2.1.1 Sistem
Sistem Multimedia. Image. Donny Reza, S.Kom
Sistem Multimedia Image Donny Reza, S.Kom Image/Citra Image: representasi grafis dan visual dari suatu informasi yang dapat ditampilkan dalam layar komputer atau dicetak Berbagai bentuk image: Foto Gambar
BAB I PENGENALAN OPENGL
BAB I PENGENALAN OPENGL A. TUJUAN a. Mampu melakukan konfigurasi Library opengl di Visual Studio 2008 b. Mampu memahami inisialisasi fungsi opengl c. Mampu membuat objek dasar dengan fungsi opengl B. MATERI
Pemodelan Objek Monitor 3D
DISCLAIMER Seluruh dokumen E-Trik di dalam CD ini dapat digunakan dan disebarkan secara bebas untuk tujuan belajar bukan komersial (non-profit), dengan syarat tidak menghapus atau merubah atribut penulis
Bab 4 Studi Kasus. 4.1 Tampilan Awal Aplikasi Perangkat Lunak
Bab 4 Studi Kasus Pada bab ini akan dibahas mengenai aplikasi perangkat lunak untuk mengimplementasikan logika-logika dan algoritma pemodelan produk berbasis feature yang telah dibuat pada bab 3 penelitian
Animation. Semua gerakan yang Anda pikirkan, dapat dilakukan dalam Maya.
Pengenalan Autodesk Maya 2009! BAB 1 Pada maya versi ini Anda akan diberi kemudahan dalam pembuatan games, film, TV, dan desain grafis. Maya 2009 memberikan sejumlah fitur baru dan perangkat tambahan yang
3D STUDIO MAX. Setting awal 3D Studio Max 9
3D STUDIO MAX Setting awal 3D Studio Max 9 1. Untuk kerja yang leluasa, aturlah resolusi desktop windows anda setinggi mungkin di Control Panel Display. Disarankan menggunakan monitor 17 atau lebih besar.
Transformasi Obyek (Lanjutan)
Transformasi Obek (Lanjutan) Grafika Komputer Semester Ganjil 28 Teknik Informatika ITS Ann Yuniarti - 28 Kompetensi. Mampu memahami konsep transformasi 3D 2. Mampu mengimplementasikan konsep transformasi
Modul 3 Objek 2 Dimensi
Modul 3 Objek 2 Dimensi A. KOMPETENSI DASAR. Memahami penerapan Objek primitif menjadi bangun 2 dimensi dasar. Memahami dan dapat membuat fungsi untuk bangun 2 dimensi dasar. B. ALOKASI WAKTU 2 JS (2x50
LAPORAN PRAKTIKUM KOMPUTER GRAFIK
LAPORAN PRAKTIKUM KOMPUTER GRAFIK KELAS TI4C SORE NAMA PRAKTIKAN Mulia Hamonangan Tambunan NOMOR TANGGAL TANDA TANGAN MAHASISWA KUMPUL PRAKTIKAN 1214370473 NAMA PENILAI TANGGAL KOREKSI NILAI TANDA TANGAN
Bekasi, Desember 2006
Kata Pengantar 3DS Max adalah program untuk modeling, rendering, dan animasi yang memungkinkan Anda untuk mempresentasikan desain Anda, seperti desain interior, arsitektur, dan iklan, secara realistik
BAB II LANDASAN TEORI
BAB II LANDASAN TEORI 2.1 Visualisasi Visualisasi (visualization) adalah penampilan informasi yang bersifat komplek ke dalam bentuk visual (gambaran) (Chapman, 2004:665). Secara umum, visualisasi dalam
Bab 3 Metode dan Perancangan Sistem 3.1 Metode Pengembangan Sistem
Bab 3 Metode dan Perancangan Sistem 3.1 Metode Pengembangan Sistem Metode yang digunakan untuk pengembangan sistem dalam penelitian ini adalah model proses Prototype. Model prototype (Prototyping model)
BAB III ANALISA MASALAH DAN PERANCANGAN
BAB III ANALISA MASALAH DAN PERANCANGAN III.1. Analisa Masalah Perkembangan teknologi informasi terutama teknologi multimedia dewasa ini telah berkembang semakin pesat sehingga membuat kehidupan manusia
PAGI. SOAL PILIHAN GANDA : No
PAGI SOAL PILIHAN GANDA : No. 1 35. 1. Salah satu contoh aplikasi Grafika Komputer adalah Virtual Reality. Yang dimaksud Virtual Reality adalah: a. lingkungan virtual seperti yang ada di dunia internet
LAPORAN PRATIKUM KOMPUTER APLIKASI
LAPORAN PRATIKUM KELAS TI VI SORE D KOMPUTER APLIKASI Nama Nomor Pratikan Mahasiswa Ayu MayaSari 1214370278 Tanggal Kumpul Tanda Tangan Pratikan Nama Penilai Tanggal Nilai Tanda Tangan Koreksi Dosen Universitas
BAB III ANALISA DAN PERANCANGAN
BAB III ANALISA DAN PERANCANGAN III.1. Analisa Pengertian secara umum, animasi adalah menghidupkan dari sistem nyata yang dikerjakan secara manual atau komputer yang kemudian di observasi dan disimpulkan
MODUL 7 OBJEK 3D A. KOMPETENSI DASAR
MODUL 7 OBJEK 3D A. KOMPETENSI DASAR Memahami Inisialisasi dunia 3D Memahami Object 3D (Wired). Memahami dasar menampilkan susunan objek 3D. B. ALOKASI WAKTU 4 js (4x50 menit) C. PETUNJUK Awali setiap
Finishing Pemodelan Objek 3D
BAB 2 Finishing Pemodelan Objek 3D 2.1 Finishing Desain Objek Untuk bisa mempresentasikan dengan bagus dan realistis sebuah desain objek 3D, perlu dilakukan beberapa hal penting dalam proses finishing.
Pemodelan Objek Pena Cantik 3D
DISCLAIMER Seluruh dokumen E-Trik di dalam CD ini dapat digunakan dan disebarkan secara bebas untuk tujuan belajar bukan komersial (non-profit), dengan syarat tidak menghapus atau merubah atribut penulis
Serba Serbi Grafika Game
Serba Serbi Grafika Game Mengenal OpenGL Open Graphics Library is a standard specification defining a cross-language, cross-platform API for writing applications that produce 2D and 3D computer graphics.
PROSES PEMBUATAN MODELING ARSITEKTUR 1. PENGATURAN BACKGROUND IMAGE
PROSES PEMBUATAN MODELING ARSITEKTUR 1. PENGATURAN BACKGROUND IMAGE Untuk memunculkan tab Transform yang ada di sebelah kanan klik N pada keyboard.lalu scroll ke bawah dan cari option background image
BAB III ANALISA DAN PERANCANGAN
BAB III ANALISA DAN PERANCANGAN 3.1 Rancangan Awal Pemodelan Blender merupakan software grafis 3 Dimensi yang sangat baik. Tidak hanya menyediakan fasilitas untuk membuat object 3D dengan mudah tapi juga
Pembuatan Simulasi Pergerakan Objek 3D (Tiga Dimensi) Menggunakan OpenGL
1 Pembuatan Simulasi Pergerakan Objek 3D (Tiga Dimensi) Menggunakan OpenGL Deddy Suhardiman, S.T.G. Kaunang, Rizal Sengkey, Arthur M. Rumagit Jurusan Teknik Elektro-FT, UNSRAT, Manado-95115, Email: [email protected]
DAFTAR ISI TOOLBAR SOLID TOOLBAR SHADE TOOLBAR 3D ORBIT TOOLBAR SURFACE TOOLBAR SOLIDS EDITING TOOLBAR MODIFY II TOOLBAR VIEW TOOLBAR TOOLBAR UCS
DAFTAR ISI TOOLBAR SOLID TOOLBAR SHADE TOOLBAR 3D ORBIT TOOLBAR SURFACE TOOLBAR SOLIDS EDITING TOOLBAR MODIFY II TOOLBAR VIEW TOOLBAR TOOLBAR UCS TOOLBAR RANDER TOOLBAR SOLIDS Box. Fungsi : untuk membuat
BAB III ANALISA DAN PERANCANGAN
BAB III ANALISA DAN PERANCANGAN III.1. Analisa Pengertian secara umum, animasi adalah menghidupkan dari sistem nyata yang dikerjakan secara manual atau komputer yang kemudian di observasi dan disimpulkan
BAB III ANALISA DAN DESAIN SISTEM
BAB III ANALISA DAN DESAIN SISTEM III.1. Analisa Sistem Yang Sedang Berjalan Perancangan animasi ini yaitu tentang perkenalan objek wisata yang ada di pulau Nias. Yang kita ketahui pulau Nias memiliki
J U R N A L I L M I A H KOMPUTASI
Volume 10 No : 2 ISSN Nomor : 1412-9434 2011 J U R N A L I L M I A H KOMPUTASI Komputer & Sistem Informasi 1-11 Arsitektur Mikroprosesor Berbasiskan Perangkat Lunak SPARC Sunny Arief Sudiro, Dwi Putra
BAB III ANALISA DAN PERANCANGAN
BAB III ANALISA DAN PERANCANGAN III.1. Analisa Masalah Pengertian secara umum, animasi adalah suatu kegiatan menghidupkan, menggerakkan benda mati, dimana benda mati tersebut diberikan dorongan kekuatan
BAB 3 PERANCANGAN PROGRAM APLIKASI
BAB 3 PERANCANGAN PROGRAM APLIKASI 3.1 Rancangan Aplikasi Program aplikasi motion detection yang akan dirancang memiliki struktur hirarki di mana terdapat 3 sub menu dari menu utamanya yaitu sub menu file,
BAB IV IMPLEMENTASI DAN PENGUJIAN
BAB IV IMPLEMENTASI DAN PENGUJIAN 4.1 IMPLEMENTASI Menurut konsep dan perancangan yang telah dijelaskan pada bab sebelumnya, maka dibawah ini akan membahas langkah - langkah pembuatan aplikasi tersebut.
TIU: Mahasiswa mampu menghasilkan aplikasi Komputer Grafik sederhana. Pemrograman OpenGL API dasar 2 dimensi. Penggunaan aplikasi pengolah grafis 3D
Matakuliah : Komputer Grafik Dosen : Yonathan Ferry Hendrawan ThAkad : 2013-2014 Semester : Genap (empat) Prodi : S1 Teknik Informatika KONTRAK KULIAH 1. Manfaat Matakuliah Dengan mengambil mata kuliah
PERANCANGAN POLIHEDRA DENGAN METODE JARING POLIGON
PERANCANGAN POLIHEDRA DENGAN METODE JARING POLIGON Ina Agustina, Agus Iskandar Jurusan Sistem Informasi, Fakultas Teknologi Komunikasi dan Informatika, Universitas Nasional Jl. Sawo Manila, Pejaten Pasar
FAKULTAS TEKNIK UNIVERSITAS NEGERI YOGYAKARTA LAB. SHEET PRAKTIKUM GRAFIKA KOMPUTER
No. : ST/EKA/PTI223/10 Revisi : 03 Senin 170511 Hal. 1 dari 16 hal. Pengantar Media berasal dari bahasa latin yang merupakan bentuk jamak dari Medium yang secara harfiah berarti Perantara atau Pengantar
Bekasi, Januari 2007
Kata Pengantar 3DS Max adalah program untuk modeling, rendering, dan animasi, yang memungkinkan Anda untuk mempresentasikan desain Anda, seperti desain interior, arsitektur, dan iklan, secara realistik
12 Model Loading & Curve. Imam Cholissodin
12 Model Loading & Curve Imam Cholissodin [email protected] Model Loading & Curve : 1. What s Model Loading & Curve 2. Model Creator 3. OpenGL Model Loading 4. General Curve 5. Fractal Curve 6.
Persiapan Sebelum mengikuti tutorial ini, ada baiknya pembaca telah membaca beberapa tutorial sebagai berikut:
Android OpenGL Part 2 - Polygon [Pemrograman OpenGL Android 02][Level: Mahir] Andi Taru Nugroho Nur Wismono S.Kom.,M.Cs. [email protected] Lisensi Dokumen: Copyright 2012 JavaClopedia.com Seluruh dokumen
BAB 1 Pengenalan 3ds Max
BAB 1 Pengenalan 3ds Max 1.1 Rekomendasi Sistem Komputer 3ds max merupakan program permodelan 3 dimensi yang lebih komunikatif, baik desain produk maupun periklanan. Agar bisa bekerja dengan baik, tentunya
BAB III ANALISA DAN PERANCANGAN
BAB III ANALISA DAN PERANCANGAN III.1. Analisa Kapal laut adalah sebuah alat transportasi laut yang sangat banyak digunakan masyarakat selama ini. Di Indonesia, kecelakan transportasi laut sering kali
1 Blender animation club. Book modeling 1
1 Blender animation club. Book modeling 1 Book modeling Modeling boleh dikatakan sebagai konsep awal dari suatu animasi. Sebelum kita menciptakan animasi, kita menciptakan suatu model atau karakter terlebih
TUTORIAL AUTODESK 3DS MAX 2011 MODELING GELAS CANTIK 3 DIMENSI
MODELING GELAS CANTIK 3 DIMENSI Gambar 1. Aneka Macam Gelas. Untuk membuat gelas cantik seperti salah satu dari contoh gelas-gelas cantik di atas dengan Autodesk 3DS max 2011, ada beberapa langkah yang
Konsep 3D dan Representasi Objek 3D. Konsep 3D. Konsep 3D. Representasi Objek 3D. Konsep 3D 12/28/2017
Objek di koordinat dunia Transformasi koordinat dunia ke koordinat kamera Clipping Konsep 3D dan Representasi Objek 3D Transformasi ke koordinat device Proyeksi ke bidang pandang Konsep 3D Untuk mendapatkan
Simulasi Transformasi Linier pada Bidang 2D Dengan Menggunakan OpenGL API
Program Studi Teknik Informatika Sekolah Teknik Elektro dan Informatika Institut Teknologi Bandung Tugas Besar II IF2123 Aljabar Geometri Simulasi Transformasi Linier pada Bidang 2D Dengan Menggunakan
TIU: Mahasiswa mampu menghasilkan aplikasi Komputer Grafik sederhana. Pemrograman OpenGL API dasar dan interaksi 2 dimensi
Matakuliah : Komputer Grafik Dosen : Yonathan Ferry Hendrawan ThAkad : 2014-2015 Semester : Genap (empat) Prodi : S1 Teknik Informatika KONTRAK KULIAH 1. Manfaat Matakuliah Dengan mengambil mata kuliah
Pemrograman Dasar C. Minggu 6
Pemrograman Dasar C Minggu 6 Topik Bahasan Fungsi Menulis sekali digunakan berulang kali Tugas yang dikompartemenkan Variabel lokal dalam fungsi Teknik Mendesain Top-Down Kode Pseudo Struktur dan Diagram
Pengantar Kuliah: Grafika Komputer. By: Nana Ramadijanti
Pengantar Kuliah: Grafika Komputer By: Nana Ramadijanti Tujuan Perkuliahan Mahasiswa dapat membuat program untuk membangun grafik 2D dan 3D menggunakan bahasa pemrograman C++ dan grafik library OpenGL.
Basic 3D Modelling dan Animasi Menggunakan 3DS MAX
Basic 3D Modelling dan Animasi Menggunakan 3DS MAX 3ds max 2010 adalah program tiga dimensi dari perusahaan Autodesk yang memiliki banyak kelebihan. Fitur baru dan tampilannya menjadi daya tarik tersendiri
