Dec 092017
ASM and C source code for M. Abrash's X Sharp 3D animation project. From Dr. Dobbs Journal.
File XSHARP21.ZIP from The Programmer’s Corner in
Category Files from Magazines
ASM and C source code for M. Abrash’s X Sharp 3D animation project. From Dr. Dobbs Journal.
File Name File Size Zip Size Zip Type
APPROT.C 4160 633 deflated
BALL 0 0 stored
ADDROT.C 3335 584 deflated
GENBALL.C 10203 2675 deflated
K.BAT 21 20 deflated
LINKRESP 134 78 deflated
MAKEFILE 170 127 deflated
MATMATH.C 1385 439 deflated
POLYGON.H 3905 1386 deflated
TURBOC.CFG 64 56 deflated
BALVERT0.INC 7687 1653 deflated
COLOR.C 1890 780 deflated
COSTABLE.INC 6803 2070 deflated
DEMO1.C 6615 2053 deflated
DRAW.ASM 7301 2136 deflated
DRAWPOBJ.C 6660 1888 deflated
DRAWTEX.ASM 18264 4478 deflated
DRAWTEXP.C 9291 2864 deflated
FILLCNVX.C 7983 2240 deflated
FILLRECT.ASM 5372 1696 deflated
FIXED.ASM 35183 4863 deflated
GAMMA 0 0 stored
GAMMA.C 825 390 deflated
K.BAT 13 13 stored
GENCOS.C 1283 586 deflated
GLOBALS.C 956 497 deflated
INITBALL.C 13415 2262 deflated
INITFIX.C 465 295 deflated
INITLIGH.C 1762 477 deflated
INITPAL.C 2831 943 deflated
K1.BAT 81 80 deflated
LIGHTING.C 4463 1181 deflated
LINKRESP 280 167 deflated
MAKEFILE 479 262 deflated
MODE.ASM 3615 1319 deflated
MOVEOBJ.C 3213 673 deflated
OLIST.C 3050 881 deflated
POLYGON.H 10762 3449 deflated
README 15445 5802 deflated
SCAN.ASM 7932 2063 deflated
SETPIXEL.ASM 1948 788 deflated
SHOWPAGE.ASM 1979 797 deflated
TURBOC.CFG 60 50 deflated
XFPROJ.C 2964 955 deflated
XSHARP21 40 40 stored

Download File XSHARP21.ZIP Here

Contents of the README file

This is the source for the X-Sharp 3-D animation package, version 21,
as presented in the Graphics Programming column in Dr. Dobb's
Journal, as of the October 1992 issue. Fast, assembly-language texture
mapped polygons have been added since the last version, version 20.
The code has been tested with Borland C++ 3.0 and TASM 3.0. To make
the X-Sharp demo program DEMO1, run K1.BAT. When you run DEMO1, I
suggest you use the '0' key to turn on a spotlight, then use the 'S'
key to speed up the rotation and switch between X, Y, and Z as the
axis of rotation. Also keep an eye peeled for "ursanauts"!

Unpack this archive with PKUNZIP -d; the ball generation code belongs
in the .\BALL subdirectory, and, because it has some of the same
filenames as the main directory, problems will result without -d.

Files in this archive:

APPROT.C - appends rotations in X, Y, and Z
BALL - subdirectory containing ball-generation code; see below
BALVERT0.INC - include file generated by .\BALL\GENBALL that defines
ball-shaped object
COLOR.C - RGB space -> adapter palette space color mapping, color
intensity adjustment
COSTABLE.INC - include file for fixed-point cosines between 0 and 90 degrees,
generated by GENCOS
DEMO1.C - X-Sharp demo program
DEMO1.EXE - demo program built by running K1.BAT
DRAW.ASM - draws the scanned-out pixels of a convex polygon in mode X
DRAWPOBJ.C - draws a polygon-based object
DRAWTEX.ASM - assembly-language implementation of inner-loop texture drawing
DRAWTEXP.C - draws a texture-mapped polygon
FILLCNVX.C - fills a convex polygon
FILLRECT.ASM - fills a rectangle with a solid color in mode X
FIXED.ASM - fixed point arithmetic routines
GAMMA - subdirectory containing gamma correction table generation
GENCOS.C - generates cosine table for fixed-point look-up
GLOBALS.C - global variables
INITBALL.C - initializes the ball-shaped object
INITFIX.C - initializes fixed-point data
INITLIGH.C - sets up initial illumination (ambient and diffuse lighting)
INITPAL.C - sets up the adapter color palette
K1.BAT - remakes X-Sharp, producing demo program DEMO1
LIGHTING.C - illumination control
LINKRESP - TLINK response file
MAKEFILE - Borland Make makefile
MODE.ASM - initializes the screen to mode X (320x240, 256 colors)
MOVEOBJ.C - updates the position and orientation of polygon-based objects
OLIST.C - object list initialization, handling, and sorting
POLYGON.H - polygon & 3-D header file
README - this file
SCAN.ASM - scans out an edge of a convex polygon
SHOWPAGE.ASM - selects the video page that's visible
TURBOC.CFG - Borland C++ 3.0 configuration file. Uses 3.0-specific
options, which must be changed for 2.0 and earlier
XFPROJ.C - transforms and projects polygon-based objects
XSHARP21 - ID file for the X-Sharp version

