Tutorial Open GL (Listing Code)

83
Program 1. Hello World dan Tampilan Rectangle #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h> void mydisplay() //diregistrasi oleh glutDisplayFunc() sebagai fungsi yang dilaksanakan saat // window digambar { glClear(GL_COLOR_BUFFER_BIT); // Menghapus layar glBegin(GL_POLYGON); glVertex2f(-0.5, -0.5); // koordinat titik kiri bawah glVertex2f(-0.5, 0.5); // koordinat titik kiri atas glVertex2f(0.5, 0.5); // koordinat titik kanan atas glVertex2f(0.5, -0.5); // koordinat titik kanan bawah glEnd(); glFlush(); } int main(int argc, char** argv) { printf("Hello World… this is 2D Rectangle"); glutCreateWindow("Simple Window"); glutDisplayFunc(mydisplay); glutMainLoop(); } Program 2. 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); glColor3f (1.0, 0.0, 1.0); // setting warna pink glVertex2f(-0.5, -0.5); glVertex2f(-0.5, 0.5); glVertex2f(0.5, 0.5); glEnd(); glFlush(); } int main(int argc, char** argv){ glutCreateWindow("Triangle Shape"); glutDisplayFunc(mydisplay); glutMainLoop(); }

description

Task of Graphic and Programming Computer

Transcript of Tutorial Open GL (Listing Code)

Page 1: Tutorial Open GL (Listing Code)

Program 1. Hello World dan Tampilan Rectangle

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <GL/glut.h>

void mydisplay() //diregistrasi oleh glutDisplayFunc() sebagai fungsi yang dilaksanakan saat // window digambar { glClear(GL_COLOR_BUFFER_BIT); // Menghapus layar glBegin(GL_POLYGON); glVertex2f(-0.5, -0.5); // koordinat titik kiri bawah glVertex2f(-0.5, 0.5); // koordinat titik kiri atas glVertex2f(0.5, 0.5); // koordinat titik kanan atas glVertex2f(0.5, -0.5); // koordinat titik kanan bawah glEnd(); glFlush(); } int main(int argc, char** argv) { printf("Hello World… this is 2D Rectangle"); glutCreateWindow("Simple Window"); glutDisplayFunc(mydisplay); glutMainLoop(); }

Program 2. 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); glColor3f (1.0, 0.0, 1.0); // setting warna pink glVertex2f(-0.5, -0.5); glVertex2f(-0.5, 0.5); glVertex2f(0.5, 0.5); glEnd(); glFlush(); } int main(int argc, char** argv){ glutCreateWindow("Triangle Shape"); glutDisplayFunc(mydisplay); glutMainLoop(); }

Page 2: Tutorial Open GL (Listing Code)

Program 3. Polygon

#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(1, 1, 0); // setting warna kuning glVertex2f(-0.5, -0.8); 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("Polygon Aila"); glutDisplayFunc(mydisplay); glutMainLoop(); }

Contoh Listing Program untuk menggambar jenis OpenGL Geometric Primitive yang lain. #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_QUADS); glColor3f(1,1,0); glVertex2f(-0.5, 0.5); glVertex2f(-0.85, -0.5); // ubah nilai vertex glVertex2f(0.5, 0); glVertex2f(0.5, 0.5); glEnd(); glFlush(); } void main(int arcg, char** argv){ printf("Hello World....this is Quad"); glutCreateWindow("Quad Windows Aila"); glutDisplayFunc(Mydisplay); glutMainLoop();

Page 3: Tutorial Open GL (Listing Code)

}

Program 4. 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("Polygon Aila"); glutDisplayFunc(mydisplay); glutMainLoop(); }

Program 5. 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); // glVertex3f () untuk memodelkan objek dalam bentuk 3D dgn menambahkan koordinat z

Page 4: Tutorial Open GL (Listing Code)

glColor3f(0, 1, 0); glVertex3f(-0.75, 0, 1); glColor3f(1, 1, 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, 1); glVertex3f(0.5, -0.5, -1); glColor3f(1, 0, 1); glVertex3f(0,-0.75, -1); glEnd(); glFlush(); } int main (int argc, char** argv) { glutCreateWindow("3D Dimensional Vertex"); glutDisplayFunc(mydisplay); glutMainLoop(); }

Program 6. 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); glColor3f(0.0, 1.0, 0.0); 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, this is 2D rectangle"); glutCreateWindow("2D Rectangle Aila");

Page 5: Tutorial Open GL (Listing Code)

glutDisplayFunc(myDisplay); glutReshapeFunc(resize); glutMainLoop(); }

Program 7. Proyeksi Persfektif

// - Viewing Volume of Perspective Projection // - Try the keyboard callback // - Reshape callback // - Timer // #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(); // Untuk menghindari flicker (objek yg berkedip)

//mode display menggunakan tipe GLUT_DOUBLE } void init( void ) { glClearColor( 1.0, 0.0, 0.0, 1.0 ); // A Background Clear Color glMatrixMode(GL_PROJECTION);

