功能: when press "c" ------ circle
"s" ------ cube with color
"t" ------ triaggle
"m" ----- cube with texture
when press "r" ----- above primitive will rotate around y axis
代码 :
#include <GL/glut.h> #include <stdlib.h> #include "FreeImage.h" #include <math.h> #include <stdio.h> #include <string.h> #define PI 3.14159265358979323846 static float rotAngle = 0.0; static int iFlag=1; static GLuint texture[1]; // Storage For One Texture ( NEW ) GLuint Texture; void output(int x, int y, float r, float g, float b, int font, char *string) { glColor3f( r, g, b ); glRasterPos2f(x, y); int len, i; len = (int)strlen(string); for (i = 0; i < len; i++) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, string[i]); } } GLuint loadBMP_custom(const char * imagepath){ printf("Reading image %s\n", imagepath); // Data read from the header of the BMP file unsigned char header[54]; unsigned int dataPos; unsigned int imageSize; unsigned int width, height; // Actual RGB data unsigned char * data; unsigned char tempRGB; // Open the file FILE * file = fopen(imagepath,"rb"); if (!file) {printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); getchar(); return 0;} // Read the header, i.e. the 54 first bytes // If less than 54 bytes are read, problem if ( fread(header, 1, 54, file)!=54 ){ printf("Not a correct BMP file\n"); return 0; } // A BMP files always begins with "BM" if ( header[0]!='B' || header[1]!='M' ){ printf("Not a correct BMP file\n"); return 0; } // Make sure this is a 24bpp file if ( *(int*)&(header[0x1E])!=0 ) {printf("Not a correct BMP file\n"); return 0;} if ( *(int*)&(header[0x1C])!=24 ) {printf("Not a correct BMP file\n"); return 0;} // Read the information about the image dataPos = *(int*)&(header[0x0A]); imageSize = *(int*)&(header[0x22]); width = *(int*)&(header[0x12]); height = *(int*)&(header[0x16]); // Some BMP files are misformatted, guess missing information if (imageSize==0) imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component if (dataPos==0) dataPos=54; // The BMP header is done that way // Create a buffer data = new unsigned char [imageSize]; // Read the actual data from the file into the buffer fread(data,1,imageSize,file); //swap R and B for(int imageIdx=0;imageIdx<imageSize;imageIdx+=3) { tempRGB = data[imageIdx]; data[imageIdx] = data[imageIdx + 2]; data[imageIdx + 2] = tempRGB; } // Everything is in memory now, the file wan be closed fclose (file); // Create one OpenGL texture &texture[0] GLuint textureID; glGenTextures(1, &textureID); // "Bind" the newly created texture : all future texture functions will modify this texture glBindTexture(GL_TEXTURE_2D, textureID); // Give the image to OpenGL glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); // OpenGL has now copied the data. Free our own version delete [] data; // Poor filtering, or ... //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // ... nice trilinear filtering. //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Return the ID of the texture we just created return textureID; } int LoadGLTextures() // Load Bitmaps And Convert To Textures { int Status=FALSE; // Status Indicator //image format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; //pointer to the image, once loaded FIBITMAP *dib=NULL; //pointer to the image data BYTE* bits=NULL; //image width and height unsigned int width, height; FreeImage_Initialise(FALSE); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //musu003.png //xiaoai0004.bmp //489.png fif = FreeImage_GetFileType("./48901.png", 0); //if still unknown, try to guess the file format from the file extension if(fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename("./48901.png"); //if still unkown, return failure if(fif == FIF_UNKNOWN) return Status; //check that the plugin has reading capabilities and load the file if(FreeImage_FIFSupportsReading(fif)) dib = FreeImage_Load(fif, "./48901.png",0); //if the image failed to load, return failure if(!dib) { //output(10,10,1.0,1.0,1.0,5,"read file error."); printf("read file error."); return Status; } printf("reach here. \n"); //retrieve the image data bits = FreeImage_GetBits(dib); //get the image width and height width = FreeImage_GetWidth(dib); height = FreeImage_GetHeight(dib); unsigned bpp = FreeImage_GetBPP(dib); //if this somehow one of these failed (they shouldn't), return failure if((bits == 0) || (width == 0) || (height == 0)) return Status; printf("already get width and height. \n"); unsigned int bytePerPixel=bpp/8; //每像素占多少字节 printf("bytePerPixel is %d , width is %d , height is %d \n" ,bytePerPixel,width,height); //bit的数据格式是BGR,B和R应该交换过来 //for(int imageIdx=0;imageIdx<(width*height*bytePerPixel);imageIdx+=bytePerPixel) //{ // unsigned char tempRGB=bits[imageIdx]; // bits[imageIdx]=bits[imageIdx+2]; // bits[imageIdx+2]=tempRGB; //} Status=TRUE; glGenTextures(1, &texture[0]); // Create The Texture // Typical Texture Generation Using Data From The Bitmap glBindTexture(GL_TEXTURE_2D, texture[0]); //倒数第三个参数是GL_RGBA,因为这里用的png图,bpp=32,如果用的jpg图,bpp=24,则此参数应为GL_RGB //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits); //original is GL_UNSIGNED_BYTE //change to GLubyte glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); return Status; // Return The Status } void init(void) { //if (!LoadGLTextures()) // Jump To Texture Loading Routine ( NEW ) //{ // return ; // If Texture Didn't Load Return FALSE //} glClearColor (0.0, 0.0, 0.0, 0.0); Texture = loadBMP_custom("48901.bmp"); //glEnable(GL_TEXTURE_2D); //glShadeModel (GL_FLAT); glShadeModel(GL_SMOOTH); glClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do } void draw_triangle(void) { glDisable(GL_TEXTURE_2D); glClearColor(0.0,0.0,0.0,0.0); glBegin (GL_LINE_LOOP); glVertex2f(0.0, 1.0); glVertex2f(1.0, -1.0); glVertex2f(-1.0, -1.0); glEnd(); } void draw_circle(void) { glDisable(GL_TEXTURE_2D); glBegin(GL_LINE_LOOP); for(int i =0; i <= 300; i++) { double angle = 2 * PI * i / 300; double x = cos(angle); double y = sin(angle); glVertex2d(x,y); } glEnd(); } void draw_TextureCube(void) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,Texture); glBegin(GL_QUADS); // Front Face 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 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 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 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 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 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(); } void draw_cube(void) { glDisable(GL_TEXTURE_2D); glBegin(GL_QUADS); // Draw A Quad glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top) glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top) glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top) glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top) glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom) glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom) glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom) glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom) glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front) glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front) glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front) glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front) glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back) glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back) glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back) glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back) glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left) glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left) glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left) glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left) glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right) glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right) glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right) glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right) glEnd(); // Done Drawing The Quad } void display(void) { //glClear (GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClearColor(0.0,0.0,0.0,0.0); //glLoadIdentity (); glColor3f (1.0, 1.0, 1.0); glPushMatrix(); glRotatef(-rotAngle, 0.0, 0.1, 0.0); switch (iFlag) { case 1: draw_triangle(); break; case 2: //glutSolidSphere(1.0,20,16); draw_circle(); break; case 3: //glScalef (2.0, 2.0, 2.0); //glutWireCube (1.0); draw_cube(); break; case 4: //glScalef (2.0, 2.0, 2.0); //glutWireCube (1.0); draw_TextureCube(); break; default: break; } glPopMatrix(); glFlush (); } void reshape (int w, int h) { //glViewport (0, 0, (GLsizei) w, (GLsizei) h); //glMatrixMode (GL_PROJECTION); //glLoadIdentity (); //if (w <= h) // glOrtho (-50.0, 50.0, -50.0*(GLfloat)h/(GLfloat)w, // 50.0*(GLfloat)h/(GLfloat)w, -1.0, 1.0); //else // glOrtho (-50.0*(GLfloat)w/(GLfloat)h, // 50.0*(GLfloat)w/(GLfloat)h, -50.0, 50.0, -1.0, 1.0); //glMatrixMode(GL_MODELVIEW); glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0); //gluPerspective(60.0,1.0,1.5,20.0); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 'r': case 'R': rotAngle += 20.; glutPostRedisplay(); break; case 't': case 'T': rotAngle =0.0; iFlag=1; glutPostRedisplay(); break; case 's': case 'S': rotAngle =0.0; iFlag=3; glutPostRedisplay(); break; case 'c': case 'C': rotAngle =0.0; iFlag=2; glutPostRedisplay(); break; case 'm': case 'M': rotAngle =0.0; iFlag=4; glutPostRedisplay(); break; case 27: /* Escape Key */ exit(0); break; default: break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc (keyboard); glutMainLoop(); return 0; }