// Peter Bui // CSE 40166 Computer Graphics (Fall 2010) // Example 21: texture demo #include "ppm.h" #include #include #include #ifdef __APPLE__ #include #else #include #endif using namespace std; // Constants ------------------------------------------------------------------- #define WHEEL_UP 3 #define WHEEL_DOWN 4 #define CAMERA_DISTANCE_MIN 1.0 #define CAMERA_DISTANCE_MAX 50.0 // Global variables ------------------------------------------------------------ static size_t WindowWidth = 640; static size_t WindowHeight = 480; static GLint MouseX = 0; static GLint MouseY = 0; static double CameraLatitude = 5.0; static double CameraLongitude = 10.0; static double CameraDistance = 10.0; static double EyeX = 20.0; static double EyeY = 20.0; static double EyeZ = 20.0; static GLubyte *ImageBuffer; static size_t ImageWidth; static size_t ImageHeight; static GLuint ImageTextureId; // Register texture ------------------------------------------------------------ void register_texture(GLuint *tid, GLubyte *buffer, size_t width, size_t height) { glGenTextures(1, tid); glBindTexture(GL_TEXTURE_2D, *tid); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer); } // Update camera --------------------------------------------------------------- void update_camera_location() { double L = CameraDistance * cos(M_PI*CameraLongitude/180.0); EyeX = L * -sin(M_PI*CameraLatitude/180.0); EyeY = CameraDistance * sin(M_PI*CameraLongitude/180.0); EyeZ = L * cos(M_PI*CameraLatitude/180.0); glutPostRedisplay(); } // Display callback ------------------------------------------------------------ void display() { double width = (GLdouble)ImageWidth/(GLdouble)ImageHeight; double height = 1.0; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(EyeX, EyeY, EyeZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, ImageTextureId); glColor3f(1.0, 1.0, 1.0); glBegin(GL_QUADS); { glTexCoord2f(0.0, 0.0); glVertex3f(-width, -height, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f( width, -height, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f( width, height, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(-width, height, 0.0); } glEnd(); glutSwapBuffers(); } // Reshape callback ------------------------------------------------------------ void reshape(GLsizei nw, GLsizei nh) { WindowWidth = nw; WindowHeight = nh; glEnable(GL_DEPTH_TEST); glViewport(0, 0, WindowWidth, WindowHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLdouble)WindowWidth/(GLdouble)WindowHeight, 1.0, 750.0); update_camera_location(); } // Keyboard callback ----------------------------------------------------------- void keyboard(unsigned char key, int x, int y) { if (key == 'q' || key == 'Q') exit(EXIT_SUCCESS); } // Special callback ----------------------------------------------------------- void special(int key, int x, int y) { switch (key) { case GLUT_KEY_LEFT: CameraLatitude -= 1.0; break; case GLUT_KEY_RIGHT: CameraLatitude += 1.0; break; case GLUT_KEY_UP: CameraLongitude -= 1.0; break; case GLUT_KEY_DOWN: CameraLongitude += 1.0; break; } update_camera_location(); } // Mouse callback -------------------------------------------------------------- void mouse(int button, int state, int x, int y) { MouseX = x; MouseY = y; switch (button) { case WHEEL_UP: CameraDistance = (CameraDistance > CAMERA_DISTANCE_MIN ? CameraDistance - 0.5 : CAMERA_DISTANCE_MIN); break; case WHEEL_DOWN: CameraDistance = (CameraDistance < CAMERA_DISTANCE_MAX ? CameraDistance + 0.1 : CAMERA_DISTANCE_MAX); break; } update_camera_location(); } // Motion callback ------------------------------------------------------------- void motion(int x, int y) { CameraLatitude += 180.0*(double)(x - MouseX)/WindowWidth; CameraLongitude += 180.0*(double)(y - MouseY)/WindowHeight; if (CameraLongitude < -90.0) CameraLongitude = -90.0; if (CameraLongitude > 90.0) CameraLongitude = 90.0; update_camera_location(); MouseX = x; MouseY = y; } // Main execution -------------------------------------------------------------- int main(int argc, char *argv[]) { glutInit(&argc, argv); if (argc != 2) { fprintf(stderr, "use: texture_demo [ppmfile]\n"); return EXIT_FAILURE; } glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(WindowWidth, WindowHeight); glutCreateWindow("simple texture demo"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutMouseFunc(mouse); glutMotionFunc(motion); ppm_read(argv[1], &ImageBuffer, &ImageWidth, &ImageHeight); register_texture(&ImageTextureId, ImageBuffer, ImageWidth, ImageHeight); glutMainLoop(); return (EXIT_SUCCESS); } // vim: sts=4 sw=4 ts=8 ft=cpp