Annotation of thwomper-c/src/thwomper.c, revision 1.1

1.1     ! nick        1: //
        !             2: // This code was created by Jeff Molofee '99 (ported to Linux/GLUT by Richard Campbell '99)
        !             3: //
        !             4: // If you've found this code useful, please let me know.
        !             5: //
        !             6: // Visit me at www.demonews.com/hosted/nehe 
        !             7: // (email Richard Campbell at ulmont@bellsouth.net)
        !             8: //
        !             9: #include <GL/glut.h>    // Header File For The GLUT Library 
        !            10: #include <GL/gl.h>     // Header File For The OpenGL32 Library
        !            11: #include <GL/glu.h>    // Header File For The GLu32 Library
        !            12: #include <stdio.h>      // Header file for standard file i/o.
        !            13: #include <stdlib.h>     // Header file for malloc/free.
        !            14: #include <unistd.h>     // needed to sleep.
        !            15: #include <math.h>      
        !            16: 
        !            17: /* ascii code for the escape key */
        !            18: #define ESCAPE 27
        !            19: #define ZMIN -100
        !            20: #define ZMAX -12
        !            21: #define MAX_DISPLAY_TIME 5     // in seconds
        !            22: #define VER $Id$
        !            23: 
        !            24: /* The number of our GLUT window */
        !            25: int window; 
        !            26: int dir = 0;
        !            27: int fullscreen = 0;
        !            28: 
        !            29: /* floats for x rotation, y rotation, z rotation */
        !            30: float xrot, yrot, zrot;
        !            31: float zoom = ZMIN;
        !            32: float locX, locY = 0.0f;
        !            33: 
        !            34: /* storage for one texture  */
        !            35: int texture[1];
        !            36: 
        !            37: /* Image type - contains height, width, and data */
        !            38: struct Image {
        !            39:     unsigned long sizeX;
        !            40:     unsigned long sizeY;
        !            41:     char *data;        
        !            42:     float locX, locY, xrot, yrot, zrot, zoom;
        !            43:     int displayTime;   // How long have we been still for?
        !            44: };
        !            45: typedef struct Image Image;
        !            46: 
        !            47: struct Nick {
        !            48:        unsigned long X;
        !            49:        unsigned long Y;
        !            50: };
        !            51: typedef struct Nick Nick;
        !            52: 
        !            53: 
        !            54: /* Letter/Shape 3D Object */
        !            55: 
        !            56: // quick and dirty bitmap loader...for 24 bit bitmaps with 1 plane only.  
        !            57: // See http://www.dcs.ed.ac.uk/~mxr/gfx/2d/BMP.txt for more info.
        !            58: int ImageLoad(char *filename, Image *image) {
        !            59:     FILE *file;
        !            60:     unsigned long size;                 // size of the image in bytes.
        !            61:     unsigned long i;                    // standard counter.
        !            62:     unsigned short int planes;          // number of planes in image (must be 1) 
        !            63:     unsigned short int bpp;             // number of bits per pixel (must be 24)
        !            64:     char temp;                          // temporary color storage for bgr-rgb conversion.
        !            65:        Nick *ntest;
        !            66: 
        !            67:     // make sure the file is there.
        !            68:     if ((file = fopen(filename, "rb"))==NULL)
        !            69:     {
        !            70:        printf("File Not Found : %s\n",filename);
        !            71:        return 0;
        !            72:     }
        !            73:     
        !            74:     // seek through the bmp header, up to the width/height:
        !            75:     fseek(file, 18, SEEK_CUR);
        !            76: 
        !            77: /*
        !            78:     ntest = ( Nick * ) malloc( sizeof( Nick ) );
        !            79:     fread( &ntest.X, 4, 1, file );
        !            80: printf( " Nick's Width Test: %lu\n", ntest.X );
        !            81: */
        !            82:     // read the width
        !            83:     if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
        !            84:        printf("Error reading width from %s.\n", filename);
        !            85:        return 0;
        !            86:     }
        !            87:     printf("Width of %s: %lu\n", filename, image->sizeX);
        !            88:     
        !            89:     // read the height 
        !            90:     if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
        !            91:        printf("Error reading height from %s.\n", filename);
        !            92:        return 0;
        !            93:     }
        !            94:     printf("Height of %s: %lu\n", filename, image->sizeY);
        !            95:     
        !            96:     // calculate the size (assuming 24 bits or 3 bytes per pixel).
        !            97:     size = image->sizeX * image->sizeY * 3;
        !            98: 
        !            99:     // read the planes
        !           100:     if ((fread(&planes, 2, 1, file)) != 1) {
        !           101:        printf("Error reading planes from %s.\n", filename);
        !           102:        return 0;
        !           103:     }
        !           104:     if (planes != 1) {
        !           105:        printf("Planes from %s is not 1: %u\n", filename, planes);
        !           106:        return 0;
        !           107:     }
        !           108: 
        !           109:     // read the bpp
        !           110:     if ((i = fread(&bpp, 2, 1, file)) != 1) {
        !           111:        printf("Error reading bpp from %s.\n", filename);
        !           112:        return 0;
        !           113:     }
        !           114:     if (bpp != 24) {
        !           115:        printf("Bpp from %s is not 24: %u\n", filename, bpp);
        !           116:        return 0;
        !           117:     }
        !           118:        
        !           119:     // seek past the rest of the bitmap header.
        !           120:     fseek(file, 24, SEEK_CUR);
        !           121: 
        !           122:     // read the data. 
        !           123:     image->data = (char *) malloc(size);
        !           124:     if (image->data == NULL) {
        !           125:        printf("Error allocating memory for color-corrected image data\n");
        !           126:        return 0;       
        !           127:     }
        !           128: 
        !           129:     if ((i = fread(image->data, size, 1, file)) != 1) {
        !           130:        printf("Error reading image data from %s.\n", filename);
        !           131:        return 0;
        !           132:     }
        !           133: 
        !           134:     for (i=0;i<size;i+=3) { // reverse all of the colors. (bgr -> rgb)
        !           135:        temp = image->data[i];
        !           136:        image->data[i] = image->data[i+2];
        !           137:        image->data[i+2] = temp;
        !           138:     }
        !           139:     
        !           140:     // we're done.
        !           141:     return 1;
        !           142: }
        !           143:     
        !           144: // Load Bitmaps And Convert To Textures
        !           145: void LoadGLTextures() {        
        !           146:     // Load Texture
        !           147:     Image *image1;
        !           148:     
        !           149:     // allocate space for texture
        !           150:     image1 = (Image *) malloc(sizeof(Image));
        !           151:     if (image1 == NULL) {
        !           152:        printf("Error allocating space for image");
        !           153:        exit(0);
        !           154:     }
        !           155: 
        !           156:     if (!ImageLoad("Data/tux-128.bmp", image1)) {
        !           157:        exit(1);
        !           158:     }        
        !           159: 
        !           160:     // Create Texture  
        !           161:     glGenTextures(1, &texture[0]);
        !           162:     glBindTexture(GL_TEXTURE_2D, texture[0]);   // 2d texture (x and y size)
        !           163: 
        !           164:     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // scale linearly when image bigger than texture
        !           165:     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // scale linearly when image smalled than texture
        !           166: 
        !           167:     // 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, 
        !           168:     // border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.
        !           169:     glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->data);
        !           170: };
        !           171: 
        !           172: /* A general OpenGL initialization function.  Sets all of the initial parameters. */
        !           173: void InitGL(int Width, int Height)             // We call this right after our OpenGL window is created.
        !           174: {
        !           175:     LoadGLTextures();                          // Load The Texture(s) 
        !           176:     glEnable(GL_TEXTURE_2D);                   // Enable Texture Mapping
        !           177:     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);      // Clear The Background Color To Blue 
        !           178:     glClearDepth(1.0);                         // Enables Clearing Of The Depth Buffer
        !           179:     glDepthFunc(GL_LESS);                      // The Type Of Depth Test To Do
        !           180:     glEnable(GL_DEPTH_TEST);                   // Enables Depth Testing
        !           181:     glShadeModel(GL_SMOOTH);                   // Enables Smooth Color Shading
        !           182: //    glEnable(GL_BLEND);
        !           183:     
        !           184:     glMatrixMode(GL_PROJECTION);
        !           185:     glLoadIdentity();                          // Reset The Projection Matrix
        !           186:     
        !           187:     gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);  // Calculate The Aspect Ratio Of The Window
        !           188:     
        !           189:     glMatrixMode(GL_MODELVIEW);
        !           190: }
        !           191: 
        !           192: /* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
        !           193: void ReSizeGLScene(int Width, int Height)
        !           194: {
        !           195:     if (Height==0)                             // Prevent A Divide By Zero If The Window Is Too Small
        !           196:        Height=1;
        !           197: 
        !           198:     glViewport(0, 0, Width, Height);           // Reset The Current Viewport And Perspective Transformation
        !           199: 
        !           200:     glMatrixMode(GL_PROJECTION);
        !           201:     glLoadIdentity();
        !           202: 
        !           203:     gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,400.0f);
        !           204:     glMatrixMode(GL_MODELVIEW);
        !           205: 
        !           206:     printf( "New Width: %i\nNew Height: %i\n", Width, Height );
        !           207: }
        !           208: 
        !           209: void drawCharacter( ) {
        !           210:        glPushMatrix();
        !           211:        glColor3f(1.0, 0.0, 0.0 );
        !           212:        glTranslatef(locX, locY, zoom);
        !           213:        glRotatef(xrot, 1.0, 0.0, 0.0);
        !           214:        glRotatef(yrot, 0.0, 1.0, 0.0);
        !           215:        glRotatef(zrot, 0.0, 0.0, 1.0);
        !           216:        glutWireCube(2);
        !           217:        glPopMatrix(); //end the current object transformations
        !           218: }
        !           219: 
        !           220: /* The main drawing function. */
        !           221: void DrawGLScene()
        !           222: {
        !           223:     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);                // Clear The Screen And The Depth Buffer
        !           224:     glLoadIdentity();                          // Reset The View
        !           225: 
        !           226:     glColor3f(1.0, 1.0, 1.0 );
        !           227:     glTranslatef(locX,locY,zoom);              // move 5 units into the screen.
        !           228:     
        !           229:     glRotatef(xrot,1.0f,0.0f,0.0f);            // Rotate On The X Axis
        !           230:     glRotatef(yrot,0.0f,1.0f,0.0f);            // Rotate On The Y Axis
        !           231:     glRotatef(zrot,0.0f,0.0f,1.0f);            // Rotate On The Z Axis
        !           232: 
        !           233:     glBindTexture(GL_TEXTURE_2D, texture[0]);   // choose the texture to use.
        !           234: 
        !           235:     glBegin(GL_QUADS);                         // begin drawing a cube
        !           236:     
        !           237:     // Front Face (note that the texture's corners have to match the quad's corners)
        !           238:     glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); // Bottom Left Of The Texture and Quad
        !           239:     glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); // Bottom Right Of The Texture and Quad
        !           240:     glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f); // Top Right Of The Texture and Quad
        !           241:     glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f); // Top Left Of The Texture and Quad
        !           242:     
        !           243:     glEnd();                                    // done with the polygon.
        !           244: 
        !           245: //    xrot+=5.3f;                              // X Axis Rotation      
        !           246: //    yrot+=5.3f;                              // Y Axis Rotation
        !           247: 
        !           248:     usleep( 25000 );
        !           249:     if ( zoom <= ZMAX ) {
        !           250:        zoom += 1.85f;
        !           251:        zrot+=30.0f;
        !           252:     }
        !           253: /*
        !           254:  * Bounce our cube around
        !           255:     zrot+=1.63f;                               // Z Axis Rotation
        !           256:  
        !           257:     if ( dir ) { 
        !           258:        zoom += 0.5f;
        !           259:         if ( zoom >= ZMAX ) { dir = 0; }
        !           260:     }
        !           261:     else {
        !           262:        zoom -= 0.5f;
        !           263:        if ( zoom <= ZMIN ) { dir = 1; }
        !           264:     } 
        !           265: */
        !           266: 
        !           267:     // since this is double buffered, swap the buffers to display what just got drawn.
        !           268:     glutSwapBuffers();
        !           269: }
        !           270: 
        !           271: /* The function called whenever a key is pressed. */
        !           272: void keyPressed(unsigned char key, int x, int y) 
        !           273: {
        !           274:     /* avoid thrashing this procedure */
        !           275:     usleep(100);
        !           276: 
        !           277:        printf( "Keypressed %c\n", key );
        !           278: 
        !           279:     /* If escape is pressed, kill everything. */
        !           280:     if (key == ESCAPE) 
        !           281:     { 
        !           282:        /* shut down our window */
        !           283:        glutDestroyWindow(window); 
        !           284:       
        !           285:       /* exit the program...normal termination. */
        !           286:        exit(0);                   
        !           287:     }
        !           288:     else if ( key == '`' ) {
        !           289:        fullscreen = !fullscreen;
        !           290: 
        !           291:        if ( fullscreen ) {
        !           292:                glutFullScreen( );
        !           293:        }
        !           294:        else {
        !           295:                glutReshapeWindow(800,600);
        !           296:        }
        !           297:     }
        !           298:     else { 
        !           299:        if ( zoom >= ZMAX ) { 
        !           300:                zoom = ZMIN; 
        !           301:                locX = rand()/(((unsigned)RAND_MAX + 1) / 7.6);
        !           302:                locY = rand()/(((unsigned)RAND_MAX + 1) / 4.1);
        !           303:                if ( (int)fmod( locX, 2.0f ) ) { locX = ( locX - ( locX * 2.0f ) ) + 1.0f; }
        !           304:                if ( (int)fmod( locY, 2.0f ) ) { locY = ( locY - ( locY * 2.0f ) ) + 1.0f; }
        !           305:        }
        !           306:     }
        !           307: }
        !           308: 
        !           309: int main(int argc, char **argv) 
        !           310: {  
        !           311:     /* Initialize GLUT state - glut will take any command line arguments that pertain to it or 
        !           312:        X Windows - look at its documentation at http://reality.sgi.com/mjk/spec3/spec3.html */  
        !           313:     glutInit(&argc, argv);  
        !           314: 
        !           315:     /* Select type of Display mode:   
        !           316:      Double buffer 
        !           317:      RGBA color
        !           318:      Alpha components supported 
        !           319:      Depth buffer */  
        !           320:     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);  
        !           321: 
        !           322:     /* get a 640 x 480 window */
        !           323:     glutInitWindowSize(800, 600);  
        !           324: 
        !           325:     /* the window starts at the upper left corner of the screen */
        !           326:     glutInitWindowPosition(0, 0);  
        !           327: 
        !           328:     /* Open a window */  
        !           329:     window = glutCreateWindow("Jeff Molofee's GL Code Tutorial ... NeHe '99");  
        !           330: 
        !           331:     printf("GL_VENDOR     : %s\n", (char *) glGetString (GL_VENDOR));
        !           332:     printf("GL_RENDERER   : %s\n", (char *) glGetString (GL_RENDERER));
        !           333:     printf("GL_VERSION    : %s\n", (char *) glGetString (GL_VERSION));
        !           334:     printf("GL_EXTENSIONS : %s\n", (char *) glGetString (GL_EXTENSIONS));
        !           335: 
        !           336: 
        !           337:     /* Register the function to do all our OpenGL drawing. */
        !           338:     glutDisplayFunc(&DrawGLScene);  
        !           339: 
        !           340:     /* Go fullscreen.  This is as soon as possible. */
        !           341: //    glutFullScreen();
        !           342: 
        !           343:     /* Even if there are no events, redraw our gl scene. */
        !           344:     glutIdleFunc(&DrawGLScene);
        !           345: 
        !           346:     /* Register the function called when our window is resized. */
        !           347:     glutReshapeFunc(&ReSizeGLScene);
        !           348: 
        !           349:     /* Register the function called when the keyboard is pressed. */
        !           350:     glutKeyboardFunc(&keyPressed);
        !           351: 
        !           352:     /* Initialize our window. */
        !           353:     InitGL(800, 600);
        !           354:   
        !           355:     /* Start Event Processing Engine */  
        !           356:     glutMainLoop();  
        !           357: 
        !           358:     return 1;
        !           359: }
        !           360: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>