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

189 lines
7.3 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: Adding a Dimension</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=50//-->
<!--PAGES=946-948//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="50-05.html">Previous</A></TD>
<TD><A HREF="index.html">Table of Contents</A></TD>
<TD><A HREF="50-07.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<P><B>LISTING 50.5 L50-5.C</B></P>
<!-- CODE //-->
<PRE>
/* Simple 3-D drawing program to view a polygon as it rotates in
Mode X. View space is congruent with world space, with the
viewpoint fixed at the origin (0,0,0) of world space, looking in
the direction of increasingly negative Z. A right-handed
coordinate system is used throughout.
Tested with Borland C&#43;&#43; in the small model. */
#include &ltconio.h&gt
#include &ltstdio.h&gt
#include &ltdos.h&gt
#include &ltmath.h&gt
#include &#147;polygon.h&#148;
void main(void);
/* 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;
/* Rectangle specifying extent to be erased in each page */
struct Rect EraseRect[2] = { {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT},
{0, 0, SCREEN_WIDTH, SCREEN_HEIGHT} };
/* Transformation from polygon&#146;s object space to world space.
Initially set up to perform no rotation and to move the polygon
into world space -140 units away from the origin down the Z axis.
Given the viewing point, -140 down the Z axis means 140 units away
straight ahead in the direction of view. The program dynamically
changes the rotation and translation. */
static double PolyWorldXform[4][4] = {
{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, -140.0},
{0.0, 0.0, 0.0, 1.0} };
/* Transformation from world space into view space. In this program,
the view point is fixed at the origin of world space, looking down
the Z axis in the direction of increasingly negative Z, so view
space is identical to world space; this is the identity matrix. */
static double WorldViewXform[4][4] = {
{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}
};
static unsigned int PageStartOffsets[2] =
{PAGE0_START_OFFSET,PAGE1_START_OFFSET};
int DisplayedPage, NonDisplayedPage;
void main() {
int Done = 0;
double WorkingXform[4][4];
static struct Point3 TestPoly[] =
{{-30,-15,0,1},{0,15,0,1},{10,-5,0,1}};
#define TEST_POLY_LENGTH (sizeof(TestPoly)/sizeof(struct Point3))
double Rotation = M_PI / 60.0; /* initial rotation = 3 degrees */
union REGS regset;
Set320x240Mode();
ShowPage(PageStartOffsets[DisplayedPage = 0]);
/* Keep rotating the polygon, drawing it to the undisplayed page,
and flipping the page to show it */
do {
CurrentPageBase = /* select other page for drawing to */
PageStartOffsets[NonDisplayedPage = DisplayedPage ^ 1];
/* Modify the object space to world space transformation matrix
for the current rotation around the Y axis */
PolyWorldXform[0][0] = PolyWorldXform[2][2] = cos(Rotation);
PolyWorldXform[2][0] = -(PolyWorldXform[0][2] = sin(Rotation));
/* Concatenate the object-to-world and world-to-view
transformations to make a transformation matrix that will
convert vertices from object space to view space in a single
operation */
ConcatXforms(WorldViewXform, PolyWorldXform, WorkingXform);
/* Clear the portion of the non-displayed page that was drawn
to last time, then reset the erase extent */
FillRectangleX(EraseRect[NonDisplayedPage].Left,
EraseRect[NonDisplayedPage].Top,
EraseRect[NonDisplayedPage].Right,
EraseRect[NonDisplayedPage].Bottom, CurrentPageBase, 0);
EraseRect[NonDisplayedPage].Left =
EraseRect[NonDisplayedPage].Top = 0x7FFF;
EraseRect[NonDisplayedPage].Right =
EraseRect[NonDisplayedPage].Bottom = 0;
/* Transform the polygon, project it on the screen, draw it */
XformAndProjectPoly(WorkingXform, TestPoly, TEST_POLY_LENGTH,9);
/* Flip to display the page into which we just drew */
ShowPage(PageStartOffsets[DisplayedPage = NonDisplayedPage]);
/* Rotate 6 degrees farther around the Y axis */
if ((Rotation &#43;= (M_PI/30.0)) &gt= (M_PI*2)) Rotation -= M_PI*2;
if (kbhit()) {
switch (getch()) {
case 0x1B: /* Esc to exit */
Done = 1; break;
case &#145;A&#146;: case &#145;a&#146;: /* away (-Z) */
PolyWorldXform[2][3] -= 3.0; break;
case &#145;T&#146;: /* towards (&#43;Z). Don&#146;t allow to get too */
case &#145;t&#146;: /* close, so Z clipping isn&#146;t needed */
if (PolyWorldXform[2][3] &lt -40.0)
PolyWorldXform[2][3] &#43;= 3.0; break;
case 0: /* extended code */
switch (getch()) {
case 0x4B: /* left (-X) */
PolyWorldXform[0][3] -= 3.0; break;
case 0x4D: /* right (&#43;X) */
PolyWorldXform[0][3] &#43;= 3.0; break;
case 0x48: /* up (&#43;Y) */
PolyWorldXform[1][3] &#43;= 3.0; break;
case 0x50: /* down (-Y) */
PolyWorldXform[1][3] -= 3.0; break;
default:
break;
}
break;
default: /* any other key to pause */
getch(); break;
}
}
} while (!Done);
/* Return to text mode and exit */
regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */
int86(0x10, &ampregset, &ampregset);
}
</PRE>
<!-- END CODE //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="50-05.html">Previous</A></TD>
<TD><A HREF="index.html">Table of Contents</A></TD>
<TD><A HREF="50-07.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 -->