CSC 706 Computer Graphics Primitives, Stippling, Fitting In Examples: OpenGL Primitives GL_POINTS GL_LINES LINES GL _ LINE _ STRIP GL_POLYGON GL_LINE_LOOP GL_TRIANGLES GL_QUAD_STRIP GL_TRIANGLE_STRIP GL_TRIANGLE_FAN Graphics Primitives Graphics Primitives cont d Points Lines void drawdot(glint x, GLint y) { glbegin(gl_points); glvertex2i(x,y); } glbegin(gl_lines); glvertex2i(10,50); glvertex2i(80,20); glvertex2i(10,45); Graphics Primitives cont d Polygon types Polylines glvertex2i(50,10); glvertex2i(20,80); glvertex2i(50,80); 1
Polygon Graphics Primitives cont d glbegin(gl_line_loop); glvertex2i(50,10); glvertex2i(20,80); glvertex2i(50,80); Remember to Flush To ensure graphics are output to the drawing window, you must follow the plotting process with: Remember to Flush glbegin(gl_line_loop); glvertex2i(50,10); glvertex2i(20,80); glvertex2i(50,80); Polygon Issues OpenGL will only display polygons correctly that are -Simple: edges cannot cross - Convex: All points on line segment between two points in a polygon are also in the polygon - Flat: all vertices are in the same plane User program can check if above true - OpenGL will produce output if these conditions are violated but it may not be what is desired Triangles satisfy all conditions nonsimple polygon nonconvex polygon Stippling Stippling means to add a pattern to a simple line or the filling of a polygon. OpenGL allows stippling to be performed using bit patterns. Turn stippling on with: glenable(gl_line_stipple); glenable(gl_poly_stipple); Turn off with: gldisable(gl_line_stipple); gldisable(gl_poly_stipple); Line Stippling Defining a line stippling pattern: gllinestipple(glint factor, GLushort pattern); The pattern is a 16 bit sequence of 1s and 0s e.g. 1110111011101110 The factor is a bit multiplier for the pattern (it enlarges it) e.g. factor = 2 turns the above pattern into: 11111100111111001111110011111100 The pattern can be expressed in hexadecimal notation e.g. 0xEECC = 1110111011001100 e.g. gllinestipple(2, 0x7733); 2
Stippled Lines cont d To make stippled (dotted or dashed) lines, you use the command gllinestipple( ) to define the stipple pattern; Then you enable line stippling with glenable( ): gllinestipple(1, 0x3F07); glenable(gl_line_stipple); Line stippling is disabled by passing argument GL_LINE_STIPPLE to gldisable( ). gldisable(gl_line_stipple); Wait a minute.. How do I convert binary to hexadecimal? Hexadecimal character equivalents to 4 bit binary expressions 2. Split the binary into groups of four digits and assign hex values 0100 0010 = 42 1110 1001 = E9 0001 1100 0011 = 1C3 3. Then put 0x in front of the number in your code, e.g. 0xE9 Line Stippling Example gllinestipple(1, 0x3F07); Lets see it in action glenable(gl_line_stipple); gllinestipple(1, 0x7733); glvertex2i(10,10); glvertex2i(600,450); gllinestipple(2, 0xFF00); LINE glvertex2i(10,30); glvertex2i(600,470); gllinestipple(5, 0xFF00); glvertex2i(130,0); glvertex2i(600,430); gldisable(gl_line_stipple); The above example and the pattern 0x3F07 (which translates to 0011111100000111 in binary), a line would be drawn with 3 pixels on, then 5 off, 6 on, and 2 off. (If this seems backward, remember that the low-order order bits are used first.) If factor had been 2, the pattern would have been elongated: 6 pixels on, 10 off, 12 on, and 4 off. Figure 4.1 shows lines drawn with different patterns and repeat factors. If you don't enable line stippling, drawing proceeds as if pattern were 0xFFFF and factor 1. (Use gldisable() with GL_LINE_STIPPLE to disable stippling.) Note that stippling can be used in combination with wide lines to produce wide stippled lines. Fig. 4.1: Stippled Lines Polygon Stippling Defining a polygon stippling pattern: glpolygonstipple(glubyte mask); The pattern is a 128 byte array of 1s and 0s (32 bits across and 32 bits down) e.g. GLubyte mask[ ] = {0xff, 0xfe, 0x34,..}; The pattern is tiled inside the polygon. e.g. glpolygonstipple(mask); Polygon stippling is enabled and disabled by using glenable( ) and gldisable( ) with GL_POLYGON_STIPPLE as an argument. Polygon Stippling The argument mask is a pointer to a 32 x 32 bitmap that's interpreted as a mask of 0s and 1s. Where a 1 appears, the corresponding pixel in the polygon is drawn, and where a 0 appears, nothing is drawn. Figure 4.2 shows how a stipple pattern is constructed from the characters in mask. 3
Polygon Stippling cont d Example 2 - Polygon Stippling Example 2 - output /* draw one solid, unstippled rectangle, */ /* then two stippled rectangles */ glrectf (25.0, 25.0, 125.0, 125.0); glenable (GL_POLYGON_STIPPLE); glpolygonstipple (fly); glrectf (125.0, 25.0, 225.0, 125.0); glpolygonstipple (fire); glrectf (225.0, 10.0, 400.0, 325.0); gldisable (GL_POLYGON_STIPPLE); Polygon Stippling Lets see it in action glenable(gl_polygon_stipple); GLubyte mask[] = {0x31, 0xfe, 0x34, 0x12, 0xff, 0xfc, 0x00, 0x12, 0xaa, 0xfe, 0x00, 0x12, 0xaa, 0xfe, 0x00, 0x12, 0xfc, 0xfe, 0x00, 0x12, 0xff, 0xfe, 0x00, 0x12, }; glpolygonstipple(mask); glbegin(gl_polygon); glvertex2i(10,10); glvertex2i(600,450); glvertex2i(45,300); glvertex2i(240,460); gldisable(gl_polygon_stipple); Sometimes you may want to print out a plot of some data when the data ranges are unknown. However, you want them to appear in the window presented in a visually pleasing manner. e x E.g. Let s plot cos( 2πx) Plotted with screen coordinates of 640 x 480 we will get: A data plot is no good if we can t see it!! 4
How do we MAGNIFY the data? Stretch out X Stretch out Y Simple Dot Plots Draw a function for values of x between 0 and 4? Steps: sample it at a collection of equispaced x- values; plot a dot at each coordinate pair (xi, f(xi)); choose some suitable increment, say 0.005, between consecutive x-values. Simple Dot Plots cont d glbegin(gl_points); for(gldouble x = 0; x < 4.0 ; x += 0.005) glvertex2d(x, f(x)); Problems: The picture produced will be impossibly tiny because values of x between 0 and 4 map to the first four pixels at the bottom left of the screen window. Further, the negative values of f(.) will lie below the window and will not be seen at all. We therefore need to scale and position the values to be plotted so they cover the screen window area appropriately. The X coordinates of the window range over 640 values (from 0 to 639). The X values for the data range from 0 to 4. We need to modify the data values so that data point 0 maps to window coordinate 0 and data point 4 maps to window coordinate 640. In essence we want 4 to be plotted at 640. 4 * A = 640; A = 160;.. or for all cases A = SCREENWIDTH/x max Therefore, x = x * A. if x ranges from 0.. x max If x ranges from say 1 to 4 then we will want to stretch a range of 3 out instead of 4, therefore: A = SCREENWIDTH/(x max x min ) The same applies for the y coordinates: C = SCREENHEIGHT/(y max -y min ) 5
Dot Plots: scaling and shifting Scaling x: Fitting In x = Ax + B and y = Cy + D A = SCREENWIDTH/(xmax-xmin) B = -xmin*a C = SCREENHEIGHT/(ymax-ymin) D = ymin *C Scaling and shifting y: A and C are scalars B and D are translators Moving it around Setting Values for A, B, C and D The conversions from x to sx,, and from y to sy,, have the form: sx = A * x + B sy = C * y + D where Example void mydisplay(void) { for(glfloat x = -4.0; x < 4.0; x += 0.1) { GLfloat y = sin(3.14159 * x) / (3.14159 * x); glvertex2f(x, y); } } 6