1 / 14

COMPUTER GRAPHICS

COMPUTER GRAPHICS. CS 482 – FALL 2014. AUGUST 20, 2014. GRAPHICS IN OPENGL. OPENGL OVERVIEW OPENGL 2D EXAMPLES OPENGL 3D EXAMPLES. OPENGL OVERVIEW. BROAD STROKES. Silicon Graphics (SGI) developed OpenGL, a low-level graphics API with fine-grained control. Triangles/Lines/Points.

idalia
Download Presentation

COMPUTER GRAPHICS

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. COMPUTER GRAPHICS CS 482 – FALL 2014 AUGUST 20, 2014 GRAPHICS IN OPENGL • OPENGL OVERVIEW • OPENGL 2D EXAMPLES • OPENGL 3D EXAMPLES

  2. OPENGL OVERVIEW BROAD STROKES Silicon Graphics (SGI) developed OpenGL, a low-level graphics API with fine-grained control. Triangles/Lines/Points Vertices API Primitive Processing Transform & Lighting Primitive Assembly Rasterizer Texture Environment Color Sum Fog Alpha Test Depth/ Stencil Color Buffer Blend Frame Buffer Applications supply geometry information for each primitive object (vertex, segment, triangle), as well as the effects to be applied to the primitives (color, transparency, fog, etc.). OpenGL provides a greater level of control for developers and is reliable across different hardware platforms. CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 16

  3. OPENGL OVERVIEW OPENGL PIPELINE An application’s OpenGL function calls are placed in the OpenGL command buffer. These functions create and manipulate primitive graphical objects (vertices, segments, polygons, curves, pixels) The image is generated from the data associated with the objects’ geometry, material properties, and texture The geometry of the objects being displayed is used to calculate visibility, orientation, and lighting The image is placed in the frame buffer of the graphics display device The command buffer is periodically flushed (possibly by explicit programmed commands) CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 17

  4. OPENGL OVERVIEW TRADITIONAL GRAPHICS PIPELINE The traditional graphics processing pipeline begins with object-space vertices, to which lighting, color, and texture are applied. Information concerning the vertices is used to generate geometric primitives, such as line segments, triangles, triangle strips, etc. The primitives are then processed (clipping, projections, etc.) to produce fragments, each of which is essentially the data needed to generate a single pixel. Each fragment’s information is used to generate a pixel for the frame buffer (i.e., raster position, depth, color, texture coordinates, and transparency). Before the development of programmable shaders, the only way to achieve hardware speed-ups in graphics was to hardwire the graphics card to perform very specific, “fixed-function” graphics algorithms. CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 18

  5. OPENGL OVERVIEW OPENGL 4.4 CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 19

  6. OPENGL 2D EXAMPLES FERN ITERATED FUNCTION SYSTEM In this example, users produce a fractal image generated via mathematical chaos theory. Noteworthy features: • The mathematical field of chaos theory includes the study of contractive, affine transformations that yield “strange attractors”, i.e., sets of points which, when graphically rendered, produce self-similar fractal images that are reminiscent of natural phenomena. CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 20

  7. OPENGL 2D EXAMPLES FERN ITERATED FUNCTION SYSTEM • Starting with the point (0,0), generate a random number in [0,1]. • If that number is in [0,p1], then apply the affine transformation W1(x,y) = (a1x+b1y+e1,c1x+d1y+f1); • if the number’s in (p1,p2], apply W2(x,y)= (a2x+b2y+e2,c2x+d2y+f2); • if the number’s in (p2,p3], apply W3(x,y)= (a3x+b3y+e3,c3x+d3y+f3); • if the number’s in (p3,p4], apply W4(x,y)= (a4x+b4y+e4,c4x+d4y+f4). • Then generate another random number and apply the appropriate transformation to the previously generated point, and so on. This list of coefficients produces the fern pattern: CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 21

  8. OPENGL 2D EXAMPLES FERN ITERATED FUNCTION SYSTEM • Points primitive • Periodic image flushing • Apple OS X & Windows • No hard-coded numerics • Generic shader setup Noteworthy: • Iterated function system implementation • Window resizing • Single-buffered (no animation) • Title bar • Reshape function specification • Display function specification /*********************************************************************/ /* Filename: Fern.cpp */ /* Produces an iterated function system in the shape of a fern leaf. */ /*********************************************************************/ #include <GLTools.h> // OpenGL toolkit #include <GLShaderManager.h> // Shader Manager Class #ifdef__APPLE__ #include <glut/glut.h> // OS X version of GLUT library #else #define FREEGLUT_STATIC #include <GL/glut.h> // Windows FreeGlut equivalent #endif ////////////////////// // Global Constants // ////////////////////// constintNBR_COLORS = 5; constGLfloatCOLOR[NBR_COLORS][3] = { 0.1f, 0.8f, 0.1f, // Bright green // 0.1f, 0.4f, 0.1f, // Dark green // 0.8f, 0.1f, 0.1f, // Bright red // 0.4f, 0.8f, 0.1f, // Medium brown // 0.8f, 0.8f, 0.1f }; // Bright yellow // constGLfloatA[4] = {0.00f, 0.85f, 0.20f, -0.15f}; constGLfloatB[4] = {0.00f, 0.04f, -0.26f, 0.28f}; constGLfloatC[4] = {0.00f, -0.04f, 0.23f, 0.26f}; constGLfloatD[4] = {0.16f, 0.85f, 0.22f, 0.24f}; constGLfloatE[4] = {0.00f, 0.00f, 0.00f, 0.00f}; constGLfloatF[4] = {0.00f, 1.60f, 1.60f, 0.44f}; constGLfloatPROB[4] = {0.01f, 0.86f, 0.93f, 1.00f}; /* The main function: uses the OpenGL Utility Toolkit to set */ /* the window up to display the iterated function system. */ void main(intargc, char **argv) { /* Set up the display window. */ gltSetWorkingDirectory(argv[0]); glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE| GLUT_RGBA); glutInitWindowPosition( INIT_WINDOW_POS[0], INIT_WINDOW_POS[1] ); glutInitWindowSize( INIT_WINDOW_SIZE[0], INIT_WINDOW_SIZE[1] ); glutCreateWindow( "Fern Iterated Function System" ); // Ensure proper OpenGL availability, with generic shader. GLenumerr = glewInit(); if(GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); return; } shaderManager.InitializeStockShaders(); /* Specify the resizing and refreshing routines. */ glutReshapeFunc( ResizeWindow ); glutDisplayFunc( Display ); glutMainLoop(); } /* Function to draw the fern, one point at a time. */ voidDrawFern() { GLfloatvert[2] = {0.0f, 0.0f}; GLfloatnewVert[2]; GLfloatdisplayVert[2]; GLfloatclr[3]; intclrIndex; intcoeffIndex; floatr; // Iterate the point generation and display. // for(int n = 1; n <= NBR_ITERATIONS; n++) { // Alternate color selection. // clrIndex= n % NBR_COLORS; clr[0] = COLOR[clrIndex][0]; clr[1] = COLOR[clrIndex][1]; clr[2] = COLOR[clrIndex][2]; // Select function coefficients using random // // numbers and weighted probabilities. // r = float(rand()) / RAND_MAX; if(r < PROB[0]) coeffIndex= 0; elseif (r < PROB[1]) coeffIndex= 1; elseif (r < PROB[2]) coeffIndex= 2; else coeffIndex= 3; // Generate next iterated point. // newVert[0] = A[coeffIndex] * vert[0] + B[coeffIndex] * vert[1] + E[coeffIndex]; newVert[1] = C[coeffIndex] * vert[0] + D[coeffIndex] * vert[1] + F[coeffIndex]; vert[0] = newVert[0]; vert[1] = newVert[1]; // Scale and translate point into display window. // displayVert[0] = IMAGE_SCALE_FACTOR[0] * vert[0] + IMAGE_DISPLACEMENT[0]; displayVert[1] = IMAGE_SCALE_FACTOR[1] * vert[1] + IMAGE_DISPLACEMENT[1]; // Display colored point. // glBegin(GL_POINTS); glColor3fv(clr); glVertex2fv(displayVert); glEnd(); // Draw all points periodically. // if(n % FLUSH_ITER_INCREMENT == 0) glFlush(); } } /* Principal display routine: clears the frame buffer */ /* and the depth buffer, and then draws the fern. */ void Display() { glClear(GL_COLOR_BUFFER_BIT); DrawFern(); } constintINIT_WINDOW_POS[2] = { 50, 50 }; constintINIT_WINDOW_SIZE[2] = { 1000, 1000 }; constintNBR_ITERATIONS = 1000000; constintFLUSH_ITER_INCREMENT = 100; const float IMAGE_SCALE_FACTOR[2] = { 0.50f, 0.35f }; const float IMAGE_DISPLACEMENT[2] = { 0.0f, -1.8f }; ////////////////////// // Global Variables // ////////////////////// GLShaderManagershaderManager; // Manager of GLTools stock shaders. ///////////////////////// // Function Prototypes // ///////////////////////// voidDrawFern(); void Display(); voidResizeWindow(GLsizei w, GLsizeih); /* Window-reshaping routine, to adjust the fern */ /* size to fit the window, scaling the image so */ /* it will be entirely visible whether the */ /* window is short and wide, or tall and thin. */ void ResizeWindow(GLsizei w, GLsizeih) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-2.0f, 2.0f, -2.0f * (GLfloat)h / (GLfloat)w, 2.0f * (GLfloat)h / (GLfloat)w, -10.0f, 10.0f); else glOrtho(-2.0f * (GLfloat)w / (GLfloat)h, 2.0f * (GLfloat)w / (GLfloat)h, -2.0f, 2.0f, -10.0f, 10.0f); glMatrixMode(GL_MODELVIEW); } CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 22

  9. OPENGL 2D EXAMPLES INTERACTIVE POLYGON DRAWING In this example, users employ the mouse to link vertices to form a polygon. Noteworthy features: • The polygon is “closed” via the ‘c’ key; once closed, the polygon may not be reopened (i.e., no more vertices may be added). • After closure, selected vertices may be deleted via the ‘d’ key; when deleted, a vertex’s predecessor and successor become joined by an edge. CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 23

  10. OPENGL 2D EXAMPLES INTERACTIVE POLYGON DRAWING • Window resizing implementation • Selected vertex drawn last • Triangle fan primitive • Vertices drawn second • Line strip primitive • Lines drawn first • Global constants & variables • 2D point class Noteworthy: • Mouse click implementation • Mouse click function • Mouse drag function • Keyboard press function • Keyboard press implementation • Mouse drag implementation /******************************************************/ /* Filename: PolygonDraw.cpp */ /* Uses the mouse to permit the user to interactively */ /* create and draw a polygon within a display window, */ /* and keyboard callbacks to change editing modes. */ /******************************************************/ #include <GLTools.h> // OpenGL toolkit #include <GLShaderManager.h> // Shader Manager Class #include<cmath> // Header File For Math Library #include"LinkedList.h" // Header File For Linked List Class #ifdef__APPLE__ #include <glut/glut.h> // OS X version of GLUT library #else #define FREEGLUT_STATIC #include <GL/glut.h> // Windows FreeGlut equivalent #endif /////////////////////////////////////// // 2D point class (for convenience). // /////////////////////////////////////// classGLfloatPoint { public: GLfloatx, y; }; ////////////////////// // Global Constants // ////////////////////// // Pixel position of upper left-hand corner of display window. constGLintINIT_WINDOW_POSITION[2] = { 100, 100 }; constGLintINIT_WINDOW_SIZE[2] = { 800, 800 }; /* The main function: uses the OpenGL Utility Toolkit to set */ /* the window up to display the window and its contents. */ void main(intargc, char **argv) { /* Set up the display window. */ currWindowSize[0] = INIT_WINDOW_SIZE[0]; currWindowSize[1] = INIT_WINDOW_SIZE[1]; gltSetWorkingDirectory(argv[0]); glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE| GLUT_RGBA); glutInitWindowPosition( INIT_WINDOW_POSITION[0], INIT_WINDOW_POSITION[1] ); glutInitWindowSize( currWindowSize[0], currWindowSize[1] ); glutCreateWindow( "POLYGON DRAW (C: Close Polygon; D: Delete Vertex)" ); // Ensure proper OpenGL availability, with generic shader. GLenumerr = glewInit(); if(GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); return; } shaderManager.InitializeStockShaders(); /* Specify the resizing and refreshing routines. */ glutReshapeFunc( ResizeWindow ); glutDisplayFunc( Display ); glutMouseFunc( MouseClick ); glutMotionFunc( MouseDrag ); glutKeyboardFunc( KeyboardPress ); glutMainLoop(); } /* Function to react to mouse clicks by adding an additional vertex */ /* to the polygon being built, or by determining whether the mouse */ /* pointer is close enough to an existing vertex to select it. */ voidMouseClick(intmouseButton, intmouseState, intmouseXPosition, intmouseYPosition) { GLfloatPointcurrPoint; GLfloatx = windowWidth * mouseXPosition/ currWindowSize[0] - 0.5f * windowWidth; GLfloaty = 0.5f * windowHeight - (windowHeight * mouseYPosition/ currWindowSize[1]); if( (createMode) && (mouseState == GLUT_DOWN) ) { GLfloatPointnewPoint; newPoint.x= x; newPoint.y= y; pointList.insert(newPoint); } elseif ( mouseState== GLUT_DOWN ) { selectMode= false; for(inti = 1; i <= pointList.getSize(); i++) { currPoint= pointList.getHeadValue(); if( sqrt(pow(x - currPoint.x, 2) + pow(y - currPoint.y, 2)) < POINT_RADIUS ) { selectMode= true; break; } ++pointList; } } Display(); } /* Function to move the position of the selected polygon */ /* vertex to the current mouse pointer position if the */ /* mouse button is pressed and the pointer is in motion. */ voidMouseDrag(intmouseXPosition, intmouseYPosition) { GLfloatPointcurrPoint; GLfloatx = windowWidth * mouseXPosition/ currWindowSize[0] - 0.5f * windowWidth; GLfloaty = 0.5f * windowHeight - (windowHeight * mouseYPosition/ currWindowSize[1]); if(selectMode) { currPoint= pointList.getHeadValue(); currPoint.x= x; currPoint.y= y; pointList.removeHead(); pointList.insert(currPoint); Display(); } glFlush(); } /* Function to react to the pressing of keyboard keys by the */ /* user, either by completing the polygon creation (by "closing" */ /* the polygon) or by deleting the selected polygon vertex. */ voidKeyboardPress(unsignedcharpressedKey, intmouseXPosition, intmouseYPosition) { switch(pressedKey) { case'c': case'C': { createMode = false; Display(); break; } case'd': case'D': { if(selectMode) { pointList.removeHead(); selectMode= false; Display(); } break; } } } /* Principal display routine: clears the frame */ /* buffer and draws the polygon in the window. */ void Display() { inti; GLfloatPointcurrPoint; floattheta; glClear(GL_COLOR_BUFFER_BIT); // Draw the polygon's (2-pixel thick) line segments. // glLineWidth(2.0f); glColor3fv(LINE_COLOR); glBegin(GL_LINE_STRIP); for (i = 1; i <= pointList.getSize(); i++) { currPoint= pointList.getHeadValue(); glVertex2f(currPoint.x, currPoint.y); ++pointList; } if ((!createMode) && (pointList.getSize() > 0)) { currPoint= pointList.getHeadValue(); glVertex2f(currPoint.x, currPoint.y); } glEnd(); glLineWidth(1.0f); // Draw the polygon vertices. // glColor3fv(POINT_COLOR); for (i = 1; i <= pointList.getSize(); i++) { currPoint= pointList.getHeadValue(); glBegin(GL_TRIANGLE_FAN); glVertex2f(currPoint.x, currPoint.y); for (int j = 0; j < NBR_SLICES; j++) { theta = 360 * j * PI_OVER_180 / NBR_SLICES; glVertex2f(currPoint.x+ POINT_RADIUS * cos(theta), currPoint.y+ POINT_RADIUS*sin(theta)); theta = 360 * (j + 1) * PI_OVER_180 / NBR_SLICES; glVertex2f(currPoint.x+ POINT_RADIUS * cos(theta), currPoint.y+ POINT_RADIUS * sin(theta)); } glEnd(); ++pointList; } // Highlight the selected vertex (if any). // if (selectMode) { glColor3fv(HIGHLIGHT_COLOR); currPoint= pointList.getHeadValue(); glBegin(GL_TRIANGLE_FAN); glVertex2f(currPoint.x, currPoint.y); for (int j = 0; j < NBR_SLICES; j++) { theta = 360 * j * PI_OVER_180 / NBR_SLICES; glVertex2f(currPoint.x+ POINT_RADIUS * cos(theta), currPoint.y+ POINT_RADIUS * sin(theta)); theta = 360 * (j + 1) * PI_OVER_180 / NBR_SLICES; glVertex2f(currPoint.x+ POINT_RADIUS * cos(theta), currPoint.y+ POINT_RADIUS * sin(theta)); } glEnd(); } glFlush(); } // RGB color of line segments and point vertices (regular and highlighted). constGLfloatLINE_COLOR[3] = { 1.0f, 0.8f, 0.1f }; constGLfloatPOINT_COLOR[3] = { 1.0f, 0.3f, 0.1f }; constGLfloatHIGHLIGHT_COLOR[3] = { 0.1f, 0.3f, 1.0f }; // Radius of circular point vertices. constGLfloatPOINT_RADIUS = 0.02f; // # of segments comprising "circular" vertex. constintNBR_SLICES = 12; // One degree (in radians). constGLfloatPI_OVER_180 = 0.0174532925f; ////////////////////// // Global Variables // ////////////////////// GLShaderManagershaderManager; // Manager of GLTools stock shaders. GLintcurrWindowSize[2]; // Window size in pixels. GLfloatwindowWidth = 2.0; // Resized window width. GLfloatwindowHeight = 2.0; // Resized window height. boolselectMode = false; // Flag indicating selected vertex. boolcreateMode = true; // Flag indicating polygon creation. LinkedList<GLfloatPoint> pointList; // Circular list of polygon vertices. ///////////////////////// // Function Prototypes // ///////////////////////// void MouseClick(intmouseButton, intmouseState, intmouseXPosition, intmouseYPosition); void MouseDrag(intmouseXPosition, intmouseYPosition); void KeyboardPress(unsignedchar pressedKey, intmouseXPosition, intmouseYPosition); void Display(); void ResizeWindow(GLsizei w, GLsizeih); /* Window-reshaping routine, to scale the rendered polygon according */ /* to the window dimensions, setting the global variables so the */ /* mouse operations will correspond to mouse pointer positions. */ voidResizeWindow(GLsizeiw, GLsizeih) { glViewport(0, 0, w, h); currWindowSize[0] = w; currWindowSize[1] = h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w <= h) { windowWidth= 2.0f; windowHeight= 2.0f * (GLfloat)h / (GLfloat)w; glOrtho(-1.0, 1.0, -1.0 * (GLfloat)h / (GLfloat)w, (GLfloat)h / (GLfloat)w, -10.0, 10.0); } else { windowWidth= 2.0f * (GLfloat)w / (GLfloat)h; windowHeight= 2.0f; glOrtho(-1.0 * (GLfloat)w / (GLfloat)h, (GLfloat)w / (GLfloat)h, -1.0, 1.0, -10.0, 10.0); } glMatrixMode(GL_MODELVIEW); } CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 24

  11. OPENGL 2D EXAMPLES ANIMATED POLYGONS In this example, users utilize the keyboard to create spinning 2D polygons. Noteworthy features: • Numerical keys ‘3’ through ‘9’ generate polygons with a corresponding number of sides, random radius and spin, and RGBYMC colors. • A pop-up menu also provides a polygon selection capability. • Each polygon “bounces” off the sides of the window, but ignores the other polygons. CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 25

  12. OPENGL 2D EXAMPLES ANIMATED POLYGONS • Display function renders polygons Noteworthy: • Polygon data will be stored in linked list • Double buffering for animation • Context menu setup • Timer function for updating polygon positions/orientations • Timer function indicates animation • Context menu merely activates keyboard code • Timer function doesn’t render – it just updates the polygons • 2D polygon class • Numerical keys generate polygons /* Default constructor. */ GLfloatPolygon::GLfloatPolygon() { for(int i = 0; i <= 2; i++) polyColor[i] = DEFAULT_COLOR[i]; nbrVerts= DEFAULT_NBR_VERTS; radius = GenerateRandomNumber(RADIUS_RANGE[0], RADIUS_RANGE[1]); x = y = spin = 0.0f; spinInc= GenerateRandomNumber(SPIN_INC_RANGE[0], SPIN_INC_RANGE[1]); xInc= GenerateRandomNumber(X_INC_RANGE[0], X_INC_RANGE[1]); yInc= GenerateRandomNumber(Y_INC_RANGE[0], Y_INC_RANGE[1]); } /* Update the position and orientation of the polygon with each clock tick. */ voidupdate(GLfloatwindowWidth, GLfloatwindowHeight) { GLfloattooHigh; GLfloattooLow; GLfloattooLeft; GLfloattooRight; GLfloattheta, xvalue, yvalue; tooHigh= tooLow = tooLeft = tooRight = 0.0f; // Update polygon position and orientation. // x += xInc; y += yInc; spin += spinInc; if(spin > 360 * PI_OVER_180) spin -= 360 * PI_OVER_180; /* Render the polygon with its latest position and orientation. */ void draw() { GLfloattheta; glColor3fv(polyColor); glBegin(GL_TRIANGLE_FAN); glVertex2f(x, y); for (int j = 0; j < nbrVerts; j++) { theta = spin + 360 * j * PI_OVER_180 / nbrVerts; glVertex2f(x + radius * cos(theta), y + radius * sin(theta)); theta = spin + 360 * (j + 1) * PI_OVER_180 / nbrVerts; glVertex2f(x + radius * cos(theta), y + radius * sin(theta)); } glEnd(); } /* Generate a random floating-point value between the two parameterized values. */ float GenerateRandomNumber(floatlowerBound, float upperBound) { static boolfirstTime = true; static time_trandomNumberSeed; if (firstTime) { time(&randomNumberSeed); firstTime= false; srand((unsigned int)randomNumberSeed); } return (lowerBound+ ((upperBound- lowerBound) * (float(rand()) / RAND_MAX))); } }; #define GLFLOAT_POLYGON_H #endif /* Function to react to the pressing of keyboard keys by the user, */ /* by creating a new polygon with the same number of vertices as the */ /* pressed numerical value, with the next consecutive RGBYMC color. */ voidKeyboardPress(unsignedcharpressedKey, intmouseXPosition, intmouseYPosition) { GLfloatPolygonpoly; staticinti = 0; switch(pressedKey) { case'3': { poly.nbrVerts = 3; break; } case'4': { poly.nbrVerts = 4; break; } case'5': { poly.nbrVerts = 5; break; } case'6': { poly.nbrVerts = 6; break; } case'7': { poly.nbrVerts = 7; break; } case'8': { poly.nbrVerts = 8; break; } case'9': { poly.nbrVerts = 9; break; } default: { return; } } poly.polyColor[0] = ((i == 0) || (i == 3) || (i == 4)) ? HIGH_SHADE : LOW_SHADE; poly.polyColor[1] = ((i == 1) || (i == 3) || (i == 5)) ? HIGH_SHADE : LOW_SHADE; poly.polyColor[2] = ((i == 2) || (i == 4) || (i == 5)) ? HIGH_SHADE : LOW_SHADE; i= (i + 1) % NBR_COLORS; polyList.insert(poly); } // Adjust position & direction if window bounds exceeded. // if(tooRight > 0.0f) { x -= tooRight; xInc*= -1.0f; } elseif (tooLeft > 0.0f) { x += tooLeft; xInc*= -1.0f; } if(tooHigh) { y -= tooHigh; yInc*= -1.0f; } elseif (tooLow) { y += tooLow; yInc*= -1.0f; } } // Determine whether polygon exceeds window boundaries. // for (int i = 0; i < nbrVerts; i++) { theta = spin + 360 * i * PI_OVER_180 / nbrVerts; xvalue= x + radius * cos(theta); yvalue= y + radius * sin(theta); if (xvalue - 0.5f * windowWidth > tooRight) tooRight= xvalue - 0.5f * windowWidth; else if (-0.5f * windowWidth - xvalue > tooLeft) tooLeft= -0.5f * windowWidth - xvalue; if (yvalue - 0.5f * windowHeight > tooHigh) tooHigh= yvalue - 0.5f * windowHeight; else if (-0.5f * windowHeight - yvalue > tooLow) tooLow= -0.5f * windowHeight - yvalue; } ///////////////////////////////////////// // 2D polygon class (for convenience). // ///////////////////////////////////////// #include<GLTools.h> // OpenGL toolkit #include<cmath> // Header File For Math Library #include<ctime> // Header File For Accessing System Time #ifndefGLFLOAT_POLYGON_H ////////////////////// // Global Constants // ////////////////////// constGLfloatPI_OVER_180 = 0.0174532925f; // One Degree. // constGLfloatDEFAULT_COLOR[3] = { 0.5f, 0.5f, 0.5f }; constGLintDEFAULT_NBR_VERTS = 3; constGLfloatRADIUS_RANGE[2] = { 0.15f, 0.45f }; constGLfloatSPIN_INC_RANGE[2] = { 0.1f, 0.2f }; constGLfloatX_INC_RANGE[2] = { 0.02f, 0.05f }; constGLfloatY_INC_RANGE[2] = { 0.02f, 0.05f }; classGLfloatPolygon { public: GLfloatpolyColor[3]; GLintnbrVerts; GLfloatradius; GLfloatx; GLfloaty; GLfloatxInc; GLfloatyInc; GLfloatspin; GLfloatspinInc; for(int i = 0; i <= 1; i++) currWindowSize[i] = INIT_WINDOW_SIZE[i]; glutInitWindowSize( currWindowSize[0], currWindowSize[1] ); glutCreateWindow( "BOUNCING POLYGONS" ); // Ensure proper OpenGL availability, with generic shader. GLenumerr = glewInit(); if(GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); return; } shaderManager.InitializeStockShaders(); /* Set up the pop-up menu. */ glutCreateMenu( MenuSelect ); glutAddMenuEntry( "Triangle", 3 ); glutAddMenuEntry( "Square", 4 ); glutAddMenuEntry( "Pentagon", 5 ); glutAddMenuEntry( "Hexagon", 6 ); glutAddMenuEntry( "Heptagon", 7 ); glutAddMenuEntry( "Octagon", 8 ); glutAddMenuEntry( "Nonagon", 9 ); glutAttachMenu(GLUT_RIGHT_BUTTON); /* Specify the resizing, refreshing, and interactive routines. */ glutReshapeFunc( ResizeWindow ); glutDisplayFunc( Display ); glutKeyboardFunc( KeyboardPress ); glutTimerFunc(CALLBACK_TIME, TimerFunction, 1); glutMainLoop(); } /* Principal display routine: clears the frame buffer */ /* and draws the polygons within the window. */ void Display() { inti; GLfloatPolygoncurrPoly; glClear(GL_COLOR_BUFFER_BIT); // Display each polygon, applying its spin as needed. // for(i = 1; i <= polyList.getSize(); i++) { currPoly= polyList.getHeadValue(); currPoly.draw(); ++polyList; } glutSwapBuffers(); glFlush(); } /* Function to update each polygon's position by "bouncing" */ /* it off the boundaries of the display window. */ void TimerFunction(int value) { GLfloatPolygoncurrPoly; // Loop through the list of polygons. // for(int i = 1; i <= polyList.getSize(); i++) { currPoly= polyList.getHeadValue(); polyList.removeHead(); currPoly.update(windowWidth, windowHeight); polyList.insert(currPoly); ++polyList; } // Force a redraw after 50 milliseconds. // glutPostRedisplay(); glutTimerFunc(CALLBACK_TIME, TimerFunction, 1); } /* Function to react to selection from the pop-up menu, */ /* by generating a polygon of the user-selected type. */ voidMenuSelect(intmenuID) { switch(menuID) { case3: { KeyboardPress( '3', 0, 0 ); break; } case4: { KeyboardPress( '4', 0, 0 ); break; } case5: { KeyboardPress( '5', 0, 0 ); break; } case6: { KeyboardPress( '6', 0, 0 ); break; } case7: { KeyboardPress( '7', 0, 0 ); break; } case8: { KeyboardPress( '8', 0, 0 ); break; } case9: { KeyboardPress( '9', 0, 0 ); break; } default: { break; } } // After processing the menu action, redraw the image without the menu. glutPostRedisplay(); } ////////////////////// // Global Constants // ////////////////////// constGLintINIT_WINDOW_POSITION[2] = { 100, 100 }; // Window Offset. // constGLintINIT_WINDOW_SIZE[2] = { 500, 500 }; // Window dimensions. // constGLfloatWINDOW_WIDTH = 2.0f; // Screen coordinates. // constGLfloatWINDOW_HEIGHT = 2.0f; // Screen coordinates. // constGLfloatORTHO_FAR = 10.0f; // Far plane z-value. // constGLfloatORTHO_NEAR = -10.0f; // Near plane z-value. // const unsigned intCALLBACK_TIME = 50; // Timer in msecs. // constintNBR_COLORS = 6; // # differentcolors. // constGLfloatHIGH_SHADE = 0.9f; // High RGB value. // constGLfloatLOW_SHADE = 0.1f; // Low RGB value. // ////////////////////// // Global Variables // ////////////////////// GLShaderManagershaderManager; // Manager of stock shaders. // GLintcurrWindowSize[2]; // Window size in pixels. // GLfloatwindowWidth = WINDOW_WIDTH; // Resized window width. // GLfloatwindowHeight = WINDOW_HEIGHT; // Resized window height. // LinkedList<GLfloatPolygon> polyList; // Current polygon list. // /* The main function: uses the OpenGL Utility Toolkit to set */ /* the window up to display the window and its contents. */ void main(intargc, char **argv) { /* Set up the display window. */ gltSetWorkingDirectory(argv[0]); glutInit(&argc, argv); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA ); glutInitWindowPosition( INIT_WINDOW_POSITION[0], INIT_WINDOW_POSITION[1] ); /**************************************************************/ /* Filename: BouncingPolygons.cpp */ /* Uses the keyboard to permit the user to interactively add */ /* rotating polygons to a list of shapes bouncing within a */ /* display window. When "lower" and "upper" polygons overlap, */ /* no clipping takes place and the lower ones are obscured. */ /**************************************************************/ #include <GLTools.h> // OpenGL toolkit #include <GLShaderManager.h> // Shader Manager Class #include <cmath> // Header File For Math Library #include <ctime> // Header File For Accessing System Time #include "LinkedList.h" // Header File For Linked List Class #include "GLfloatPolygon.h" // Header File For 2D Polygon Class #ifdef__APPLE__ #include <glut/glut.h>// OS X version of GLUT library #else #define FREEGLUT_STATIC #include <GL/glut.h> // Windows FreeGlut equivalent #endif ///////////////////////// // Function Prototypes // ///////////////////////// void KeyboardPress(unsignedchar pressedKey, intmouseXPosition, intmouseYPosition); void MenuSelect(intmenuID); void TimerFunction(int value); void Display(); void ResizeWindow(GLsizei w, GLsizeih); float GenerateRandomNumber(floatlowerBound, float upperBound); /* Window-reshaping routine, to scale the rendered scene according */ /* to the window dimensions, setting the global variables so the */ /* mouse operations will correspond to mouse pointer positions. */ voidResizeWindow(GLsizeiw, GLsizeih) { glViewport(0, 0, w, h); currWindowSize[0] = w; currWindowSize[1] = h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w <= h) { windowWidth= WINDOW_WIDTH ; windowHeight= WINDOW_HEIGHT * (GLfloat)h / (GLfloat)w; glOrtho(-0.5f * WINDOW_WIDTH, 0.5f * WINDOW_WIDTH, -0.5f * WINDOW_HEIGHT * (GLfloat)h / (GLfloat)w, 0.5f * WINDOW_HEIGHT * (GLfloat)h / (GLfloat)w, ORTHO_NEAR, ORTHO_FAR); } else { windowWidth= WINDOW_WIDTH * (GLfloat)w / (GLfloat)h; windowHeight= WINDOW_HEIGHT; glOrtho(-0.5f * WINDOW_WIDTH * (GLfloat)w / (GLfloat)h, 0.5f * WINDOW_WIDTH * (GLfloat)w / (GLfloat)h, -0.5f * WINDOW_HEIGHT, 0.5f * WINDOW_HEIGHT, ORTHO_NEAR, ORTHO_FAR ); } glMatrixMode(GL_MODELVIEW); } CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 26

  13. OPENGL 3D EXAMPLES QUADRIC SURFACES In this example, users interact with a 3D snowman by tossing 3D snowballs. Noteworthy features: • The scene is composed of various quadric surfaces (spheres, cylinders, disks, cones, etc.) that may be displayed as solid or wireframe objects. • Noteworthy: • Graphical object classes • Global constant header file • Non-ASCII character control • Wireframe & solid implementation • Material & lighting properties • Quadric surfaces CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 27

  14. OPENGL 3D EXAMPLES QUADRIC SURFACES In this example, users employ mouse operations to target and explode 3D asteroid clusters. Noteworthy features: • Instead of using the quadric surfaces from the GLU library, this program makes use of the sphere rendering capabilities of the GLUT library. • Noteworthy: • Mouse-motion reticle control • Ray casting to implement firing • Color morphing • Lifetime-based particle regeneration • User orientation via gluLookAt CS 482 – FALL 2014 AUGUST 20, 2014: GRAPHICS IN OPENGL PAGE 28

More Related