// mytest2.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include #include #include "shaders.h" #include "geometry.h" int mouseoldx, mouseoldy ; // For mouse motion GLdouble eyeloc = 2.0 ; // Where to look from; initially 0 -2, 2 GLfloat teapotloc = -0.5 ; // ** NEW ** where the teapot is located GLint animate = 0 ; // ** NEW ** whether to animate or not GLuint vertexshader, fragmentshader, shaderprogram ; // shaders const int DEMO = 0 ; // ** NEW ** To turn on and off features void display(void) { // clear all pixels // If (DEMO >= 2) also clear the depth buffer if (DEMO >= 2) glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ; else glClear (GL_COLOR_BUFFER_BIT); // draw white polygon (square) of unit length centered at the origin // Note that vertices must generally go counterclockwise // Change from the first program, in that I just made it white. // The old OpenGL code of using glBegin... glEnd no longer appears. // The new version uses vertex buffer objects from init. // Does the order of drawing matter? What happens if I draw the ground // after the pillars? I will show this in class drawobject(FLOOR) ; // Now draw several cubes with different transforms, colors // I continue to use the deprecated push-pop and matrix mode // Since it is convenient (or you have to write your own stack). if (DEMO > 0) { glMatrixMode(GL_MODELVIEW) ; // 1st pillar glPushMatrix() ; glTranslatef(-0.4,-0.4,0.0) ; drawcolor(CUBE, 0) ; glPopMatrix() ; // 2nd pillar glPushMatrix() ; glTranslatef(0.4,-0.4,0.0) ; drawcolor(CUBE, 1) ; glPopMatrix() ; // 3rd pillar glPushMatrix() ; glTranslatef(0.4,0.4,0.0) ; drawcolor(CUBE, 2) ; glPopMatrix() ; // 4th pillar glPushMatrix() ; glTranslatef(-0.4,0.4,0.0) ; drawcolor(CUBE, 3) ; glPopMatrix() ; } // Draw the glut teapot // This is using deprecated old-style OpenGL certainly if (DEMO >= 3) { // ** NEW ** Put a teapot in the middle that animates glColor3f(0.0,1.0,1.0) ; // Deprecated command to set the color glPushMatrix() ; // I now transform by the teapot translation for animation */ glTranslatef(teapotloc, 0.0, 0.0) ; // The following two transforms set up and center the teapot // Remember that transforms right-multiply the stack glTranslatef(0.0,0.0,0.1) ; glRotatef(90.0,1.0,0.0,0.0) ; glutSolidTeapot(0.15) ; glPopMatrix() ; } // Does order of drawing matter? // What happens if I draw the ground after the pillars? // I will show this in class. // drawobject(FLOOR) ; // don't wait! // start processing buffered OpenGL routines if (DEMO >= 2) glutSwapBuffers() ; glFlush (); } // ** NEW ** in this assignment, is an animation of a teapot // Hitting p will pause this animation; see keyboard callback void animation(void) { teapotloc = teapotloc + 0.005 ; if (teapotloc > 0.5) teapotloc = -0.5 ; glutPostRedisplay() ; } // Defines a Mouse callback to zoom in and out // This is done by modifying gluLookAt // The actual motion is in mousedrag // mouse simply sets state for mousedrag void mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON) { if (state == GLUT_UP) { // Do Nothing ; } else if (state == GLUT_DOWN) { mouseoldx = x ; mouseoldy = y ; // so we can move wrt x , y } } else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { // Reset gluLookAt eyeloc = 2.0 ; glMatrixMode(GL_MODELVIEW) ; glLoadIdentity() ; gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ; glutPostRedisplay() ; } } void mousedrag(int x, int y) { int yloc = y - mouseoldy ; // We will use the y coord to zoom in/out eyeloc += 0.005*yloc ; // Where do we look from if (eyeloc < 0) eyeloc = 0.0 ; mouseoldy = y ; /* Set the eye location */ glMatrixMode(GL_MODELVIEW) ; glLoadIdentity() ; gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ; glutPostRedisplay() ; } // Defines what to do when various keys are pressed void keyboard (unsigned char key, int x, int y) { switch (key) { case 27: // Escape to quit exit(0) ; break ; case 'p': // ** NEW ** to pause/restart animation animate = !animate ; if (DEMO >= 3) { if (animate) glutIdleFunc(animation) ; else glutIdleFunc(NULL) ; } break ; default: break ; } } /* Reshapes the window appropriately */ void reshape(int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Think about the rationale for this choice for gluPerspective // What would happen if you changed near and far planes? gluPerspective(30.0, (GLdouble)w/(GLdouble)h, 1.0, 10.0) ; } void init (void) { /* select clearing color */ glClearColor (0.0, 0.0, 0.0, 0.0); /* initialize viewing values */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Think about this. Why is the up vector not normalized? glMatrixMode(GL_MODELVIEW) ; glLoadIdentity() ; gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ; // Set up the Geometry for the scene. // From OpenGL book pages 103-109 glGenBuffers(numperobj*numobjects+ncolors, buffers) ; initcolorscube() ; initobject(FLOOR, (GLfloat *) floorverts, sizeof(floorverts), (GLfloat *) floorcol, sizeof (floorcol), (GLubyte *) floorinds, sizeof (floorinds), GL_POLYGON) ; // initobject(CUBE, (GLfloat *) cubeverts, sizeof(cubeverts), (GLfloat *) cubecol, sizeof (cubecol), (GLubyte *) cubeinds, sizeof (cubeinds), GL_QUADS) ; initobjectnocol(CUBE, (GLfloat *) cubeverts, sizeof(cubeverts), (GLubyte *) cubeinds, sizeof (cubeinds), GL_QUADS) ; if (DEMO >= 2) { // Enable the depth test glEnable(GL_DEPTH_TEST) ; glDepthFunc (GL_LESS) ; // The default option } //initshaders(GL_VERTEX_SHADER, "shaders/nop.vert") ; //initshaders(GL_FRAGMENT_SHADER, "shaders/nop.frag") ; vertexshader = initshaders(GL_VERTEX_SHADER, "shaders/nop.vert") ; fragmentshader = initshaders(GL_FRAGMENT_SHADER, "shaders/nop.frag") ; shaderprogram = initprogram(vertexshader, fragmentshader) ; } int _tmain(int argc, char ** argv) { glutInit(&argc, argv); // Requests the type of buffers (Single, RGB). // Think about what buffers you would need... // Request the depth if needed, later swith to double buffer if (DEMO >= 2) glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); else glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB) ; glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow ("Simple Demo with Shaders"); GLenum err = glewInit() ; printf("err is %d\n GLEW_OK is %d\n", err, GLEW_OK) ; if (GLEW_OK != err) { std::cerr << "Error: " << glewGetString(err) << std::endl; } init (); // Always initialize first // Now, we define callbacks and functions for various tasks. glutDisplayFunc(display); glutReshapeFunc(reshape) ; glutKeyboardFunc(keyboard); glutMouseFunc(mouse) ; glutMotionFunc(mousedrag) ; glutMainLoop(); // Start the main code return 0; /* ANSI C requires main to return int. */ }