'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