If you the painter's algorithme for 3D games like Wolfensteine and Doom.
When you build up your frame, You start with sorting every object on depth.
Then you draw every object starting with the most far object.
This algorithme is not very efficient, because you 'll draw most of the
pixels 2 or more times.
I've added a program in qbasic. it's a simple demo. about this. I didn't
wrote it, I only include it as example.
I hope other people have more info on this.
RedX
------------------------------------<cut>-----------------------------------
--------------------
DEFINT A-Z: CONST XDIM = 320&, YDIM = 200&, BPL = 80, PI =
3.141592653589793#
SCREEN 13: DEF SEG = &HA000: RANDOMIZE TIMER
'Code originally from LABDEMO.BAS
'Modified on 10/14/1999 by Ken Silverman for rendering cleanliness
OUT &H3C8, 0 'Make interesting palette
FOR x = 0 TO 63: OUT &H3C9, x: OUT &H3C9, 0: OUT &H3C9, 0: NEXT x
FOR x = 0 TO 63: OUT &H3C9, 0: OUT &H3C9, x: OUT &H3C9, 0: NEXT x
FOR x = 0 TO 63: OUT &H3C9, 0: OUT &H3C9, 0: OUT &H3C9, x: NEXT x
FOR x = 0 TO 63: OUT &H3C9, x: OUT &H3C9, x: OUT &H3C9, x: NEXT x
OUT &H3C4, &H4: OUT &H3C5, &H6 'Set Mode X (unchained mode)
OUT &H3D4, &H14: OUT &H3D5, &H0
OUT &H3D4, &H17: OUT &H3D5, &HE3
DIM pic(64 * 64 * 4), board(64, 64)
FOR y = 0 TO 63 'Generate interesting bitmaps (without loading a file)
FOR x = 0 TO 63
pic(x * 64 + y + 0) = (x + y) \ 2 + 0
pic(x * 64 + y + 4096) = ((x XOR y) * .875 + RND * 64 * .125) * .5 +
64
pic(x * 64 + y + 8192) = ((x OR y) * .875 + RND * 64 * .125) * .5 +
128
pic(x * 64 + y + 12288) = (x * x + y * y) \ 128 + 192
NEXT x
NEXT y
FOR z = 0 TO 63 'Generate random board (0 is invisible, 1-4 are walls)
board(z, 0) = INT(4 * RND) + 1
board(0, z) = INT(4 * RND) + 1
board(z, 63) = INT(4 * RND) + 1
board(63, z) = INT(4 * RND) + 1
NEXT z
FOR z = 0 TO 1023
board(INT(62 * RND) + 1, INT(62 * RND) + 1) = INT(4 * RND) + 1
NEXT z
'The length of the side of a cube is 1
'Since the 2D board map is 64*64, posx# and posy# range from 0-64
'posz# ranges from -.5 to .5 (0 is the middle)
DO 'Make sure starting position isn't inside a cube
x = INT(62 * RND) + 2
y = INT(62 * RND) + 2
LOOP WHILE board(x, y) <> 0
posx# = x + .5#: posy# = y + .5#: posz# = 0#: ang = PI * 2 * RND
pagoffs& = 0: OUT &H3C4, &H2: OUT &H3D4, &HC
DO
cosang# = COS(ang#)
sinang# = SIN(ang#)
vxinc# = sinang# * -2# / XDIM: vx# = cosang# + sinang# + vxinc# * .5#
vyinc# = cosang# * 2# / XDIM: vy# = sinang# - cosang# + vyinc# * .5#
FOR sx = 0 TO XDIM - 1
'Raytrace in 2D to see what block is hit, and where it gets hit
xscan = INT(posx#): xdir = SGN(vx#): incx# = ABS(vx#)
yscan = INT(posy#): ydir = SGN(vy#): incy# = ABS(vy#)
xtemp# = posx# - xscan: IF xdir > 0 THEN xtemp# = 1 - xtemp#
ytemp# = posy# - yscan: IF ydir > 0 THEN ytemp# = 1 - ytemp#
d# = xtemp# * incy# - ytemp# * incx#
DO
IF d# < 0 THEN
xscan = xscan + xdir
IF board(xscan, yscan) THEN
hx# = xscan: IF xdir < 0 THEN hx# = hx# + 1
hy# = posy# + vy# * (hx# - posx#) / vx#
bx = INT((hy# - INT(hy#)) * 64)
IF xdir < 0 THEN bx = 63 - bx
EXIT DO
END IF
d# = d# + incy#
ELSE
yscan = yscan + ydir
IF board(xscan, yscan) THEN
hy# = yscan: IF ydir < 0 THEN hy# = hy# + 1
hx# = posx# + vx# * (hy# - posy#) / vy#
bx = INT((hx# - INT(hx#)) * 64)
IF ydir > 0 THEN bx = 63 - bx
EXIT DO
END IF
d# = d# - incx#
END IF
LOOP
dist# = cosang# * (hx# - posx#) + sinang# * (hy# - posy#)
'Find the ceiling & floor borders, and the texture mapping equation
IF dist# > 1# / 64# THEN
sy1 = INT(YDIM \ 2 + (-posz# - .5) * 64# * 2# / dist#)
sy2 = INT(YDIM \ 2 + (-posz# + .5) * 64# * 2# / dist#)
IF sy1 < 0 THEN sy1 = 0
IF sy2 > YDIM THEN sy2 = YDIM
byi& = INT(dist# * 65536# * .5#)
by& = (sy1 + 1 - YDIM \ 2) * byi& + (posz# + .5#) * 64# * 65536# -
1
by& = by& + ((board(xscan, yscan) - 1) * 4096& + bx * 64&) * 65536
ELSE
sy1 = YDIM \ 2: sy2 = sy1
END IF
'Draw vertical line at column sx:
OUT &H3C5, 2 ^ (sx AND 3): p& = pagoffs& + sx \ 4: sy = 0
p1& = BPL * sy1 + p&: p2& = BPL * sy2 + p&: pe& = BPL * YDIM + p&
DO WHILE p& < p1&: POKE p&, 176: p& = p& + BPL: LOOP 'Ceilings
'Walls
DO WHILE p& < p2&
POKE p&, pic(by& \ 65536): p& = p& + BPL: by& = by& + byi&
LOOP
DO WHILE p& < pe&: POKE p&, 80: p& = p& + BPL: LOOP 'Floors
vx# = vx# + vxinc#
vy# = vy# + vyinc#
NEXT sx
'Flip page
OUT &H3D5, pagoffs& \ 256: pagoffs& = (pagoffs& + 16384) AND 65535
'Keyboard control code
DO
z$ = INKEY$
IF z$ = CHR$(0) + CHR$(75) THEN ang# = ang# - .1#
IF z$ = CHR$(0) + CHR$(77) THEN ang# = ang# + .1#
IF z$ = "<" OR z$ = "," THEN
posx# = posx# + sinang# * .25#
posy# = posy# - cosang# * .25#
END IF
IF z$ = ">" OR z$ = "." THEN
posx# = posx# - sinang# * .25#
posy# = posy# + cosang# * .25#
END IF
IF z$ = CHR$(0) + CHR$(72) THEN
posx# = posx# + cosang# * .25#
posy# = posy# + sinang# * .25#
END IF
IF z$ = CHR$(0) + CHR$(80) THEN
posx# = posx# - cosang# * .25#
posy# = posy# - sinang# * .25#
END IF
IF UCASE$(z$) = "A" THEN posz# = posz# - .05#
IF UCASE$(z$) = "Z" THEN posz# = posz# + .05#
IF z$ = CHR$(27) THEN SCREEN 0: END
LOOP WHILE z$ <> ""
'Mouse control code (enable this, unless you're stuck using QBasic!)
regs%(0) = 5: CALL int86old(&H33, regs%(), regs%()): bstatus% = regs%(0)
regs%(0) = 11: CALL int86old(&H33, regs%(), regs%())
IF (bstatus% AND 2) = 0 THEN
ang# = ang# + regs%(2) * .01#
ELSE
posx# = posx# + sinang# * regs%(2) * -.02#
posy# = posy# - cosang# * regs%(2) * -.02#
END IF
IF (bstatus% AND 1) = 0 THEN
posx# = posx# + cosang# * regs%(3) * -.02#
posy# = posy# + sinang# * regs%(3) * -.02#
ELSE
posz# = posz# + regs%(3) * .02#
END IF
'Don't let your view escape the board
IF posx# < 1.25# THEN posx# = 1.25#
IF posy# < 1.25# THEN posy# = 1.25#
IF posx# > 62.75# THEN posx# = 62.75#
IF posy# > 62.75# THEN posy# = 62.75#
IF posz# < -.5# THEN posz# = -.5#
IF posz# > .5# THEN posz# = .5#
LOOP
-----------------------------<END OF
FILE>------------------------------------------------