230 likes | 357 Views
Chapter 2 – Making them Move with OpenGL. Dr. Paige H. Meeker CSC 458. Composing Transformations. In your homework, you were to find a matrix that combined transformations Were you able to do it? Did you find any facts to be true?. Composing Transformations.
E N D
Chapter 2 – Making them Move with OpenGL Dr. Paige H. Meeker CSC 458
Composing Transformations • In your homework, you were to find a matrix that combined transformations • Were you able to do it? • Did you find any facts to be true?
Composing Transformations • We can represent the effects of transforms by two matrices in a single matrix of the same size by multiplying the two matrices: M = RS • It is important to remember that these transformations are applied right side first. So M=RS first applies S, then R. • Matrix multiplication is not commutative. Order of transformations DOES matter. Scaling then rotating is different from rotating then scaling. (Do a sanity check.)
Composing Transformations • Need to take a minute to rework that homework? We should have some time at the end of class!
Getting Ready • Before we begin using the OpenGL commands for translating, scaling, and rotating objects, we must first apply the identity matrix to the problem. • This sets the transformation state in the object space to have no transformation is being applied. glLoadIdentity() • We do this because we do not wish to reuse old transformation states.
Translation • Transformations are applied when we want to move something • The floating-point routine for performing translations in OpenGL is: glTranslatef(Tx, Ty, Tz) • It accepts three arguments for translation along the x-, y-, and z-axes. • The z-axis is used for 3D worlds, and we can ignore it for now by setting the Tz value to be 0.
Bouncing a Ball • The example from your author is to move a circle up and down – i.e. “bounce a ball”. • Then, we constantly add (or subtract) to the ty component along the y-axis, and draw the ball in this newly transformed position.
Bouncing a Ball //Example2_1.cpp : A bouncing ball #include <windows.h> //the windows include file, required by all windows applications #include <math.h> // Math libraries for cos and sin functions #include <gl\glut.h> //the glut file for windows operations // it also includes gl.h and glu.h for the openGL library calls
Bouncing a Ball double xpos, ypos, ydir, xdir; // x and y position for ball to be drawn int SPEED = 50; // speed of timer call back in msecs #define PI 3.1415926535898 GLintcircle_points = 100;
Bouncing a Ball void MyCircle2f(GLfloatcenterx, GLfloatcentery, GLfloat radius){ GLinti; GLdouble angle; glBegin(GL_POLYGON); for (i = 0; i < circle_points; i++) { angle = 2*PI*i/circle_points; glVertex2f(centerx+radius*cos(angle), centery+radius*sin(angle)); } glEnd(); }
Bouncing a Ball GLfloatRadiusOfBall = 15.; // Draw the ball, centered at the origin void draw_ball() { glColor3f(0.6,0.3,0.); MyCircle2f(0.,0.,RadiusOfBall); }
Bouncing a Ball void Display(void) { glClear(GL_COLOR_BUFFER_BIT); //clear all pixels with the specified clear color // 160 is max X value in our world xpos = 80.; // Define X position of the ball to be at center of window // 120 is max Y value in our world ypos = ypos+ydir *1.5; // set Y position to increment 1.5 times the direction of the bounce if (ypos == 120-RadiusOfBall) // If ball touches the top, change direction of ball downwards ydir = -1; else if (ypos <RadiusOfBall) // If ball touches the bottom, change direction of ball upwards ydir = 1; glLoadIdentity(); //reset transformation state glTranslatef(xpos,ypos, 0.); // apply translation draw_ball(); // draw the ball glutSwapBuffers(); // swap the buffers glutPostRedisplay(); }
Bouncing a Ball void reshape (int w, int h) { // on reshape and on startup, keep the viewport to be the entire size of the window glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); // keep our logical coordinate system constant gluOrtho2D(0.0, 160.0, 0.0, 120.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity (); }
Bouncing a Ball void init(void){ //set the clear color to be white glClearColor(0.0,0.8,0.0,1.0); // initial ball position set to 0,0 xpos = 60; ypos = RadiusOfBall; xdir = 1; ydir = 1; }
Bouncing a Ball void main(intargc, char* argv[]) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (320, 240); glutCreateWindow("Bouncing Ball"); init(); glutDisplayFunc(Display); glutReshapeFunc(reshape); glutMainLoop(); }
Making Animations Smooth • The previous code will be a little “jumpy.” • To keep animations smooth we use the “double buffering” technique. • The foreground buffer is what is displayed on the screen. • The background buffer is what is used to draw into – then the two are switched. • It will appear almost instantaneous.
Double Buffering To use double buffering, you need to activate it by specifying the display mode to be GLUT_DOUBLE: glInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); When using double buffering, OpenGL automatically renders everything to the background buffer. To swap the buffers, we must call: glutSwapBuffers(); After the swap, we ask OpenGL to redraw the window: glutPostRedisplay();
Bouncing Ball – Double Buffered Display void Displaylvoid) { glClearlGL-COLOR-BUFFER-BIT); glClearlGL-COLOR-BUFFER-BIT); 11 I60 is max X value in our world 11 Define X position of the ball to be at center of window xpos - 80.; 11 120 is max Y value in our world 11 set Y position to increment 1.5 times the direction of the bounce ypos - ypos+ydir "1.5; 11 If ball touches the top, change direction of ball downwards if lypos - - 120-RadiusOfBall) ydir - -1; 11 If ball touches the bottom, change direction of ball downwards else if lypos 4adiusOfBall) ydir - 1; llreset transformation state glLoadldentii0; 11 apply the translation glTranslateflxpos,ypos, 0.); I1 draw the ball with the current transformation state applied draw-ball0; 11 swap the buffers glutSwapBuffers0; 11 force a redraw using the new contents glutPostRedisplay0; 1
Scaling • Objects can be stretched or shrunk by multiplying all the points by the Sx and Sy scaling factors. • The floating-point routine for performing scale in OpenGL is: glScalef(Sx, Sy, Sz) • It accepts three arguments for scaling along the x-, y-, and z-axes. • Scaling has no effect if Sx=Sy=Sz=1 • The z-axis is used for 3D worlds, and we can ignore it for now by setting the Sz value to be 1.
Rotation • Objects can be rotated about any of the axes. Rotation about the z-axis will rotate the object in the xy-plane. • The floating-point routine for performing rotation in OpenGL is: glRotatef(Rot, vx, vy, vz) • Rot – the angle of rotation in degrees • vx,vy,vz is the vector around which you want the rotation. • Rotations in the xy-plane is vx=vy=0; vz=1.
Other Transformations • What would the matrix look like that would “shear” an object (or slant an object)? • How about reflection about an axis?
Shearing • Shear parallel to the x-axis: • Shear parallel to the y-axis: • Take some time and prove to yourself this will work on an object (like the unit cube) • How would you write this in homogeneous coordinates?
Reflection • Reflection about the x-axis looks like • Reflection about the y-axis: • About both…