home *** CD-ROM | disk | FTP | other *** search
- /* Simple 3D 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++ 4.02 in small model by Jim Mischel 12/16/94
- */
- #include <conio.h>
- #include <stdio.h>
- #include <dos.h>
- #include <math.h>
- #include "polygon.h"
- 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'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 += (M_PI/30.0)) >= (M_PI*2)) Rotation -= M_PI*2;
- if (kbhit()) {
- switch (getch()) {
- case 0x1B: /* Esc to exit */
- Done = 1; break;
- case 'A': case 'a': /* away (-Z) */
- PolyWorldXform[2][3] -= 3.0; break;
- case 'T': /* towards (+Z). Don't allow to get too */
- case 't': /* close, so Z clipping isn't needed */
- if (PolyWorldXform[2][3] < -40.0)
- PolyWorldXform[2][3] += 3.0; break;
- case 0: /* extended code */
- switch (getch()) {
- case 0x4B: /* left (-X) */
- PolyWorldXform[0][3] -= 3.0; break;
- case 0x4D: /* right (+X) */
- PolyWorldXform[0][3] += 3.0; break;
- case 0x48: /* up (+Y) */
- PolyWorldXform[1][3] += 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, ®set, ®set);
- }
-