'> Merged with Zom-B's smart $include merger 0.51
' Best viewed with 120 or more columns
'####################################################################################################################
'# Math Library V1.0 (include)
'# By Zom-B
'####################################################################################################################
CONST sqrt2
= 1.41421356237309504880168872420969807856967187537695 ' Knuth01 CONST sqrt3
= 1.73205080756887729352744634150587236694280525381038 ' Knuth02 CONST sqrt5
= 2.23606797749978969640917366873127623544061835961153 ' Knuth03 CONST sqrt10
= 3.16227766016837933199889354443271853371955513932522 ' Knuth04 CONST cubert2
= 1.25992104989487316476721060727822835057025146470151 ' Knuth05 CONST cubert3
= 1.44224957030740838232163831078010958839186925349935 ' Knuth06 CONST q2pow025
= 1.18920711500272106671749997056047591529297209246382 ' Knuth07 CONST phi
= 1.61803398874989484820458683436563811772030917980576 ' Knuth08 CONST log2
= 0.69314718055994530941723212145817656807550013436026 ' Knuth09 CONST log3
= 1.09861228866810969139524523692252570464749055782275 ' Knuth10 CONST log10
= 2.30258509299404568401799145468436420760110148862877 ' Knuth11 CONST logpi
= 1.14472988584940017414342735135305871164729481291531 ' Knuth12 CONST logphi
= 0.48121182505960344749775891342436842313518433438566 ' Knuth13 CONST q1log2
= 1.44269504088896340735992468100189213742664595415299 ' Knuth14 CONST q1log10
= 0.43429448190325182765112891891660508229439700580367 ' Knuth15 CONST q1logphi
= 2.07808692123502753760132260611779576774219226778328 ' Knuth16 CONST pi
= 3.14159265358979323846264338327950288419716939937511 ' Knuth17 CONST deg2rad
= 0.01745329251994329576923690768488612713442871888542 ' Knuth18 CONST q1pi
= 0.31830988618379067153776752674502872406891929148091 ' Knuth19 CONST pisqr
= 9.86960440108935861883449099987615113531369940724079 ' Knuth20 CONST gamma05
= 1.7724538509055160272981674833411451827975494561224 ' Knuth21 CONST gamma033
= 2.6789385347077476336556929409746776441286893779573 ' Knuth22 CONST gamma067
= 1.3541179394264004169452880281545137855193272660568 ' Knuth23 CONST e
= 2.71828182845904523536028747135266249775724709369996 ' Knuth24 CONST q1e
= 0.36787944117144232159552377016146086744581113103177 ' Knuth25 CONST esqr
= 7.38905609893065022723042746057500781318031557055185 ' Knuth26 CONST eulergamma
= 0.57721566490153286060651209008240243104215933593992 ' Knuth27 CONST expeulergamma
= 1.7810724179901979852365041031071795491696452143034 ' Knuth28 CONST exppi025
= 2.19328005073801545655976965927873822346163764199427 ' Knuth29 CONST sin1
= 0.84147098480789650665250232163029899962256306079837 ' Knuth30 CONST cos1
= 0.54030230586813971740093660744297660373231042061792 ' Knuth31 CONST zeta3
= 1.2020569031595942853997381615114499907649862923405 ' Knuth32 CONST nloglog2
= 0.36651292058166432701243915823266946945426344783711 ' Knuth33
CONST logr10
= 0.43429448190325182765112891891660508229439700580367 CONST logr2
= 1.44269504088896340735992468100189213742664595415299 CONST pi05
= 1.57079632679489661923132169163975144209858469968755 CONST pi2
= 6.28318530717958647692528676655900576839433879875021 CONST q05log10
= 0.21714724095162591382556445945830254114719850290183 CONST q05log2
= 0.72134752044448170367996234050094606871332297707649 CONST q05pi
= 0.15915494309189533576888376337251436203445964574046 CONST q13
= 0.33333333333333333333333333333333333333333333333333 CONST q16
= 0.16666666666666666666666666666666666666666666666667 CONST q2pi
= 0.63661977236758134307553505349005744813783858296183 CONST q2sqrt5
= 0.89442719099991587856366946749251049417624734384461 CONST rad2deg
= 57.2957795130823208767981548141051703324054724665643 CONST sqrt02
= 0.44721359549995793928183473374625524708812367192231 CONST sqrt05
= 0.70710678118654752440084436210484903928483593768847 CONST sqrt075
= 0.86602540378443864676372317075293618347140262690519 CONST y2q112
= 1.05946309435929526456182529494634170077920431749419 ' Chromatic base
'####################################################################################################################
'# Vector math library v0.1 (include part)
'# By Zom-B
'####################################################################################################################
'####################################################################################################################
'# Screen mode selector v1.0 (include)
'# By Zom-B
'####################################################################################################################
videoaspect:
videomodes:
'####################################################################################################################
'# Ray Tracer (Beta version)
'# By Zom-B
'####################################################################################################################
'Speed required with these variables, so not using TYPEs here
DIM SHARED positionX
(7), positionY
(7), positionZ
(7) ' Object position DIM SHARED size
(7) ' Radius (in case of a sphere) DIM SHARED colorR!
(7), colorG!
(7), colorB!
(7), colorA!
(7) ' RGBA color DIM SHARED specular!
(7), highlight!
(7) ' Phong parameters DIM SHARED reflection!
(7) ' Ray reflection amount DIM SHARED textures
(7) AS TEXTURE
, bumpmap
(7) AS TEXTURE
' image handle
DIM SHARED lightX
(4), lightY
(4), lightZ
(4) ' Light position DIM SHARED lightR!
(4), lightG!
(4), lightB!
(4) ' Light color
init
main
worldMap:
DATA "!~#!~#!~#!-#(.69AEGFC@5.224;DJMORQND:)(*$!:#'#$!e#+.+1WX\_`ab\MCOZ!/baaQ5&!)#'<;CB=,&!&#$06,8@6/$!%#&&##$8NL" DATA ":1%!P#-=@@D25CGHIKJYZ]A)=^b`!0b]:!+#$0M?80!.#*-6.!&#%#%#/6?VR=6)!*#'%!B#,DDID?>>/LLPRINQE,!%#$#'F!.bZ0!;#=P=" DATA "-%$'$%)7GV^!)bA/)&6.##-BL/0+!,#/!'#$/80)&!'#$)5NA\]^]W3EQZ,[]baaN>0!&#J_!+bZ2!%#$$!+#$/3-!)#8V*##+R]PUV\!/ba" DATA "bb8CBN[XRF26/!(#(=*##&B`!'b_YQPYaaVVMTVVX]YJY]YFMaZ_!%b9$##/Q!(b]TJ6$!-#%>V`ba`UJ<),2;<DCSTL[`O]!%ba!:baSTVT" DATA "[XOOWT06OZ!.b_PNa!+b`WH._a]aOP%#&[!%baP@%##1@CF&!*#Dab\Mba\FFLQ`!*b\_!Gb##*--VS!1baa^ab_`abN0?E.=8GVT'!%#1_bb" DATA "<!(#8=/##&!%#$9RbbN=Ya^aV\!,baY]`!@b^!%b]G##$#CUab`WXGKQ^!)b__a]!%abA!&#%ObZ3.,!&#-@I!0#&#/aa`b=6TLUQ[a!,b!%a" DATA "!9ba^]Xa:)RNGF1!*#+AJ>!&#$@Y!+baZbb^=.##%Cbb^][)!4#2T+##9>Q^,3Q`!%b_!EbO*##$$1U\(!+#),3+!*#6Qa_a!&ba_abb`bbU" DATA "G,Taab``U8!2#/LJK$#-ZO;>T!>babTa!'babbN1'!&#L`=#&!&#')'%&!-#$)L`baa!*b_!%bGa`baabaX-!1#;?KaGJ!@babbabZ\!-bT$" DATA "!%#;6!&#&#'!4#*FYaa!)b`bQZ!'b[L7,PI%!2#9DZ!Rb[<*!%#'!=#+a!,bYPAU[!&b_@4(2)!2#%N!&b^!'bZMZWbbaW!@b^/5#'&!?#/a" DATA "!-bYPQVXb_84-!4#)C@PbMEER=[bb`-$(.Sb`(T!*b`!4b\R.(Q;%!@#,a!-baa^`bY9%!6#-!%bA($:2N3aNWJW[KPbbG3!9b]``X)##08!C#" DATA "N!1ba1!2#$!'#/[aP&*,3.;$B>D!%abbabM-!9b[7?U##)K2!C#)X!0bW&!9#4KJ`bbX!&#+('19!?bU&,Q.HQI$!E#K]!-bD!:#5a!(bQ:$" DATA "HA/)/M!@b@$%J-$!G#*B^!&b`GJ<8Q/!7#$%(N!+b]!&b`a!&bL`!:bC##%!J#;=_!%bA!J5!7#+Z!2b=!&bW:KV!7bX&#'!L#:0]bb6!&#" DATA "4BU,!6#I!3bLB!&b]\E(',\!2bU>3%!<#'*!3#Dbb@#-L)79Q4/!4#%a!4b5]!'b])##/V!&b_A?!&b`FL-#%!?#(!3#(H``HYX!%#/)E3,$" DATA "!/#$##V!4bJ5!&b\2!&#(!%bU(##G!%bV1-##*6!R#';;^ZM8$!(#(!.#*#&_!5b?YbZ=!)#TbP'!%#0<!%bK!%#6;!U#&7\8##$4-$#%!1#" DATA "a!6bJ3)'&!(#:bC!%#&'.PWbZ!%#)A5!V#5E31[^^QU:!1#2^!5b\[b+!*#ZF!%#$#,A)S-##&+9>!W#(0N!(b>0!0#8]!%bZX!1bJ!)#%#&" DATA "E&!%#'$G-! $3Q##$!V#F!*bQ!0#*;/0#&@W!.b[)!)#%%!(#&L?U$%%C_0!?#$!<#1a!+bG!6#J!)b`!%bS*!3#0[_,/Wb_/2*4!1#%!C#" DATA "(!%#P!-bS4'!3#Q!(baB_bW&!5#=bR0`bK@<'*6F35$#%%!*#$!F#T!0bI+!1#)\!'b^bba-!6#$Da/05-=B%0+<Mb]C$,+!N#A!1bL!2#B!'b" DATA "Xbba(!8#8EH:!&'$)/,\b\C.#0)!M#X!/ba7!2#3!'b`b^b3!;#&-5-6$(%%&U,?2%#'+!*#%!C#7!/bA!3#8!)bXb?$#;!<#'&U_K#R,##%" DATA "!&#$!1#$!:#$Ia_!,b/!3#R!+b;)EY!;#1W`bbW4^T!)#.!%#)!,#$!=#1!-b)!3#Qa!(b]3#:bF!;#R!*b.!(#$$##0!I#`!+bJ!4#/a!(b" DATA "F##@b2#%%!5#,M^!+b`:!?*!L#(!*bJ1$!5#X!(bE##A\!9#L!.bY*!Q#/!)bT!8#K!'bO!&#%!9#J!/bC!Q#=!)b:!8#(_!%ba0!>#/!/b" DATA "C!Q#@!(bF!:#Hbb^6!@#]bbM=4I!'b^/!Q#R!&b^:!;#*3*$!@#$=0'!&#?[bb`D!)#/&!H#*a!%b]C!g#-NP@)!)#%Q1!G#/_b_K&!j#1:!*#" DATA "=C##%!E#1^bZ*!k#'1!(#)K>!I#Cbb;!t#8;!J#Wb`3!Q#-!n#G_W##0*!P#$!l#%AO5$!*#'&!~#!H#(!~#!;#$##%!(#%!~#!8#)8;'!W#" DATA "&!f#+>\O!G#&/EH3&!)#5?@:>[NLA7BD52;ONCDA92/!'#$$!F#$!'#.@>`bM%!5#+,)*+-41-'+8CD1GWa!(b_ZH8BY!9bTNOA8&!B#$6BA" DATA "30.%#'4E`!%bM!0#.6DX^a!,babb`!,b^_!Cb^W7!0#'/37>DIQZVUPOIB>K!'b`X`!(bL*!,#)IT!@b]`!BbaK2&!%#21!%./7?JHTa!Bb_" DATA "RG:7?;:GT`!db_;DDC?7!~b!=ba_!Uba!%baa!hbaabaa!%b`^!%bab]a`ba!?b_a!qba\_!~b!Ib"
'####################################################################################################################
'####################################################################################################################
'####################################################################################################################
PRINT TAB(27);
"Ray Tracer (Beta version)"
scrn& = selectScreenMode&(4, 32)
makeTextures
'texture&(1) = _LOADIMAGE("d:\0synced\software\qb64\wTex.png", 32)
'texture&(2) = _LOADIMAGE("d:\0synced\software\qb64\wBump.png", 32)
'texture&(3) = _LOADIMAGE("d:\0synced\software\qb64\fTex.png", 32)
'texture&(4) = _LOADIMAGE("d:\0synced\software\qb64\fBump.png", 32)
makeScene
'SCREEN _NEWIMAGE(640, 480, 32)
maxX% = sizeX% - 1
maxY% = sizeY% - 1
halfX% = sizeX% \ 2
halfY% = sizeY% \ 2
cameraPrepare 150, -250, 200, 0, 0, 66, 0, 0, 1, 60, maxX% / maxY%
'cameraPrepare 0, 0, 400, 0, 0, 132, 0, -1, 0, 45, maxX% / maxY%
'####################################################################################################################
'FOR i% = 0 TO 360 STEP 30
' x = 100 * COS(i% * _deg2rad)
' y = 100 * SIN(i% * _deg2rad)
' cameraPrepare x, y, 400, 0, 0, 200, 0, 0, 1, 60, maxX% / maxY%
renderProgressive 256, 4
CIRCLE (maxX% \
2, maxY% \
2), 3, _RGB32(255, 255, 255), , , 1 'NEXT
'####################################################################################################################
'####################################################################################################################
'####################################################################################################################
SUB cameraPrepare
(posX
, posY
, posZ
, lookAtX
, lookAtY
, lookAtZ
, upX
, upY
, upZ
, fov
, aspect
) camPos.x = posX
camPos.y = posY
camPos.z = posZ
camDir.x = lookAtX - posX
camDir.y = lookAtY - posY
camDir.z = lookAtZ - posZ
vectorNormalize camDir
'PRINT camDir.x, camDir.y, camDir.z
camUp.x = upX
camUp.y = upY
camUp.z = upZ
'vectorNormalize camUp
'PRINT camUp.x, camUp.y, camUp.z
'Right vec
vectorCross camUp, camDir, camRight
vectorNormalize camRight
'PRINT camRight.x, camRight.y, camRight.z
vectorCross camDir, camRight, camUp
vectorNormalize camUp
'PRINT camUp.x, camUp.y, camUp.z
'END
scaleY
= TAN(fov
* (_PI / 360)) * 0.75scaleX = scaleY * aspect
vectorScale camRight, scaleX
vectorScale camUp, scaleY
'PRINT fov, scaleX, scaleY
'END
'####################################################################################################################
SUB renderProgressive
(startSize%
, endSize%
) pixStep% = startSize%
pixWidth% = pixStep% - 1
tracePoint x%, y%, r!, g!, b!
LINE (x%
, y%
)-STEP(pixWidth%
, pixWidth%
), _RGB(r!
* 255, g!
* 255, b!
* 255), BF
pixSize% = pixStep% \ 2
pixWidth% = pixSize% - 1
y1% = y% + pixSize%
x1% = x% + pixSize%
tracePoint x1%, y%, r!, g!, b!
LINE (x1%
, y%
)-STEP(pixWidth%
, pixWidth%
), _RGB(r!
* 255, g!
* 255, b!
* 255), BF
tracePoint x%, y1%, r!, g!, b!
LINE (x%
, y1%
)-STEP(pixWidth%
, pixWidth%
), _RGB(r!
* 255, g!
* 255, b!
* 255), BF
tracePoint x1%, y1%, r!, g!, b!
LINE (x1%
, y1%
)-STEP(pixWidth%
, pixWidth%
), _RGB(r!
* 255, g!
* 255, b!
* 255), BF
pixStep% = pixStep% \ 2
y1% = y% + 1
x1% = x% + 1
tracePoint x1%, y%, r!, g!, b!
PSET (x1%
, y%
), _RGB(r!
* 255, g!
* 255, b!
* 255) tracePoint x%, y1%, r!, g!, b!
PSET (x%
, y1%
), _RGB(r!
* 255, g!
* 255, b!
* 255) tracePoint x1%, y1%, r!, g!, b!
PSET (x1%
, y1%
), _RGB(r!
* 255, g!
* 255, b!
* 255)
factor! = 255 / (endSize% * endSize%)
DO 'Marsaglia polar method for random gaussian s! = u! * u! + v! * v!
s!
= SQR(-2 * LOG(s!
) / s!
) * 0.5 u! = u! * s!
v! = v! * s!
tracePoint x% + u!, y% + v!, r1!, g1!, b1!
r! = r! + r1!
g! = g! + g1!
b! = b! + b1!
PSET (x%
, y%
), _RGB(r!
* factor!
, g!
* factor!
, b!
* factor!
) r! = 0
g! = 0
b! = 0
FOR v%
= 0 TO endSize%
- 1 y1! = y% + v% / endSize%
FOR u%
= 0 TO endSize%
- 1 x1! = x% + u% / endSize%
tracePoint x1!, y1!, r1!, g1!, b1!
r! = r! + r1!
g! = g! + g1!
b! = b! + b1!
PSET (x%
, y%
), _RGB(r!
* factor!
, g!
* factor!
, b!
* factor!
)
'####################################################################################################################
SUB tracePoint
(x!
, y!
, r!
, g!
, b!
) x0! = (x! - halfX%) / halfX%
y0! = (halfY% - y!) / halfY%
rayX = camDir.x + x0! * camRight.x + y0! * camUp.x
rayY = camDir.y + x0! * camRight.y + y0! * camUp.y
rayZ = camDir.z + x0! * camRight.z + y0! * camUp.z
'normalize to a vector length of 1
d
= 1 / SQR(rayX
* rayX
+ rayY
* rayY
+ rayZ
* rayZ
)traceRay camPos.x, camPos.y, camPos.z, rayX * d, rayY * d, rayZ * d, 3, -1, r!, g!, b!
'####################################################################################################################
SUB traceRay
(startX
, startY
, startZ
, rayX
, rayY
, rayZ
, depth%
, lastObj%
, lightR!
, lightG!
, lightB!
) findMinObj startX, startY, startZ, rayX, rayY, rayZ, lastObj%, minobj%, minDepth
IF minobj%
= 0 THEN ' Infinity lightR! = 0
lightG! = 0
lightB! = 0
ELSE ' An object was found intersectX = startX + rayX * minDepth
intersectY = startY + rayY * minDepth
intersectZ = startZ + rayZ * minDepth
'Calculate normal vector
normalX = 0
normalY = 0
normalZ = 1
normalX = (intersectX - positionX(minobj%)) / size(minobj%)
normalY = (intersectY - positionY(minobj%)) / size(minobj%)
normalZ = (intersectZ - positionZ(minobj%)) / size(minobj%)
'Calculate UV coordinates
IF textures
(minobj%
).image
<> -1 OR bumpmap
(minobj%
).image
<> -1 THEN texcoordU! = intersectX
texcoordV! = intersectY
IF normalY
<= 0 THEN texcoordU!
= 0 ELSE texcoordU!
= 0.5 texcoordU! = atan2(normalX, normalY) / pi2 + 0.5
texcoordV!
= acos
(normalZ
) / _PI
'Bumpmapping
IF bumpmap
(minobj%
).image
<> -1 THEN texdirxx = 1
texdirxy = 0
texdirxz = 0
texdiryx = 0
texdiryy = 1
texdiryz = 0
texdirxx = normalY
texdirxy = -normalX
texdirxz = 0
texdiryx = normalZ * normalX
texdiryy = normalZ * normalY
texdiryz = -(normalX * normalX + normalY * normalY)
x! = texcoordU! * bumpmap(minobj%).scaleU - bumpmap(minobj%).offsetU
y! = texcoordV! * bumpmap(minobj%).scaleV - bumpmap(minobj%).offsetV
dx1! = x! - x1%
dy1! = y! - y1%
dx2! = 1 - dx1!
dy2! = 1 - dy1!
dx1dy1! = dx1! * dy1!
dx1dy2! = dx1! * dy2!
dx2dy1! = dx2! * dy1!
dx2dy2! = dx2! * dy2!
x0% = remainder%(x1%, bumpmap(minobj%).w)
y0% = remainder%(y1%, bumpmap(minobj%).h)
x1% = remainder%(x1% + 1, bumpmap(minobj%).w)
y1% = remainder%(y1% + 1, bumpmap(minobj%).h)
sx!
= ((_RED(c0&
) - 127) * dx2dy2!
+ (_RED(c1&
) - 127) * dx1dy2!
+ (_RED(c2&
) - 127) * dx2dy1!
+ (_RED(c3&
) - 127) * dx1dy1!
) * bumpmap
(minobj%
).bumpfactor
/ 127 sy!
= ((_GREEN(c0&
) - 127) * dx2dy2!
+ (_GREEN(c1&
) - 127) * dx1dy2!
+ (_GREEN(c2&
) - 127) * dx2dy1!
+ (_GREEN(c3&
) - 127) * dx1dy1!
) * bumpmap
(minobj%
).bumpfactor
/ 127
normalX = normalX - (texdirxx * sx! + texdiryx * sy)
normalY = normalY - (texdirxy * sx! + texdiryy * sy)
normalZ = normalZ - (texdirxz * sx! + texdiryz * sy)
r
= SQR(normalX
* normalX
+ normalY
* normalY
+ normalZ
* normalZ
) normalX = normalX / r
normalY = normalY / r
normalZ = normalZ / r
'lighting
r = 2 * (rayX * normalX + rayY * normalY + rayZ * normalZ)
rayX = rayX - normalX * r
rayY = rayY - normalY * r
rayZ = rayZ - normalZ * r
diffuseR! = 0
diffuseG! = 0
diffuseB! = 0
specularR! = 0
specularG! = 0
specularB! = 0
dirX = lightX(a%) - intersectX
dirY = lightY(a%) - intersectY
dirZ = lightZ(a%) - intersectZ
r
= 1 / SQR(dirX
* dirX
+ dirY
* dirY
+ dirZ
* dirZ
) dirX = dirX * r
dirY = dirY * r
dirZ = dirZ * r
'Shadows testing
findShadow intersectX, intersectY, intersectZ, dirX, dirY, dirZ, minobj%, noShadows%
'Diffuse lighting
r = normalX * dirX + normalY * dirY + normalZ * dirZ
diffuseR! = diffuseR! + colorR!(minobj%) * lightR!(a%) * r
diffuseG! = diffuseG! + colorG!(minobj%) * lightG!(a%) * r
diffuseB! = diffuseB! + colorB!(minobj%) * lightB!(a%) * r
'Specular lighting
r = rayX * dirX + rayY * dirY + rayZ * dirZ
c! = r ^ (1 / highlight!(minobj%)) * specular!(minobj%)
specularR! = specularR! + lightR!(a%) * c!
specularG! = specularG! + lightG!(a%) * c!
specularB! = specularB! + lightB!(a%) * c!
lightR! = diffuseR! + specularR!
lightG! = diffuseG! + specularG!
lightB! = diffuseB! + specularB!
'texturing
IF textures
(minobj%
).image
<> -1 THEN x! = texcoordU! * textures(minobj%).scaleU - textures(minobj%).offsetU
y! = texcoordV! * textures(minobj%).scaleV - textures(minobj%).offsetV
dx1! = x! - x0%
dy1! = y! - y0%
dx2! = 1 - dx1!
dy2! = 1 - dy1!
dx1dy1! = dx1! * dy1!
dx1dy2! = dx1! * dy2!
dx2dy1! = dx2! * dy1!
dx2dy2! = dx2! * dy2!
x1% = remainder%(x0% + 1, textures(minobj%).w) ' returns positive value only, in contrast to MOD
y1% = remainder%(y0% + 1, textures(minobj%).h)
x0% = remainder%(x0%, textures(minobj%).w)
y0% = remainder%(y0%, textures(minobj%).h)
materialr!
= _RED(c0&
) * dx2dy2!
+ _RED(c1&
) * dx1dy2!
+ _RED(c2&
) * dx2dy1!
+ _RED(c3&
) * dx1dy1!
materialb!
= _BLUE(c0&
) * dx2dy2!
+ _BLUE(c1&
) * dx1dy2!
+ _BLUE(c2&
) * dx2dy1!
+ _BLUE(c3&
) * dx1dy1!
lightR! = lightR! * materialr! / 255F
lightG! = lightG! * materialg! / 255F
lightB! = lightB! * materialb! / 255F
'Reflection
IF reflection!
(minobj%
) > 0 AND depth%
> 0 THEN traceRay intersectX, intersectY, intersectZ, rayX, rayY, rayZ, depth% - 1, minobj%, reflectR!, reflectG!, reflectB!
lightR! = lightR! + (reflectR! - lightR!) * reflection!(minobj%)
lightG! = lightG! + (reflectG! - lightG!) * reflection!(minobj%)
lightB! = lightB! + (reflectB! - lightB!) * reflection!(minobj%)
' Global intensity
r
= EXP(-minDepth
/ 1000.0)
lightR! = lightR! * r
lightG! = lightG! * r
lightB! = lightB! * r
'####################################################################################################################
SUB findMinObj
(startX
, startY
, startZ
, rayX
, rayY
, rayZ
, lastObj%
, minObj%
, minDepth
) minObj% = 0
minDepth = 1E+308
depth = -startZ / rayZ
posX = positionX(a%) - startX
posY = positionY(a%) - startY
posZ = positionZ(a%) - startZ
r = rayX * posX + rayY * posY + rayZ * posZ
d = r * r - posX * posX - posY * posY - posZ * posZ + size(a%) * size(a%)
IF minDepth
> depth
THEN minDepth
= depth: minObj%
= a%
'####################################################################################################################
SUB findShadow
(startX
, startY
, startZ
, rayX
, rayY
, rayZ
, lastObj%
, noShadows%
) noShadows% = -1
depth = -startZ / rayZ
posX = positionX(a%) - startX
posY = positionY(a%) - startY
posZ = positionZ(a%) - startZ
r = rayX * posX + rayY * posY + rayZ * posZ
d = r * r - posX * posX - posY * posY - posZ * posZ + size(a%) * size(a%)
noShadows% = 0
'####################################################################################################################
'####################################################################################################################
'####################################################################################################################
PRINT "Generating textures. Press any key to see them generating." showing = 0
x% = 0: y% = 0
c%
= (ASC(MID$(a$
, b!
, 1)) - 35) * 4 x%
= x%
+ 1:
IF x%
= 128 THEN x%
= 0: y%
= y%
+ 1
getWorldBump x% / 3000, y% / 2000, a!
a! = (a! - 0.387) / 0.502: a! = a! * a!
getWorldPixel x% / 8 - 0.5, y% / 8 - 0.50, c!
c!
= c!
/ 255:
IF c!
> 1 THEN c!
= 1
r! = 11 + (24 + 231 * a! - 11) * c!
g! = 10 + (49 + 198 * a! - 10) * c!
b! = 50 + (8 + 181 * a! - 50) * c!
getWorldPixel x% / 8 - 0.46, y% / 8 - 0.50, c0!: getWorldBump x% / 300 + 0.001, y% / 300, a0!: a0! = a0! * c0!
getWorldPixel x% / 8 - 0.54, y% / 8 - 0.50, c1!: getWorldBump x% / 300 - 0.001, y% / 300, a1!: a1! = a1! * c1!
getWorldPixel x% / 8 - 0.50, y% / 8 - 0.46, c2!: getWorldBump x% / 300, y% / 300 + 0.001, a2!: a2! = a2! * c2!
getWorldPixel x% / 8 - 0.50, y% / 8 - 0.54, c3!: getWorldBump x% / 300, y% / 300 - 0.001, a3!: a3! = a3! * c3!
r! = (a1! - a0!) * 7
g! = (a2! - a3!) * 7
getFloorTexture x% / 256, y% / 256, r!, g!, b!
PSET (x%
, y%
), _RGB32(r!
* 255, g!
* 255, b!
* 255)
getFloorBump x% / 256 - 0.002, y% / 256, a0!
getFloorBump x% / 256 + 0.002, y% / 256, a1!
getFloorBump x% / 256, y% / 256 + 0.002, a2!
getFloorBump x% / 256, y% / 256 - 0.002, a3!
r! = (a1! - a0!) * 1400
g! = (a2! - a3!) * 1400
'####################################################################################################################
SUB getWorldPixel
(x!
, y!
, c0!
) dx!
= x!
- x%:
IF dx!
< 0 THEN dx!
= dx!
+ 128dy! = y! - y%
c0! = c0! + (c1! - c0!) * dx!
c2! = c2! + (c3! - c2!) * dx!
c0! = c0! + (c2! - c0!) * dy!
c0!
= c0!
- 72:
IF c0!
< 0 THEN c0!
= 0
SUB getWorldBump
(u!
, v!
, a!
) l! = 0
fbm u!, v!, 1, l!
a! = 0.3 * l! + 0.2
SUB getFloorTexture
(u!
, v!
, r!
, g!
, b!
) v1%
= v!
- INT(v!
) < 0.5: u1%
= u!
- INT(u!
) < 0.5
l! = 0
fbm u!, v!, 3, l!
l! = l! * 0.7
fbm u!, v!, 2, l!
r! = 0.054 * l! + 0.61
g! = 0.054 * l! + 0.42
b! = 0.054 * l! + 0.25
l! = 0
fbm u!, v!, 1, l!
l! = l! * 0.6
fbm u!, v!, 0, l!
r! = 0.10 * l! + 0.05
g! = 0.08 * l! - 0.04
b! = 0.07 * l! - 0.06
SUB getFloorBump
(u!
, v!
, a!
) v1%
= v!
- INT(v!
) < 0.5: u1%
= u!
- INT(u!
) < 0.5v2!
= v!
* 2 - INT(v!
* 2): v2!
= 1 - v2!
* (1 - v2!
) * 4: v2!
= v2!
* v2!: v2!
= 1 - v2!
* v2!
u2!
= u!
* 2 - INT(u!
* 2): u2!
= 1 - u2!
* (1 - u2!
) * 4: u2!
= u2!
* u2!: u2!
= 1 - u2!
* u2!
l! = 0
fbm u!, v!, 3, l!
l! = l! * 0.7
fbm u!, v!, 2, l!
a! = 0.02 * l! + 0.7
l! = 0
fbm u!, v!, 1, l!
l! = l! * 0.6
fbm u!, v!, 0, l!
a! = 0.05 * l! + 0.6
a! = a! * u2! * v2!
'a! = a! + (u2! * v2! - 1) ' * 0.88
'IF a! < 0.06 THEN a = RND * 0.02
'####################################################################################################################
zx! = x! * 40 - y! * 2
zy! = y!
i% = -5
zx! = x! * 50
zy! = y! * 50
i% = -2
zx! = x! * 80
zy! = y! * 80
i% = -2
zx! = x! * 30 + y! * 0.5
zy! = y! * 2
i% = -2
scale! = 1
zcx! = zx!: zx! = zcx! * 0.6 - zy! * 0.8: zy! = zcx! * 0.8 + zy! * 0.6
zcx!
= CINT(zx!
/ scale!
) * scale!: zcy!
= CINT(zy!
/ scale!
) * scale!
rx1! = zcx! + 0.5 * scale! + 14: ry1! = zcy! + 0.5 * scale!: r! = 123094 / (rx1! * rx1! + ry1! * ry1!)
rx1!
= rx1!
* r!: ry1!
= ry1!
* r!: rx1!
= rx1!
- INT(rx1!
): ry1!
= ry1!
- INT(ry1!
) rx2! = zcx! - 0.5 * scale! + 14: ry2! = zcy! + 0.5 * scale!: r! = 123094 / (rx2! * rx2! + ry2! * ry2!)
rx2!
= rx2!
* r!: ry2!
= ry2!
* r!: rx2!
= rx2!
- INT(rx2!
): ry2!
= ry2!
- INT(ry2!
) rx3! = zcx! + 0.5 * scale! + 14: ry3! = zcy! - 0.5 * scale!: r! = 123094 / (rx3! * rx3! + ry3! * ry3!)
rx3!
= rx3!
* r!: ry3!
= ry3!
* r!: rx3!
= rx3!
- INT(rx3!
): ry3!
= ry3!
- INT(ry3!
) rx4! = zcx! - 0.5 * scale! + 14: ry4! = zcy! - 0.5 * scale!: r! = 123094 / (rx4! * rx4! + ry4! * ry4!)
rx4!
= rx4!
* r!: ry4!
= ry4!
* r!: rx4!
= rx4!
- INT(rx4!
): ry4!
= ry4!
- INT(ry4!
) x0! = (zx! - zcx!) / scale! + 0.5: x0! = (3 - 2 * x0!) * x0! * x0!: x1! = 1 - x0!
y0! = (zy! - zcy!) / scale! + 0.5: y0! = (3 - 2 * y0!) * y0! * y0!: y1! = 1 - y0!
pixcompx! = rx1! * x0! * y0! + rx3! * x0! * y1! + rx2! * x1! * y0! + rx4! * x1! * y1!
pixcompy! = ry1! * x0! * y0! + ry3! * x0! * y1! + ry2! * x1! * y0! + ry4! * x1! * y1!
o!
= o!
+ SQR(pixcompx!
* pixcompx!
+ pixcompy!
* pixcompy!
) * scale!
* scale!: scale!
= scale!
* 0.8
'####################################################################################################################
'####################################################################################################################
'####################################################################################################################
objectType%(1) = FLOOR
colorR!(1) = 1
colorG!(1) = 1
colorB!(1) = 1
colorA!(1) = 1
specular!(1) = 2
highlight!(1) = 0.002
reflection!(1) = 0.5
texturePrepare textures(1), texture&(3), .005, .005, 0, 0, 0
texturePrepare bumpmap(1), texture&(4), .005, .005, 0, 0, 1
objectType%(2) = SPHERE
positionX(2) = 0
positionY(2) = 57.735
positionZ(2) = 50
size(2) = 50
colorR!(2) = 1
colorG!(2) = 0
colorB!(2) = 0
colorA!(2) = 1
specular!(2) = 1
highlight!(2) = 0.1
reflection!(2) = 0.1
texturePrepare textures(2), -1, 1, 1, 0, 0, 0
texturePrepare bumpmap(2), -1, 1, 1, 0, 0, 1
objectType%(3) = SPHERE
positionX(3) = -50
positionY(3) = -28.8675
positionZ(3) = 50
size(3) = 50
colorR!(3) = 0
colorG!(3) = 0
colorB!(3) = 1
colorA!(3) = 1
specular!(3) = 1
highlight!(3) = 0.04
reflection!(3) = 0.4
texturePrepare textures(3), -1, 1, 1, 0, 0, 0
texturePrepare bumpmap(3), -1, 1, 1, 0, 0, 1
objectType%(4) = SPHERE
positionX(4) = 50
positionY(4) = -28.8675
positionZ(4) = 50
size(4) = 50
colorR!(4) = 0
colorG!(4) = 1
colorB!(4) = 0
colorA!(4) = 1
specular!(4) = 10
highlight!(4) = 0.01
reflection!(4) = 0.2
texturePrepare textures(4), -1, 1, 1, 0, 0, 0
texturePrepare bumpmap(4), -1, 1, 1, 0, 0, 1
objectType%(5) = SPHERE
positionX(5) = 0
positionY(5) = 0
positionZ(5) = 132
size(5) = 50
colorR!(5) = 1
colorG!(5) = 1
colorB!(5) = 1
colorA!(5) = 1
specular!(5) = 5
highlight!(5) = 0.002
reflection!(5) = 0.15
texturePrepare textures(5), texture&(1), 1, 1, 0.35, 0, 0
texturePrepare bumpmap(5), texture&(2), 1, 1, 0.35, 0, 1
numObjects% = 5
lightX(1) = 460
lightY(1) = -460
lightZ(1) = 460
lightR!(1) = 1
lightG!(1) = 0.25
lightB!(1) = 0.25
lightX(2) = -640
lightY(2) = -180
lightZ(2) = 460
lightR!(2) = 0.25
lightG!(2) = 1
lightB!(2) = 0.25
lightX(3) = 80
lightY(3) = 260
lightZ(3) = 760
lightR!(3) = 0.25
lightG!(3) = 0.25
lightB!(3) = 1
lightX(4) = 0
lightY(4) = 0
lightZ(4) = 400
lightR!(4) = 1
lightG!(4) = 1
lightB!(4) = 1
numLights% = 4
'####################################################################################################################
SUB texturePrepare
(tex
AS TEXTURE
, handle&
, sU!
, sV!
, oU!
, oV!
, bumpfactor!
) tex.image = handle&
tex.scaleU = sU! * tex.w
tex.scaleV = sV! * tex.h
tex.offsetU = oU! * tex.w
tex.offsetV = oV! * tex.h
tex.bumpfactor = bumpfactor!
'####################################################################################################################
'# Math Library V0.11 (routines)
'# By Zom-B
'####################################################################################################################
remainder%
= a%
- INT(a%
/ b%
) * b%
'> merger: Skipping unused FUNCTION fRemainder (a, b)
'####################################################################################################################
'> merger: Skipping unused FUNCTION safeLog (x)
'####################################################################################################################
'> merger: Skipping unused FUNCTION asin (y)
acos
= pi05
- ATN(y
/ SQR(1 - y
* y
))
'> merger: Skipping unused FUNCTION safeAcos (y)
'####################################################################################################################
'# Vector math library v0.1 (module part)
'# By Zom-B
'####################################################################################################################
SUB vectorScale
(a
AS VECTOR
, scale
) a.x = a.x * scale
a.y = a.y * scale
a.z = a.z * scale
SUB vectorNormalize
(a
AS VECTOR
) r
= 1 / SQR(a.x
* a.x
+ a.y
* a.y
+ a.z
* a.z
)a.x = a.x * r
a.y = a.y * r
a.z = a.z * r
'####################################################################################################################
SUB vectorCross
(a
AS VECTOR
, b
AS VECTOR
, o
AS VECTOR
) o.x = a.y * b.z - a.z * b.y
o.y = a.z * b.x - a.x * b.z
o.z = a.x * b.y - a.y * b.x
'####################################################################################################################
'# Screen mode selector v1.1 (routines)
'# By Zom-B
'####################################################################################################################
FUNCTION selectScreenMode&
(yOffset%
, colors%
) DIM aspectName$
(0 TO 9), aspectCol%
(0 TO 9) READ aspectName$
(y%
), aspectCol%
(y%
)
DIM vidX%
(1 TO 100), vidY%
(1 TO 100), vidA%
(1 TO 100) READ vidX%
(y%
), vidY%
(y%
), vidA%
(y%
)
PRINT "Select video mode:";
TAB(61);
"Click " POKE yOffset%
* 160 + 132, 31
y% = 0
lastY% = 0
selectedAspect% = 0
reprint% = 1
lastButton% = 0
reprint% = 0
COLOR aspectCol%
(vidA%
(x%
))
PRINT "<"; aspectName$
(x%
);
">"
y% = (yOffset% + y%) * 160 + 1
y% = 0
selectedAspect% = y% - 1
reprint% = 1
y% = (yOffset% + y%) * 160 + 1
y% = 0
lastY% = y%
selectScreenMode&
= _NEWIMAGE(vidX%
(y%
), vidY%
(y%
), colors%
)