Page 6: Tutorial Open GL (Listing Code)

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) { // called if timer event // ...advance the state of animation incrementally... rot+=5; //speed rotation glutPostRedisplay(); // request redisplay glutTimerFunc(100, myTimeOut, 0); // request next timer event } void myKeyboard(unsigned char key,int x, int y) { // key untuk translasi objek Zoom in(memperbesar) if((key=='<')||(key==',')) z_pos-=0.1f; // key untuk translasi objek Zoom out (memperkecil) 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("Persfektif"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); }

Program 8. Urutan Transformasi

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

Page 7: Tutorial Open GL (Listing Code)

// // 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); glMatrixMode (GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (float)width / (float)height, 1.0, 300.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void myTimeOut (int id) { 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); glLoadIdentity(); //fungsi transformasi glTranslatef (0.0, 0.0f, z_pos); // Objek melakukan translasi glRotatef(rot, 0, 1, 0); // Objek melakukan rotasi 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);

Page 8: Tutorial Open GL (Listing Code)

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); // Left Face, magenta glColor3f(1.0,0.0,1.0); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); glFlush(); glutSwapBuffers(); } void init() { //glEnable(GL_DEPTH_TEST); // harus di komen agar bisa di render 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); glutInitWindowSize(500, 500); glutInitWindowPosition(0,0); glutCreateWindow("Transformasi Aila"); //callbacks glutDisplayFunc(myDisplay); glutKeyboardFunc(myKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }

Page 9: Tutorial Open GL (Listing Code)

Program 9. Texture Mapping dan Blending

// file bmp.h #include <GL/GLAUX.H> AUX_RGBImageRec *LoadBMP(char *Filename);

// file bmp.cpp #include <windows.h> #include <stdio.h> // Header File For Standard Input/Output #include <GL\GL.H> // Header File For The OpenGL32 Library #include <GL\GLU.H> // Header File For The GLu32 Library #include <GL\GLAUX.H> // Header File For The Glaux Library #include "bmp.h" AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image { FILE *File=NULL; //File Handle if (!Filename)// Make Sure A Filename Was Given { return NULL; // If Not Return NULL } File=fopen(Filename,"r"); //Check To See If The File Exists if (File) // Does The File Exist? { fclose(File); // Close The Handle //return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer return auxDIBImageLoadA(Filename); // load The Bitmap and Return A pointer for Multicode type character } return NULL; // If Load Failed Return NULL }

// File Program_9.cpp // OpenGL // - Function to load bitmap // - Texture Mapping Magnification Filter // filter=0 --> Nearest Filtered Texture // filter=1 --> Linear Interpolation Texture // filter=2 --> Mipmapped Texture // Beda Filter Belum terlihat? #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;

Page 10: Tutorial Open GL (Listing Code)

float rot=0.0f; GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f }; /* array to hold texture handles */ GLuint filter; // Which Filter To Use GLuint texture[3]; // Storage For 3 Textures int LoadGLTextures() // Load Bitmaps And Convert To Textures { int Status=FALSE; //Status Indicator AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit if (TextureImage[0]=LoadBMP("aila.bmp")) { Status=TRUE; // Set The Status To TRUE glGenTextures(3, &texture[0]); //Create Three Textures // Create Nearest Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // Create Linear Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[1]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // Create MipMapped Texture glBindTexture(GL_TEXTURE_2D, texture[2]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); } if (TextureImage[0]) // If Texture Exists { if (TextureImage[0]->data) //If Texture Image Exists { free(TextureImage[0]->data); // Free The Texture Image Memory } free(TextureImage[0]); // Free The Image Structure } return Status; // Return The Status } void resize(int width, int height) {

Page 11: Tutorial Open GL (Listing Code)

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+=5; 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 | 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); // red 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

