mirror of
https://github.com/QB64-Phoenix-Edition/QB64pe.git
synced 2024-09-20 09:04:43 +00:00
177 lines
5.9 KiB
QBasic
177 lines
5.9 KiB
QBasic
|
'Pure QB Realtime Raytracer Demo
|
||
|
'Translated to/optimized for QB by Antoni Gual agual@eic.ictnet.es
|
||
|
'The original was written in C by Texel, a Spanish demo coder.
|
||
|
'It will not work in the IDE due to integer overflow errors.
|
||
|
'Compile with QB 4.0 or QB4.5 + ffix. It does 12.5 fps in my P4 1,4.
|
||
|
'The C version (DOS protected mode, DJGPP) does 50 fps :(
|
||
|
|
||
|
'DECLARE SUB ffix
|
||
|
'ffix
|
||
|
CONST objnum = 4
|
||
|
|
||
|
DIM n AS INTEGER, K AS INTEGER, OBJMIN AS INTEGER, OBJMIN2 AS INTEGER
|
||
|
DIM OBJ(objnum) AS INTEGER, l AS INTEGER, posi AS INTEGER, POS2 AS INTEGER
|
||
|
DIM s AS INTEGER, t(8200) AS INTEGER, XX AS INTEGER, YY AS INTEGER, XQ AS INTEGER
|
||
|
DIM YQ AS INTEGER, mmmm AS INTEGER, xx1 AS INTEGER, yy1 AS INTEGER
|
||
|
DIM t2(8200) AS INTEGER, ipos AS INTEGER
|
||
|
|
||
|
DIM A(objnum) AS SINGLE, B(objnum) AS SINGLE, C(objnum) AS SINGLE
|
||
|
DIM R(objnum) AS SINGLE
|
||
|
|
||
|
SCREEN 13
|
||
|
DEF SEG = &HA000
|
||
|
'Cambiar la paleta a tonos de azul
|
||
|
OUT &H3C8, 0'
|
||
|
FOR n = 0 TO 127
|
||
|
OUT &H3C9, 0
|
||
|
OUT &H3C9, INT(n / 4)
|
||
|
OUT &H3C9, INT(n / 2)
|
||
|
NEXT
|
||
|
FOR n = 0 TO 127
|
||
|
OUT &H3C9, INT(n / 2)
|
||
|
OUT &H3C9, INT(31 + n / 4)
|
||
|
OUT &H3C9, 63
|
||
|
NEXT
|
||
|
D = 230
|
||
|
l = 0
|
||
|
|
||
|
'four objects
|
||
|
OBJ(0) = 0: A(0) = -50 + l: B(0) = 0: C(0) = -100: R(0) = -55 * 55
|
||
|
OBJ(1) = 0: A(1) = 50 - l: B(1) = -25: C(1) = -120: R(1) = -55 * 55
|
||
|
OBJ(2) = 0: A(2) = 0: B(2) = 500: C(2) = -220: R(2) = -500! * 500
|
||
|
OBJ(3) = 1: A(3) = 60: B(3) = -35: C(3) = -30
|
||
|
|
||
|
tt! = TIMER
|
||
|
FOR l = 0 TO 199
|
||
|
|
||
|
A(0) = -50 + l
|
||
|
A(1) = 50 - l
|
||
|
posi = 400
|
||
|
mmmm = -1
|
||
|
'calculamos uno de cada 4 pixels a buffer t()
|
||
|
FOR Y = -40 TO 39 STEP 2
|
||
|
FOR X = -80 TO 79 STEP 2
|
||
|
X0 = X
|
||
|
Y0 = Y
|
||
|
GOSUB raytrace
|
||
|
t(posi) = COL
|
||
|
posi = posi + 1
|
||
|
NEXT
|
||
|
NEXT
|
||
|
posi = 482
|
||
|
POS2 = 0
|
||
|
'calculamos pixels restantes, interpolando si podemos
|
||
|
FOR YQ = 6 TO 43
|
||
|
FOR XQ = 2 TO 77
|
||
|
'interpolar
|
||
|
IF t2(posi) = t2(posi + 1) AND t2(posi) = t2(posi + 80) AND t2(posi) = t2(posi + 81) THEN
|
||
|
ipos = (YQ * 1280 + (XQ * 4))
|
||
|
FOR YY = 0 TO 3
|
||
|
FOR XX = 0 TO 3
|
||
|
POKE ipos, (YY * (t(posi + 80) * (4 - XX) + t(posi + 81) * XX) + (t(posi) * (4 - XX) + t(posi + 1) * XX) * (4 - YY)) \ 16
|
||
|
ipos = ipos + 1
|
||
|
NEXT
|
||
|
ipos = ipos + 316
|
||
|
NEXT
|
||
|
'no interpolar
|
||
|
ELSE
|
||
|
mmmm = 0
|
||
|
FOR yy1 = 0 TO 3
|
||
|
FOR xx1 = 0 TO 3
|
||
|
IF xx1 OR yy1 THEN
|
||
|
X0 = (-160 + XQ * 4 + xx1) / 2
|
||
|
Y0 = (-100 + YQ * 4 + yy1) / 2
|
||
|
GOSUB raytrace
|
||
|
POKE (YQ * 4 + yy1) * 320 + XQ * 4 + xx1, COL
|
||
|
ELSE
|
||
|
POKE YQ * 1280 + XQ * 4, t(posi)
|
||
|
END IF
|
||
|
NEXT
|
||
|
NEXT
|
||
|
END IF
|
||
|
posi = posi + 1
|
||
|
NEXT
|
||
|
posi = posi + 4
|
||
|
NEXT
|
||
|
IF LEN(INKEY$) THEN EXIT FOR
|
||
|
NEXT
|
||
|
COLOR 255: PRINT l / (TIMER - tt!)
|
||
|
KK$ = INPUT$(1)
|
||
|
END
|
||
|
|
||
|
raytrace:
|
||
|
Z0 = 0
|
||
|
MD = 1 / SQR(X0 * X0 + Y0 * Y0 + D * D)
|
||
|
X1 = X0 * MD
|
||
|
Y1 = Y0 * MD
|
||
|
Z1 = -(D + Z0) * MD
|
||
|
K = 0
|
||
|
COL = 0
|
||
|
OBJMIN = objnum
|
||
|
IF mmmm THEN t2(posi) = objnum
|
||
|
DO
|
||
|
TMIN = 327680
|
||
|
FOR n = 0 TO 2
|
||
|
IF OBJ(n) = 0 AND (OBJ(n) <> OBJMIN) THEN
|
||
|
A0 = A(n) - X0
|
||
|
B0 = B(n) - Y0
|
||
|
C0 = C(n) - Z0
|
||
|
TB = A0 * X1 + B0 * Y1 + C0 * Z1
|
||
|
RZ = TB * TB - A0 * A0 - B0 * B0 - C0 * C0
|
||
|
IF RZ >= R(n) THEN
|
||
|
TN = TB - SQR(RZ - R(n))
|
||
|
IF TN < TMIN AND TN > 0 THEN TMIN = TN: OBJMIN2 = n
|
||
|
END IF
|
||
|
END IF
|
||
|
NEXT
|
||
|
OBJMIN = OBJMIN2
|
||
|
IF TMIN < 327680 AND (OBJ(OBJMIN) = 0) THEN
|
||
|
IF mmmm THEN t2(posi) = t2(posi) * K * objnum * 3 + OBJMIN
|
||
|
X0 = X0 + X1 * TMIN
|
||
|
Y0 = Y0 + Y1 * TMIN
|
||
|
Z0 = Z0 + Z1 * TMIN
|
||
|
NX = X0 - A(OBJMIN)
|
||
|
NY = Y0 - B(OBJMIN)
|
||
|
NZ = Z0 - C(OBJMIN)
|
||
|
CA = 2 * (NX * X1 + NY * Y1 + NZ * Z1) / (NX * NX + NY * NY + NZ * NZ + 1)
|
||
|
X1 = X1 - NX * CA
|
||
|
Y1 = Y1 - NY * CA
|
||
|
Z1 = Z1 - NZ * CA
|
||
|
A2 = A(3) - X0
|
||
|
B2 = B(3) - Y0
|
||
|
C2 = C(3) - Z0
|
||
|
MV = 1 / SQR(A2 * A2 + B2 * B2 + C2 * C2)
|
||
|
A2 = A2 * MV
|
||
|
B2 = B2 * MV
|
||
|
C2 = C2 * MV
|
||
|
s = 0
|
||
|
FOR n = 0 TO 2
|
||
|
IF OBJ(n) = 0 AND NOT s THEN
|
||
|
A0 = X0 - A(n)
|
||
|
B0 = Y0 - B(n)
|
||
|
C0 = Z0 - C(n)
|
||
|
TB = A2 * A0 + B2 * B0 + C2 * C0
|
||
|
RZ = TB * TB - A0 * A0 - B0 * B0 - C0 * C0
|
||
|
IF RZ >= R(n) AND TB < 0 THEN s = -1: IF mmmm THEN t2(posi) = t2(posi) * 32
|
||
|
END IF
|
||
|
NEXT
|
||
|
IF NOT s THEN
|
||
|
IF mmmm THEN t2(posi) = t2(posi) + 1
|
||
|
col2 = X1 * A2 + Y1 * B2 + Z1 * C2
|
||
|
IF col2 < 0 THEN col2 = 0
|
||
|
cc = col2 * col2
|
||
|
col2 = cc * cc
|
||
|
MV = SQR(NX * NX + NY * NY + NZ * NZ)
|
||
|
'IF COL2 < 0 THEN COL2 = 0
|
||
|
col2 = col2 + (NX * A2 + NY * B2 + NZ * C2) / MV
|
||
|
IF col2 < 0 THEN col2 = 0
|
||
|
COL = COL + col2 / ((K + 1) * (K + 1) * 2)
|
||
|
IF COL > 1 THEN COL = 1
|
||
|
END IF
|
||
|
K = K + 1
|
||
|
END IF
|
||
|
LOOP WHILE TMIN < 327680 AND K <= 2
|
||
|
IF K = 0 THEN COL = 50 ELSE COL = COL * 255
|
||
|
RETURN
|
||
|
|