Author Topic: Texel Raytracer by Antoni Gual  (Read 733 times)

Offline The Librarian

  • Moderator
Texel Raytracer by Antoni Gual
« on: March 17, 2018, 10:39:44 AM »
Texel Raytracer

Author: Antoni Gual
Source: petesqbsite
URL: http://www.petesqbsite.com/downloads/graphics.shtml
Version: 2004
Tags: [3d], [raytrace], [poke]

Description:
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 [...]

Source Code:
Code: [Select]
'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

« Last Edit: August 09, 2018, 12:17:06 AM by odin »