Page 12: Tutorial Open GL (Listing Code)

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 glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light glEnable(GL_LIGHT1); return; } int main(int argc, char** argv) {

Page 13: Tutorial Open GL (Listing Code)

glutInit(&argc,argv); glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("Mapping and Blending Aila"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }

Program 10. Ubah warna blending pada tiap surface box

// Source code diambil dari Program 9 , diubah di fungsi mydisplay 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); // blending texture on glColor3f (1.0, 0.0, 0.0); // blending color glBindTexture(GL_TEXTURE_2D, texture[filter]); glBegin(GL_QUADS); // Front Face glColor3f (1.0, 1.0, 0.0); // setting warna untuk sisi depan

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 glColor3f (1.0, 0.0, 0.0); // setting warna untuk sisi belakang 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 glColor3f (0.0, 1.0, 1.0); // setting warna untuk sisi atas

Page 14: Tutorial Open GL (Listing Code)

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 glColor3f (0.0, 0.0, 1.0); // setting warna untuk sisi bawah 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 glColor3f (1.0, 0.0, 1.0); // setting warna untuk sisi kanan 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 glColor3f (1.0, 1.0, 0.0); // setting warna untuk sisi kiri 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(); }

Program 11. Transparency

// Source code program 11 diambil dari Program 10, di ubah di fungsi mydisplay dan init

//Untuk membuat objek transparan, gunakan fungsi:

//glColor4f(1.0f, 1.0f, 1.0f, 0.5);// Full Brightness. 50% Alpha //glBlendFunc(GL_SRC_ALPHA,GL_ONE); 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); // blending texture on glDisable (GL_DEPTH_TEST); // turn depth testing off

Page 15: Tutorial Open GL (Listing Code)

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(); } void init() { if (!LoadGLTextures()) //Jump To Texture Loading Routine { return; //If Texture Didn't Load Return FALSE } glEnable(GL_TEXTURE_2D); //Enable Texture Mapping

Page 16: Tutorial Open GL (Listing Code)

glShadeModel(GL_SMOOTH); //Enable Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background with alpha 50% glClearDepth(1.0f); // Depth Buffer setup glEnable (GL_DEPTH_TEST); // enables depth testing glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //glDepthFunc(GL_LEQUAL); //The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light glColor4f (1.0f, 1.0f, 1.0f, 0.5f ); // Full Brightness , 50% Alpha glEnable(GL_LIGHT1); glBlendFunc(GL_SRC_ALPHA, GL_ONE); return; }

Program 12. Fog // 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

Page 17: Tutorial Open GL (Listing Code)

{ int Status=FALSE; //Status Indicator AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit if (TextureImage[0]=LoadBMP("aila.bmp")) { Status=TRUE; // Set The Status To TRUE glGenTextures(3, &texture[0]); //Create Three Textures // Create Nearest Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // Create Linear Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[1]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // Create MipMapped Texture glBindTexture(GL_TEXTURE_2D, texture[2]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); } if (TextureImage[0]) //If Texture Exists { if (TextureImage[0]->data) //If Texture Image Exists { free(TextureImage[0]->data); // Free The Texture Image Memory } free(TextureImage[0]); //Free The Image Structure } return Status; } 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) {

Page 18: Tutorial Open GL (Listing Code)

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

Page 19: Tutorial Open GL (Listing Code)

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 // FOG glClearColor(0.5f,0.5f,0.5f,1.0f); // We'll Clear To The Color Of The Fog glFogi(GL_FOG_MODE, fogMode[fogfilter]); // Fog Mode glFogfv(GL_FOG_COLOR, fogColor); // Set Fog Color glFogf(GL_FOG_DENSITY, 0.35f); // How Dense Will The Fog Be glHint(GL_FOG_HINT, GL_DONT_CARE); // Fog Hint Value glFogf(GL_FOG_START, 100.0f); // Fog Start Depth glFogf(GL_FOG_END, 1000.0f); // Fog End Depth glEnable(GL_FOG); glClearDepth(1.0f); // Depth Buffer Setup

Page 20: Tutorial Open GL (Listing Code)

glEnable(GL_DEPTH_TEST); //Enables Depth Testing glDepthFunc(GL_LEQUAL); //The Type Of Depth Testing To Do glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light glEnable(GL_LIGHT1); return; } int main(int argc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("Fog Window"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }

Tugas 12 : Ubah variable Fog pada fungsi init, untuk melihat pengaruhnya. // 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 };

Page 21: Tutorial Open GL (Listing Code)

/* 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 AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit if (TextureImage[0]=LoadBMP("aila.bmp")) { Status=TRUE; // Set The Status To TRUE glGenTextures(3, &texture[0]); //Create Three Textures // Create Nearest Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // Create Linear Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[1]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // Create MipMapped Texture glBindTexture(GL_TEXTURE_2D, texture[2]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); } if (TextureImage[0]) //If Texture Exists { if (TextureImage[0]->data) //If Texture Image Exists { free(TextureImage[0]->data); // Free The Texture Image Memory } free(TextureImage[0]); //Free The Image Structure } return Status; }

Page 22: Tutorial Open GL (Listing Code)

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); } } void mydisplay(void) { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLoadIdentity();

Page 23: Tutorial Open GL (Listing Code)

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

Page 24: Tutorial Open GL (Listing Code)

// FOG glClearColor(0.5f,0.5f,0.5f,1.0f); // We'll Clear To The Color Of The Fog glFogi(GL_FOG_MODE, fogMode[GL_EXP2]); // Fog Mode , diinisiasi dg 3 nilai glFogfv(GL_FOG_COLOR, fogColor); // Set Fog Color glFogf(GL_FOG_DENSITY, 0.20f); // How Dense Will The Fog Be glHint(GL_FOG_HINT, GL_NICEST); // Fog Hint Value glFogf(GL_FOG_START, 100.0f); // Fog Start Depth glFogf(GL_FOG_END, 500.0f); // Fog End Depth glEnable(GL_FOG); glClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); //Enables Depth Testing glDepthFunc(GL_LEQUAL); //The Type Of Depth Testing To Do glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light glEnable(GL_LIGHT1); return; } int main(int argc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("Fog Window"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; } Program 13. Objek Komplek

#include<Windows.h> #include<math.h>// Math Library Header File #include<stdio.h> #include<stdlib.h> #include<string.h> #include<stdarg.h> #include<GL/glut.h>

Page 25: Tutorial Open GL (Listing Code)

#include<GL/GLAUX.H> # pragma comment ( lib, "GLAUX.LIB") const float piover180 = 0.0174532925f; float heading; float xpos; float zpos; GLfloat yrot; // Y Rotation GLfloat walkbias = 0; GLfloat walkbiasangle = 0; GLfloat lookupdown = 0.0f; GLfloat z=0.0f; // Depth Into The Screen GLuint filter; // Which Filter To Use GLuint texture[3]; // Storage For 3 Textures typedef struct tagVERTEX { float x, y, z; float u, v; } VERTEX; typedef struct tagTRIANGLE { VERTEX vertex[3]; } TRIANGLE; typedef struct tagSECTOR { int numtriangles; TRIANGLE* triangle; } SECTOR; SECTOR sector1; // Our Model Goes Here: void readstr(FILE *f,char *string) { do { fgets(string, 255, f); } while ((string[0] == '/') || (string[0] == '\n')); return; } void SetupWorld() { float x, y, z, u, v; int numtriangles; FILE *filein; char oneline[255]; filein = fopen("test_world.txt", "rt"); // File To Load World Data From readstr(filein,oneline); sscanf(oneline, "NUMPOLLIES %d\n", &numtriangles); sector1.triangle = new TRIANGLE[numtriangles]; sector1.numtriangles = numtriangles; for (int loop = 0; loop < numtriangles; loop++) {

Page 26: Tutorial Open GL (Listing Code)

for (int vert = 0; vert < 3; vert++) { readstr(filein,oneline); sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v); sector1.triangle[loop].vertex[vert].x = x; sector1.triangle[loop].vertex[vert].y = y; sector1.triangle[loop].vertex[vert].z = z; sector1.triangle[loop].vertex[vert].u = u; sector1.triangle[loop].vertex[vert].v = v; } } fclose(filein); return; } AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image { FILE *File=NULL; // File Handle if (!Filename) // Make Sure A Filename Was Given { return NULL; // If Not Return NULL } File=fopen(Filename,"r"); // Check To See If The File Exists if (File) // Does The File Exist? { fclose(File); // Close The Handle //return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer return auxDIBImageLoadA(Filename); // Load The Bitmap And Return A Pointer } return NULL; // If Load Failed Return NULL } int LoadGLTextures() // Load Bitmaps And Convert To Textures { int Status=FALSE; // Status Indicator AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit if (TextureImage[0]=LoadBMP("aila.bmp")) { Status=TRUE; // Set The Status To TRUE glGenTextures(3, &texture[0]); // Create ThreeTextures // 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);

Page 27: Tutorial Open GL (Listing Code)

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX,TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // Create MipMapped Texture glBindTexture(GL_TEXTURE_2D, texture[2]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX,TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); } if (TextureImage[0]) // If Texture Exists { if (TextureImage[0]->data) // If Texture Image Exists { free(TextureImage[0]->data); // Free The Texture Image Memory } free(TextureImage[0]); // Free The Image Structure } return Status; // Return The Status } void resize(int width, int height) // Resize And Initialize The GL Window { if (height==0) // Prevent A Divide By Zero By { height=1; // Making Height Equal One } glViewport(0,0,width,height); // Reset The Current Viewport glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrix } void init() // All Setup For OpenGL Goes Here { if (!LoadGLTextures()) // Jump To Texture Loading Routine { return; // If Texture Didn't Load Return FALSE } glEnable(GL_TEXTURE_2D); //Enable Texture Mapping glBlendFunc(GL_SRC_ALPHA,GL_ONE); // SetThe 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

Page 28: Tutorial Open GL (Listing Code)

SetupWorld(); return; // Initialization Went OK } 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) { } 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;

Page 29: Tutorial Open GL (Listing Code)

yrot = heading; } else if(key==GLUT_KEY_PAGE_UP) { 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; glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);

Page 30: Tutorial Open GL (Listing Code)

glEnd(); } glFlush(); glutSwapBuffers(); } int main(int argc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("Objek Kompleks"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutSpecialFunc(mySpecialKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }

Program 14. Load file .3ds (Animasi Pesawat)

// Tutorial14h /********************************************************** * * 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{ 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;

Page 31: Tutorial Open GL (Listing Code)

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

Page 32: Tutorial Open GL (Listing Code)

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

Page 33: Tutorial Open GL (Listing Code)

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

Page 34: Tutorial Open GL (Listing Code)

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

Page 35: Tutorial Open GL (Listing Code)

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

Page 36: Tutorial Open GL (Listing Code)

// 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 "Tutorial14.h" #include "Texture.h" #include "3dsloader.h" // 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 foreach 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

Page 37: Tutorial Open GL (Listing Code)

// Viewport transformation glViewport(0,0,screen_width,screen_height); // Projection transformation glMatrixMode(GL_PROJECTION); // Specifies which matrix stack is the target for matrix operations glLoadIdentity(); // We initialize the projection matrix as identity gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,10.0f,10000.0f); // We define the "viewing volume" glEnable(GL_DEPTH_TEST); // We enable the depth test (also called z buffer) glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled) glEnable(GL_TEXTURE_2D); // This Enable the Texture mapping Load3DS (&object,"spaceship.3ds"); object.id_texture=LoadBitmap("spaceshiptexture.bmp"); // The Function LoadBitmap() return the current texture ID // If the last function returns -1 it means the file was not found so we exit from the program if (object.id_texture==-1) { MessageBox(NULL,"Image file: spaceshiptexture.bmp not found", "Zetadeck",MB_OK | MB_ICONERROR); exit (0); } } void resize (int width, int height) { screen_width=width; // We obtain the new screen width values and store it screen_height=height; // Height value glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // We clear both the color and the depth buffer so to draw the next frame glViewport(0,0,screen_width,screen_height); // Viewport transformation glMatrixMode(GL_PROJECTION); // Projection transformation glLoadIdentity(); // We initialize the projection matrix as identity gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,10.0f,10000.0f); glutPostRedisplay (); // This command redraw the scene (it calls the same routine of glutDisplayFunc) } void keyboard (unsigned char key, int x, int y) { switch (key) { case' ': rotation_x_increment=0; rotation_y_increment=0; rotation_z_increment=0; break; case'r': case'R': if (filling==0) { glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled) filling=1; } else { glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); // Polygon rasterization mode (polygon outlined) filling=0;

Page 38: Tutorial Open GL (Listing Code)

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

Page 39: Tutorial Open GL (Listing Code)

object.polygon[l_index].b ].v); // Coordinates of the second vertex 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("Animasi Pesawat Objek 3ds"); glutDisplayFunc(display); glutIdleFunc(display); glutReshapeFunc (resize); glutKeyboardFunc (keyboard); glutSpecialFunc (keyboard_s); init(); glutMainLoop(); return(0); }

Program 16. Particle

// Particle.h #ifndef PARTICLE_H_ typedef struct { float lifetime; // total lifetime of the particle float decay; // decay speed of the particle float r,g,b; // color values of the particle float xpos,ypos,zpos; // position of the particle float xspeed,yspeed,zspeed; // speed of the particle boolean active; // is particle active or not? } PARTICLE; void CreateParticle(int i); void InitParticle(); void EvolveParticle();

Page 40: Tutorial Open GL (Listing Code)

#endif

//Particle.cpp #include <windows.h> #include <stdlib.h> #include <math.h> #include "particle.h" const int maxparticle=2000; // set maximum number of particles PARTICLE particle[maxparticle]; void CreateParticle(int i) { particle[i].lifetime= (float)(500000*rand()/RAND_MAX)/500000.0; particle[i].decay=0.001; particle[i].r = 0.7; particle[i].g = 0.7; particle[i].b = 1.0; particle[i].xpos= 0.0; particle[i].ypos= 0.0; particle[i].zpos= 0.0; particle[i].xspeed = 10*(0.0005-(float)(100*rand()/RAND_MAX)/100000.0); particle[i].yspeed = 0.01-(float)(100*rand()/RAND_MAX)/100000.0; particle[i].zspeed = 0.0005-(float)(100*rand()/RAND_MAX)/100000.0; particle[i].active = true; } //--------------------------------------------------------------------------- void InitParticle() { for(int i=0;i<=maxparticle;i++){ // initialize the particle parameters CreateParticle(i); particle[i].active = false; // set all particles inactive } } //--------------------------------------------------------------------------- void EvolveParticle() { for(int i=0;i<=maxparticle;i++){ // evolve the particle parameters particle[i].lifetime-=particle[i].decay; particle[i].xpos+=particle[i].xspeed; particle[i].ypos+=particle[i].yspeed; particle[i].zpos+=particle[i].zspeed; particle[i].yspeed-=0.00010; } }

// Program.cpp // OpenGL // - Texture Mapping Magnification Filter // filter=0 --> Nearest Filtered Texture // filter=1 --> Linear Interpolation Texture

Page 41: Tutorial Open GL (Listing Code)

// 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 int maxparticle=2000; // set maximum number ofparticles extern PARTICLE particle[maxparticle]; int LoadGLTextures() //Load Bitmaps And Convert To Textures { int Status=FALSE; //Status Indicator AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit if (TextureImage[0]=LoadBMP("aila.bmp")) { Status=TRUE; // Set The Status To TRUE glGenTextures(1, &texture[0]); //Create Three Textures // Create Nearest Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); } if (TextureImage[0]) // If Texture Exists { if (TextureImage[0]->data) // If Texture Image Exists { free(TextureImage[0]->data); // Free The Texture Image Memory } free(TextureImage[0]); // Free The Image Structure } glEnable(GL_TEXTURE_2D); // Enable Texture Mapping return Status; // Return The Status } void resize(int width, int height) { glViewport(0, 0, width, height); //glMatrixMode(GL_PROJECTION); //glLoadIdentity(); //gluPerspective(45.0, (float)width/(float)height, 0.0, 300.0); glMatrixMode(GL_PROJECTION); // the following operations affect the projection matrix glLoadIdentity(); // restore matrix to original state

Page 42: Tutorial Open GL (Listing Code)

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(); } else CreateParticle(i); } EvolveParticle(); glFlush(); glutSwapBuffers(); } void init() { glDisable(GL_DEPTH_TEST); // deactivate hidden surface removal

Page 43: Tutorial Open GL (Listing Code)

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

Program 17. Lighting

// Material.h float Brass[] = { 0.329412, 0.223529, 0.027451, 1.000000, 0.780392, 0.568627, 0.113725, 1.000000, 0.992157, 0.941176, 0.807843, 1.000000, 27.897400 }; float Bronze[] = { 0.212500, 0.127500, 0.054000, 1.000000, 0.714000, 0.428400, 0.181440, 1.000000, 0.393548, 0.271906, 0.166721, 1.000000, 25.600000 }; float Polished_Bronze[] = { 0.250000, 0.148000, 0.064750, 1.000000, 0.400000, 0.236800, 0.103600, 1.000000, 0.774597, 0.458561, 0.200621, 1.000000, 76.800003 }; float Chrome[] = { 0.250000, 0.250000, 0.250000, 1.000000, 0.400000, 0.400000, 0.400000, 1.000000, 0.774597, 0.774597, 0.774597, 1.000000,

Page 44: Tutorial Open GL (Listing Code)

76.800003 }; float Copper[] = { 0.191250, 0.073500, 0.022500, 1.000000, 0.703800, 0.270480, 0.082800, 1.000000, 0.256777, 0.137622, 0.086014, 1.000000, 12.800000 }; float Polished_Copper[] = { 0.229500, 0.088250, 0.027500, 1.000000, 0.550800, 0.211800, 0.066000, 1.000000, 0.580594, 0.223257, 0.069570, 1.000000, 51.200001 }; float Gold[] = { 0.247250, 0.199500, 0.074500, 1.000000, 0.751640, 0.606480, 0.226480, 1.000000, 0.628281, 0.555802, 0.366065, 1.000000, 51.200001 }; float Polished_Gold[] = { 0.247250, 0.224500, 0.064500, 1.000000, 0.346150, 0.314300, 0.090300, 1.000000, 0.797357, 0.723991, 0.208006, 1.000000, 83.199997 }; float Pewter[] = { 0.105882, 0.058824, 0.113725, 1.000000, 0.427451, 0.470588, 0.541176, 1.000000, 0.333333, 0.333333, 0.521569, 1.000000, 9.846150 }; float Silver[] = { 0.192250, 0.192250, 0.192250, 1.000000, 0.507540, 0.507540, 0.507540, 1.000000, 0.508273, 0.508273, 0.508273, 1.000000, 51.200001 }; float Polished_Silver[] = { 0.231250, 0.231250, 0.231250, 1.000000, 0.277500, 0.277500, 0.277500, 1.000000, 0.773911, 0.773911, 0.773911, 1.000000, 89.599998 }; float Emerald[] = { 0.021500, 0.174500, 0.021500, 0.550000, 0.075680, 0.614240, 0.075680, 0.550000, 0.633000, 0.727811, 0.633000, 0.550000, 76.800003 }; float Jade[] = { 0.135000, 0.222500, 0.157500, 0.950000, 0.540000, 0.890000, 0.630000, 0.950000, 0.316228, 0.316228, 0.316228, 0.950000, 12.800000 }; float Obsidian[] = { 0.053750, 0.050000, 0.066250, 0.820000,

Page 45: Tutorial Open GL (Listing Code)

0.182750, 0.170000, 0.225250, 0.820000, 0.332741, 0.328634, 0.346435, 0.820000, 38.400002 }; float Pearl[] = { 0.250000, 0.207250, 0.207250, 0.922000, 1.000000, 0.829000, 0.829000, 0.922000, 0.296648, 0.296648, 0.296648, 0.922000, 11.264000 }; float Ruby[] = { 0.174500, 0.011750, 0.011750, 0.550000, 0.614240, 0.041360, 0.041360, 0.550000, 0.727811, 0.626959, 0.626959, 0.550000, 76.800003 }; float Turquoise[] = { 0.100000, 0.187250, 0.174500, 0.800000, 0.396000, 0.741510, 0.691020, 0.800000, 0.297254, 0.308290, 0.306678, 0.800000, 12.800000 }; float Black_Plastic[] = { 0.000000, 0.000000, 0.000000, 1.000000, 0.010000, 0.010000, 0.010000, 1.000000, 0.500000, 0.500000, 0.500000, 1.000000, 32.000000 }; float Black_Rubber[] = { 0.020000, 0.020000, 0.020000, 1.000000, 0.010000, 0.010000, 0.010000, 1.000000, 0.400000, 0.400000, 0.400000, 1.000000, 10.000000 };

// Program 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 "Material.h" #pragma comment( linker, "/entry:\"mainCRTStartup\"" ) // set the entry point to be main() typedef struct _cell { int id; int x, y;

Page 46: Tutorial Open GL (Listing Code)

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" }, }; 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

Page 47: Tutorial Open GL (Listing Code)

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] = { { 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" }, { 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

Page 48: Tutorial Open GL (Listing Code)

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

Page 49: Tutorial Open GL (Listing Code)

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

Page 50: Tutorial Open GL (Listing Code)

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++) {/* 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; }

Page 51: Tutorial Open GL (Listing Code)

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

Page 52: Tutorial Open GL (Listing Code)

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

Page 53: Tutorial Open GL (Listing Code)

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

Page 54: Tutorial Open GL (Listing Code)

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

Page 55: Tutorial Open GL (Listing Code)

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

Page 56: Tutorial Open GL (Listing Code)

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

Page 57: Tutorial Open GL (Listing Code)

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

Page 58: Tutorial Open GL (Listing Code)

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

Page 59: Tutorial Open GL (Listing Code)

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 =""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."); }

Page 60: Tutorial Open GL (Listing Code)

glutSwapBuffers(); } void material_display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3ub(255, 255, 255); lighting_display(); 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]); cell_draw(&material_Se); if (!selection) { glColor3ub(255, 255, 0); drawstr(10, 525,"Click on the arguments and move the mouse to modify values."); }

Page 61: Tutorial Open GL (Listing Code)

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

Page 62: Tutorial Open GL (Listing Code)

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

Page 63: Tutorial Open GL (Listing Code)

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

Page 64: Tutorial Open GL (Listing Code)

glutSetWindow(command); glutPostRedisplay(); glutSetWindow(world); world_reshape(sub_width, sub_height); glutPostRedisplay(); glutSetWindow(screen); screen_reshape(sub_width, sub_height); glutPostRedisplay(); } 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);

Page 65: Tutorial Open GL (Listing Code)

glutDisplayFunc(lmodel_display); break; case 27: exit(0); } 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); glutCreateMenu(screen_menu); glutAddMenuEntry("Models", 0); glutAddMenuEntry("", 0);

Page 66: Tutorial Open GL (Listing Code)

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. Lighting Position

/* lightposition.c Nate Robins, 1997 Tool for teaching about OpenGL light positioning. */ #include <math.h> #include <stdio.h> #include <stdlib.h> #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;

Page 67: Tutorial Open GL (Listing Code)

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

Page 68: Tutorial Open GL (Listing Code)

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); } 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/dolphins.obj"); if (!pmodel) exit(0);

