Annotation of thwomper-c/src/thwomper.c, revision 1.1.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>