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

Tutorial Open GL (Listing Code)

Dec 25, 2014

Download

Education

Aila Gema

Task of Graphic and Programming Computer
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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; }