The subdirectory .\BALL contains the source code and executable for
the program GENBALL, which creates the vertex and face lists for a
ball made from rectangular faces (BALVERT0.INC was created by GENBALL).
Remake GENBALL by running K.BAT in the .\BALL directory. See the
12/29/91 log entry for details.

Note that TURBOC.CFG specifies full optimization for BC++ 3.0 with
-O2 -Oa. You will have to change these switches for earlier versions
of BC++.

Note that this code uses 386-specific instructions unless USE386 is
set to 0 in FIXED.ASM. With USE386 set to 0, the demo will run on an 8088
or 286, but performance is poor except on a very fast 286. Performance is
quite good on a 20 MHz 386, and very good--30 to 60 frames per second--on
a 33 MHz 486.

Comments and questions may be directed to me in the following ways:

Bix: graphic.disp or graphic.pgms conferences or Bixmail (mabrash)
MCI mail (mabrash)
M&T Online conference (mabrash)
U.S. Mail (7 Adirondack Street, South Burlington, VT 05403)

I will do my best to respond, time permitting. No guarantees.

Bix is the best way to get hold of me.

This material may be used freely; it is provided free of charge, as
are responses to questions and comments, within reason. Should the
spirit move you, a contribution to the Vermont Assocation for the
Blind and Visually Impaired, sent care of Dr. Dobb's Journal, myself,
or directly to VABVI, would be appreciated, and would motivate me to
keep enhancing X-Sharp. Please make checks payable to the Vermont
Association for the Blind and Visually Impaired.

Vermont Association for the Blind and Visually Impaired
37 Elmwood Avenue
Burlington, VT 05401

Dr. Dobb's Journal
411 Borel Avenue, Suite 100
San Mateo, CA 94403-3522

* This code is provided as-is, with no warranties of any sort. *
* So far as I know, it works fine, but use it at your own risk! *

--Michael Abrash 7/5/92

* Log of changes *

Begin entry for 7/5/92

Implemented single-scan-line texture-map drawing (inner loop for drawing
texture-mapped polygons) in reasonably tight assembly language in
DRAWTEX.ASM. Also changed texture-map algorithm to half-include all
texture-map pixels that map to edges, so that textures will remain
reasonably symmetric as the destination polygons to which they are
mapped rotate.

Begin entry for 6/10/92

Added texture-mapped polygons, drawn by DRAWTEXP.ASM. Implementation
is currently in C and not particularly fast, but does work pretty
well. There are rough edges remaining in which source pixels get
mapped to which destination pixels; right now, things follow the
standard polygon edge rules, which hold that pixels exactly on the
right and bottom edges aren't drawn. This causes slightly different
portions of the image to be mapped in depending on the orientation of
the destination polygon. Also, there are some problems resulting from
the use of truncated integers as screen coordinates. Still, the results
look good and don't miss any destination pixels, so the code is
certainly usable right now.

Begin entry for 5/2/92

Altered DRAW.ASM to draw as much as possible a word at a time.

Begin entry for 4/3/92

Implemented support for 8088 and 286 fixed-point math in FIXED.ASM.
Previously, only 386 and up processors were supported. See comments in
FIXED.ASM for limitations of the 8088/286 version of FixedDiv().

Altered the polygon Face structure so that the first vertex in the vertex
list (VertNums) for any shaded polygon must now be the endpoint of a unit
normal vector that has the second vertex in the vertex list as the
startpoint. This unit vector is then transformed along with the rest of the
polygon, and is used for calculating diffuse shading. Note that the first
vertex in the polygon's vertex list is *not* a vertex of the actual polygon,
just the endpoint of the unit normal. However, the second vertex in the
polygon's vertex list *is* a vertex of the actual polygon. Look at
GENBALL.C, in subdirectory BALL, to see an example of the creation of
polygon vertices and face lists. Note that NumVerts in the polygon
Face structure does not count the first (unit-normal endpoint) vertex.

Changed XFPROJ.C so that unit normal endpoints are only transformed into
view space, not into screen space or screen coordinates. Since the unit
normals are useless once they're transformed into screen space (they're not
normals at that point, because perspective transformation doesn't preserve
angles), there's no reason to waste time transforming them into screen space,
so we don't. This requires that the unit normal endpoints *always* be the
last endpoints in an object's vertex list, and that NumRealVerts (a new entry
in the PObject structure) now specifies how many real polgyon vertices there
are (that is, how many vertices there are excluding unit normal endpoints),
so that XFPROJ.C knows to only transform NumRealVerts vertices into screen

