home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
FAQSYS18.ZIP
/
FAQS.DAT
/
RGP.FAQ
< prev
next >
Wrap
Text File
|
1996-08-02
|
68KB
|
1,692 lines
VGA programming and ModeX
TBA - To Be Added
[Frequently Asked Questions about VGA]
Q1.1 How do I program in mode xxx on my XXX?
Q1.2 What is modeX?
Q1.3 How do I program the VGA?
[Frequently Asked Questions about Sound Cards]
Q2.1 How do I program my XXX?
--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER IBM FAQ VGA
--------------------------------------------------------------------------------
Q1.1 How do I program in mode xxx on my XXX?
Perhaps the most frustrating thing that has ever been done is
the plithera of extended VGA modes. Unfortunately on the VGA
is general enough for this FAQ to cover. There is much too
much to know about other mode other than those supported by
VGA, that can be covered in such a SMALL amount of FAQ room.
Q1.2 What is modeX?
The VGA card has 256K of memory built into it. It uses the 64K
segment located at segment A000 for a "frame" into the 256K of
memory. In other words, when you write to A000, the VGA card
wakes up, grabs the data, and puts it somewhere in its 256K of
memory.
In VGA's mode 13H, the pixels are stored in planes like this:
(x,y) = 1 byte of pixel data for location x,y
---------------------
Plane 3 | 3,0 | 7,0 | 11,0 | ...
---------------------
Plane 2 | 2,0 | 6,0 | 10,0 | ...
--------------------
Plane 1 | 1,0 | 5,0 | 9,0 | ...
--------------------
Plane 0 | 0,0 | 4,0 | 8,0 | ...
| 0,1 | 4,1 | 8,1 | ...
.
.
In mode 13h, you access a pixel by using a 16-bit offset into
the video frame. The VGA card takes the lower 2 bits and uses this
to select the plane that the byte will go to. The other 14 bits
are used as the offset into the plane. This is what is called
"chain 4" mode.
ModeX is identical to mode 13h, but "chain 4" mode is turned
off so that now when you access the VGA card with a 16-bit offset
into the video frame, it uses the "Map Mask" register value to
determine what plane to write to and then uses your 16-bit offset
to offset into the plane. In other words, you now have an 18-bit
address by using a 16-bit pointer and a 2-bit out. This allows you
to then access all 256K of the VGA memory, at the expense of having
to do an OUT for every pixel.
But remember, internally, the data is stored *IDENTICALLY*.
You just have to choose between a "slow" 18-bit pointer or
a "fast" 16-bit pointer to decide whether to use ModeX or not.
Q1.3 How do I program the VGA?
Well the following should help, there are several books on
programing the VGA chipset. If the following appears
complicated, sorry such is the nature of VGA!
Documentation over the I/O registers for standard VGA-cards
Documentated by Shaggy of The Yellow One.
Email: D91-SJD@TEKN.HJ.SE
Feel free to spread this to who ever wants it.....
------------------------------------------------------------
Port-Index: - Port: Write/03c2h Read/03cch
usage: d7 Vertical sync polarity
d6 Horizontal sunc polarity
d5 Odd /even page
d4 Disable video
d3 Clock select 1
d2 Clock select 0
d1 Enable/Disable display RAM
d0 I/O address select
Description: Sync polarity: Bits are set as below for VGA displays
that use sync polarity to determine screen resolution.
Many newer multiple frequency displays are insensitive
to sync polarity
d7 d6 Resolution
0 0 Invalid
0 1 400 lines
1 0 350 lines
1 1 480 lines
I/o address select: When set to zero, selects the
monochrome I/O address space (3bx). When set to one,
it selects the color I/O address space (3dx)
------------------------------------------------------------
Port-Index: - Port: 03c2h ; read only
usage: d7 Vertical Retrace Interrupt pendling
d6 Feature connector bit 1
d5 Feature connector bit 0
d4 Switch sense
d0-d3 Unused
Description: d7 uses IRQ2
------------------------------------------------------------
Port-Index: - Port: 03bah,03dah ; read only
usage: d3 Vertical retrace
d0 Horizontal retrace
------------------------------------------------------------
Port-Index: - Port: 03c3h,46e8h
usage: d7-d1 Reserved
d0 VGA enable/disable (03c3h only)
Description: Disables access to display memmory and the other
VGA's ports
------------------------------------------------------------
Port-Index: 00h Port: 03d4h, 03b4h
usage: Horizontal total
Description: Total number of characters in horizontal scan minus
five ( including blanked and border characters)
------------------------------------------------------------
Port-Index: 01h Port: 03d4h, 03b4h
usage: Horizontal display enable
Description: Total number of characters displayed in horizontal
scan minus one.
------------------------------------------------------------
Port-Index: 02h Port: 03d4h, 03b4h
usage: Start horizontal blanking
Description: Character at which blanking starts
------------------------------------------------------------
Port-Index: 03h Port: 03d4h, 03b4h
usage: End horizontal blanking
d7 Test
d6 Skew control
d5 Skew control
d0-d4 End blanking
Description: End blanking: is five LSB bits of six-bit value,
which define the character at which blanking stops.
The MSB bit of this value is in register index 5.
------------------------------------------------------------
Port-Index: 04h Port: 03d4h, 03b4h
usage: Start horizontal retrace
Description: Character at which horizontal retrace starts
------------------------------------------------------------
Port-Index: 05h Port: 03d4h, 03b4h
usage: End horizontal retrace
d7 End horizontal blanking bit 5
d6 Horizontal retrace delay
d5 Horizontal retrace delay
d0-d4 End horizontal retrace
Description: End horizontal retrace: defines the character at
which horizontal retrace ends
------------------------------------------------------------
Port-Index: 06h Port: 03d4h, 03b4h
usage: Vertical total
Description: Total number of horizontal scan lines minus two
(including blanked and border characters). MSB bits
of this value are in register index 7
------------------------------------------------------------
Port-Index: 07h Port: 03d4h, 03b4h
usage: Overflow register
d7 Vertical retrace start (bit 9)
d6 Vertical display enable end (bit 9)
d5 Vertical total (bit 9)
d4 Line compare (bit 8)
d3 Start vertical blank (bit 8)
d2 Vertical retrace start (bit 8)
d1 Vertical display enable end (bit 8)
d0 Vertical total (bit 8)
------------------------------------------------------------
Port-Index: 08h Port: 03d4h, 03b4h
usage: Preset row scan
d7 Unused
d6 Byte panning control
d5 Byte panning control
d0-d4 Preset row scan
Description: Byte panning control: is used to control byte
panning. This register together with attribute
controller register 13h allows for up to 31 pixels of
panning in double word modes
Preset row scan: Which character scan line is the
first to be displayed
------------------------------------------------------------
Port-Index: 09h Port: 03d4h, 03b4h
usage: Maximum scan line/Character height
d7 double scan
d6 bit d9 of line compare register
d5 bit d9 of start vertical blank register
d0-d4 Maximum scan line
Description: d0-d5=Character height-1, only in textmodes
------------------------------------------------------------
Port-Index: 0ah Port: 03d4h, 03b4h
usage: Cursor start
d7,d6 Reserved (0)
d5 Cursor off
d4-d0 Cursor start
Description:
------------------------------------------------------------
Port-Index: 0bh Port: 03d4h, 03b4h
usage: Cursor end
d7 reserved
d6,d5 Cursor skew
d4-d0 Cursor end
Description:
------------------------------------------------------------
Port-Index: 0ch Port: 03d4h, 03b4h
usage: Start address high
------------------------------------------------------------
Port-Index: 0dh Port: 03d4h, 03b4h
usage: Start address low
Description: Determine the offset in display memory to be
displayed on the upper-left corner on the screen
------------------------------------------------------------
Port-Index: 0eh Port: 03d4h, 03b4h
usage: Cursor location (high byte)
------------------------------------------------------------
Port-Index: 0fh Port: 03d4h, 03b4h
usage: Cursor location (low byte)
Description: Where the cursor is displayed on screen
------------------------------------------------------------
Port-Index: 10h Port: 03d4h, 03b4h
usage: Vertical retrace start
Description: 8 bits out of 10
------------------------------------------------------------
Port-Index: 11h Port: 03d4h, 03b4h
usage: Vertical retrace end
d7 Write protect CRTC register 0 to 7
d6 refresh cycle select
d5 enable vertical interrupt (when 0)
d4 Clear vertical interrupt (when 0)
d0-d3 Vertical retrace end
------------------------------------------------------------
Port-Index: 12h Port: 03d4h, 03b4h
usage: Vertical display enable end
Description: eight LSB bits out of ten-bit value which define
scan line minus one at which the display ends.
The other two are in CRTC register index 7
------------------------------------------------------------
Port-Index: 13h Port: 03d4h, 03b4h
usage: Offset / Logical screen width
Description: Logical screen width between successive scan lines
------------------------------------------------------------
Port-Index: 14h Port: 03d4h, 03b4h
usage: Underline location register
d7 Reserved
d6 Double word mode
d5 count by 4
d0-d4 Underline location
Description: Underline location: Monochrome textmode only
------------------------------------------------------------
Port-Index: 15h Port: 03d4h, 03b4h
usage: Start vertical blanking
Description: eight LSB bits of ten-bit value minus one which
define at which scan line the vertical blanking
starts. The other two bits are in CRTC registers
index 7 and 9
------------------------------------------------------------
Port-Index: 16h Port: 03d4h, 03b4h
usage: End vertical blanking
Description: eight LSB bits of a value which determine the scan
line after which vertical blanking ends.
------------------------------------------------------------
Port-Index: 17h Port: 03d4h, 03b4h
usage: Mode control register
d7 Enable vertical and hoizontal retrace
d6 Byte mode (1), word mode (0)
d5 Address wrap
d4 Reserved
d3 count by 2
d2 multiple vertical by 2 (use half in
CRTC (8,10,12,14,18)
d1 Select row scan counter (not used)
d0 compatibilty mode support (enable interleave)
------------------------------------------------------------
Port-Index: 18h Port: 03d4h, 03b4h
usage: Line compare register
Description: Split screen, 8 bit value out of a ten-bit value
------------------------------------------------------------
Port-Index: 00h Port: 03c4h
usage: Reset register
d7-d2 Reserved
d1 Synchronous reset
d0 Asynchronous reset
Description: Synchr. when set to zero, will halt and reset
the sequencer at the end of its current cycle
Asyncht. when set to zero, will immediatly halt
and reset the sequencer. Data can be loss.
------------------------------------------------------------
Port-Index: 01h Port: 03c4h
usage: Clock mode register
d7,d6 Reserved
d5 display off
d4 Allow 32-bit Fetch (not used in standard modes)
d3 Divide dot clock by 2 (used in some 320*200 modes)
d2 Allow 16-bit fetch (used in mon graphics modes)
d1 Reserved
d0 Enable (0) 9 dot characters (mono text and 400-line)
Description: Display off: Will blank screen and give the cpu
uninterrupted access the display memory.
------------------------------------------------------------
Port-Index: 02h Port: 03c4h
usage: Color plane write enable register
d7,d6 Reserved
d3 Plane 3 Write enable
d2 Plane 2 Write enable
d1 Plane 1 Write enable
d0 Plane 0 Write enable
Description:
------------------------------------------------------------
Port-Index: 03h Port: 03c4h
usage: Character generator select register
d7,d6 Reserved
d5 Character generator table select A (MSB)
d4 Character generator table select B (MSB)
d3,d2 Character generator table select A
d1,d0 Character generator table select B
Description: This register is only of interest if your software
will be using multiple character sets. Either one
or two character sets can be active. Table A selects
the charcater with attribute d3 set to zero and
Table B is the one with d3 set to one.
------------------------------------------------------------
Port-Index: 04h Port: 03c4h
usage: Memory mode register
d4-d7 Reserved
d3 Chain 4 (address bits 0&1 to select plan, mode 13h)
d2 Odd/even (address bit 0 to select plane 0&2 or
1&3 text modes)
d1 Extended memory (disable 64k modes)
d0 Reserved
Description:
------------------------------------------------------------
Port-Index: 00h Port: 03ceh
usage: Set / Reset register
d7-d4 Reserved (0)
d3 Fill data for plane 3
d2 Fill data for plane 2
d1 Fill data for plane 1
d0 Fill data for plane 0
------------------------------------------------------------
Port-Index: 01h Port: 03ceh
usage: Set / Reset enable register
d7-d4 Reserved (0)
d3 enable set/reset for plane 3 (1 = enable)
d2 enable set/reset for plane 2 (1 = enable)
d1 enable set/reset for plane 1 (1 = enable)
d0 enable set/reset for plane 0 (1 = enable)
Description: Set/Reset enable defines which memory planes will
receive fill data from set/reset register. Any plane
that is disable for set/reset will be written with
normal processor output data
------------------------------------------------------------
Port-Index: 02h Port: 03ceh
usage: Color compare register
d7-d4 Reserved
d3 Color compare value for plane 3
d2 Color compare value for plane 2
d1 Color compare value for plane 1
d0 Color compare value for plane 0
Description: one indicate that color is the same
------------------------------------------------------------
Port-Index: 03h Port: 03ceh
usage: Data rotate / Function select register
d7-d5 Resrved (0)
d4,d3 Function select
d2-d0 Rotate count
d4 d3 Function
0 0 Write data unmodified
0 1 Write data ANDed with processor latches
1 0 Write data ORed with processor latches
1 1 Write data XORed with processor latches
Description: Rotation is made before writing data
------------------------------------------------------------
Port-Index: 04h Port: 03ceh
usage: Read plane select register
d7-d2 Reserved (0)
d1,d0 Defines color plane for reading (0-3)
Description: Doesnt matter in color compare mode
------------------------------------------------------------
Port-Index: 05h Port: 03ceh
usage: Mode register
d7 Reserved (0)
d6 256-colour mode
d5 Shift register mode
d4 Odd / Even mode
d3 Color compare mode enable (1 = enable)
d2 Reserved (0)
d1,d0 Write mode
d1 d0 Write mode
0 0 Direct write (data rotate, set/reset may apply)
0 1 Use processor latches as write data
1 0 Color plane n (0-3) is filled with the value of
bit n in the write data
1 1 Use (rotated) write data ANDed with Bit mask as
bit mask. Use set/reset as if set/reset was
enable for all planes
Description:
------------------------------------------------------------
Port-Index: 06h Port: 03ceh
usage: Miscellaneous register
d7-d4 Reserved
d3-d2 Memory map
00 = A000h for 128k
01 = A000h for 64k
10 = B000h for 32k
11 = B800h for 32k
d1 Odd/even enable (used in text modes)
d0 Graphics mode enable
Description: Memory map defines the location and size of the
host window
------------------------------------------------------------
Port-Index: 07h Port: 03ceh
usage: Color don't care register
d7-d4 Reserved (0)
d3 Plane 3 don't care
d2 Plane 2 don't care
d1 Plane 1 don't care
d0 Plane 0 don't care
Description: Color don't care is used in conjunction with color
compare mode. This register masks particular planes
from being tested during color compare cycles.
------------------------------------------------------------
Port-Index: 08h Port: 03ceh
usage: Bitmask register
Description: The bitmask register is used to mask certain bit
positons from being modified.
------------------------------------------------------------
Port-Index: - Port: 03c0h both index and data
usage: d7,d6 Reserved
d5 Palette address source
0 = palette can be modified, screen is blanked
1 = screen is enable, palette cannot be modified
d4-d0 Palette register address
Description: Palette register address selects which register of
the attributes controller will be addres,sed by the
next I/O write cycle
------------------------------------------------------------
Port-Index: 00h-0fh Port: 03c0h
usage: Color palette register
d6,d7 Reserved
d5-d0 Color value
Description: not used in 256 color modes
------------------------------------------------------------
Port-Index: 10h Port: 03c0h
usage: Mode control register
d7 p4,p5 source select
d6 pixel width
d5 Horizontal panning compatibility
d4 Reserved
d3 Background intensify / enable blinking
d2 Line graphics enable (text modes only)
d1 display type
d0 graphics / text mode
Description: p4,p5 source select: selects the source fZ outputs p4 and p5 to the DACs. If set to zero, p4
and p5 are driven from the palette registers (normal
operation). If set to one, p4 and p5 video outputs
come from bits 0 and 1 of the color select register.
pixel width: is set to one in mode 13h (256-color mode)
horizontal panning compatibility: enhances the
operation of the line compare register of the CRT
controller, which allows one section of the screen
to be scrolled while another section remains stationary.
When this bit is set to one, the stationary
section of the screen will also be immune to horizontal
panning.
------------------------------------------------------------
Port-Index: 11h Port: 03c0h
usage: Screen border color
Description: In text modes, the screen border color register
selects the color of the border that sorrounds the
text display area on the screen. This is also referred
to by IBM as overscan. Unfortunately, this feature
does not work properly on EGA displays in 350-line
modes.
------------------------------------------------------------
Port-Index: 12h Port: 03c0h
usage: Color plane enable register
d7,d6 Reserved
d5,d4 Video status mux
d3 Enable color plane 3
d2 Enable color plane 2
d1 Enable color plane 1
d0 Enable color plane 0
Description: The video status mux bits can be used in conjunction
with the diagnostic bits of input status register 1
to read palette registers. For the EGA, this is the
only means available for reading the palette registers.
Enable color planes can be used to enable or disable
color planes at the input to the color lockup table.
A zero in any of these bit positions will mask the
data from that color plane. The effect on the display
will be the same as if that color plane were cleared
to all zeros.
------------------------------------------------------------
Port-Index: 13h Port: 03c0h
usage: Horizontal panning register
d7-d4 reserved
d3-d0 Horizontal pan
Description: Horizontal pan allows the display to be shifted
horizontally one pixel at a time.
d3-d0 Number of pixels shifted to the left
0+,1+,2+ 13h Other modes
3+,7,7+
0 1 0 0
1 2 1 -
2 3 2 1
3 4 3 -
4 5 4 2
5 6 5 -
6 7 6 3
7 8 7 -
8 9 - -
------------------------------------------------------------
Port-Index: 14h Port: 03c0h
usage: Color select register
d7-d4 Reserved
d3 color 7
d2 color 6
d1 color 5
d0 color 4
Description: Color 7 and color 6: are normally used as the high
order bits of the eight-bit video color data from the
attribute controller to the DACs. The only exceptions
are 256-color modes
Color 5 and color 4: can be used in place of the p5
and p6 outputs from the palette registers (see mode
control register - index 10h). In 16-color modes, the
color select register can be used to rapidly cycle
between sets of colors in the video DAC.
------------------------------------------------------------
Port-Index: - Port: 03c6h
usage: Pixel mask register
Description: ???
------------------------------------------------------------
Port-Index: - Port: 03c7h
usage: DAC state register (read-only)
Description: if d0 and d1 is set to zero it indicates that
the lookup table is in a write mode
------------------------------------------------------------
Port-Index: - Port: 03c7h
usage: Lookup table read index register (Write only)
Description: Used when you want to read the palette (set color
number)
------------------------------------------------------------
Port-Index: - Port: 03c8h
usage: Lookup table write index register
Description: Used when you want to change palette (set color
number)
------------------------------------------------------------
Port-Index: - Port: 03c9h
usage: Lookup table data register
Description: Read color value (Red-Green-Blue) or write same data.
--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER IBM FAQ Sound Cards
--------------------------------------------------------------------------------
Q2.1 How do I program my XXX?
This question is asked a lot, there is information available
for the adlib, but for many of the NEWER cards this is a
problem. The suggestion of rec.games.programmers is to read
the pc sound card group or the pc demos group. Why? Too
many cards unless someone else wishes to get the information
and make YAF! (yet another FAQ)
--------------------------------------------------------------------------------
END OF FAQ
Article 17548 of rec.games.programmer:
Newsgroups: rec.games.programmer
Path: usenet.ucs.indiana.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!news.intercon.com!panix!ddsw1!news.kei.com!ub!acsu.buffalo.edu!pleung
From: pleung@cs.buffalo.edu (Patrick Leung)
Subject: REPOST: Mode X FAQ, part 2/2
Message-ID: <Cp3uE7.9EA@acsu.buffalo.edu>
Sender: nntp@acsu.buffalo.edu
Nntp-Posting-Host: gagarin.cs.buffalo.edu
Organization: State University of New York at Buffalo/Comp Sci
Date: Sun, 1 May 1994 03:44:30 GMT
Lines: 1087
Article 21306 of rec.games.programmer:
Path: acsu.buffalo.edu!ub!toz!news
From: cyberman@toz.buffalo.ny.us
Newsgroups: rec.games.programmer
Subject: RGP FAQ
Message-ID: <gate.75gkHc1w165w@toz.buffalo.ny.us>
Date: Fri, 11 Feb 94 00:01:28 EST
Organization: TOZ automated posting
Revision 0.0.5 of REC.GAMES.FAQ
This document will be made available by mail request at a later
date (mail server difficulties). You may attempt to see if this
mail server works by sending to:
aser@toz.buffalo.ny.us
I cannot be sure it's working yet, please leave feedback on what
state it is in.
There are currently 3 FAQ's
RGP.FAQ - rec.games.programmer General FAQ
RGP.IBM - rec.games.ibm relevant FAQ
MAZE.FAQ - FAQ about MAZE's (more of a compilation of articles)
This was done so that someone who is looking for more general
information will be able to find game programing information
without being inundated by IBM, other computer-SPECIFIC
information, or the topsy turvey world of maze generation.
The current Editor is Cyberman@toz.buffalo.ny.us
--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER General FAQ Contents
--------------------------------------------------------------------------------
LEGAL
This document is FREE! It is for your self enlightenment. No
warranty is provided nor implied with this information. The
accuracy of the information contained herein is subject to
conjecture. Therefore the editor and contributers will take NO
liability for improper use, misuse, or abuse of this information,
and any damage to ANYTHING or ANYONE whether physical, financial,
etc. in no way, shape, or form can be attributed to this
document. Use this information at your OWN risk.
The above statement is to keep those who contributed and the
editor free from personal injury for being nice.
Special thanks to:
andrean@cs.utexas.edu (Andre A. Nurwono)
roberts@brahms.amd.com (Dave Roberts)
sean@stat.tamu.edu (Sean Barrett)
Cyberman@toz.buffalo.ny.us (Cyberman)
(and anyone else I forgot to mention for that matter)
If you wish to contribute CODE be sure it's something you DO NOT
wish to COPYRIGHT!
All contributions and suggestions should be sent to me at:
Cyberman@toz.buffalo.ny.us
place in subject header
RGP.FAQ.*
where * is any of the following
SUGGESTION - to suggest Adding an area (I recommend that
you send the information if you want it
added)
ADD - an addition (ie TBA's [see KEY for what TBA
means])
EDIT - for a correction somewhere (it is suggested
contributers do there own editing)
FLAME - complaints - I'll read these but be sure to
be tasteful in you commentary. You may or
may NOT get a reply.
For now I'm going to use my personal mail account. So please be
careful.
Format:
There are several categories and each category contains it's
relevant questions as suggested.
Key:
TBA - To Be Added
[Frequently Asked Questions about terminology]
Q1.1 What are .MOD files?
Q1.2 What is a pixel?
Q1.3 What is a bitmap?
Q1.4 What is flicker?
Q1.5 What is snow?
Q1.6 What is a frame buffer?
Q1.7 What is a Sprite?
Q1.8 What is vertical/horizontal retrace?
[Frequently Asked Questions about Animation]
Q2.1 How do I make sprites on my xxx?
Q2.2 What about collision detection? TBA
Q2.3 What about bitmap scaling? TBA
Q2.4 What is perspective mapping? TBA
Q2.5 What about 3d objects and manipulation?
[Frequently Asked Questions about Map Generation]
Q3.1 How do I generate a maze?
Q3.2 How do I generate a landscape/terrain? TBA
Q3.3 How do I generate a hex map? TBA
Q3.4 What about random number generators?
[Frequently Asked Questions about Libraries and support software]
Q4.1 What is there for the IBM compatible?
Q4.2 " " " " " Amiga? TBA
Q4.3 " " " " " Atari? TBA
Q4.4 " " " " " Macintosh? TBA
Q4.5 " " " " " Sun/Sparc?
Q4.6 " " " " " X? TBA
[Frequently Asked Question about Where is ...]
Q5.1 Where is Joshua Jensens famous Perspective Mapping Code?
Q5.2 Where else should I read?
Q5.3 Where can I find out about ray traceing?
Note 1: Fixing snow and flicker
Note 2: 2 Part Tutorial on 3d graphics
--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER General FAQ Terminology
--------------------------------------------------------------------------------
Q1.1 What are .MOD files?
A .MOD file is a file generated for the Amiga. A tracker is
used to play the MOD. A mod consists of digitized sound and
sequencing information to play music. Here is a BRIEF and
incomplete text file that is somewhat informative on the
subject.
Note - Joshua Jensen has written a mod player that can be
linked into your code. So has the author of mod play.
SEE ALSO - Mod Format specification file. (Modform.zoo)
Q1.2 What is a Pixel?
Pixel is short for Picture Element. It is a single dot
address on a grid used to display images on a monitor (Tv
included).
Q1.3 What is a bitmap?
A bitmap aka bitimage is the representation of an image in
the form of a sequence of bits. For example most graphic
modes on computers represent the pixels using a BITMAP.
Q1.4 What is flicker?
Flicker is a noticeable pulse or change in an image. This
can be on a CRT (Cathode Ray Tube) or other type display
device. The cause is that the refresh rate of the CRT is
lower than the persistance of vision of the person observing
it.
Another form of flicker is due to rapid drawing of data on
the screen. What happens is that the data is drawn out of
syncronization with the horizontal and vertical scan. So
your image apears to fade in and out of visability.
SEE ALSO fixing snow and Flicker
Q1.5 What is SNOW?
Snow are small specals on the screen that appear like SNOW
falling on the screen (hence the name).
Snow is caused by a number of things. One of which is when
one is writting to the screen while the display card is
scanning that address of the screen, this causes a conflict
and can produce random specals.
Another cause of snow is an improperly connected monitor.
This can damage the monitor. Yet another source is noise
from an electro magnetic source, if indeed it's not from
anything you own the FCC might need to be notified.
SEE ALSO fixing snow and Flicker
Q1.6 What is a frame buffer?
Memory that contains image data that is translated to the image
on your screen. A frame buffer does not have to be
"visible". Also the methode of this tranformation is not
always the same, so no effort here will be made to explain
further.
Q1.7 What is a Sprite?
A sprite is an image usually moveable about the screen.
Common information stored in a sprite are, width, height,
position, and image data. A sprite ussually does not effect
the screen background, this is of course dependant on
implementation.
Q1.8 What is vertical/horizontal retrace?
Most monitors are what is called a RASTER display. This
means that an image is represented by setting the intensity
of a grid of dots on the display. Each dot is called a
pixel. In order to display the grid a CRT sweeps an electron
beam across the display surface sending pulses corresponding
to the intensity of the pixel. However the stream of video
information is almost always represented left to right top to
bottom. This mean that the beam must scan across the screen
and then move BACK to start a line. This is called
Horizontal retrace.
Vertical retrace is when the beam finishes painting the
screen from top to bottom again the beam must be moved to the
top of the screen.
The horizontal sweep is controlled by an electric field the
vertical sweep is controlled usually magnetic field.
--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER General FAQ Animation
--------------------------------------------------------------------------------
[Frequently Asked Questions about Animation]
Q2.1 How do I make sprites on my xxx?
This, unfortunately, is a rather complex problem and its
implementation is often computer-specific, however some of it
can be addressed in the general FAQ.
Sprites require one to copy pixels to the display in a
certain area of the screen. There are various issues that
must be addressed about this.
Getting and Putting an image: getting means you copy a
section of a screen (bitmap) to a buffer, putting means you
dump a buffer of data (bitmap) to a screen location. These
are often used for less sophisticated sprite animation.
The problem with this technique is put destroys the
background information. So if you want a background at all,
there must be a way to "overlay" an image onto it without
causing a large area around the sprite to disappear. An old
way of "fixing" this is to copy the background of an image
before you destroy it, then put the background back after you
move it.
Another methode of sprite creation requires custome hardware
(Amiga C64 Atari 8bits).
Q2.2 What about collision detection? TBA
Q2.3 What about bitmap scaling? TBA
Q2.4 What is perspective mapping?
What is it? Basically it takes an image and "pastes" it in
3d perspective onto a surface. This is much faster than
rendering surfaces in real time. Article 7716 of r.g.p
written by Joshua C. Jensen (sl8nl@cc.usu.edu) is an example
of this technique (implemented in Turbo Pascal).
Unfortunately this article # may not corespond to anything in
usenet! :) However the date it was posted was 1 Aug 92
01:36:51 GMT. SO you can grab the coresponding articles
there! :)
Q2.5 What about 3d objects and manipulation?
Note 2 is a pair of tutorials on this subject.
Another suggestion is to check comp.graphics FAQ and the
comp.graphics resources guide as well.
--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER General FAQ Map Generation
--------------------------------------------------------------------------------
Q3.1 How do I generate a maze?
This is a VERY frequently asked question in rgp so we have
a unoffical maze FAQ. It's is now posted WITH the RGP Faq.
Q3.2 How do I generate a landscape/terrain?
Another fun filled FAQ it has too many answers. A suggestion
is to read sci.fractals. Now if someone would conribute some
information on this I would be happy to construct the
"land.faq".
Q3.3 How do I generate/use a hex map?
Well this has discussed considerably on rgp. We haven't a
FAQ for it until I get permission to use something I
captured.
Q3.4 What about random number generators?
These are mandatory for making a "new" universe each time a
program loads. Usually the ones included in a C compiler
library are sufficient for most needs. However sometimes one
must go the extra mile and use there own random number
generator. Currently we have no FAQ on random number
generators. (sorry)
--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER General FAQ Libraries and support software
--------------------------------------------------------------------------------
Q4.1 What is there for the IBM and Compatibles?
There is a lot. I suggest scrounging around wuarchive
personally, but here is a terse UNOFFICIAL list!
contributed by
andrean@cs.utexas.edu (Andre A. Nurwono)
==========
--------
Graphics
--------
*. Executable
File(s) : TWEAK06.ZIP
Who : Robert Schmidt (robert@solan.unit.no)
When : 1992
What : A program to experiment w/ VGA registers, very useful
if you want to define new modes (like mode X & 360x400 modes)
Where : simtel & mirrors
*. Executable, (source code)
File : SPRITE.ZIP
Who : Billy Dalrymple
When : 1989
What : A sprite editor, produces sprites w/ mask in files.
info available for $10
source code available for $25
Where : I forget
*. Executable, Source Code
File(s) : VGA.ZIP
Who : wardt@a.cs.okstate.edu
When : 1992
What : A sprite editor, includes full source (.ASM & .C)
Where : I forget
*. Source Code, Library
File(s) : DDJ****.ZIP, XSHARP**.ZIP
Who : M. Abrash
When : Aug-Dec 1991, Jun-Aug 1992
What : Mode X introduction. Sources to do animation,
polygon plotting, anti-aliasing, etc, on Mode X.
Where : SIMTEL and mirrors,
ftp.mv.com (Official DDJ site) in pub/ddj
*. Source Code
File(s) : article 7198 of rec.games.programmer
Who : Frederick J. Haab (otto@nevada.edu)
When : 26 Jun 92 00:17:52 GMT
What : Scrolling in mode 13h, C program
Where : USENET archives
*. Source Code
File(s) : article 7716 of rec.games.programmer
Who : Joshua C. Jensen (sl8nl@cc.usu.edu)
When : 30 Jul 92 00:02:36 GMT
What : Bitmap manipulation (scaling + perspective), Turbo Pascal
source w/ inline assembly.
Where : USENET archives
*. Source Code
File(s) : VESAVGA.ZIP
Who : Randy Buckland
When : 6/18/92
What : .ASM & .C source to provide fast routines for VESA VGA modes.
Where : garbo
*. Sprite Library, Code
File(s) : STK110.LZH
Who : Jari Karjala
When : 1991 (v 1.1)
What : Sprite library & toolkit for Hi-Res EGA, BW
includes C source, demo & good docs.
Where : simtel & mirrors
*. Sprite Library, Source Code
File : SPRITES.ZIP
Who : Marius Kjeldahl
When : 1991
What : Sprite library for VGA mode $13
includes TPU, .PAS source.
(shareware, $69 ?)
Where : garbo
*. Sprite Library, Toolkit
File(s) : WGT_SPR2.ZIP, WGT_TC21.ZIP, WGT_TP2.ZIP
Who :
When : 1992
What : Shareware Sprite toolkit for VGA mode $13
includes TPU (WGT_TP2.ZIP), example programs for usage
Nag-shareware program
Where : wuarchive, if somebody hasn't erased it yet
*. Library (Pascal)
Files : EGOF10.ZIP, EGOF10P.ZIP, EGOF10M.ZIP,
EGOF10B.ZIP, EGOF106.ZIP
Who : Logi Ragnarsson
When : 1993
What : 256-colour graphics library for Turbo/Borland Pascal 6.0
and 7.0, VESA SVGA, Mode-X (and more), VGA/MCGA 320x200,
example programs, manual, shareware ($20).
Where : garbo
*. Library Source
File(s) : Xlib04c.zip
Who : Themie Gouthas (and company)
When : 11 Mar 93
What : mode X library for game, to many feature to mention
Where : pub/MSDOS_UPLOADS@wuarchive.wustl.edu
-------------
Sound & Music
-------------
*. Documentation
File(s) : Article 6077 of rec.games.programmer
Who : Jeffrey S. Lee (jlee@smylex.uucp)
When : 25 Feb 92 15:02:02 GMT
What : Programming the AdLib/Sound Blaster FM Music Chips
Where : usenet archives, also at the SB project site
(tybalt.cco.caltech.edu), & SB mailserver
(listserv@porter.geo.brown.edu)
*. Executable, Runtime Library
File(s) : MODTECH.ZIP
Who : Mark J. Cox (M.J.H.Cox@bradford.ac.uk)
When : 1991
What : TSR Library to play .MOD files in the background
Supports PC Speaker, SB, DisneySS, LPT DACs, etc
Where : ftp.brad.ac.uk in /misc/msdos/mp
*. Library
File(s) : MODOBJ.ZIP
Who : Mark J. Cox (M.J.H.Cox@bradford.ac.uk)
When : 1992
What : .OBJ file w/ routines to play .MOD files in the background
Supports PC Speaker, SB, DisneySS, LPT DACs, etc
Includes examples in TC & TP
(shareware, $30)
Where : ftp.brad.ac.uk in /misc/msdos/mp
*. Source code
File(s) : NH10SRC.ZIP
Who :
When :
What : Eliminate noise on sound samples, incl. .C source
Where : SB project site & mailserv site
*. Source code, Executable
File(s) : SB_OSC.ZIP
Who :
When :
What : SB input scope / oscillator. Incl. .ASM source
Where : SB project site & mailserv site
*. Source code, Executable
File(s) : SBDAC.ZIP
Who : Jeff Bird (cejjb@marlin.jcu.edu.au)
When : 12 Feb 92
What : SB DAC programming using DMA. Incl. .ASM & .C source
Where : I forget (probably on SB project sites too)
==========
Q4.2 " " " " " Amiga? TBA
Q4.3 What is there for the Atari?
from warwick@cs.uq.oz.au
AMS library - Atari Machine Specific library
- C++ classes for Sprites, Screen, Joysticks, Double buffering, etc.
- beta testing now
- contact: warwick@cs.uq.oz.au
Q4.4 " " " " " Macintosh?
from jmunkki@vipunen.hut.fi
*. Source code
Files : Arashi_Source.cpt.bin
Who : ???
When : ???
What : source code for an arcade quality game, vector
graphics, multichannel sound, (no sprites)
Where : pub/mac/think-c/code@ics.uci.edu
Q4.5 " " " " " Sun/Sparcs?
contributed by
andrean@cs.utexas.edu (Andre A. Nurwono)
==========
--------
Graphics
--------
*. Library
What : Standard PIXRECT library
Bitmap manipulation routines for frame buffer.
-------------
Music & Audio
-------------
*. Source code
File(s) : tracker.tar.Z
Who :
When :
What : .MOD file player through the audio device. Works on SPARCS
w/ audio devices.
Where :
*. Source code
File(s) : csound.tar.Z
What : FFT & signal processor
*. Source code
What : MixView
==========
Q4.6 " " " " " X TBA
Additions are welcome.
--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER General FAQ FAQ's about Where is ...
--------------------------------------------------------------------------------
Q5.1 Where is Joshua Jensens famous Perspective Mapping Code?
Beats me no one has found it yet (or at least hasn't told me
they have and where to get it!) in one of the many usenet
archive sites. Places to look are gatekeeper.com and
wuarchive.wustl.edu. Both of these ftp sites archive usenet
news. I suspect all the rec.games.programmer articles are on
these sites and maybe (heavem forbid) the original FAQ even.
Q5.2 Where else should I read?
Here are SUGGESTED places you get information for things like
perspective mapping programming the SB etc.
comp.graphics
comp.graphics.animation
comp.sys.ibm.pc.soundcard
I suggest before posting you read ALL newsgroups a minimum of
1 week. Ussually you will see the FAQ or where to get it.
places suggested NOT to look for information
comp.graphics.research
if you want to get famed for posting off topic do it
there. That group is for research IE new frontiers.
Q5.3 Where can I find out about ray traceing?
Ask about POV in comp.graphics should be good for about 30 to
40 replies in your mailbox. There are several packages
available for free and comercially. I suggest POV because
it's free and actually quite good. Vivid, Rayshade are just
a few of the others. POV seems to be the most popular (and
portable also), with the most handy utilities.
--------------------------------------------------------------------------------
END OF FAQ
--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER General FAQ NOTES
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
NOTE 1: contributed by
--------------------------------------------------------------------------------
sean@stat.tamu.edu (Sean Barrett)
There are two things that qualify as flicker. Well, hell, to make it
simpler, let's call it three. At the end of this list I'll give a
rough definition of the problem.
1) You move a shape by erasing it and plotting it in a new position,
and there is a screen refresh during the time it is erased, resulting in
the background showing through.
2) You're using CGA and you try to write anywhere on the screen
during retrace, causing "noise" (due to DMA problems, I guess?).
3) You're moving a shape by some sort of "one-pass" technique in which
the screen memory is never set to the background temporarily, so (1)
can't happen, but the screen area the shape is in is refreshed during
the draw, so half of it gets displayed at the old location, and half
at the new.
I think a general rule would be that flicker occurs when a pixel on
the screen is displayed with a color other than the "correct" or
"intended" pixel value, as compared to an ideal "intended" case. (Thus,
if you're simulating something moving, you shouldn't see the
background; if you're trying to simulate something moving and
turning on and off simultaneously, then you should see it; it's
all a question of intent.)
Back to the above problems.
Now, so far as I know, there are only two solutions to #2. Only redraw
during the vertical retrace (blank), or don't support CGA. So I'm going
to forget about this problem.
You can handle #1, as I suggested in #3, by simply making sure you never
write to the screen a value you don't want displayed. Below I'll put a
list of ways I can think of to do this for bitmapped graphics--i.e.,
how to avoid the erase-redraw cycle.
If you really want to handle #3, then things get funky, and more power
to you. I don't personally believe it's a problem. If it's periodic,
so this one shape when you move it horizontally in the middle of the
screen is always split with the top half leading the bottom half by
a pixel, it's a problem; but if it just happens randomly once in a while
I doubt it's noticeable. In general, though, the solutions require
paying attention to where the screen refresh is in some way. My main
point, the reason I'm posting this whole thing, is that *solving problem
#1 does not require messing with knowing what section of the screen
is being refreshed.* As far as I know, the methods to combatting #3
are to redraw everything during vertical refresh (same as #2, but
overkill) or drawing your shapes from top to bottom lagging about half
the time of a screen refresh behind the refresh, or some such.
Solutions to #1 that don't require timing considerations, e.g., how
never to write a wrong pixel to the screen.
o Don't use raw bitmaps, use sprite hardware.
o Use hardware page flipping: display one screen, draw a new
screen "off-screen" and when it's finished, direct the
display hardware to display the new one. This can get messy
for fast animation because you have to keep track of where
sprites were the last two frames to erase and update them.
o Use software page flipping; display one screen, draw a new
screen "off-screen" and when it's finished, copy the new
screen into screen memory.
o Use techniques such as "store" sprites which overwrite the
background. Generally an out-of-date technique now, though;
only works for mono-color backgrounds. You simply write the
sprite onto the screen; the sprite has enough border around
it to overwrite its previous image. This is gross, very
fast, and flicker-free except when shapes get on top of each
other, at which point you get massive flicker.
o Use scratch-pad calculations, a variant of software page flipping.
Copy the section of the screen off that you need to update,
update it offscreen, and put it back on the screen. A lengthy
time ago I posted a discussion of how to do this effectively
for XOR-style graphics for 8-bit type machines--you can xor
a single image onto the screen that both erases and replots
in a new place the old sprite. And you can calculate the
image to do it on the fly, without additional memory, if you
set up your shape tables, and it's faster than the normal
draw shape with XOR to erase, draw shape with XOR to plot cycle
because it only reads and writes screen memory once.
Performance enhancements for bit blitting:
o Unroll loops.
o Write a custom bit blit for each shape, dedicated to that shape.
Cuts your memory accessing down if the machine has an
"immediate" operand mode that's faster than an index-addressed
one.
Memory performance enhancements for techniques that require many copies
of shapes or large routines (such as pre-shifted shape tables):
o If you're only using some of your shapes at any point in time
(e.g. if you can divide your display up into "scenes"; for a
certain period of time only these shapes are used), calculate
the "larger" derived tables on the fly when the scene starts
up. For large games (this is rec.games.programmer, not
rec.graphics.programmer, right?) that have to access the disk
anyway to change scenes, this is no big time loss. Also, if
you write the code right then while you're idling the processor
before starting work on the next display, you can do this stuff
then.
--------------------------------------------------------------------------------
NOTE 2: contributed by
--------------------------------------------------------------------------------
sean@stat.tamu.edu (Sean Barrett)
3D graphics: Using matrices and vectors Part 1
- Allows you to independently rotate objects and move the camera
anywhere.
- Does not discuss clipping.
- Algorithm uses 9 multiplies, 2 divides, and 9 additions per point,
plus overhead per independently located object.
- Part 2 gives the derivation for these formulas.
Assume a right-handed universe, with x horizontal, y
depth, and z vertical, and a screen display unit with
x horizontal to the right and y vertical downward.
The following are the rotation matrices:
Rx(t) Ry(t) Rz(t)
__ __ __ __ __ __
| 1 0 0 0 | | cos(t) 0 -sin(t) 0 | | cos(t) sin(t) 0 0 |
| 0 cos(t) sin(t) 0 | | 0 1 0 0 | | -sin(t) cos(t) 0 0 |
| 0 -sin(t) cos(t) 0 | | sin(t) 0 cos(t) 0 | | 0 0 1 0 |
| 0 0 0 1 | | 0 0 0 1 | | 0 0 0 1 |
-- -- -- -- -- --
rotate about x rotate about y rotate about z
The following is the translation matrix:
T(a,b,c)
__ __
| 1 0 0 a |
| 0 1 0 b |
| 0 0 1 c |
| 0 0 0 1 |
-- --
Let each object be a collection of points or lines. If lines, they
are drawn as lines connecting two 3D points, which can each be
individually transformed. So this derivation just handles converting
individual points in three-space into pixel coordinates.
---- BEGIN FORMULAS ----
If d is the distance from the eye to the window, h is the width
of the window, v is the height of the window (use the sizes
of the actual display if you don't know what else, but this is
actually referring to the virtual camera's window); num_x
is the number of pixels on the display in the x direction, num_y
the number of pixels in the y direction, and (center_x,center_y)
the location of the center of the display;
let scale_x = d/h*number_of_x_pixels, scale_y = d/v*number_of_y_pixels.
Then let S be defined as
__ __
| scale_x center_x 0 0 |
| 0 1 0 0 |
| 0 center_y -scale_y 0 |
| 0 0 0 1 |
-- --
Let the camera be located at (cx,cy,cz). Let the vector E be pointing
in the direction the camera is facing, the vector D be pointing to
the right (along the camera's x axis), and the vector F be pointing
up (along the camera's z axis); and let D, E, and F be of length 1.
Then define the following matrices:
matrix J matrix C
| Dx Dy Dz 0 | | 1 0 0 -cx |
| Ex Ey Ez 0 | | 0 1 0 -cy |
| Fx Fy Fz 0 | | 0 0 1 -cz |
| 0 0 0 1 | | 0 0 0 1 |
and let N = S*J*C.
Let each object i be at location cix, ciy, ciz, and let the matrix
which holds the current rotation for that object be O(i). To rotate
the object around the q axis by n degrees, let new O(i) = Rq(n) * O(i).
To rotate the object about *its* q axis, let new O(i) = O(i) * Rq(n)
(I think. I haven't looked at this closely, so it's probably wrong).
Let Otemp(i) be O(i) with the rightmost column of zeros replaced by
cix, ciy, and ciz, or in other words, the product of Temp(i)*O(i) where
Temp(i) is
__ __
| 1 0 0 cix |
| 0 1 0 ciy |
| 0 0 1 ciz |
| 0 0 0 1 |
-- --
Now, for each object i let M = N * Otemp(i).
Now, for each point P in i, let V = M * P, that is:
Vx = M[0,0]*Px + M[0,1]*Py + M[0,2]*Pz + M[0,3];
Vy = M[1,0]*Px + M[1,1]*Py + M[1,2]*Pz + M[1,3];
Vz = M[2,0]*Px + M[2,1]*Py + M[2,2]*Pz + M[2,3];
Then the pixel to plot to is:
If Vy>0
(Vx/Vy, Vz/Vy)
Done.
-- 2 --
3D graphics: using matrices and vectors Part 2
- Allows you to independently rotate objects and move the camera
anywhere.
- Does not discuss clipping.
- Algorithm uses 16 multiplies, 2 divides, and 12 adds for each point,
plus overhead per independently located object. Also shows how some
of the calculations are wasted, and reduces it to 9 multiplies and 9
additions.
The folowomg is a derivation of some of the math for using 3D
graphics with matrices and vectors. I don't see any way of
explaining how to use the matrix formulas without all the extra
context, so you'll have to wade through it. In general, you can
simplify things by multiplying out the matrices and similar
techniques.
You have a world described by three dimensional coordinates--it
could be lines or points or polygons, whatever. You have an
imaginary camera in this world, and you want to draw exactly
what this camera would see.
We represent the camera as a point where an "eye" is and a window
through which it's looking--that is, a point for the eye, a vector
from the eye to the center of the window, and another vector to tell
us which way is the up direction on the window. We can figure out
the sideways direction of the window by taking a cross-product, but
it may be better to represent it explicitly, as discussed far
eventually below.
What we want to know is where on our screen we should plot a
particular point. The solution is to figure out where on the
imaginary window the point would appear to be, and then to map
the window onto our screen.
Suppose the eye is at the origin, facing along the X axis, and
the point is in the XY plane so we can only look at two dimensions
for illustration purposes.
Y axis
| ___---
| ___---
| ___--- | Point
| --- |
eye----------+------------------ X axis
---___ |
---_|_
window ---___
---___
Suppose the window ranges from (d,h/2) to (d,-h/2) and the point is at
(a,b). We want to know where the line from the point to the eye
intersects the window line. Well, the point is only visible if
it's in front of the eye, so assume a>0. Now, the two lines are
y = (b/a)*x (from Point to eye)
and x = d (line window is on)
So the location of intersection is (d,(b/a)*d). In other words,
the point appears on our imaginary window with horizontal position
d*b/a if |d*b/a| <= h/2.
Thus, the quick and dirty 3d graphics formula for assuming an eyepoint
at the origin, X horizontal, positive to the right, Y vertical, positive
up, and Z depth, positive going into the distance (this is a left-handed
universe, whereas the rest of the derivations will be for a right handed
universe), and screen coordinates sx horizontal, positive to the right
sy vertical, positive down, is:
if (Z>0) then
sx = x_scale * X / Z + x_center;
sy = - y_scale * Y / Z + y_center;
endif
where x_center, y_center is the pixel address of the center of the
screen; x_scale is d/h*number_of_pixels_horizontally and y_scale is
d/v*number_of_pixels_vertically; d is the distance between the eye
and the window in the imaginary camera, h and v are the height and
width respectively of the imaginary window.
Ok, back to the messy stuff. Since our eyepoint won't necessarily
be at the origin and facing in the right direction, we need to be
able to handle arbitrary translations and rotations. In general,
to rotate (a,b) into (a',b') based on a given angle t, we do
a' = cos(t)*a + sin(t)*b;
b' = cos(t)*b - sin(t)*a;
(or switch the signs depending on which way you want to define as
the positive direction of rotation).
Now, to cleanly handle multiple rotations, we want to use matrices
to handle this. This is the same as
| cos(t) sin(t)| |a| _ |a'|
|-sin(t) cos(t)| |b| - |b'|
that is, a 2x2 matrix times a 2x1 matrix gives a 2x1 matrix. Now
to handle an arbitrary 3D rotation, we need to rotate on any axis:
rotate about x rotate about y rotate about z
| 1 0 0 | | cos(t) 0 -sin(t) | | cos(t) sin(t) 0 |
| 0 cos(t) sin(t) | | 0 1 0 | | -sin(t) cos(t) 0 |
| 0 -sin(t) cos(t) | | sin(t) 0 cos(t) | | 0 0 1 |
Now, to rotate about a particular point, we have to translate to that
point. Say we want to rotate about (d,e,f). Then we subtract (d,e,f)
from our point, rotate, and then add (d,e,f) again. It would be nice
if we could do that automatically with the matrices, and there is a way
to, a cute trick. We switch from 3x3 matrices to 4x4 matrices, and use
4-vectors. For the rotation matrices, the new elements are all zero,
except the bottom right one which is 1; for example:
| cos(t) sin(t) 0 0 |
| -sin(t) cos(t) 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
Also, all of our vectors have a fourth element, which is always 1.
(In programming this, you can just continue to use three-vectors and
program the 'multiply matrix by vector routine' to pretend there's
one there.) Now, to do a translation we want:
x' = x + k1;
y' = y + k2;
z' = z + k3;
It turns out that this does the trick:
| 1 0 0 k1 | | x |
| 0 1 0 k2 | | y |
| 0 0 1 k3 | | z |
| 0 0 0 1 | | 1 |
Now, let's define some matrix terms so we can compress our notation.
Let Rx(t), Ry(t), and Rz(t) be the 4x4 rotation matrices, and let
T(k1,k2,k3) signify the appropriate matrix as above. To rotate a point
(a,b,c) theta around the y axis at point (d,e,f), we do the following
in sequence: T(-d,-e,-f), Ry(theta), T(d,e,f). Now, one nice thing
about matrices is that we can get the effect of sequential application
by multiplying matrices; that is, if U = (a,b,c,1) and V=(a',b',c',1),
then do T(-d,-e,-f)*U, and take that and do Ry(theta)*that, and take
this and do T(d,e,f)*this, giving V, then this is:
T(d,e,f) * ( Ry(theta) * ( T(-d,-e,-f) * U ) ) ) = V
Since matrix operations are associative, this is the same as
T(d,e,f) * Ry(theta) * T(-d,-e,-f) * U = V
or, in other words, let M = T(d,e,f)*Ry(theta)*T(-d,-e,-f), then
M is a matrix which performs the rotation we desire.
Ok, now to wrap it all up. Suppose we have a bunch of objects in
3D we want to display, and the aforementioned camera. The camera
is at (cx,cy,cz), and we have a vector E pointing in the direction
the camera is aiming, a vector D which shows which way the window
is pointing to the right, and a vector F which points along the window
upward. These vectors form an orthonormal basis, so to rotate into
the frame of reference for them we use the matrix
| Dx Dy Dz |
| Ex Ey Ez |
| Fx Fy Fz |
also, we want to use 4x4 matrices and first we want to translate
to cx..cz, so we use
matrix J matrix C
| Dx Dy Dz 0 | | 0 0 0 -cx |
| Ex Ey Ez 0 | | 0 0 0 -cy |
| Fx Fy Fz 0 | | 0 0 0 -cz |
| 0 0 0 1 | | 0 0 0 1 |
So for an arbitrary point (a,b,c) in three space, the screen coordinates
for it sx, sy are: let U = (a,b,c,1); let V = J*C*U. Then
if (Vy>0) then
sx = scale_x * Vx/Vy + center_x;
sy = - scale_y * Vz/Vy + center_y;
endif
Generally, we want to store J and C separately. It is pretty simple
to move the camera, now; if the camera is always moving in the direction
its facing, use the E vector and factor direction in by hand, and
put this into C. To rotate the camera, just multiply a rotation
matrix on the left by J.
Now, to rotate objects properly, keep a separate rotation matrix
for each object. Then for each point in that object, rotate it and
translate it. It's simplest to store each object with the origin
as the center of the object. Then to calculate a point, you multiply
by the rotation matrix and then by the translation to put the objects
center where it should be in world space; because you're doing the
translation second, it's easy to put it into one matrix:
translation rotation
| 1 0 0 l | | a b c 0 | | a b c l |
| 0 1 0 m | | d e f 0 | _ | d e f m |
| 0 0 1 n | * | g h i 0 | - | g h i n |
| 0 0 0 1 | | 0 0 0 1 | | 0 0 0 1 |
Call this matrix O(q) where q is the object number.
Then, for each point in object q, the final multiply is
V = J * C * O(q) * U.
Finally, we can move some of the final calculation into a matrix.
We have:
sx = scale_x * Vx/Vy + center_x;
sy = -scale_y * Vz/Vy + center_y;
If we factor out Vy, we get
sx = (scale_x * Vx + center_x * Vy)/Vy;
sy = (-scale_y * Vz + center_y * Vy)/Vy;
Suppose from V we calculate V':
(scale_x*Vx + center_x*Vy, Vy, -scale_y*Vz + center_y*Vz, 1)
Then
sx = V'x / V'y;
sy = V'z / V'y;
Well, to get V', we just multiply V by the matrix
| scale_x center_x 0 0 |
| 0 1 0 0 |
| 0 center_y -scale_y 0 |
| 0 0 0 1 |
Let us call this matrix S. Remember, scale_x = d/h*number_of_x_pixels,
scale_y = d/v*number_of_y_pixels, d is distance from eye to window,
h is width of imaginary screen, v is height of imaginary screen.
So, now, the basic idea is this. To minimize calculation, let
N = S * J * C. For each object q, let M = N * O(q). For every point
U in q, let V = M * U. If Vy>0, then that point is at (Vx/Vy,Vz/Vy)
on the screen.
In pseudo-code, that's
/* matrix_multiply (destination, left_multiplicand, right_multiplicand) */
for each time slice do
if camera has moved then
matrix_multiply ( N, J, C);
matrix_multiply ( N, S, N);
endif
for q an object do
matrix_multiply( M, N, O[q]);
for p a point in object q do
matrix_by_vector_multiply( V, M, U[q][p]);
do something with ( V[0]/V[1], V[2]/V[1] );
endfor
endfor
endfor
In truth, the matrix_by_vector_multiply wastes a bit of time, if you're
trying to tune the code, it'd be worth tuning it. Normally, it does
this:
V0 = M00*U0 + M01*U1 + M02*U2 + M03*U3;
V1 = M10*U0 + M11*U1 + M12*U2 + M13*U3;
V2 = M20*U0 + M21*U1 + M22*U2 + M23*U3;
V3 = M30*U0 + M31*U1 + M32*U2 + M33*U3;
However, we know that the bottom row is never used, since V3 is always
1; furthermore, we know that U3 is 1, so we can just do
V0 = M00*U0 + M01*U1 + M02*U2 + M03;
V1 = M10*U0 + M11*U1 + M12*U2 + M13;
V2 = M20*U0 + M21*U1 + M22*U2 + M23;
This uses nine multiplies and nine adds, plus the two divides required
to calculate the screen coordinate. I believe this is the minimum
possible for arbitrary 3D graphics. (You can turn the two divides into
one divide and two multiplies by calculating 1/Vy and multiplying by
that, which may be a win on some machines.)