Beruflich Dokumente
Kultur Dokumente
Graphics commands specify straight lines or other geometric primitives that are scan-converted into a set of discrete intensity pixels in the framebuffer (back buffer) Color points in the frame buffer are sent to the corresponding pixels in the display device by a video controller
The purpose of this section is to understand how the drawing primitives and clipping are implemented
1
.1.
2
.2.
Example: J1_2_Line
void line(int x0,int y0,int xn,int yn) { // for 1 m 1 int x; float m, y; m = (float) (yn-y0)/(xn-x0); x=x0; y=y0; while (x<xn+1) { // write a pixel into the framebuffer glBegin(GL_POINTS); glVertex2i (x, (int) (y+0.5)); glEnd(); x++; y+=m;/* next pixel's position */ } }
Copyright @ 2011 by Jim X. Chen: jchen@cs.gmu.edu
.3.
1.2.line
The shortcoming of the previous algorithm is that rounding y to an integer takes time.
NE P (xp, yp) M1 Q E
1.2.line 1.3.line
y = (dy/dx)x +B, that is F(x,y)=dy*x - dx*y + B*dx =0 F(x,y) = ax + by + c = 0 when (x,y) on the line, where a=dy>0, b=-dx<0, and c=B*dx>0. F(x,y) > 0 when (x,y) below the line, and F(x,y) < 0 when (x,y) above the line.
Copyright @ 2006 by Jim X. Chen: jchen@cs.gmu.edu 4
.4.
If F(xp +1, yp +1/2)>0, Q above M, choose NE; else choose E. Therefore we have a decision variable: dold = F(xp +1, yp +1/2) = F(xp, yp) + a + b/2 = a + b/2 If dold <=0, E is chosen: dnew = F(xp +2, yp +1/2) = dold + a If dold >0, NE is chosen: dnew = F(xp +2, yp +3/2) = dold + a+b a and b are integers. Multiply the decision equations by 2 for integer operation: dold = 2F(xp +1, yp +1/2) = 2F(xp, yp) + 2a + b = 2a + b If dold <=0, E is chosen: dnew = 2F(xp +2, yp +1/2) = dold + 2a If dold >0, NE is chosen: dnew = 2F(xp +2, yp +3/2) = dold + 2a+2b Lets call dE = 2a = 2dy, dNE = 2(a + b) = 2(dy dx), then If dold <=0: dnew = dold + dE If dold >0: dnew = dold + dNE
5
.5.
We only need to decide if (d old >0) to choose NE or E, and update dnew accordingly with an integer addition.
Example: J1_3_Line
void line(int x0,int y0,int xn,int yn) { // Bresenham's midpoint line algorithm int dx, dy, dE, dNE, d, x, y, flag = 0; ...; // taking care of all slopes x=x0; y=y0; d=2*dy-dx; dE=2*dy; dNE=2*(dy-dx); while (x<xn+1) { writepixel(x,y,flag); x++; // next pixel if (d<=0) d+=dE; else { y++; d+=dNE; }; } }
Copyright @ 2006 by Jim X. Chen: jchen@cs.gmu.edu 6
.6.
x2+y2 =R2, therefore y=(R2-x2)1/2. We can increase x form 0 to R/2 to draw the corresponding points at (x,y), (y,x), (y,-x), (x,-y), (-x,-y), (-y,-x), (-y,x), (-x,y). void circlePixel(float x, float y) { WritePixel(x,y);WritePixel(y,x); WritePixel(-x,y);WritePixel(-y,x); WritePixel(x,-y);WritePixel(y,-x); WritePixel(-x,-y);WritePixel(-y,-x); }
Poloar Coordinates
x = xc + rcos(a); y = yc + rsin(a);
double cx = WIDTH/2, cy = HEIGHT/2, //center of the circle r = WIDTH/3, // radius of the circle delta = 1/r; // angle for one unit apart: 2PI/2PI*r public void drawCircle(double x0, double y0, double r) { double th = 0; while (th<=Math.PI/4) { th = th+delta; double x = r*Math.cos(th); double y = r*Math.sin(th); drawPoint(x+x0, y+y0); drawPoint(x+x0, -y+y0); drawPoint(-x+x0, y+y0); drawPoint(-x+x0, -y+y0); drawPoint(y+x0, x+y0); drawPoint(y+x0, -x+y0); drawPoint(-y+x0, x+y0); drawPoint(-y+x0, -x+y0); } }
8
Example: J1_3_CircleLine
We often draw line segments instead of real curves
void circle(double cx, double cy, double r) { double xn, yn, theta = 0, delta = 0.1; // the delta angle for a line segment double x0 = r*Math.cos(theta)+cx; double y0 = r*Math.sin(theta)+cy; while (theta<2*Math.PI) { theta = theta + delta; xn = r*Math.cos(theta)+cx; yn = r*Math.sin(theta)+cy; bresenhamLine((int)x0, (int)y0, (int)xn, (int)yn); x0 = xn; y0 = yn; } }
SE
10
.10.
Parabolic path: (parametric equation) x = x0 + vx0t y = y0 + vy0t gt2/2 Hyperbolic pathes: (x/rx) 2 - (y/ry) 2 = 1
11
.11.
12
3D Spline: two adjacent curve sections have the same coordinate position at the boundary and the slopes at the boundary are equal. x = ax + bxt + cxt2 + dxt3
FILLING RECTANGLES
for (y=ymin; y<ymax; y++) for (x=xmin; x<xmax; x++) WritePixel(x,y,value);
SCAN-CONVERTING POLYGONS
Find the intersections of the scan-line with all edges of the polygon. Sort the intersections by increasing the x coordinate. Fill in all pixels between pairs of intersections that lie interior to the polygon, using the odd-parity rule to determine that a point is inside a region.
14
.14.
Scan-line algorithm for filling polygons ET (edge table) -- all edges sorted by the smaller y coords; AET (active-edge table) corresponds to the current scan-line
11 10 9 8 7 6 5 4 3 2 1 0
y
EF
9 7 -5/2
DE
11 7 3/2
CD
11 13 0
FA
9 2 0
AB
3 7
-5/2
BC
5 7 3/2
ymax x 1/m
11 10 9 8 7 6 5 4 3 2 1 0
y
F E
C A B 1 2 3 4 5 6 7 8 9 10 11 12 13
FA
y=9
9 2 0 9
EF
2 -5/2
DE
11 10 3/2
CD
11 13 0
y=10
DE
11
23/2 3/2
CD
11 13 0
ymax x 1/m
15
.15.
Set y to the smallest y that has an entry in the ET. Initialize the AET to be empty. Repeat until the AET and ET are empty:
1. 2. 3. 4. 5. 6. Move from ET bucket y to AET those edges whose ymin = y. Sort the AET on x. Fill-in desired pixel values on scan-line y by using pairs of x coord. From the AET. Increment y by 1. Remove from the AET those entries that y=ymax. For each non-vertical edge remaining in the AET, update x for the new y: x = x + 1/m.
Example: J1_3_Triangle
16
.16.
OpenGL Implementation
A convex polygon means that all the angles inside the polygon formed by the edges are smaller than 180 degrees. If a polygon is not convex, it is concave. Convex polygons can be scan-converted faster than concave polygons.
2.
18
.18.
CHARACTERS Characters are polygons. However, they are used very often Type-face, font: the overall design style for a set of characters, Courier, Helvetica, Times, etc. Bitmap Can represent the character shapes by rectangular grid patterns (bitmap font) Or describe character shapes by lines and curves, as in Postscript (outline font)
Outline
Bitmap fonts require more space, because each variation (size or format) must be stored
19
.19.
Outline fonts require more time to produce, because they must be scan converted Small bitmaps do not scale well. Different bitmaps (sizes and typefaces) are defined
accessing fonts is platform dependent. GLUT provides a simple platform independent subset of font functions. GLX provides font functions and interfaces between OpenGL and the X window system. WGL is the equivalent of GLX on the Microsoft Windows platform. Example: J1_3_xFont
Copyright @ 2006 by Jim X. Chen: jchen@cs.gmu.edu 20
.20.
Example: J1_3_xFont
import javax.media.opengl.*; import com.sun.opengl.util.*; public class J1_3_xFont extends J1_3_Triangle { static GLUT glut = new GLUT();
21
.21.
CLIPPING
Window is defined by: glOrtho(l, r, b, t, n, f);
22
.22.
23
J1_3_windowClipping
public void drawPoint(double x, double y) {
// clip against the window if (x < lLeft[0] || x > uRight[0]) { return; } if (y < lLeft[1] || y > uRight[1]) { return; }
super.drawPoint(x, y);
24
A plane equation Ax + By + Cz + D = 0 A 3D line equation x = x0 + t(x1 - x0); y = y0 + t(y1 - y0); z = z0 + t(z1 - z0); The intersection of the line with the plane is at a specific t
Copyright @ 2006 by Jim X. Chen: jchen@cs.gmu.edu 25
At each step, 0, 1, or 2 vertices are added to the output list of vertices that defines the clipped polygon edge. Four possible cases must be analyzed: starting & ending vertices inside (add ending vertice p to the output list) starting inside, ending outside (add intersection vertice i) starting outside, ending inside (add i, p) starting outside, ending outside (continue)
26
.26.
4.