Use backtick code blocks for syntax highlighting

This commit is contained in:
James Gregory 2013-12-31 11:38:48 +11:00
commit f658bfbb40
203 changed files with 26546 additions and 25801 deletions

174
51-04.md
View file

@ -12,98 +12,102 @@ pages: 960-963
**LISTING 51.2 L51-2.C**
/* Transforms all vertices in the specified object into view spa ce, then
perspective projects them to screen space and maps them to screen coordinates,
storing the results in the object. */
#include <math.h>
#include "polygon.h"/
```c
/* Transforms all vertices in the specified object into view spa ce, then
perspective projects them to screen space and maps them to screen coordinates,
storing the results in the object. */
#include <math.h>
#include "polygon.h"/
void XformAndProjectPoints(double Xform[4][4],
struct Object * ObjectToXform)
{
int i, NumPoints = ObjectToXform->NumVerts;
struct Point3 * Points = ObjectToXform->VertexList;
struct Point3 * XformedPoints = ObjectToXform->XformedVertexList;
struct Point3 * ProjectedPoints = ObjectToXform->ProjectedVertexList;
struct Point * ScreenPoints = ObjectToXform->ScreenVertexList;
void XformAndProjectPoints(double Xform[4][4],
struct Object * ObjectToXform)
{
int i, NumPoints = ObjectToXform->NumVerts;
struct Point3 * Points = ObjectToXform->VertexList;
struct Point3 * XformedPoints = ObjectToXform->XformedVertexList;
struct Point3 * ProjectedPoints = ObjectToXform->ProjectedVertexList;
struct Point * ScreenPoints = ObjectToXform->ScreenVertexList;
for (i=0; i<NumPoints; i++, Points++, XformedPoints++,
ProjectedPoints++, ScreenPoints++) {
/* Transform to view space */
XformVec(Xform, (double *)Points, (double *)XformedPoints);
/* Perspective-project to screen space */
ProjectedPoints->X = XformedPoints->X / XformedPoints->Z *
PROJECTION_RATIO * (SCREEN_WIDTH / 2.0);
ProjectedPoints->Y = XformedPoints->Y / XformedPoints->Z *
PROJECTION_RATIO * (SCREEN_WIDTH / 2.0);
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) floor(ProjectedPoints->X + 0.5)) + SCREEN_WIDTH/2;
ScreenPoints->Y = (-((int) floor(ProjectedPoints->Y + 0.5))) +
SCREEN_HEIGHT/2;
}
}
for (i=0; i<NumPoints; i++, Points++, XformedPoints++,
ProjectedPoints++, ScreenPoints++) {
/* Transform to view space */
XformVec(Xform, (double *)Points, (double *)XformedPoints);
/* Perspective-project to screen space */
ProjectedPoints->X = XformedPoints->X / XformedPoints->Z *
PROJECTION_RATIO * (SCREEN_WIDTH / 2.0);
ProjectedPoints->Y = XformedPoints->Y / XformedPoints->Z *
PROJECTION_RATIO * (SCREEN_WIDTH / 2.0);
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) floor(ProjectedPoints->X + 0.5)) + SCREEN_WIDTH/2;
ScreenPoints->Y = (-((int) floor(ProjectedPoints->Y + 0.5))) +
SCREEN_HEIGHT/2;
}
}
```
**LISTING 51.3 L51-3.C**
/* Draws all visible faces (faces pointing toward the viewer) in the specified
object. The object must have previously been transformed and projected, so
that the ScreenVertexList array is filled in. */
#include "polygon.h"
```c
/* Draws all visible faces (faces pointing toward the viewer) in the specified
object. The object must have previously been transformed and projected, so
that the ScreenVertexList array is filled in. */
#include "polygon.h"
void DrawVisibleFaces(struct Object * ObjectToXform)
{
int i, j, NumFaces = ObjectToXform->NumFaces, NumVertices;
int * VertNumsPtr;
struct Face * FacePtr = ObjectToXform->FaceList;
struct Point * ScreenPoints = ObjectToXform->ScreenVertexList;
long v1,v2,w1,w2;
struct Point Vertices[MAX_POLY_LENGTH];
struct PointListHeader Polygon;
void DrawVisibleFaces(struct Object * ObjectToXform)
{
int i, j, NumFaces = ObjectToXform->NumFaces, NumVertices;
int * VertNumsPtr;
struct Face * FacePtr = ObjectToXform->FaceList;
struct Point * ScreenPoints = ObjectToXform->ScreenVertexList;
long v1,v2,w1,w2;
struct Point Vertices[MAX_POLY_LENGTH];
struct PointListHeader Polygon;
/* Draw each visible face (polygon) of the object in turn */
for (i=0; i<NumFaces; i++, FacePtr++) {
NumVertices = FacePtr->NumVerts;
/* Copy over the face's vertices from the vertex list */
for (j=0, VertNumsPtr=FacePtr->VertNums; j<NumVertices; j++)
Vertices[j] = ScreenPoints[*VertNumsPtr++];
/* Draw only if outside face showing (if the normal to the
polygon points toward the viewer; that is, has a positive
Z component) */
v1 = Vertices[1].X - Vertices[0].X;
w1 = Vertices[NumVertices-1].X - Vertices[0].X;
v2 = Vertices[1].Y - Vertices[0].Y;
w2 = Vertices[NumVertices-1].Y - Vertices[0].Y;
if ((v1*w2 - v2*w1) > 0) {
/* It is facing the screen, so draw */
/* Appropriately adjust the extent of the rectangle used to
erase this page later */
for (j=0; j<NumVertices; j++) {
if (Vertices[j].X > EraseRect[NonDisplayedPage].Right)
if (Vertices[j].X < SCREEN_WIDTH)
EraseRect[NonDisplayedPage].Right = Vertices[j].X;
else EraseRect[NonDisplayedPage].Right = SCREEN_WIDTH;
if (Vertices[j].Y > EraseRect[NonDisplayedPage].Bottom)
if (Vertices[j].Y < SCREEN_HEIGHT)
EraseRect[NonDisplayedPage].Bottom = Vertices[j].Y;
else EraseRect[NonDisplayedPage].Bottom=SCREEN_HEIGHT;
if (Vertices[j].X < EraseRect[NonDisplayedPage].Left)
if (Vertices[j].X > 0)
EraseRect[NonDisplayedPage].Left = Vertices[j].X;
else EraseRect[NonDisplayedPage].Left = 0;
if (Vertices[j].Y < EraseRect[NonDisplayedPage].Top)
if (Vertices[j].Y > 0)
EraseRect[NonDisplayedPage].Top = Vertices[j].Y;
else EraseRect[NonDisplayedPage].Top = 0;
}
/* Draw the polygon */
DRAW_POLYGON(Vertices, NumVertices, FacePtr->Color, 0, 0);
}
}
}
/* Draw each visible face (polygon) of the object in turn */
for (i=0; i<NumFaces; i++, FacePtr++) {
NumVertices = FacePtr->NumVerts;
/* Copy over the face's vertices from the vertex list */
for (j=0, VertNumsPtr=FacePtr->VertNums; j<NumVertices; j++)
Vertices[j] = ScreenPoints[*VertNumsPtr++];
/* Draw only if outside face showing (if the normal to the
polygon points toward the viewer; that is, has a positive
Z component) */
v1 = Vertices[1].X - Vertices[0].X;
w1 = Vertices[NumVertices-1].X - Vertices[0].X;
v2 = Vertices[1].Y - Vertices[0].Y;
w2 = Vertices[NumVertices-1].Y - Vertices[0].Y;
if ((v1*w2 - v2*w1) > 0) {
/* It is facing the screen, so draw */
/* Appropriately adjust the extent of the rectangle used to
erase this page later */
for (j=0; j<NumVertices; j++) {
if (Vertices[j].X > EraseRect[NonDisplayedPage].Right)
if (Vertices[j].X < SCREEN_WIDTH)
EraseRect[NonDisplayedPage].Right = Vertices[j].X;
else EraseRect[NonDisplayedPage].Right = SCREEN_WIDTH;
if (Vertices[j].Y > EraseRect[NonDisplayedPage].Bottom)
if (Vertices[j].Y < SCREEN_HEIGHT)
EraseRect[NonDisplayedPage].Bottom = Vertices[j].Y;
else EraseRect[NonDisplayedPage].Bottom=SCREEN_HEIGHT;
if (Vertices[j].X < EraseRect[NonDisplayedPage].Left)
if (Vertices[j].X > 0)
EraseRect[NonDisplayedPage].Left = Vertices[j].X;
else EraseRect[NonDisplayedPage].Left = 0;
if (Vertices[j].Y < EraseRect[NonDisplayedPage].Top)
if (Vertices[j].Y > 0)
EraseRect[NonDisplayedPage].Top = Vertices[j].Y;
else EraseRect[NonDisplayedPage].Top = 0;
}
/* Draw the polygon */
DRAW_POLYGON(Vertices, NumVertices, FacePtr->Color, 0, 0);
}
}
}
```
The sample program, as shown in Figure 51.3, places a cube, floating in
three-space, under the complete control of the user. The arrow keys may