Example: Texture-Mapped Cube

TMcube is quite similar to the Cube example, but it draws a perspective texture-mapped cube instead of a cube with single-color faces.

Six different 64x64 texture maps are used, one for each cube face. The texture maps are stored in CUBE.PCX, a 384x64 256-color PCX file with six 64x64 images arranged horizontally:

The code to initialize Fastgraph's texture map manager and obtain the six texture maps appears in TMcube's WM_CREATE handler:

C/C++:

fg_tminit(6);
fg_showpcx("CUBE.PCX",FG_AT_XY|FG_KEEPCOLORS);
fg_move(0,tmWidth-1);
for (i = 0; i < 6; i++)
{
#if (vbDepth == 8)
   fg_getimage(Texture[i],tmWidth,tmWidth);
   fg_invert(Texture[i],tmWidth,tmWidth);
#else
   fg_getdcb(Texture[i],tmWidth,tmWidth);
   fg_invdcb(Texture[i],tmWidth,tmWidth);
#endif
   hTM[i] = fg_tmdefine(Texture[i],tmWidth,tmWidth);
   fg_moverel(tmWidth,0);
}

Delphi:

fg_tminit(6);
fg_showpcx('CUBE.PCX'+chr(0),FG_AT_XY or FG_KEEPCOLORS);
fg_move(0,tmWidth-1);
for i := 1 to 6 do
begin
  if (vbDepth = 8) then
  begin
    fg_getimage(Texture[i],tmWidth,tmWidth);
    fg_invert(Texture[i],tmWidth,tmWidth);
  end
  else
  begin
    fg_getdcb(Texture[i],tmWidth,tmWidth);
    fg_invdcb(Texture[i],tmWidth,tmWidth);
  end;
  hTM[i] := fg_tmdefine(Texture[i],tmWidth,tmWidth);
  fg_moverel(tmWidth,0);
end;

Visual Basic:

Call fg_tminit(6)
Call fg_showpcx(App.Path & "\CUBE.PCX", FG_AT_XY + FG_KEEPCOLORS)
Call fg_move(0, tmWidth - 1)
For I = 1 To 6
   #If vbDepth = 8 Then
   Call fg_getimage(Texture(1, I), tmWidth, tmWidth)
   Call fg_invert(Texture(1, I), tmWidth, tmWidth)
   #Else
   Call fg_getdcb(Texture(1, I), tmWidth, tmWidth)
   Call fg_invdcb(Texture(1, I), tmWidth, tmWidth)
   #End If
   hTM(I) = fg_tmdefine(Texture(1, I), tmWidth, tmWidth)
   Call fg_moverel(tmWidth, 0)
Next

After loading CUBE.PCX into the virtual buffer and establishing the graphics position at the lower left corner of the CUBE.PCX image, we begin a loop that obtains the texture bitmaps and makes them available to Fastgraph's texture-mapped polygon drawing functions. In each iteration of this loop, we call fg_getimage() or fg_getdcb() to read one 64x64 texture as a 256-color or direct color bitmap, depending on the virtual buffer color depth. We store each texture bitmap in the two-dimensional array Texture, which holds six 64x64 bitmaps. Unlike Fastgraph's ordinary bitmaps, texture bitmaps are stored top-down, so we call fg_invert() or fg_invdcb() to translate them from the bottom-up to the top-down format. Next we call fg_tmdefine() to make the texture available to Fastgraph, saving the texture handle in the hTM array. Finally, we move the graphics position 64 pixels to the right so we can get the next 64x64 texture in the next loop iteration.

Besides creating the texture maps, TMcube's WM_CREATE handler also sets up a z-buffer, defines 3D clipping limits, and sets the render state for perspective texture mapping, z-buffering, and 3D clipping. We set the near clipping plane at z=40, so when a near face passes in front of this plane, we can look inside the cube and see some or all of its otherwise hidden faces. This happens because backface removal isn't applied to z-buffered polygons; instead the z-buffer values determine which faces or parts thereof are visible.

The TMcube program's CheckForMovement() function is almost the same as the one from the Cube example. The only difference is the call to fg_zbframe() at the beginning of the code that redraws the cube in its new position, needed because TMcube uses z-buffering and Cube doesn't.

The DrawCube() functions in the two programs serve the same purpose but are rather different. In the Cube program, we define the polygon's colors with fg_setcolor() and we render each face with fg_3Dpolygonobject(). In TMcube, DrawCube() calls fg_tmselect() to select a texture map for the cube face (using one of the handles returned by fg_tmdefine() in the WM_CREATE handler) and we render it with fg_3Dtexturemapobject(). The tmSource array passed to fg_3Dtexturemapobject() contains the (u,v) texture map coordinates corresponding to each polygon vertex. For each cube face, we store the (x,y,z) object space vertex coordinates starting with the lower right vertex (when the face is viewed straight on) and proceed clockwise around the polygon's perimeter. We do the same thing for the texture map coordinates - that is, we start with the (u,v) coordinates at the lower right corner of the texture map and proceed clockwise around its perimeter.

C/C++ version

C++Builder version

Delphi version

Visual Basic version

<< Prev

Next >>

Contents
Fastgraph Home Page

 

copyright 2001 Ted Gruber Software, Inc.