// Some of you might be wondering about animating your textures. Well I have // some bad news for you. OpenGL does not support texture animation. So you // will have no luck loading in a Gif or Movie file into your application and // rendering it straight to your shape. But I also have some good news. There are // ways around this. And I am going to show you the way that I know. // Now my way consists of creating a different image file for every frame in your // animation. If you have a gif file, you can probably find an exporter through a // quick search on the internet to render out every frame from your animation. // So why don't we get started. // I am only adding one extra variable which will control which frame we are // currently displaying for our animation. You will probably need another // variable for each animation you wish you use. And this variable is simple // enough to call. I am just using: // double frame; // Now we don't have to set our frame to 0 at the start of our application // because if we do not set a value, it will default to 0. // So far so good? // After that I am then loading every frame when the application loads as a // new part of the texture array. There are 9 files in total, so I am loading // them as 0-8 in my array. // texture[0] = LoadTextureRAW( "textures/1.raw", 256, 256 ); // texture[1] = LoadTextureRAW( "textures/2.raw", 256, 256 ); // texture[2] = LoadTextureRAW( "textures/3.raw", 256, 256 ); // texture[3] = LoadTextureRAW( "textures/4.raw", 256, 256 ); // texture[4] = LoadTextureRAW( "textures/5.raw", 256, 256 ); // texture[5] = LoadTextureRAW( "textures/6.raw", 256, 256 ); // texture[6] = LoadTextureRAW( "textures/7.raw", 256, 256 ); // texture[7] = LoadTextureRAW( "textures/8.raw", 256, 256 ); // texture[8] = LoadTextureRAW( "textures/9.raw", 256, 256 ); // Now if we go to our display function, this is where we are going to set the // texture to our quad. I am simply calling our Texture array as the texture, with // the array number being which frame of the animation we are on. The (int) is to // set our frame to an integer. // glBindTexture( GL_TEXTURE_2D, texture[(int)frame] ); // Then I am going to add at the bottom of our display function, the code // that will update which frame we are currently on for the current animation. // So our function will look like: // Here we are increasing which frame of the animation we are on each pass of the // display function. Changing this number will change the speed of the animation. // frame+=0.2; // Now I am checking to see if the frame is above the maximum, and if it is, // change it back to the first frame for a steady loop. // if (frame > 8) // { // frame = 1; // } // And if you run this you will have an animation of a man whose arms spin around. // Well, have fun, but keep in mind that this can be time consuming. And I don't // really see a use for it at this point in time. // If you have any questions, email me at swiftless@gmail.com. #include #include #include #include GLuint texture[8]; double frame; GLuint LoadTexture( const char * filename, int width, int height ) { GLuint texture; unsigned char * data; FILE * file; //The following code will read in our RAW file file = fopen( filename, "rb" ); if ( file == NULL ) return 0; data = (unsigned char *)malloc( width * height * 3 ); fread( data, width * height * 3, 1, file ); fclose( file ); glGenTextures( 1, &texture ); //generate the texture with the loaded data glBindTexture( GL_TEXTURE_2D, texture ); //bind the texture to it's array glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); //set texture environment parameters //here we are setting what textures to use and when. The MIN filter is which quality to show //when the texture is near the view, and the MAG filter is which quality to show when the texture //is far from the view. //The qualities are (in order from worst to best) //GL_NEAREST //GL_LINEAR //GL_LINEAR_MIPMAP_NEAREST //GL_LINEAR_MIPMAP_LINEAR //And if you go and use extensions, you can use Anisotropic filtering textures which are of an //even better quality, but this will do for now. glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR ); //Here we are setting the parameter to repeat the texture instead of clamping the texture //to the edge of our shape. glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); //Generate the texture with mipmaps gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data ); free( data ); //free the texture return texture; //return whether it was successfull } void FreeTexture( GLuint texture ) { glDeleteTextures( 1, &texture ); } void cube (void) { glBindTexture( GL_TEXTURE_2D, texture[(int)frame] ); glScalef(2,2,1); glBegin (GL_QUADS); glTexCoord2d(0,0); glVertex3f(-1,1,0); glTexCoord2d(1,0); glVertex3f(1,1,0); glTexCoord2d(1,1); glVertex3f(1,-1,0); glTexCoord2d(0,1); glVertex3f(-1,-1,0); glEnd(); } void display (void) { glClearColor (0.0,0.0,0.0,1.0); glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity(); glEnable( GL_TEXTURE_2D ); glTranslatef(0,0,-5); cube(); glutSwapBuffers(); frame+=0.2; if (frame > 8) { frame = 1; } } void reshape (int w, int h) { glViewport (0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0); glMatrixMode (GL_MODELVIEW); } void init (void) { texture[0] = LoadTexture( "textures/1.raw", 256, 256 ); texture[1] = LoadTexture( "textures/2.raw", 256, 256 ); texture[2] = LoadTexture( "textures/3.raw", 256, 256 ); texture[3] = LoadTexture( "textures/4.raw", 256, 256 ); texture[4] = LoadTexture( "textures/5.raw", 256, 256 ); texture[5] = LoadTexture( "textures/6.raw", 256, 256 ); texture[6] = LoadTexture( "textures/7.raw", 256, 256 ); texture[7] = LoadTexture( "textures/8.raw", 256, 256 ); texture[8] = LoadTexture( "textures/9.raw", 256, 256 ); } int main (int argc, char **argv) { glutInit (&argc, argv); glutInitDisplayMode (GLUT_DOUBLE); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow ("A basic OpenGL Window"); init(); glutDisplayFunc (display); glutIdleFunc (display); glutReshapeFunc (reshape); glutMainLoop (); return 0; }