#include #include #include #include #include #include "bmp.h" #include "geometry.h" using namespace std; #define PI 3.14159 // function prototypes void display(void); void reshape(int width, int height); void keyboard(unsigned char key, int x, int y); void motion(int x, int y); void init(void); unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader); // viewpoint double theta=0, phi=0, distanceToViewpoint=200; // window int width=400; int height=400; // skeleton for ball class // this draws a texture mapped ball with radius // 3 sitting above the origin on the y=0 plane // your init routine should call the initialize // function to set up the golf ball class golfBall { public: golfBall() {}; ~golfBall() {}; void initializeGraphics(); void draw(); private: int hBall; // handle to the ball call list int hTexture; // handle to the ball texture void drawTexuredSphere(float radius, int slices, int stacks); }; void golfBall::draw() { glCallList(hBall); } void golfBall::initializeGraphics() { // read in the texture // the texture file name is hard coded as ball.bmp BITMAPINFOHEADER bitmapInfoHeader; // bitmap info header unsigned char* bitmapData; // the bitmap data bitmapData = LoadBitmapFile("ball.bmp", &bitmapInfoHeader); // generate texture object unsigned int hTexture; glGenTextures(1,&hTexture); // create texture glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, hTexture); // the following two commands tell openGL how to interpolate texture // values between the sampled values in your texture bitmap glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // the following two commands tell openGL how to extend the texture // when needed glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // now give it the texture map glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmapData); // initialize the list hBall = glGenLists(1); glNewList(hBall, GL_COMPILE); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, hTexture); double radius =3.0f; // radius int slices = 10; // slices and stacks int stacks = 10; // control the resolution glTranslatef(0.0f,(float) radius,0.0f); glShadeModel(GL_FLAT); glBegin(GL_QUADS); for (int i=0;i. * You should make this class a singleton!! */ class golfClub { public: void initializeGraphics(); void draw(); golfClub(); ~golfClub(); private: int hClub; // handle to the club call list int hTexture; // handle to the club texture }; golfClub::golfClub() { hClub=0; hTexture=0; } void golfClub::initializeGraphics() { // Read in the texture. // The file name is hard-coded // is hard-coded as club.bmp BITMAPINFOHEADER bitmapInfoHeader; // bitmap info header unsigned char* bitmapData; // the bitmap data bitmapData = LoadBitmapFile("club.bmp", &bitmapInfoHeader); // generate texture object unsigned int hTexture; glGenTextures(1,&hTexture); // create texture glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, hTexture); // the following two commands tell openGL how to interpolate texture // values between the sampled values in your texture bitmap glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // the following two commands tell openGL how to extend the texture // when needed glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // replace color of textured object glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // now give it the texture map glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmapData); // initialize the club display list // the geometry is created once at initialization hClub = glGenLists(1); glNewList(hClub, GL_COMPILE); // draw the shaft of the club with its texture // enable & bind the texture glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, hTexture); // position and orient the shaft glPushMatrix(); glTranslatef(1.0f, 4.0f, 0.0f); glRotatef(10.0f,0.0f,0.0f,1.0f); // create the cylinder int numStrips=10; float topRadius=2; float bottomRadius=1; float clubHeight=50; glBegin(GL_QUAD_STRIP); for (int i=0;i10) distanceToViewpoint-=10; break; case 'h': case 'H': case '?': cout << "Use 'z'/'Z' to zoom in/out" << endl; break; default: break; } glutPostRedisplay(); } /******************************************************************* * BMP reader from: Program: Chapter 7 Bitmap Example 4 * Author: Kevin Hawkins * ********************************************************************/ // LoadBitmapFile // desc: Returns a pointer to the bitmap image of the bitmap specified // by filename. Also returns the bitmap header information. // No support for 8-bit bitmaps. unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader) { FILE *filePtr; // the file pointer BITMAPFILEHEADER bitmapFileHeader; // bitmap file header unsigned char *bitmapImage; // bitmap image data unsigned int imageIdx = 0; // image index counter unsigned char tempRGB; // swap variable // open filename in "read binary" mode filePtr = fopen(filename, "rb"); if (filePtr == NULL) return NULL; // read the bitmap file header fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr); // verify that this is a bitmap by checking for the universal bitmap id if (bitmapFileHeader.bfType != BITMAP_ID) { fclose(filePtr); return NULL; } // read the bitmap information header fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr); // move file pointer to beginning of bitmap data fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET); // allocate enough memory for the bitmap image data bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage); // verify memory allocation if (!bitmapImage) { free(bitmapImage); fclose(filePtr); return NULL; } // read in the bitmap image data fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr); // make sure bitmap image data was read if (bitmapImage == NULL) { fclose(filePtr); return NULL; } // swap the R and B values to get RGB since the bitmap color format is in BGR for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3) { tempRGB = bitmapImage[imageIdx]; bitmapImage[imageIdx] = bitmapImage[imageIdx + 2]; bitmapImage[imageIdx + 2] = tempRGB; } // close the file and return the bitmap image data fclose(filePtr); return bitmapImage; } void motion(int x, int y) { static int currX=-1; static int currY=-1; if (currX>0 && abs(x-currX) < width/6 && abs(y-currY) < height/6) { phi += (double) (x-currX)/ (double) width * 3.14159; theta += (double) (y-currY)/ (double) height * 3.14159; // limit theta to -4pi/9 and 4pi/9 if (theta < -4*3.14159/9.0) theta = -4*3.14159/9.0; if (theta > 4*3.14159/9.0) theta = 4*3.14159/9.0; } currX = x; currY = y; glutPostRedisplay(); }