home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 3
/
TheARMClub_PDCD3.iso
/
hensa
/
graphics
/
b109_1
/
!3D_Utils
/
!Help
< prev
next >
Wrap
Text File
|
1994-01-15
|
11KB
|
279 lines
version=1.07
The 3D_utils module provides some useful and very fast swi's to draw 3d
graphics in 256 colour modes. It can draw dithered quadrangles 10 to 20 times
as fast as the OS, can take care of rotating vectors, adding perspective and
showing simple 3d objects.
Question: Why would you use such a routine
Answer: - It is much faster as the OS-routines. It is made of optimised
machine code. I think I can garantee it is at least 2.5x as fast as
the OS routine for any convex quadrangle. In normal use it will be
about 10 times as fast.
- It provides dithering without any speed decrement, thus giving more
colours. If I remember correctly you have 1704 shades.
- It is easy to use.
Question: Why not to use such a routine
Answer: - You are restricted to >=256 color modes.
- It has problems with very large quadrangles (but so has the OS)
- There may be some bugs
It provides the following SWI's:
SWI "TD_ScreenAddress",r0
Sets the screenaddress, which is needed by the module.
r0=ScreenAddress (of the top-left point)
The current screenaddress can be asked by:
DIM p 8:p!0=149:p!4=-1:SYS"OS_ReadVduVariables",p,p:ScreenAd=!p
Note that the screenaddress changes when scrolling happens
SWI "TD_QuadrangleList",r0,r1
draws a number of quadrangles.
r0=pointer to first data structure. The structure must be word-aligned
and looks like this:
x0,y0,x1,y1,x2,y2,x3,y3,16bit colour
The origin is on the middle of the screen, x and y are in
OS-units. The 16bit colour allows you to dither two colours;
colour=256*colour0+colour1, where colour0,1 is the 'poke-
colour' which varies from 0 to 255. Each structure takes 36
bytes of memory. More in the general notes on drawing
quadrangles.
r1=number of data structures. Checked to be smaller than 65536.
SWI "TD_Rotate",r0,r1,r2,r3,r4
rotates a number of 3 dimensional integer vectors
r0=pointer to data to be rotated. The data consist of a number of
vectors, looking like:x0,y0,z0, x1,y1,z1, x2,y2,z2, etc.
r1=pointer to place rotated points
r2=pointer to the rotation matrix. This consist of 9 integers:
a0,a1,a2,b0,b1,b2,c0,c1,c2
The new coordinates are calculated as follows:
x'=a0*x+a1*y+a2*z
y'=b0*x+b1*y+b2*z
z'=c0*x+c1*y+c2*z
Be aware of overflows! Look at the demo for a nice matrix.
r3=number of points to be rotated. Checked to be smaller than 65536.
r4=right shift factor
after calculation, the values for x and y are right shifted by
this value.
SWI "TD_ClrScreen",r0
Fills the screen with a certain colour.
r0=16 bit colour
SWI "TD_Quadrangle",x0,y0,x1,y1,x2,y2,x3,y3,16b colour
Draws one quadrangle. Read the general notes on drawing quadrangles.
SWI "TD_Point",x,y,8b colour
Places one point.
SWI "TD_Perspective",r0,r1,r2,r3,r4
Does a simple perspective transformation on 3d integer vectors.
x'=(x+x0)*(2^r2-z)*2^-r2
y'=(y+y0)*(2^r2-z)*2^-r2
z'=z
r0=pointer to rotated points: array of (x,y,z)
r1=number of points
r2=perspective factor (in bits)
r3=X movement position (x0)
r4=Y movement position (y0)
Look at the demo for an example on its use.
SWI "TD_DrawSimple",r0,r1,r2
Displays convex 3-dimensional objects. In no way the polygons are
sorted. The first in the list is the first to be drawn. Still this
allows you to draw open or closed convex objects. (Elite uses only
such objects) Even some closed, concave objects may be drawn by the
swi, if you sort the polygons in the right way.
r0=pointer to list of vectors (X, Y, and Z) X and Y are screen
coordinates, Z is not used. 12 bytes per vector.
r1=pointer to list of quadrangles. The quadrangles must be flat. Only
polygons that are positively orientated are drawn. This means
that each polygon has a front and a back. The back is never
drawn. The orientation is calculated from points 1,2 and 3.
data structure: char reference to point1
char reference to point2
char reference to point3
char reference to point4, or if you want a
triangle equal to point3
char colour 1
char colour 2
The case (colour1=254 and colour2<128) is
reserved for future use.
the structure takes up 6 bytes.
r2=number of quadrangles to be drawn
SWI "TD_CurrentScreen"
Sets the screenaddress to the currently displayed screen.
SWI "TD_GetInfo" TO R0
Gives some info about the module
r0=pointer to infoblock:
struct infoblock {
( 0) int version*100
( 4) int screenmode
( 8) int arm optimisation
(12) int offset /*screen offset */
(16) int x0,y0,x1,y1 /*original working window in
pixels*/
(32) int screensize /*in bytes*/
(36) int X os units/pixel, Y os units/pixel
(44) int count /*number of quadrangles drawn
since startup*/
(48) void *debug /*pointer to debug field*/
(52) int flags /*bit field of flags 0 is false,
1 is true.
bit 0:a test for convexivity
is done.
bit 1:this module is a special
hack. It may behave un-
defined. */
(56) int swicount /*number of times a SWI was
invoked*/
(60) int colourbits /*bits per pixel: 1,2,4,8 or 16*/
}
SWI "TD_PointList",R0,R1
Plots a number of points
r0=pointer to first data structure. The structures must be word-
aligned and looks like this: struct pointlist {int x,int y,int color}.
The color is an 8 bit value.
r1=number of structures, checked to be smaller than 524288.
SWI "TD_RGBto16bit",R0,R1,R2 TO R0
converts RGB values to a 16 bit number which can be used by this
module. If you use another palette than the default, or you don't
like the colour the swi gives, feel free to change it yourself.
R0=red value, in the range 0 to 255
R1=green value, in the range 0 to 255
R2=blue value, in the range 0 to 255
R0 on exit=16 bit colour. It is (in this version) not garanteed that
this is the best fitting colour in the palette.
SWI "TD_Decompress",R0,R1
decompresses a piece of memory which was compressed with TD_Compress
(does not exists [yet]) Be careful with its use.
R0=pointer to place decompressed data
R1=pointer to read compressed data
SWI "TD_DrawSorted",R0,R1,R2,R3
As TD_DrawSimple, but now the polygons are sorted according to its
distance in the Z-direction. Although this will draw more objects
correctly than TD_DrawSimple, this is still not enough to draw complex
objects.
R3=0 (reserved)
SWI "TD_SetWindow",R0,R1,R2,R3 TO R0,R1,R2,R3
Sets the graphic window for TD_Point and TD_Line. The values are not
checked to fit the screen; this is your responsibility.
R0=X of point left-under
R1=Y of point left-under
R2=X of point top-right
R3=Y of point top-right
If you set one or more of the coordinates larger than 65535, that
coordinate will not change.
On exit, R0 to R3 will contain the current value of the corresponding
window coordinate.
SWI "TD_Line",R0,R1,R2,R3,R4
Draws a line
R0,R1,R2,R3 coordinates
R4 colour of the line (8 bit)
SWI "TD_LineList",R0,R1
R0=pointer to line structure: struct linelist {
int x0,int y0,int x1,int y1,int colour}.
R1=number of structures, checked to be smaller than 524288.
Look at the demo program for examples on their use.
All pointers are checked to be larger than &8000.
--- DRAWING QUADRANGLES ---
Quadrangles need not to be convex. You may give coordinates in a random order.
Note however that you can compile a module that does not check the
order/convexivity of the coordinates, in order to get a faster routine.
Drawing concave quadrangles will go slower than convex ones as the quadrangle
will be split in two triangles. Of the 16 bit colour you should leave the
top 16 bits set to 0, because these are reserved for future expansions. (Did
I say spritemapping?) There is a swi for calculating 16 bit colour; use it, so
it will be compatible with 16 bit true colour screen modes and different
palettes. You can also draw triangles by taking two points the same.
By default take the third and the fourth the same, but you are free to choose
otherwise.
Restrictions on drawing quadrangles by default compiling options:
1) X-coordinates must be smaller than 32768 pixels, otherwise you get strange
effects. (I think the x-coordinates are cyclic)
2) The height of the quadrangles should be smaller than 1,024 pixels,
otherwise quadrangles may be drawn inaccurate or not be drawn at all.
In normal use, you will never encounter these restrictions. Also if you would
use (heaven forbid) the OS-routines, you will have worse restrictions.
--- DRAWING LINES ---
The quadrangle routine will also draw lines; By default, take the last three
points the same, but you are free to do otherwise. However, the quadrangle
routine has no dedicated line drawing code, so it will be rather slow. (It
will still beat the hell out of the OS routines). The lines will be fairly
good, but not perfect.
--- COMPILING THE MODULE ---
To compile a module, load the file '<3D_Utils$Dir>.MakeModule' to a BASIC
editor and change the variables in the first few lines to get the desired
options. The quadrangle module may be compiled for most 256 colour
screenmodes, including mode 10 (Set b16=TRUE). You may compile the module for
all other modes with 2,4 and 16 colours, but the colours will be messed up,
and the outlines are still drawn with an accuracy of one byte (that is 8
pixels in mode 0). It can be compiled to work in a fixed graphics window.
Optimizing can be either for the arm2 and arm3 processor. The origin is by
default the middle of screen. Coordinates are in OS-units. For specific
requirements (arm 700?, mode 32, etc) you can ask me. The program can be
easily adapted for 16 and 32 bit colour modes, the code is already written,
but never tested.
--- BUGS ---
:-( outlines may be drawn slightly wrong if dx/dy does not change sign over a
corner. You will probably never notice this.
--- THINGIES ---
For use in C there is the file 'h.3D_Utils', for use in basic there is the
file 'DefVars' which defines variables with the swi numbers. You can use it to
get much faster access (20 x) to the SWI's.
The module automatically checks if any virus has attached itself to the module
on startup. If it finds any, the module will warn you, but start up anyway. I
never checked if it really works, cause I don't have virusses and want to keep
it that way.
Most of the routines were written in 1991 on an arm2 A3000. The module and
improvements were written on an 2 MB arm3 based A3000 with RO3.10 and should
work on all systems.
--- CREDITS ---
- Steven de Rooy for his fast division routine.
<not used yet>
--- PLANNED ---
- Set window, at least in Y direction
- Draw complex (concave) objects
- Draw convex/concave polygons ?
- Spritemapping ??
COPYRIGHT NOTICE:you are free to distribute and use this software for private
use, shareware programs and public domain software. If you want to use it in
commercial software you need permission from me, which I will give for some
amount of money (say £150). On every distribution this copyright notice must
be included.
If you distribute this module in pd-software, I would like to know.
Now go write some games/demos !
Michel Grimminck
Email:grimmink@phys.uva.nl
Westerstraat 155²
1015 MA Amsterdam
The Netherlands