home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Programming Black Book (Special Edition)
/
BlackBook.bin
/
disk1
/
source
/
chapter57
/
xsharp21.exe
/
XFPROJ.C
< prev
next >
Wrap
Text File
|
1992-04-03
|
3KB
|
69 lines
/* 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 the results in the object.
Recalculates object->view transformation because only if the
transform changes would we bother to retransform the vertices.
Also recalculates CenterInView and moves the object through the
object list accordingly.
*/
#include <math.h>
#include "polygon.h"
static Point3 CenterPoint = {0, 0, 0};
void XformAndProjectPObject(PObject * ObjectToXform)
{
int i, NumPoints = ObjectToXform->NumVerts;
int NumRealPoints = ObjectToXform->NumRealVerts;
Point3 * Points = ObjectToXform->VertexList;
Point3 * XformedPoints = ObjectToXform->XformedVertexList;
Point3 * ProjectedPoints =
ObjectToXform->ProjectedVertexList;
Point * ScreenPoints = ObjectToXform->ScreenVertexList;
/* Recalculate the object->view transform */
ConcatXforms(WorldViewXform, ObjectToXform->XformToWorld,
ObjectToXform->XformToView);
/* Recalculate CenterInView */
XformVec(ObjectToXform->XformToView, (Fixedpoint *) &CenterPoint,
(Fixedpoint *) &ObjectToXform->CenterInView);
/* Apply that new transformation and project all polygon vertices (not
unit normal endpoints yet, though) */
for (i=0; i<NumRealPoints; i++, Points++, XformedPoints++,
ProjectedPoints++, ScreenPoints++) {
/* Transform to view space */
XformVec(ObjectToXform->XformToView, (Fixedpoint *) Points,
(Fixedpoint *) XformedPoints);
/* Perspective-project to screen space */
ProjectedPoints->X =
FixedMul(FixedDiv(XformedPoints->X, XformedPoints->Z),
DOUBLE_TO_FIXED(PROJECTION_RATIO * (SCREEN_WIDTH/2)));
ProjectedPoints->Y =
FixedMul(FixedDiv(XformedPoints->Y, XformedPoints->Z),
DOUBLE_TO_FIXED(PROJECTION_RATIO * (SCREEN_WIDTH/2)));
ProjectedPoints->Z = XformedPoints->Z;
/* Convert to screen coordinates. The Y coord is negated to
flip from increasing Y being up to increasing Y being down,
as expected by the polygon filler. Add in half the screen
width and height to center on the screen */
ScreenPoints->X = ((int) ((ProjectedPoints->X +
DOUBLE_TO_FIXED(0.5)) >> 16)) + SCREEN_WIDTH/2;
ScreenPoints->Y = (-((int) ((ProjectedPoints->Y +
DOUBLE_TO_FIXED(0.5)) >> 16))) + SCREEN_HEIGHT/2;
}
/* Now transform the unit normal endpoints into view space, but there's
no reason to waste time getting them into screen space or screen
coordinates */
for (i=NumRealPoints; i<NumPoints; i++, Points++, XformedPoints++) {
/* Transform to view space */
XformVec(ObjectToXform->XformToView, (Fixedpoint *) Points,
(Fixedpoint *) XformedPoints);
}
}