Code: Select all
/' -- "fb 1337 h4x.bas" - 2020 Jan 28 - by dafhi -- '/
#undef int
#define def #define
def int as Integer
def sng as single
def dbl as double
def ac as const
def decl declare
def func function
def prop property
def virt virtual
def op operator
def csr constructor
def ret return
def float single
def By ByRef
def abst abstract
function c255(in sng) int '2020 Jan 22
return iif( in<0, 0, iif( in>=1, 255, sqr(in)*256-.5 ) )
end function
' -------- fb 1337 h4x
/' -- vec3.bas - 2020 Jan 28 - by dafhi '/
#ifndef VEC3H
#define VEC3H
'#include "fb 1337 h4x.bas"
#ifndef piBy4
const Tau = 8*atn(1)
const piBy4 = 4*atn(1)
#EndIf
const as float EPS=1e-6
const as float INF=1e9f
def v3 vec3 '' v3 and vec3 equivalency
type vec3 extends object
decl csr(sng=0, sng=0, sng=0)
decl csr(ac v3)
decl const op [](int) byref as float
'decl op + byref ac v3
'decl op -
'decl op []
decl op += (byref ac v3)
decl op -= (byref ac v3)
decl op *= (byref ac v3)
decl op /= (byref ac v3)
decl op *= (ac float)
decl op /= (as float)
decl prop unit_v ac v3
decl prop length as float
decl prop squared_length as float
decl sub make_unit_vector
decl op cast as string
as float x, y, z
End type
op v3.cast as string
return str(x)+" "+str(y)+" "+str(z)
end op
csr vec3(xx sng, yy sng, zz sng)
x=xx: y=yy: z=zz
end csr
csr vec3(i ac v3)
x=i.x: y=i.y: z=i.z
end csr
const op v3.[](index int) byref as float
ret cptr(float ptr,@x)[index]
end op
operator -(r ac v3) as v3
return v3(-r.x,-r.y,-r.z)
end operator
prop v3.unit_v ac v3
static as float s: s = x*x+y*y+z*z
if s > EPS then s=1/sqr(s): return v3(x*s,y*s,z*s)
return this
end prop
function unit_vector(v ac v3) ac v3
static as float s: s = v.x*v.x+v.y*v.y+v.z*v.z
if s > EPS then s=1/sqr(s): return v3(v.x*s,v.y*s,v.z*s)
return v3(1,0,0)
end function
sub vec3.make_unit_vector
var k = x*x + y*y + z*z
if k<>0 then k = 1/sqr(k): _
x *= k: y *= k: z *= k
end sub
#undef _ops
#macro _ops(oper)
op vec3.oper= ( byref rhs ac vec3 )
x oper= rhs.x
y oper= rhs.y
z oper= rhs.z
end op
#endmacro
_ops(+)
_ops(-)
_ops(*)
_ops(/)
op v3.*= (i ac float)
x *= i: y *= i: z *= i
end op
op v3./= (i as float)
i = 1/i
x *= i: y *= i: z *= i
end op
#undef _ops
#macro _ops(oper, arg1, arg2)
op oper(arg1, arg2) as v3
ret v3( v.x oper t, v.y oper t, v.z oper t )
end op
#endmacro
_ops(*, t as float, byref v as v3)
_ops(*, byref v ac v3, t as float)
_ops(/, byref v ac v3, t as float)
#undef _ops
#macro _ops(oper)
op oper(l as v3, r as v3) as v3
op = v3(l.x oper r.x,l.y oper r.y,l.z oper r.z)
end op
#endmacro
_ops(+)
_ops(-)
_ops(*)
_ops(/)
#undef _ops
prop v3.squared_length as float
return x*x+y*y+z*z
end prop
prop v3.length as float
return sqr(x*x+y*y+z*z)
end prop
func dot(byref v1 ac v3, byref v2 ac v3) as float
ret v1.x * v2.x + v1.y * v2.y + v1.z * v2.z
end func
func cross(byref v1 ac v3, byref v2 ac v3) as v3
#if 1
ret v3( _
v1.y*v2.z - v1.z*v2.y, _
v1.z*v2.x - v1.x*v2.z, _
v1.x*v2.y - v1.y*v2.x)
#else
ret v3( _
v1.y*v2.z - v1.z*v2.y, _
-(v1.x*v2.z - v1.z*v2.x), _
v1.x*v2.y - v1.y*v2.x)
#endif
end func
#EndIf
' ------- vec3
/' -- ray.bas (FreeBASIC) - 2020 Jan 28 - by dafhi
"Ray Tracing In One Weekend" '/
'#include "vec3.bas"
type ray
decl csr
decl csr( ac vec3, ac vec3 )
decl func point_at_parameter( as float) as vec3
as vec3 origin, direction
End Type
csr ray
end csr
csr ray( a ac vec3, b ac vec3 )
origin=a: direction=b
end csr
func ray.point_at_parameter(t as float) as vec3
ret origin + t*direction
end func
' ------ ray
/' -- renderable.bas - 2020 Feb 1 - by dafhi
formerly: hittable.bas, named from "Ray Tracing in one Weekend" '/
#ifndef RENDERABLEH
#define RENDERABLEH
'#include once "ray.bas"
type ref_mat as material '' forward reference
type hit_record
as float t
as vec3 p
as vec3 normal
' as ref_mat ptr mat_ptr
End Type
type renderable extends object
declare virtual function hit(ac ray, sng, sng, as hit_record) as boolean
End Type
virtual function renderable.hit(r ac ray, t_min sng, t_max sng, rec as hit_record) as boolean
return false
end func
#EndIf
' ------ renderable
/' -- "renderable_list.bas" - 2020 Jan 31 - by dafhi -- '/
#ifndef RENDERABLE_LISTH
#define RENDERABLE_LISTH
type renderable_list extends renderable
decl csr '' constructor
decl csr( as renderable ptr ptr, int)
decl virt func hit( ac ray, sng, sng, as hit_record) ac boolean
as renderable ptr ptr list
int list_size
End Type
csr renderable_list
end csr
csr renderable_list(l as renderable ptr ptr, n int)
list = l: list_size = n
end csr
virt func renderable_list.hit( r ac ray, t_min sng, t_max sng, rec as hit_record) ac boolean
dim as hit_record temp_rec
var hit_anything = false
var closest_so_far = t_max
for i int = 0 to list_size-1
if list[i]->hit(r, t_min, closest_so_far, temp_rec) then
hit_anything = true
closest_so_far = temp_rec.t
rec = temp_rec
EndIf
Next
ret hit_anything
end func
#EndIf
' ------- renderable_list
/' -- "sphere.bas" - 2020 Jan 28 - by dafhi -- '/
#ifndef SPHEREH
#define SPHEREH
#include once "renderable.bas"
type sphere extends renderable
decl csr '' constructor
decl csr(as vec3, as float)', as material ptr)
decl virt func hit( as ray, sng, sng, as hit_record) as boolean
decl prop radius(as float) '' updates rad and r2
decl prop radius as float '' returns rad
as vec3 center
as float rad, r2
'as material ptr mat_ptr
'int debug
End Type
csr sphere
end csr
csr sphere(cen as vec3, r as float)', pmat as material ptr)
center = cen: radius = r': mat_ptr = pmat
end csr
prop sphere.radius(in as float)
rad = in: r2 = in*in
end prop
prop sphere.radius as float
return rad
end prop
virt func sphere.hit( r as ray, t_min sng, t_max sng, rec as hit_record) as boolean
var oc = r.origin - center
var a = dot(r.direction, r.direction) '' dot
var b = dot(oc, r.direction)
var c = dot(oc, oc) - r2
var disc = b*b - a*c
'? rnd
return 1
if disc > 0 then
#macro dupl()
if temp < t_max andalso temp > t_min then
rec.t = temp
rec.p = r.point_at_parameter(rec.t)
rec.normal = (rec.p - center) / rad
'rec.mat_ptr = mat_ptr
ret true
EndIf
#endmacro
var temp = (-b - sqr(disc))/a
dupl()
temp = (-b + sqr(disc))/a
dupl()
EndIf
ret false
end func
#EndIf
' ------- sphere
function sky( r as ray ) as vec3
var unit_direction = r.direction.unit_v
var t = .5*(unit_direction.y + 1)
return (1-t)*v3(1,1,1) + t*v3(.5,.7,1)
End Function
#undef color
function color( r as ray, world as renderable ptr ) as v3
dim as hit_record rec
if world->hit( r, 0, INF, rec ) then
#define n rec.normal
ret .5*v3(n.x+1,n.y+1,n.z+1)
EndIf
return sky(r)
End Function
#macro show_pixel( _col )
var ir = c255( _col[0] )
var ig = c255( _col[1] )
var ib = c255( _col[2] )
pset (i,ny-1-j), rgb( ir, ig, ib )
#EndMacro
sub main
' -------
var scale = 2.4
var nx = 200 * scale
var ny = 100 * scale
var ns = 11 '' samples
const borderless = 8
screenres nx, ny, 32', borderless
var lower_left_corner = v3(-2,-1,-1)
var horizontal = v3(4,0,0)
var vertical = v3(0,2,0)
var origin = v3(0,0,0)
' ------
var num_objects = 2
var list = new renderable ptr[2]
list[0] = new sphere( v3(0,0,-1), .5 )
list[1] = new sphere( v3(0,-100.5,-1), 100 )
dim as renderable ptr world = new renderable_list( list, num_objects )
dim as string kstr
for j int = ny-1 to 0 step -1
for i int = 0 to nx-1
var u = i/nx
var v = j/ny
var r = ray(origin, lower_left_corner + u*horizontal + v*vertical)
show_pixel( color(r, world) )
Next
if j mod 2=0 then kstr=inkey: sleep 1 '' small rest every N scanlines
if kstr<>"" then exit for
next
if kstr=chr(27) then exit sub
sleep
End Sub
Main