Page 69: Tutorial Open GL (Listing Code)

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

Page 70: Tutorial Open GL (Listing Code)

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

Page 71: Tutorial Open GL (Listing Code)

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)/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; lookat[5].value = 0.0; lookat[6].value = 0.0;

Page 72: Tutorial Open GL (Listing Code)

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

Page 73: Tutorial Open GL (Listing Code)

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

Page 74: Tutorial Open GL (Listing Code)

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

Page 75: Tutorial Open GL (Listing Code)

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); } redisplay_all(); } void command_reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, width, height, 0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0.0, 0.0, 0.0, 0.0); } void command_display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3ub(255, 255, 255); setfont("helvetica", 18); if (swapped) { lookat[0].y = 120; lookat[1].y = 120; lookat[2].y = 120; lookat[3].y = 120+40; lookat[4].y = 120+40; lookat[5].y = 120+40; lookat[6].y = 120+80; lookat[7].y = 120+80; lookat[8].y = 120+80; } else {

Page 76: Tutorial Open GL (Listing Code)

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

Page 77: Tutorial Open GL (Listing Code)

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

Page 78: Tutorial Open GL (Listing Code)

glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize(512+GAP*3, 512+GAP*3); glutInitWindowPosition(50, 50); glutInit(&argc, argv); 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; }

