400 likes | 571 Views
Graphics Systems and OpenGL. CS 445/645 Introduction to Computer Graphics. Cool Video Games. http://www.stanford.edu/~mazzella/university/cs248/pacman/pacman.htm http://www.liquid.se/pong.html. Transform. Illuminate. Transform. Clip. Project. Rasterize. Model & Camera Parameters.
E N D
Graphics Systemsand OpenGL CS 445/645 Introduction to Computer Graphics
Cool Video Games • http://www.stanford.edu/~mazzella/university/cs248/pacman/pacman.htm • http://www.liquid.se/pong.html
Transform Illuminate Transform Clip Project Rasterize Model & CameraParameters Rendering Pipeline Framebuffer Display Rendering 3D Scenes
Transform Illuminate Transform Clip Project Rasterize Model & CameraParameters Rendering Pipeline Framebuffer Display The Rendering Pipeline
Rendering: Transformations • So far, discussion has been in screen space • But model is stored in model space(a.k.a. object space or world space) • Three sets of geometric transformations: • Modeling transforms • Viewing transforms • Projection transforms
The Rendering Pipeline: 3-D Scene graphObject geometry • Result: • All vertices of scene in shared 3-D “world” coordinate system • Vertices shaded according to lighting model • Scene vertices in 3-D “view” or “camera” coordinate system • Exactly those vertices & portions of polygons in view frustum • 2-D screen coordinates of clipped vertices ModelingTransforms LightingCalculations ViewingTransform Clipping ProjectionTransform
Scene graphObject geometry • Result: • All vertices of scene in shared 3-D “world” coordinate system ModelingTransforms LightingCalculations ViewingTransform Clipping ProjectionTransform The Rendering Pipeline: 3-D
Y X Z Rendering: Transformations • Modeling transforms • Size, place, scale, and rotate objects and parts of the model w.r.t. each other • Object coordinates world coordinates Y Z X
The Rendering Pipeline: 3-D Scene graphObject geometry • Result: • Scene vertices in 3-D “view” or “camera” coordinate system ModelingTransforms LightingCalculations ViewingTransform Clipping ProjectionTransform
Rendering: Transformations • Viewing transform • Rotate & translate the world to lie directly in front of the camera • Typically place camera at origin • Typically looking down -Z axis • World coordinates view coordinates
The Rendering Pipeline: 3-D Scene graphObject geometry • Result: • 2-D screen coordinates of clipped vertices ModelingTransforms LightingCalculations ViewingTransform Clipping ProjectionTransform
Rendering: Transformations • Projection transform • Apply perspective foreshortening • Distant = small: the pinhole camera model • View coordinates screen coordinates
Rendering: Transformations • Perspective Camera • Orthographic Camera
¢ q - q é ù é ù é ù X cos sin X = ê ú ê ú ê ú ¢ q q Y sin cos Y ë û ë û ë û Rendering: Transformations • All these transformations involve shifting coordinate systems (i.e., basis sets) • That’s what matrices do… • Represent coordinates as vectors, transforms as matrices • Multiply matrices = concatenate transforms!
Rendering: Transformations • Example: Rotate point [1,0]T by 90 degrees CCW (Counter-clockwise) y (1,0) x y (0,1) x
Introducing OpenGL • mid-level, device-independent, portable graphics subroutine package • developed primarily by SGI • 2D/3D graphics, lower-level primitives (polygons) • does not include low-level I/O management • basis for higher-level libraries/toolkits
Introducing OpenGL • Recall the rendering pipeline: • Transform geometry (object world, world eye) • Apply perspective projection (eye screen) • Clip to the view frustum • Perform visible-surface processing (Z-buffer) • Calculate surface lighting • Implementing all this is a lot of work • OpenGL provides a standard implementation • So why study the basics?
OpenGL Design Goals • SGI’s design goals for OpenGL: • High-performance (hardware-accelerated) graphics API • Some hardware independence • Natural, terse API with some built-in extensibility • OpenGL has become a standard because: • It doesn’t try to do too much • Only renders the image, doesn’t manage windows, etc. • No high-level animation, modeling, sound (!), etc. • It does enough • Useful rendering effects + high performance • It is promoted by SGI (& Microsoft, half-heartedly)
OpenGL: Conventions • Functions in OpenGL start with gl • Most functions just gl (e.g., glColor()) • Functions starting with glu are utility functions (e.g., gluLookAt()) • Functions starting with glx are for interfacing with the X Windows system (e.g., in gfx.c)
OpenGL: Conventions • Function names indicate argument type and number • Functions ending with f take floats • Functions ending with i take ints • Functions ending with b take bytes • Functions ending with ub take unsigned bytes • Functions that end with v take an array. • Examples • glColor3f() takes 3 floats • glColor4fv() takes an array of 4 floats
OpenGL: Conventions • Variables written in CAPITAL letters • Example: GLUT_SINGLE, GLUT_RGB • usually constants • use the bitwise or command (x | y) to combine constants
OpenGL Matrix Stacks • OpenGL basically just renders vertices • Vertices can be grouped to form polygons • Polygons can be grouped to form shapes (solids) • Each glVertex rendered by OpenGL is transformed by the top matrix on the MODELVIEW matrix stack • As we saw before, a matrix corresponding to a CCW rotation of 90 degrees could be put on the stack
OpenGL Matrix Stacks • Every vertex rendered by an OpenGL camera is also multiplied by the top matrix on the PROJECTION matrix • The projection matrix controls such effects as: • Field of view • Perspective vs. Orthographic • Clipping planes • Viewing frustum
OpenGL Matrix Stacks • glMatrixMode() specifies which matrix stack is being altered • glPushMatrix() and glPopMatrix() are two common commands to control stack • glLoadIdentity() will put identity matrix on top of stack • glTranslate and glRotate also place matrices on stack that cause translations and rotations
OpenGL Matrix Stacks • Warning about declaring matrices in C • matrix m[4][4] can be accesses as m[ i ] [ j ], but this accesses the ith column and the jth row of the OpenGL transformation matrix • Because C convention is opposite the OpenGL convention, m[16] is recommended declaration
OpenGL: Basics • Include • #include <GL/glut.h> • Libraries • -lglut -lGL -lGLU -lXmu -lXext -lX11
OpenGL: main() • Open a window and attach OpenGL to it • Set camera parameters (e.g., field of view) • Setup lighting, if any • Register callback functions • Key press, mouse movement, screen resize • Main rendering loop • OpenGL controls execution from this point forward
main(): Open a window • glutInit(&argc, argv); • argc and argv potentially used by glutInit and preserved • glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); • Red, green, blue, and alpha (transparency), double buffer, and depth buffered • glutInitWindowSize(INITIAL_WIDTH, INITIAL_HEIGHT); • glutInitWindowPosition(INITIAL_X_POS, INITIAL_Y_POS); • glutCreateWindow(WINDOW_NAME);
main(): Setup Camera Parameters • PONG camera is defined in resize_scene() • glViewport(0, 0, width, height); • Define the portion of the window you’ve created that you wish to render using this camera • glMatrixMode(GL_PROJECTION); • The matrix we’re going to affect is the PROJECTION • glLoadIdentity(); • Make PROJECTION matrix identity • glOrtho (0.0, width, 0.0, height, -1, 1); • Create the matrix that defines an orthographic camera and place this matrix on the stack. We don’t care about depth in PONG. • Default camera at (0,0,0) with y up and looking down –z. • glMatrixMode (GL_MODELVIEW); • Future transformations will affect MODELVIEW
main(): Register Callback Functions These functions are executed upon interrupt caused by user or by OpenGL main loop • glutDisplayFunc(draw_scene); • draw_scene() does the rendering • glutReshapeFunc(resize_scene); • resize_screen() is executed upon startup and upon window resize • glutKeyboardFunc(key_press); • key_press() is executed when a key is pressed • glutMouseFunc(handle_mouse_click); • handle_mouse_click() is executed when a mouse button pressed • glutMotionFunc(handle_mouse_motion); • handle_mouse_motion() is executed when key clicked and mouse moved
main(): Initiate main rendering loop • glutMainLoop(); • Your program never regains explicit control • return 1;
Callback: Display_Func() • Defines geometry for rendering • glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); • Clear the palette • glLoadIdentity(); • Reset the MODELVIEW matrix • draw_border(); • Draw the outline of playing court
Callback: Display_Func() • glPushMatrix(); • Isolate upcoming glTranslate by pushing and popping • glTranslatef(0, paddle_y_pos, 0); • Move to where the center of the paddle is • draw_paddle(); • Draw the quadrilateral that defines the paddle geometry • glPopMatrix(); • Remove the glTranslate from the stack
Callback: Display_Func() • glPushMatrix(); • Push • glTranslatef(ball_x_pos, ball_y_pos, 0); • Move to ball center • draw_ball(); • Draw quadrilateral for ball • glPopMatrix(); • Pop • glutSwapBuffers(); • Move image to frame buffer for rendering
Callback: Display_Func() • glClear • glLoadIdentity • draw_border • glPush; glTranslate; draw_paddle(); glPop • glPush; glTranslate; draw_ball(); glPop • glSwapBuffer
draw_paddle(void) • Geometry in OpenGL consists of a list of vertices in between calls to glBegin() and glEnd() • glBegin(GL_QUADS); • glVertex3f(xpos,-yoff,0); • glVertex3f(xpos,yoff,0); • glVertex3f(xpos+BORDER_SIZE,yoff,0); • glVertex3f(xpos+BORDER_SIZE,-yoff,0); • glEnd(); • Usage: glBegin(geomtype) where geomtype is: • Points, lines, polygons, triangles, quadrilaterals, etc...
Callback: keyboard_func() • If a key is pressed, this function is called • ‘s’ will start game • game_over is set to 0.0 • move_ball(int) is called • ‘r’ will reset game • ‘ESC’ will quit
Callback: move_ball() • Ball_x_pos += -BALL_STEP; • You will fix this so ball can move in any direction • if (!game_over) { • glutTimerFunc(ball_delay, move_ball, current_game); • This creates a timer-based interrupt for OpenGL • move_ball will be called again after ball_delay milliseconds • }
Callback: mouseFunc, motionFunc • When left button is pressed, update global var • switch (btn) { • case GLUT_LEFT_BUTTON: • left_button_state = state; • left_button_lasty = y; • break; • }
Callback: mouseFunc, motionFunc • When mouse moves, update global var • if (left_button_state == GLUT_DOWN) { • paddle_y_pos += left_button_lasty - y; • left_button_lasty = y; • glutPostRedisplay(); • }