abrash-black-book/52-02.html
2013-12-30 12:21:49 +11:00

191 lines
7.2 KiB
HTML

<HTML>
<HEAD>
<META name=vsisbn content="1576101746">
<META name=vstitle content="Michael Abrash's Graphics Programming Black Book, Special Edition">
<META name=vsauthor content="Michael Abrash">
<META name=vspublisher content="The Coriolis Group">
<META name=vspubdate content="07/01/97">
<META name=vscategory content="Web and Software Development: Game Development,Web and Software Development: Graphics and Multimedia Development">
<TITLE>Michael Abrash's Graphics Programming Black Book Special Edition: Fast 3-D Animation: Meet X-Sharp</TITLE>
<!-- HEADER -->
<!-- Empty Reference Subhead -->
<!--ISBN=1576101746//-->
<!--TITLE=Michael Abrash's Graphics Programming Black Book Special Edition//-->
<!--AUTHOR=Michael Abrash//-->
<!--PUBLISHER=The Coriolis Group, Inc.//-->
<!--CHAPTER=52//-->
<!--PAGES=973-974//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="52-01.html">Previous</A></TD>
<TD><A HREF="index.html">Table of Contents</A></TD>
<TD><A HREF="52-03.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<P><B>LISTING 52.1 L52-1.C</B></P>
<!-- CODE //-->
<PRE>
/* 3-D animation program to rotate 12 cubes. Uses fixed point. All C code
tested with Borland C++ in C compilation mode and the small model. */
#include &ltconio.h&gt
#include &ltdos.h&gt
#include &#147;polygon.h&#148;
/* base offset of page to which to draw */
unsigned int CurrentPageBase = 0;
/* clip rectangle; clips to the screen */
int ClipMinX = 0, ClipMinY = 0;
int ClipMaxX = SCREEN_WIDTH, ClipMaxY = SCREEN_HEIGHT;
static unsigned int PageStartOffsets[2] =
{PAGE0_START_OFFSET,PAGE1_START_OFFSET};
int DisplayedPage, NonDisplayedPage;
int RecalcAllXforms = 1, NumObjects = 0;
Xform WorldViewXform; /* initialized from floats */
/* pointers to objects */
Object *ObjectList[MAX_OBJECTS];
void main() {
int Done = 0, i;
Object *ObjectPtr;
union REGS regset;
InitializeFixedPoint(); /* set up fixed-point data */
InitializeCubes(); /* set up cubes and add them to object list; other
objects would be initialized now, if there were any */
Set320x240Mode(); /* set the screen to mode X */
ShowPage(PageStartOffsets[DisplayedPage = 0]);
/* Keep transforming the cube, drawing it to the undisplayed page,
and flipping the page to show it */
do {
/* For each object, regenerate viewing info, if necessary */
for (i=0; i&ltNumObjects; i++) {
if ((ObjectPtr = ObjectList[i])-&gtRecalcXform ||
RecalcAllXforms) {
ObjectPtr-&gtRecalcFunc(ObjectPtr);
ObjectPtr-&gtRecalcXform = 0;
}
}
RecalcAllXforms = 0;
CurrentPageBase = /* select other page for drawing to */
PageStartOffsets[NonDisplayedPage = DisplayedPage ^ 1];
/* For each object, clear the portion of the non-displayed page
that was drawn to last time, then reset the erase extent */
for (i=0; i&ltNumObjects; i++) {
ObjectPtr = ObjectList[i];
FillRectangleX(ObjectPtr-&gtEraseRect[NonDisplayedPage].Left,
ObjectPtr-&gtEraseRect[NonDisplayedPage].Top,
ObjectPtr-&gtEraseRect[NonDisplayedPage].Right,
ObjectPtr-&gtEraseRect[NonDisplayedPage].Bottom,
CurrentPageBase, 0);
ObjectPtr-&gtEraseRect[NonDisplayedPage].Left =
ObjectPtr-&gtEraseRect[NonDisplayedPage].Top = 0x7FFF;
ObjectPtr-&gtEraseRect[NonDisplayedPage].Right =
ObjectPtr-&gtEraseRect[NonDisplayedPage].Bottom = 0;
}
/* Draw all objects */
for (i=0; i&ltNumObjects; i++)
ObjectList[i]-&gtDrawFunc(ObjectList[i]);
/* Flip to display the page into which we just drew */
ShowPage(PageStartOffsets[DisplayedPage = NonDisplayedPage]);
/* Move and reorient each object */
for (i=0; i&ltNumObjects; i++)
ObjectList[i]-&gtMoveFunc(ObjectList[i]);
if (kbhit())
if (getch() == 0x1B) Done = 1; /* Esc to exit */
} while (!Done);
/* Return to text mode and exit */
regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */
int86(0x10, &ampregset, &ampregset);
exit(1);
}
</PRE>
<!-- END CODE //-->
<P><B>LISTING 52.2 L52-2.C</B></P>
<!-- CODE //-->
<PRE>
/* Transforms all vertices in the specified polygon-based object into view
space, then perspective projects them to screen space and maps them to screen
coordinates, storing results in the object. Recalculates object-&gtview
transformation because only if transform changes would we bother
to retransform the vertices. */
#include &ltmath.h&gt
#include &#147;polygon.h&#148;
void XformAndProjectPObject(PObject * ObjectToXform)
{
int i, NumPoints = ObjectToXform-&gtNumVerts;
Point3 * Points = ObjectToXform-&gtVertexList;
Point3 * XformedPoints = ObjectToXform-&gtXformedVertexList;
Point3 * ProjectedPoints = ObjectToXform-&gtProjectedVertexList;
Point * ScreenPoints = ObjectToXform-&gtScreenVertexList;
/* Recalculate the object-&gtview transform */
ConcatXforms(WorldViewXform, ObjectToXform-&gtXformToWorld,
ObjectToXform-&gtXformToView);
/* Apply that new transformation and project the points */
for (i=0; i&ltNumPoints; i++, Points++, XformedPoints++,
ProjectedPoints++, ScreenPoints++) {
/* Transform to view space */
XformVec(ObjectToXform-&gtXformToView, (Fixedpoint *) Points,
(Fixedpoint *) XformedPoints);
/* Perspective-project to screen space */
ProjectedPoints-&gtX =
FixedMul(FixedDiv(XformedPoints-&gtX, XformedPoints-&gtZ),
DOUBLE_TO_FIXED(PROJECTION_RATIO * (SCREEN_WIDTH/2)));
ProjectedPoints-&gtY =
FixedMul(FixedDiv(XformedPoints-&gtY, XformedPoints-&gtZ),
DOUBLE_TO_FIXED(PROJECTION_RATIO * (SCREEN_WIDTH/2)));
ProjectedPoints-&gtZ = XformedPoints-&gtZ;
/* Convert to screen coordinates. The Y coord is negated to flip from
increasing Y being up to increasing Y being down, as expected by polygon
filler. Add in half the screen width and height to center on screen. */
ScreenPoints-&gtX = ((int) ((ProjectedPoints-&gtX +
DOUBLE_TO_FIXED(0.5)) &gt&gt 16)) + SCREEN_WIDTH/2;
ScreenPoints-&gtY = (-((int) ((ProjectedPoints-&gtY +
DOUBLE_TO_FIXED(0.5)) &gt&gt 16))) + SCREEN_HEIGHT/2;
}
}<B></B>
</PRE>
<!-- END CODE //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="52-01.html">Previous</A></TD>
<TD><A HREF="index.html">Table of Contents</A></TD>
<TD><A HREF="52-03.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<hr width="90%" size="1" noshade>
<div align="center">
<font face="Verdana,sans-serif" size="1">Graphics Programming Black Book &copy; 2001 Michael Abrash</font>
</div>
<!-- all of the reference materials (books) have the footer and subfoot reveresed -->
<!-- reference_subfoot = footer -->
<!-- reference_footer = subfoot -->
<!-- BEGIN SUB FOOTER -->
</BODY>
</HTML>
<!-- END FOOTER -->