Program 19. Vertex Animation

Page 79: Tutorial Open GL (Listing Code)

//Program 19 Vertex Animation #include<windows.h> #include<math.h>// Math Library Header File #include<stdio.h> #include<stdlib.h> #include<string.h> #include<stdarg.h> #include<GL/glut.h> #include<GL/GLAUX.H> float points[45][45][3]; // The Array For The Points On The Grid Of Our "Wave" int wiggle_count = 0; // Counter Used To Control How Fast Flag Waves GLfloat xrot; // X Rotation ( NEW ) GLfloat yrot; // Y Rotation ( NEW ) GLfloat zrot; // Z Rotation ( NEW ) GLfloat hold; // Temporarily Holds A Floating Point Value GLuint texture[1]; // Storage For One Texture ( NEW ) AUX_RGBImageRec *LoadBMP( char *Filename) // Loads A Bitmap Image { FILE *File=NULL; // File Handle if (!Filename) // Make Sure A Filename Was Given { return NULL; // If Not Return NULL } File=fopen(Filename,"r"); // Check To See If The File Exists if (File) // Does The File Exist? { fclose(File); // Close The Handle return auxDIBImageLoadA(Filename); // Load The Bitmap And Return A Pointer } return NULL; } int LoadGLTextures() // Load Bitmaps And Convert To Textures { int Status=FALSE; // Status Indicator AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture memset(TextureImage,0,sizeof ( void *)*1); // Set The Pointer To NULL // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit

