// Tex.cpp // NKU CSC 480 - Kirby // ----------------------------------------------------------------------- // Demonstrating texture mapping. // // Requires a 256x256 24-bit .bmp file (e.g "stucco24.bmp" or "turl.bmp"). // You can use a program (like Windows Paint) to convert your favorite jpg. // ----------------------------------------------------------------------- #include #include #include "Stopwatch.h" // on course website #include "Bmp.h" // on course website using namespace std ; // Bitmap dimensions for texture mapping (must be power of 2). const int W = 256, H = 256 ; // Stopwatch for controlling animation. static Stopwatch* G_pStopwatch ; void lighting() // Set up lighting. { // Initialize lighting mechanisms. glEnable( GL_DEPTH_TEST ) ; glPolygonMode( GL_FRONT, GL_FILL ) ; glEnable( GL_NORMALIZE ) ; glEnable( GL_LIGHTING ) ; // One Phong light source. float lightPos[]= {1,1,1,0} ; // at infinity float GRAY[]= {0.7,0.7,0.7,0}, WHITE[]={1,1,1,0} ; glLightfv( GL_LIGHT0, GL_POSITION, lightPos ) ; glLightfv( GL_LIGHT0, GL_DIFFUSE, WHITE ) ; glLightfv( GL_LIGHT0, GL_AMBIENT, GRAY ) ; glEnable( GL_LIGHT0 ) ; } void projectionTrans() // Set up projection. { // Projection: slight perspective. glMatrixMode( GL_PROJECTION ) ; glLoadIdentity() ; gluPerspective( 25.0, 1, 10,14 ) ; } void viewTrans() // Set up viewing. { // View: Camera out on z axis looking toward origin. glMatrixMode( GL_MODELVIEW ) ; glLoadIdentity() ; gluLookAt( 0,0,12, 0,0,0, 0,1,0 ) ; } void modelTrans() // Set up modeling. { // Model: tumbling as a composition of rotations. glMatrixMode( GL_MODELVIEW ) ; double degrees= G_pStopwatch->getValue() * 0.04 ; glRotated( degrees, 1,1,1 ) ; glRotated( degrees, -1,1,1) ; } void texturedSquare() // Draw a 2x2 square with current texture, centered at (0,0,1) parallel xy plane. { glBegin( GL_POLYGON ) ; glNormal3d( 0,0,1 ) ; // same normal for all four vertices glTexCoord2d( 0, 0 ) ; glVertex3d( -1,-1, 1 ) ; // lower left z=1 plane glTexCoord2d( 1, 0 ) ; glVertex3d( 1,-1, 1 ) ; // lower right z=1 plane glTexCoord2d( 1, 1 ) ; glVertex3d( 1, 1, 1 ) ; // upper right z=1 plane glTexCoord2d( 0, 1 ) ; glVertex3d( -1, 1, 1 ) ; // upper left z=1 plane glEnd() ; } void texturedCube() // Textured cube with corners at +/- 1.0. Made out of 6 textured squares. { glEnable( GL_TEXTURE_2D ); texturedSquare() ; // +z face glPushMatrix() ; glRotated( 180, 0,1,0 ) ; texturedSquare() ; // -z face glPopMatrix() ; glPushMatrix() ; glRotated( 90, 0,1,0 ) ; texturedSquare() ; // +x face glPopMatrix() ; glPushMatrix() ; glRotated( -90, 0,1,0 ) ; texturedSquare() ; // -x face glPopMatrix() ; glPushMatrix() ; glRotated( 90, 1,0,0 ) ; texturedSquare() ; // +y face glPopMatrix() ; glPushMatrix() ; glRotated( -90, 1,0,0 ) ; texturedSquare() ; // -y face glPopMatrix() ; glDisable(GL_TEXTURE_2D); } void display() // Display the scene: a rotating cube. { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ; viewTrans() ; modelTrans() ; texturedCube() ; glutSwapBuffers() ; } void animate() // One frame of animation. { glutPostRedisplay() ; } void toggleAnimation() // Toggle animation on and off. { if ( G_pStopwatch->isStopped() ) { G_pStopwatch->start() ; glutIdleFunc( animate ) ; } else { G_pStopwatch->stop() ; glutIdleFunc( NULL ) ; } } void kbDispatch( unsigned char ch, int x, int y ) // Space bar toggles animation. { if ( ch == ' ' ) toggleAnimation() ; glutPostRedisplay() ; } void initTextureMapping( GLubyte img[W][H][3] ) // Define how the texture is to be mapped to polygons. { // Set current texture to img[][][]. glTexImage2D( GL_TEXTURE_2D, 0, 3, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, img ) ; // Repeat the texture outside when texture coordinates exceed [0,1]^2. glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); // Optimal handling of magnification and minimization with perspective. glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) ; glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ) ; } void getTextureFromBMP( GLubyte img[W][H][3], const string& bmpfilename ) // Load a bitmap from a 24-bit *.bmp file into the OpenGL-style "texture array" img[][][]. { Bmp bmp( bmpfilename ) ; assert( W <= bmp.getWidth() && H <= bmp.getHeight() ) ; for ( int i=0 ; i < H ; ++i ) for ( int j=0 ; j < W ; ++j ) bmp.getPixel( i,j, img[i][j] ) ; } int main( int argc, char** argv ) { // Initialize OpenGL. glutInit( &argc, argv ) ; glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH ) ; // Window attributes. glutInitWindowSize( 700, 700 ) ; glutInitWindowPosition( 100, 100 ) ; glutCreateWindow( "Tex" ) ; // Register callbacks. glutKeyboardFunc( kbDispatch ) ; glutDisplayFunc( display ) ; glutIdleFunc( animate ) ; // Initialize animation motor, initially on. G_pStopwatch= new Stopwatch ; G_pStopwatch->start() ; // Texture from file. GLubyte img[H][W][3] ; // OpenGL style texture array getTextureFromBMP( img, "stucco24.bmp" ) ; initTextureMapping( img ) ; // Set up fixed light source and perspective. lighting() ; projectionTrans() ; // Go. glutMainLoop() ; return 0 ; }