Implemented a full-color color model. Polygon colors are now described as
RGB triples, with 8 bits of resolution for each color component. These
colors are stored in ModelColor structures. There is a ModelColor entry
in each polygon's Face structure. There is also a ColorIndex entry,
specifying a direct color index to be used for drawing the polygon; this is
equivalent to the previous style of drawing polygons, and is used only for
unshaded (unilluminated) polygons. Of course, the VGA doesn't have 24 bits
per pixel. InitializePalette(), in INITPAL.C, sets up the palette however
you'd like; currently with 64 levels each of pure red, green, and blue, and
2 levels each of red, green, and blue for mixing. This is a good model for
displaying pure primary colors, but suffers severe color quantization for
mixed colors. ModelColorToColorIndex(), in COLOR.C, maps colors from the
model 24-bit RGB color space into the actual available palette. Note that
InitializePalette() and ModelColorToColorIndex() are designed as replaceable
modules, so any desired adapter-specific color mapping can easily be
implemented; the rest of X-Sharp works in 24-bit RGB space.

Implemented two types of shading: ambient and diffuse (Lambert). Ambient
shading is nondirectional illumination, basically background light.
Diffuse shading is directed illumination, treated as illumination by
infinitely distant spotlights in X-Sharp and defined by a unit vector for
direction and an RGB intensity for illumination level. Added the ShadingType
field to the polygon Face structure to select either, both, or neither of
selected shading, using the unit normal of each polygon (discussed above),
the RGB color of the polygon, the unit vector of each spotlight, and the
intensity of each spotlight to calculate the shading for each polygon.
Created the ModelIntensity structure to describe ambient and spotlight
intensity levels as fixed-point RGB values. Added a variety of functions
to control illumination in LIGHTING.C. Added InitializeLighting() to set
up the initial lighting state.

Implemented main program DEMO1.C, which displays a shaded, faceted ball with
ambient lighting and three user-controllable spotlights, as well as
user-controllable positioning, as the current X-Sharp demo program. This
replaces the previous demo program XS.C.

Modified INITBALL.C to support the new polygon format, new color model, and
shading. The ball now has 71 faces that are illuminated with both diffuse
and ambient shading, and 1 unshaded face that always has a constant color,

Eliminated INITCUBE.C.

Renamed MOVEPOLY.C to MOVEOBJ.C and changed function RotateAndMovePObject()
to handle movement events set in main() and renamed the function to

Modified .\BALL\GENBALL.C to generate the new polygon format, with the
first vertex for each face now the endpoint of a unit normal coming out of
the second vertex. The first vertex is not a part of the polygon, but is
only used to determine the polygon's orientation. See the above entry on
the polygon Face structure for details.

Other, minor changes such as the addition of some macros have been made. I'm
afraid I don't remember 'em all...

End entry for 4/3/92
Begin entry for 1/5/92

Altered ConcatXforms to add in the translation element from matrix #1

only when multiplying by the fourth column of matrix #2, because only
the fourth column has a 1 at the bottom. This fixes a bug in earlier
versions that showed up when a world->view transformation involving
translation was used.

Removed setting of non-existent element XformToWorld[3][3] in INITCUBE.C

End entry for 1/5/92
Begin entry for 12/29/91

Converted XformVec and ConcatXforms to assembly language, reducing
transformation and concatenation time to 5% or less of total time.

Converted sin() and cos() calls to calls to the assembly language
function CosSin(), which performs a table look-up. Changed angle
representations from radians to tenths of degrees to facilitate table
look-up and to maximize accuracy.

Put all the assembly language functions in fixed.asm, replacing
l4.c and l9.asm.

Deleted one cube from the animation, and substituted a ball. The
ball has a radius of 25, slightly larger than the cube it replaces.
It has 6 bands of 12 facets each, for a total of 72 faces,
approximately doubling the number of polygons in the animation, and
has 62 vertices, increasing the number of vertices by more than 50%.
Added INITBALL.C to initialize the ball, and added a call to
InitializeBalls() to create the ball in main(). Only one ball is
created, but more balls could easily be added, and the size of and
number of bands in the ball(s) could easily be changed.

The program GENBALL, in .\BALL, generates all vertex and face info
for a generic ball (it doesn't generate the color info, which varies
from instance to instance). The number of bands of faces and the
size of the ball are prompted for when GENBALL is run. The output of
GENBALL with 6 bands and a radius of 25 is in BALVERT0.INC, and is
included in INITBALL.C, which initializes a ball for use in the
animation program. To change the size, just regenerate BALVERT0.INC
by running GENBALL with bands = 6 and the desired radius. To change
the number of bands, run GENBALL with the desired number of bands and
radius, and then change the Colors array in INITBALL.C to have one
color entry for each face in the new ball. (The number of faces is
shown as a define at the top of the output file from GENBALL.)
Additional balls may be added by changing NUM_BALLS, and by adding a
new entry to each array at the top of GENBALL.C.

Changed object list from an array to a linked list that is sorted
in back-to-front order after each set of moves, so drawing the list
in order performs proper hiding of objects.

Renamed source files more meaningfully, and renamed executable XS.EXE.

Added a center (0,0,0) point to each object, which is transformed into
view space each time the object is transformed. This is used for
Z-sorting objects for drawing precedence purposes, and can also be
used for collision detection and the like.

End entry for 12/29/91

 December 9, 2017  Add comments

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>