Page 80: Tutorial Open GL (Listing Code)

if (TextureImage[0]=LoadBMP("aila.bmp")) { Status=TRUE; // Set The Status To TRUE glGenTextures(1, &texture[0]); // Create The Texture // Typical Texture Generation Using Data From The Bitmap glBindTexture(GL_TEXTURE_2D, texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); } if (TextureImage[0]) // If Texture Exists { if (TextureImage[0]->data) // If Texture Image Exists { free(TextureImage[0]->data); // Free The Texture Image Memory } free(TextureImage[0]); // Free The Image Structure } return Status; // Return The Status } void resize(GLsizei width, GLsizei height) // Resize And Initialize The GL Window { if (height==0) // Prevent A Divide By Zero By { height=5; // Making Height Equal One } glViewport(0,0,width,height); // Reset The Current Viewport glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrix } int init(GLvoid) // All Setup For OpenGL Goes Here

Page 81: Tutorial Open GL (Listing Code)

{ if (!LoadGLTextures()) // Jump To Texture Loading Routine ( NEW ) { return FALSE; // If Texture Didn't Load Return FALSE } glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW ) glShadeModel(GL_SMOOTH); // Enable Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background glClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations glPolygonMode( GL_BACK, GL_FILL ); // Back Face Is Solid glPolygonMode( GL_FRONT, GL_LINE ); // Front Face Is Made Of Lines for (int x=0; x<45; x++) { for ( int y=0; y<45; y++) { points[x][y][0]=float ((x/5.0f)-4.5f); points[x][y][1]=float ((y/5.0f)-4.5f); points[x][y][2]=float (sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f)); } } return TRUE; // Initialization Went OK } void mydisplay(GLvoid) // Here's Where We Do All The Drawing { int x, y; float float_x, float_y, float_xb, float_yb; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer glLoadIdentity(); // Reset The View glTranslatef(0.0f,0.0f,-12.0f); glRotatef(xrot,1.0f,0.0f,0.0f); glRotatef(yrot,0.0f,1.0f,0.0f); glRotatef(zrot,0.0f,0.0f,1.0f); glBindTexture(GL_TEXTURE_2D, texture[0]); glBegin(GL_QUADS); for ( x = 0; x < 44; x++ ) { for ( y = 0; y < 44; y++ )

Page 82: Tutorial Open GL (Listing Code)

{ float_x = float (x)/44.0f; float_y = float (y)/44.0f; float_xb = float (x+1)/44.0f; float_yb = float (y+1)/44.0f; glTexCoord2f( float_x, float_y); glVertex3f( points[x][y][0], points[x][y][1], points[x][y][2] ); glTexCoord2f( float_x, float_yb ); glVertex3f( points[x][y+1][0], points[x][y+1][1], points[x][y+1][2] ); glTexCoord2f( float_xb, float_yb ); glVertex3f( points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2] ); glTexCoord2f( float_xb, float_y ); glVertex3f( points[x+1][y][0], points[x+1][y][1], points[x+1][y][2] ); } } glEnd(); if( wiggle_count == 2 ) { for ( y = 0; y < 45; y++ ) { hold=points[0][y][2]; for ( x = 0; x < 44; x++) { points[x][y][2] = points[x+1][y][2]; } points[44][y][2]=hold; } wiggle_count = 0; } wiggle_count++; xrot+=0.3f; yrot+=0.2f; zrot+=0.4f; glFlush(); glutSwapBuffers(); } void myTimeOut( int id) { // called if timer event // ...advance the state of animation incrementally... //rot+=1; glutPostRedisplay(); // request redisplay glutTimerFunc(15, myTimeOut, 0); // request next timer event } void myKeyboard(unsigned char key, int x, int y) { }

Page 83: Tutorial Open GL (Listing Code)

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("Vertex Animation Aila"); // callbacks glutDisplayFunc(mydisplay); glutKeyboardFunc(myKeyboard); glutSpecialFunc(mySpecialKeyboard); glutTimerFunc(100, myTimeOut, 0); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }