Graphics Systems and OpenGL CS 551/654 Introduction to Computer Graphics What is a graphics package? software – – Application Model 2 that takes user input and passes it to applications that displays graphical output for applications Application Program Graphics System (2D/3D graphics, UI toolkit, input manager window system) Application Model (world): – – – Program: – – 3 the database & objects to be displayed may be geometry/attributes may be abstract data (e.g. fractal description) responsible for mapping the model to primitives supported by graphics package responsible for mapping user input to model changes Graphics system components 4 Set of primitives Primitive attributes Graphics output Input handling Window management 2D Primitive possibilities 5 geometrical objects (point, line, circle, polygon, ...) mathematical curves text primitives fill patterns bitmapped images/textures 3D primitive possibilities 6 geometrical objects (line, polygon, polyhedron, sphere, …) mathematical surfaces light sources camera/eye points hierarchy placeholders object boundaries Primitive attributes 7 color thickness position orientation transparency behavior Graphics output 8 scan-conversion: used to map graphics commands (sets of primitives/attributes) to pixel values to be placed in frame buffer rendering of objects into screen space providing a view of the application model Input handling receive input from physical devices map this input to logical devices for applications apps register interest in events or devices event-driven programming render_from_database(); while(1){ wait for input switch(input){ case 1: call_routine1(); case 2: call_routine2(); … } render_from_database(); } 9 Window management 10 manage screen space mediate between application programs provide logical output “canvases” each app. believes it has an entire “screen” with its own coordinate system Goals of graphics packages Abstraction; Device-independence – – – – 11 logical input devices logical output devices (!) provide abstraction from hardware for app. produce application portability Appropriate primitive/attribute types Introducing OpenGL 12 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: – – – – – Implementing all this is a lot of work OpenGL provides a standard implementation – 13 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 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 – It does enough 14 – Only renders the image, doesn’t manage windows, etc. No high-level animation, modeling, sound (!), etc. Useful rendering effects + high performance It is promoted by SGI (& Microsoft, half-heartedly) OpenGL: Conventions Functions in OpenGL start with gl – – – 15 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) Wireframe 16 Wireframe with depth-cueing Wireframe with antialiasing Flat-shaded polygons 17 Smooth-shaded polygons Texture maps and shadows 18 Close-up With Fog 19 OpenGL: Conventions Function names indicate argument type and number – – – – – Examples – – 20 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. glColor3f() takes 3 floats glColor4fv() takes an array of 4 floats OpenGL: Conventions Variables written in CAPITAL letters – – – 21 Example: GLUT_SINGLE, GLUT_RGB usually constants use the bitwise or command (x | y) to combine constants OpenGL: Simple Use Open a window and attach OpenGL to it Set projection parameters (e.g., field of view) Setup lighting, if any Main rendering loop – Set camera pose with gluLookAt() – Render polygons of model 22 Camera position specified in world coordinates Simplest case: vertices of polygons in world coordinates OpenGL: Simple Use Open a window and attach OpenGL to it – glutCreateWindow() Set projection parameters (e.g., field of view) Setup lighting, if any Main rendering loop – Set camera pose with gluLookAt() – Render polygons of model 23 Camera position specified in world coordinates Simplest case: vertices of polygons in world coordinates OpenGL: Simple Use Open a window and attach OpenGL to it Set projection parameters (e.g., field of view) Setup lighting, if any Main rendering loop – Set camera pose with gluLookAt() – Render polygons of model 24 Camera position specified in world coordinates Simplest case: vertices of polygons in world coordinates OpenGL: Perspective Projection Typically, we use a perspective projection – – – 25 Distant objects appear smaller than near objects Vanishing point at center of screen Defined by a view frustum (draw it) Other projections: orthographic, isometric OpenGL: Perspective Projection In OpenGL: – – Projections implemented by projection matrix gluPerspective() creates a perspective projection matrix: glSetMatrix(GL_PROJECTION); glLoadIdentity(); //load an identity matrix gluPerspective(vfov, aspect, near, far); Parameters to gluPerspective(): – – – 26 vfov: vertical field of view aspect: window width/height near, far: distance to near & far clipping planes OpenGL: Simple Use Open a window and attach OpenGL to it Set projection parameters (e.g., field of view) Setup lighting, if any Main rendering loop – Set camera pose with gluLookAt() – Render polygons of model 27 Camera position specified in world coordinates Simplest case: vertices of polygons in world coordinates OpenGL: Lighting Simplest option: change the current color between polygons or vertices – glColor() sets the current color Or OpenGL provides a simple lighting model: – Set parameters for light(s) – 28 Intensity, position, direction & falloff (if applicable) Set material parameters to describe how light reflects from the surface Won’t go into details now; check the red book if interested OpenGL: Simple Use Open a window and attach OpenGL to it Set projection parameters (e.g., field of view) Setup lighting, if any Main rendering loop – Set camera pose with gluLookAt() – Render polygons of model 29 Camera position specified in world coordinates Simplest case: vertices of polygons in world coordinates OpenGL: Specifying Viewpoint glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ); – – – Creates a matrix that transforms points in world coordinates to camera coordinates – – 30 eye[XYZ]: camera position in world coordinates look[XYZ]: a point centered in camera’s view up[XYZ]: a vector defining the camera’s vertical – Camera at origin Looking down -Z axis Up vector aligned with Y axis OpenGL: Specifying Geometry Geometry in OpenGL consists of a list of vertices in between calls to glBegin() and glEnd() – A simple example: telling GL to render a triangle glBegin(GL_POLYGON); glVertex3f(x1, y1, z1); glVertex3f(x2, y2, z2); glVertex3f(x3, y3, z3); glEnd(); – Usage: glBegin(geomtype) where geomtype is: 31 Points, lines, polygons, triangles, quadrilaterals, etc... OpenGL: More Examples Example: GL supports quadrilaterals: glBegin(GL_QUADS); glVertex3f(-1, 1, 0); glVertex3f(-1, -1, 0); glVertex3f(1, -1, 0); glVertex3f(1, 1, 0); glEnd(); – 32 This type of operation is called immediate-mode rendering; each command happens immediatelt OpenGL: Front/Back Rendering Each polygon has two sides, front and back OpenGL can render the two differently The ordering of vertices in the list determines which is the front side: – When looking at the front side, the vertices go counterclockwise 33 This is basically the right-hand rule Note that this still holds after perspective projection OpenGL: Drawing Triangles You can draw multiple triangles between glBegin(GL_TRIANGLES) and glEnd(): float v1[3], v2[3], v3[3], v4[3]; ... glBegin(GL_TRIANGLES); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); glVertex3fv(v1); glVertex3fv(v3); glVertex3fv(v4); glEnd(); Each set of 3 vertices forms a triangle – – 34 What do the triangles drawn above look like? How much redundant computation is happening? OpenGL: Triangle Strips An OpenGL triangle strip primitive reduces this redundancy by sharing vertices: glBegin(GL_TRIANGLE_STRIP); v2 glVertex3fv(v0); glVertex3fv(v1); v0 glVertex3fv(v2); glVertex3fv(v3); glVertex3fv(v4); v1 glVertex3fv(v5); glEnd(); – – – 35 – v4 v5 v3 triangle 0 is v0, v1, v2 triangle 1 is v2, v1, v3 (why not v1, v2, v3?) triangle 2 is v2, v3, v4 triangle 3 is v4, v3, v5 (again, not v3, v4, v5) OpenGL: Specifying Color Can specify other properties such as color – To produce a single aqua-colored triangle: glColor3f(0.1, 0.5, 1.0); glVertex3fv(v0); glVertex3fv(v1); glVertex3fv(v2); – To produce a Gouraud-shaded triangle: glColor3f(1, 0, 0); glVertex3fv(v0); glColor3f(0, 1, 0); glVertex3fv(v1); glColor3f(0, 0, 1); glVertex3fv(v2); – In OpenGL, colors can also have a fourth component (opacity) 36 Generally want = 1.0 (opaque); OpenGL: Specifying Normals Calling glColor() sets the color for vertices following, until the next call to glColor() Calling glNormal() sets the normal vector for the following vertices, till next glNormal() So flat-shaded lighting requires: glNormal3f(Nx, Ny, Nz); glVertex3fv(v0);glVertex3fv(v1);glVertex3fv(v2); – While smooth shading requires: glNormal3f(N0x, N0y, N0z); glVertex3fv(v0); glNormal3f(N1x, N1y, N1z); glVertex3fv(v1); glNormal3f(N2x, N2y, N2z); glVertex3fv(v2); – 37 (Of course, lighting requires additional setup…) Double Buffering 38 Avoids displaying partially rendered frame buffer OpenGL generates one raster image while another raster image is displayed on monitor glxSwapBuffers (Display *dpy, Window, w) glutSwapBuffers (void)