Low-Level 3D Functions
Fastgraph implements the simplified 3D functions by calling its own low-level 3D functions that perform more specific tasks. There may be times, however, when you need or want to call the low-level 3D functions yourself, so we will briefly describe them in this section. The low-level 3D functions are summarized here:
fg_3Dgetmatrix()
|
Retrieves the elements from one of Fastgraph's 3D rotation, translation, or transformation matrices.
|
fg_3Dproject()
|
Projects a series of transformed 3D points to 2D screen space points.
|
fg_3Dsetmatrix()
|
Defines the elements in one of Fastgraph's 3D rotation, translation, or transformation matrices, and optionally updates any matrix dependencies.
|
fg_3Dtransform()
|
Transforms a series of 3D (x,y,z) points from world space to view space.
|
fg_3Dtransformobject()
|
Transforms a series of 3D (x,y,z) points from object space to view space.
|
fg_3Dupvector()
|
Defines the 3D geometry system's up vector.
|
fg_3Dzclip()
|
Clips a series of 3D (x,y,z) polygon vertices against the z plane clipping value.
|
fg_3Dzcliprgb()
|
Clips 3D polygon vertices and corresponding RGB shading values.
|
fg_3Dzcliptm()
|
Clips 3D polygon vertices and corresponding 2D texture map coordinates.
|
fg_drawz()
|
Draws a projected z-buffered line.
|
fg_gouraud()
|
Draws a projected Gouraud-shaded convex polygon.
|
fg_gouraudz()
|
Draws a projected z-buffered Gouraud-shaded convex polygon.
|
fg_polyfilz()
|
Draws a projected z-buffered filled convex polygon.
|
fg_texmap()
|
Draws a projected linear texture-mapped convex polygon.
|
fg_texmapp()
|
Draws a projected perspective corrected texture-mapped convex polygon.
|
fg_texmappz()
|
Draws a projected z-buffered linear texture-mapped convex polygon.
|
fg_texmapz()
|
Draws a projected z-buffered perspective corrected texture-mapped convex polygon.
|
fg_trig()
|
Returns the floating point cosine and sine of a given angle.
|
To illustrate a typical use of Fastgraph's low-level 3D functions, let's look at how we render the six cube faces in the Cube example:
C/C++:
for (i = 0; i < 6; i++)
{
fg_setcolor(Colors[i]);
fg_3Dpolygonobject((double *)Faces[i],4);
}
Delphi:
for i := 1 to 6 do
begin
fg_setcolor(Colors[i]);
fg_3Dpolygonobject(Faces[i]^,4);
end;
Visual Basic:
For I = 1 To 6
Call fg_setcolor(Colors(I))
Call fg_3Dpolygonobject(Faces(1, I).X, 4)
Next
The Cube program calls fg_3Drenderstate() to enable 3D clipping in its WM_CREATE handler, so fg_3Dpolygonobject() draws a single-color filled polygon with 3D clipping. To achieve this same behavior with the low-level 3D functions, we must do these things for each cube face:
- Call fg_3Dtransformobject() to transform the object space vertices to world space.
- Call fg_3Dzclip() to perform 3D clipping on the transformed vertices.
- Call fg_3Dproject() to project the clipped vertices to screen space.
- Call fg_polyfill() to draw the 2D projected polygon.
If POINT3D is a structure containing three floating point values (x, y, and z), and POINT2D is a structure containing two integer values (x and y), the following code snippet illustrates this sequence:
C/C++:
POINT3D ClippedFace[5];
POINT2D ProjectedFace[5];
POINT3D TransformedFace[4];
for (i = 0; i < 6; i++)
{
fg_setcolor(Colors[i]);
fg_3Dtransformobject((double *)Faces[i],
(double *)TransformedFace,4);
n = fg_3Dzclip((double *)TransformedFace,
(double *)ClippedFace,4);
fg_3Dproject((double *)ClippedFace,(int *)ProjectedFace,n);
fg_polyfill((int *)ProjectedFace,NULL,-n);
}
Delphi:
ClippedFace : array [1..5] of POINT3D;
ProjectedFace : array [1..5] of POINT2D;
TransformedFace : array [1..4] of POINT3D;
for i := 1 to 6 do
begin
fg_setcolor(Colors[i]);
fg_3Dtransformobject(Faces[i]^,TransformedFace,4);
n := fg_3Dzclip(TransformedFace,ClippedFace,4);
fg_3Dproject(ClippedFace,ProjectedFace,n);
fg_polyfill(ProjectedFace,nil^,-n);
end;
Visual Basic:
Dim ClippedFace(5) As Point3D
Dim ProjectedFace(5) As Point2D
Dim TransformedFace(4) As Point3D
For I = 1 To 6
Call fg_setcolor(Colors(I))
Call fg_3Dtransformobject(Faces(1,I).X,TransformedFace(1).X,4)
N = fg_3Dzclip(TransformedFace(1).X,ClippedFace(1).X,4)
Call fg_3Dproject(ClippedFace(1).X,ProjectedFace(1).X,N)
Call fg_polyfill(ProjectedFace(1).X,Null,-N)
Next
Three things are worth pointing out in the above code. First, note how the values calculated by one function become the input values for the next function. Second, 3D clipping can produce a clipped polygon with one more vertex than the unclipped rectangular polygon; we allow for this by making the ClippedFace and ProjectedFace arrays one vertex larger. Finally, we pass a negative vertex count to fg_polyfill() so it performs backface removal.
If we wanted to draw a z-buffered polygon, we would change the fg_polyfill() call to fg_polyfilz(), as shown here:
C/C++:
fg_polyfilz((int *)ProjectedFace,(double *)ClippedFace,n);
Delphi:
fg_polyfilz(ProjectedFace,ClippedFace,n);
Visual Basic:
Call fg_polyfilz(ProjectedFace(1).X, ClippedFace(1).X, N)
Because we don't want backface removal when drawing z-buffered polygons (z-buffering takes care of this automatically), we pass fg_polyfilz() the actual clipped vertex count instead of negating it as we did for fg_polyfill().
If we wanted to draw a Gouraud-shaded cube, we would use fg_3Dzcliprgb() in place of fg_3Dzclip(), and fg_gouraud() or fg_gouraudz() in place of fg_polyfill() or fg_polyfilz(). Similarly, we could draw a texture-mapped cube by calling fg_3Dzcliptm() in place of fg_3Dzclip(), and one of the four low-level texture mapping functions - fg_texmap() , fg_texmapz(), fg_texmapp(), or fg_texmappz() - in place of fg_polyfill() or fg_polyfilz().
The fg_3Dgetmatrix() and fg_3Dsetmatrix() functions are provided for the benefit of experienced 3D programmers who need access to Fastgraph's internal 3D matrices. If you're not familiar with how rotation matrices, translation matrices, and transformation matrices are used in a 3D geometry system, you probably shouldn't call these functions. Similarly, fg_3Dupvector() lets you modify Fastgraph's up vector. If you don't know what an up vector does, you shouldn't change it.
|