virtual func not overriding

General FreeBASIC programming questions.
Post Reply
dafhi
Posts: 1645
Joined: Jun 04, 2005 9:51

virtual func not overriding

Post by dafhi »

sphere.hit is intended to take precedent

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
paul doe
Moderator
Posts: 1735
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: virtual func not overriding

Post by paul doe »

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"
'function hit(ac ray, sng, sng, as hit_record) as boolean

type sphere extends renderable
   
    decl      csr '' constructor
    decl      csr(as vec3, as float)', as material ptr)
   
    decl virt func hit(ac ray, sng, sng, as hit_record) as boolean override
   
    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 ac 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
You made a typo (written 'as' instead of 'ac'):

Code: Select all

    decl virt func hit(as ray, sng, sng, as hit_record) as boolean override '' Error
    decl virt func hit(ac ray, sng, sng, as hit_record) as boolean override '' Correct
Perhaps if the code wasn't almost unreadable, these kind of errors would be easier to spot? Now it's up to you to resolve the constness issue (can't really know your intent there). The override keyword is your friend.
dafhi
Posts: 1645
Joined: Jun 04, 2005 9:51

Re: virtual func not overriding

Post by dafhi »

ah. thanks! i wasn't aware that const would have an effect in such a manner

mostly i'm chomping at the bit to get a new ray tracer running. once i'm satisfied i'll *possibly* do away with the shorthand
fxm
Moderator
Posts: 12131
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: virtual func not overriding

Post by fxm »

dafhi wrote:i'll *possibly* do away with the shorthand
It would be good for us, otherwise it forces us to create and then work on the file '*.pp.bas' !
dafhi
Posts: 1645
Joined: Jun 04, 2005 9:51

Re: virtual func not overriding

Post by dafhi »

aww. yeah I'll do it for you guys :3

if that was a joke thought i didn't get it
paul doe
Moderator
Posts: 1735
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: virtual func not overriding

Post by paul doe »

dafhi wrote:ah. thanks! i wasn't aware that const would have an effect in such a manner

mostly i'm chomping at the bit to get a new ray tracer running. once i'm satisfied i'll *possibly* do away with the shorthand
You're welcome. Fair enough, I just don't understand the urge for these obfuscating 'shorthands' (that all they ultimately do is waste your time). #Macros and #defines aren't meant to obfuscate, but to clarify and/or help with tedious and repetitive, error-prone tasks (such as castings):

Code: Select all

type as sub( _
    byval as any ptr, _
    byval as any ptr ) _
  EventHandler

#define asHandler( __e__ ) _
  cast( EventHandler, @__e__ )

sub _
  fireEvent( _
    byval aHandler as EventHandler )
  
  dim as integer _
    foo => -4
  dim as string _
    bar => "Hello!"
  
  aHandler( @foo, @bar )
end sub

sub _
  handler( _
    byval aFoo as integer ptr, _
    byval aBar as string ptr )
  
  ? *aFoo
  ? *aBar
end sub

fireEvent( asHandler( handler ) )

sleep()
fxm
Moderator
Posts: 12131
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: virtual func not overriding

Post by fxm »

fxm wrote:
dafhi wrote:i'll *possibly* do away with the shorthand
It would be good for us, otherwise it forces us to create and then work on the file '*.pp.bas' !
[doc]
The -pp compiler option enables the preprocessor-only mode. The code is parsed & checked as usual, but is not compiled. For every input file <source>.bas passed to the compiler, a pre-processed version named <source>.pp.bas is generated.
Specifically, preprocessor commands such as conditional compilation (#if, #ifdef, #ifndef, etc.), text replacement (#define, #macro, etc.) and file inclusion (#include) are processed recursively, and the resulting expanded code is written to the pp.bas file.
dafhi
Posts: 1645
Joined: Jun 04, 2005 9:51

Re: virtual func not overriding

Post by dafhi »

well thanks guys. ima keep pushing till i get this thing done then i'll .pp it out

[edit] nice example there Mr. doe. It took me some time away from the screen and then a re-visit .. the code is short enough .. to grok what you were showcasing
Post Reply