238 lines
9.3 KiB
HTML
238 lines
9.3 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<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>
|
|
<meta name="chapter" content="52" />
|
|
<meta name="pages" content="981-984" />
|
|
</head>
|
|
|
|
<body>
|
|
<center>
|
|
<table border="1">
|
|
<tr>
|
|
<td>
|
|
<a href="52-05.html">Previous</a>
|
|
</td>
|
|
|
|
<td>
|
|
<a href="index.html">Table of Contents</a>
|
|
</td>
|
|
|
|
<td>
|
|
<a href="52-07.html">Next</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</center>
|
|
|
|
<p><b>LISTING 52.9 L52-9.ASM</b></p>
|
|
<pre>
|
|
; 386-specific fixed point multiply and divide.
|
|
;
|
|
; C near-callable as: Fixedpoint FixedMul(Fixedpoint M1, Fixedpoint M2);
|
|
; Fixedpoint FixedDiv(Fixedpoint Dividend, Fixedpoint Divisor);
|
|
;
|
|
; Tested with TASM
|
|
;
|
|
.model small
|
|
.386
|
|
.code
|
|
public _FixedMul,_FixedDiv
|
|
; Multiplies two fixed-point values together.
|
|
FMparms struc
|
|
dw 2 dup(?) ;return address & pushed BP
|
|
M1 dd ?
|
|
M2 dd ?
|
|
FMparms ends
|
|
align 2
|
|
_FixedMul proc near
|
|
push bp
|
|
mov bp,sp
|
|
mov eax,[bp+M1]
|
|
imul dword ptr [bp+M2] ;multiply
|
|
add eax,8000h ;round by adding 2^(-16)
|
|
adc edx,0 ;whole part of result is in DX
|
|
shr eax,16 ;put the fractional part in AX
|
|
pop bp
|
|
ret
|
|
_FixedMul endp
|
|
; Divides one fixed-point value by another.
|
|
FDparms struc
|
|
dw 2 dup(?) ;return address & pushed BP
|
|
Dividend dd ?
|
|
Divisor dd ?
|
|
FDparms ends
|
|
align 2
|
|
_FixedDiv proc near
|
|
push bp
|
|
mov bp,sp
|
|
sub cx,cx ;assume positive result
|
|
mov eax,[bp+Dividend]
|
|
and eax,eax ;positive dividend?
|
|
jns FDP1 ;yes
|
|
inc cx ;mark it's a negative dividend
|
|
neg eax ;make the dividend positive
|
|
FDP1: sub edx,edx ;make it a 64-bit dividend, then shift
|
|
; left 16 bits so that result will be in EAX
|
|
rol eax,16 ;put fractional part of dividend in
|
|
; high word of EAX
|
|
mov dx,ax ;put whole part of dividend in DX
|
|
sub ax,ax ;clear low word of EAX
|
|
mov ebx,dword ptr [bp+Divisor]
|
|
and ebx,ebx ;positive divisor?
|
|
jns FDP2 ;yes
|
|
dec cx ;mark it's a negative divisor
|
|
neg ebx ;make divisor positive
|
|
FDP2: div ebx ;divide
|
|
shr ebx,1 ;divisor/2, minus 1 if the divisor is
|
|
adc ebx,0 ; even
|
|
dec ebx
|
|
cmp ebx,edx ;set Carry if remainder is at least
|
|
adc eax,0 ; half as large as the divisor, then
|
|
; use that to round up if necessary
|
|
and cx,cx ;should the result be made negative?
|
|
jz FDP3 ;no
|
|
neg eax ;yes, negate it
|
|
FDP3: mov edx,eax ;return result in DX:AX; fractional
|
|
; part is already in AX
|
|
shr edx,16 ;whole part of result in DX
|
|
pop bp
|
|
ret
|
|
_FixedDiv endp
|
|
end
|
|
</pre>
|
|
|
|
<p><b>LISTING 52.10 POLYGON.H</b></p>
|
|
<pre>
|
|
/* POLYGON.H: Header file for polygon-filling code, also includes
|
|
a number of useful items for 3-D animation. */
|
|
|
|
#define MAX_OBJECTS 100 /* max simultaneous # objects supported */
|
|
#define MAX_POLY_LENGTH 4 /* four vertices is the max per poly */
|
|
#define SCREEN_WIDTH 320
|
|
#define SCREEN_HEIGHT 240
|
|
#define PAGE0_START_OFFSET 0
|
|
#define PAGE1_START_OFFSET (((long)SCREEN_HEIGHT*SCREEN_WIDTH)/4)
|
|
#define NUM_CUBE_VERTS 8 /* # of vertices per cube */
|
|
#define NUM_CUBE_FACES 6 /* # of faces per cube */
|
|
/* Ratio: distance from viewpoint to projection plane / width of
|
|
projection plane. Defines the width of the field of view. Lower
|
|
absolute values = wider fields of view; higher values = narrower */
|
|
#define PROJECTION_RATIO -2.0 /* negative because visible Z
|
|
coordinates are negative */
|
|
/* Draws the polygon described by the point list PointList in color
|
|
Color with all vertices offset by (X,Y) */
|
|
#define DRAW_POLYGON(PointList,NumPoints,Color,X,Y) \
|
|
Polygon.Length = NumPoints; Polygon.PointPtr = PointList; \
|
|
FillConvexPolygon(&Polygon, Color, X, Y);
|
|
#define INT_TO_FIXED(x) (((long)(int)x) << 16)
|
|
#define DOUBLE_TO_FIXED(x) ((long) (x * 65536.0 + 0.5))
|
|
|
|
typedef long Fixedpoint;
|
|
typedef Fixedpoint Xform[3][4];
|
|
/* Describes a single 2D point */
|
|
typedef struct { int X; int Y; } Point;
|
|
/* Describes a single 3D point in homogeneous coordinates; the W
|
|
coordinate isn't present, though; assumed to be 1 and implied */
|
|
typedef struct { Fixedpoint X, Y, Z; } Point3;
|
|
typedef struct { int X; int Y; int Z; } IntPoint3;
|
|
/* Describes a series of points (used to store a list of vertices that
|
|
describe a polygon; each vertex is assumed to connect to the two
|
|
adjacent vertices; last vertex is assumed to connect to first) */
|
|
typedef struct { int Length; Point * PointPtr; } PointListHeader;
|
|
/* Describes the beginning and ending X coordinates of a single
|
|
horizontal line */
|
|
typedef struct { int XStart; int XEnd; } HLine;
|
|
/* Describes a Length-long series of horizontal lines, all assumed to
|
|
be on contiguous scan lines starting at YStart and proceeding
|
|
downward (used to describe a scan-converted polygon to the
|
|
low-level hardware-dependent drawing code). */
|
|
typedef struct { int Length; int YStart; HLine * HLinePtr;} HLineList;
|
|
typedef struct { int Left, Top, Right, Bottom; } Rect;
|
|
/* structure describing one face of an object (one polygon) */
|
|
typedef struct { int * VertNums; int NumVerts; int Color; } Face;
|
|
typedef struct { double RotateX, RotateY, RotateZ; } RotateControl;
|
|
typedef struct { Fixedpoint MoveX, MoveY, MoveZ, MinX, MinY, MinZ,
|
|
MaxX, MaxY, MaxZ; } MoveControl;
|
|
/* fields common to every object */
|
|
#define BASE_OBJECT \
|
|
void (*DrawFunc)(); /* draws object */ \
|
|
void (*RecalcFunc)(); /* prepares object for drawing */ \
|
|
void (*MoveFunc)(); /* moves object */ \
|
|
int RecalcXform; /* 1 to indicate need to recalc */ \
|
|
Rect EraseRect[2]; /* rectangle to erase in each page */
|
|
/* basic object */
|
|
typedef struct { BASE_OBJECT } Object;
|
|
/* structure describing a polygon-based object */
|
|
typedef struct {
|
|
BASE_OBJECT
|
|
int RDelayCount, RDelayCountBase; /* controls rotation speed */
|
|
int MDelayCount, MDelayCountBase; /* controls movement speed */
|
|
Xform XformToWorld; /* transform from object->world space */
|
|
Xform XformToView; /* transform from object->view space */
|
|
RotateControl Rotate; /* controls rotation change over time */
|
|
MoveControl Move; /* controls object movement over time */
|
|
int NumVerts; /* # vertices in VertexList */
|
|
Point3 * VertexList; /* untransformed vertices */
|
|
Point3 * XformedVertexList; /* transformed into view space */
|
|
Point3 * ProjectedVertexList; /* projected into screen space */
|
|
Point * ScreenVertexList; /* converted to screen coordinates */
|
|
int NumFaces; /* # of faces in object */
|
|
Face * FaceList; /* pointer to face info */
|
|
} PObject;
|
|
|
|
extern void XformVec(Xform, Fixedpoint *, Fixedpoint *);
|
|
extern void ConcatXforms(Xform, Xform, Xform);
|
|
extern int FillConvexPolygon(PointListHeader *, int, int, int);
|
|
extern void Set320x240Mode(void);
|
|
extern void ShowPage(unsigned int);
|
|
extern void FillRectangleX(int, int, int, int, unsigned int, int);
|
|
extern void XformAndProjectPObject(PObject *);
|
|
extern void DrawPObject(PObject *);
|
|
extern void AppendRotationX(Xform, double);
|
|
extern void AppendRotationY(Xform, double);
|
|
extern void AppendRotationZ(Xform, double);
|
|
extern near Fixedpoint FixedMul(Fixedpoint, Fixedpoint);
|
|
extern near Fixedpoint FixedDiv(Fixedpoint, Fixedpoint);
|
|
extern void InitializeFixedPoint(void);
|
|
extern void RotateAndMovePObject(PObject *);
|
|
extern void InitializeCubes(void);
|
|
extern int DisplayedPage, NonDisplayedPage, RecalcAllXforms;
|
|
extern int NumObjects;
|
|
extern Xform WorldViewXform;
|
|
extern Object *ObjectList[];
|
|
extern Point3 CubeVerts[];
|
|
</pre>
|
|
|
|
<center>
|
|
<table border="1">
|
|
<tr>
|
|
<td>
|
|
<a href="52-05.html">Previous</a>
|
|
</td>
|
|
|
|
<td>
|
|
<a href="index.html">Table of Contents</a>
|
|
</td>
|
|
|
|
<td>
|
|
<a href="52-07.html">Next</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</center>
|
|
<hr width="90%" size="1" noshade="noshade" />
|
|
|
|
<div align="center">
|
|
Graphics Programming Black Book © 2001 Michael Abrash
|
|
</div>
|
|
</body>
|
|
</html>
|