its late and im tired i managed to put inplace the frame work and write in point light code althought i haven't tested it yet
But theres a ton of bugs...
the screen is black for one and nothing shows
so im going to post the code here so you guys can see whats wrong
im going to sleep on it in hopes to have refresh my brain and hope that i can solve it in the morning if you guys don't frist

Code: Select all
;/Title: PBRay
;/Author: Dreglor
;/Date: 6-21-05
;/Version: Alpha
;/Function: Renders scenes using raytracing
;/Notes: Special Thanks to MrMat for helping me :)
;/Todo: Fix Bugs, Reflect, Refract
;- Constants
#Version="Alpha"
#Tolerance=0.0001
#ObjectType_Null=0
#ObjectType_PointLight=1
#ObjectType_Sphere=2
#TraceFor_Nothing=0 ;NULL basicly, kinda funny thought
#TraceFor_Visables=1
#TraceFor_Lights=2
#TraceFor_Shadows=3
#Render_Nothing=0 ;NULL
#Render_IntersectionTest=1
#Render_Soild=2
#Render_Diffuse=3
#MaxChildren=6
;- Structures
Structure xyz
x.f
y.f
z.f
EndStructure
Structure Matrix
e11.f
e12.f
e13.f
e21.f
e22.f
e23.f
e31.f
e32.f
e33.f
EndStructure
Structure Camera
Origin.xyz
Direction.xyz
ViewingAngle.xyz
EndStructure
Structure Color
Red.f
Green.f
Blue.f
EndStructure
Structure Material
SoildColor.Color
Diffuse.f
Reflect.f
Refract.f
EndStructure
Structure PointLight
Color.Color
Position.xyz
EndStructure
Structure DirectionalLight
Color.Color
Direction.xyz ;normilized
EndStructure
Structure Sphere
radius.f
EndStructure
; Structure Plane ;incomplete
; normal.xyz
; Distance.xyz ;???
; EndStructure
; Structure Triangle ;incomplete
; v1.xyz
; v2.xyz
; v3.xyz
; normal.xyz
; EndStructure
Structure Object
Type.b
Material.Material
Origin.xyz
Direction.xyz
IsLight.b
Primitive.l ;points to a memory that get[primitive]structure will use to fill a structure with
EndStructure
Structure Scene
Ambient.Color
Perspective.f
ScreenWidth.w
ScreenHeight.w
HalfScreenWidth.w
HalfScreenHeight.w
EndStructure
;- Globals
Global MainScene.Scene
NewList ObjectList.Object()
;- Procedures
;- Color Math
Procedure.b ColorScalarMuilply(*a.Color, b.f, *result.Color);returns a pointer to a Color that has been muiltiplied by a scalar
*result\Red = *a\Red * b
*result\Green = *a\Green * b
*result\Blue = *a\Blue * b
EndProcedure
Procedure.b ColorMuilply(*a.Color, *b.Color, *result.Color);returns a pointer to a Color that has been muiltiplied
*result\Red = *a\Red * *b\Red
*result\Green = *a\Green * *b\Green
*result\Blue = *a\Blue * *b\Blue
EndProcedure
Procedure.b ColorAdd(*a.Color, *b.Color, *result.Color);returns a pointer to a Color that has been added
*result\Red = *a\Red + *b\Red
*result\Green = *a\Green + *b\Green
*result\Blue = *a\Blue + *b\Blue
EndProcedure
Procedure ColorRangeCheck(*a.Color)
If *a\Red>255
*a\Red=255
EndIf
If *a\Green>255
*a\Green=255
EndIf
If *a\Blue>255
*a\Blue=255
EndIf
EndProcedure
;-Vector Math
Procedure.f VectorMagnitude(*this.xyz);returns the maginitude of a Vector
ProcedureReturn Sqr((*this\x * *this\x)+(*this\y * *this\y)+(*this\z * *this\z))
EndProcedure
Procedure.f VectorDotProduct(*a.xyz, *b.xyz)
ProcedureReturn *a\x * *b\x + *a\y * *b\y + *a\z * *b\z
EndProcedure
Procedure.b VectorNormalize(*this.xyz);normilzes a vector
m.f = Sqr(*this\x * *this\x + *this\y * *this\y + *this\z * *this\z)
If m < = #Tolerance
m = 1
Else
*this\x = *this\x / m
*this\y = *this\y / m
*this\z = *this\z / m
EndIf
If Abs(*this\x) < #Tolerance
*this\x = 0
EndIf
If Abs(*this\y) < #Tolerance
*this\y = 0
EndIf
If Abs(*this\z) < #Tolerance
*this\z = 0
EndIf
EndProcedure
Procedure.b VectorReverse(*this.xyz);reverses a Vector
*this\x = -*this\x
*this\y = -*this\y
*this\z = -*this\z
EndProcedure
Procedure.b VectorCrossMuiltply(*a.xyz, *b.xyz, *result.xyz);returns a pointer to a vector that has been crossed muiltiplied
*result\x = *a\y * *b\z - *a\z * *b\y
*result\y = -*a\x * *b\z + *a\z * *b\x
*result\z = *a\x * *b\y - *a\y * *b\x
ProcedureReturn @result
EndProcedure
Procedure.b VectorAdd(*a.xyz, *b.xyz, *result.xyz);returns a pointer to a vector that has been added
*result\x = *a\x + *b\x
*result\y = *a\y + *b\y
*result\z = *a\z + *b\z
ProcedureReturn @result
EndProcedure
Procedure.b VectorSubtract(*a.xyz, *b.xyz, *result.xyz);returns a pointer to a vector that has been Subtracted
*result\x = *a\x - *b\x
*result\y = *a\y - *b\y
*result\z = *a\z - *b\z
ProcedureReturn @result
EndProcedure
Procedure.b VectorScalarMuilply(*a.xyz, *b.xyz, *result.xyz);returns a pointer to a vector that has been muiltiplied
*result\x = *a\x * *b\x
*result\y = *a\y * *b\y
*result\z = *a\z * *b\z
ProcedureReturn @result
EndProcedure
Procedure.b VectorScalarDivide(*a.xyz, *b.xyz, *result.xyz);returns a pointer to a vector that has been divided
*result\x = *a\x / *b\x
*result\y = *a\y / *b\y
*result\z = *a\z / *b\z
ProcedureReturn @result
EndProcedure
Procedure.f VectorTripleScalarProduct(*a.xyz, *b.xyz, *c.xyz);returns triple scalar product of 3 vectors
ProcedureReturn *a\x * (*b\y * *c\z - *b\z * *c\y)+(*a\y * (-*b\x * *c\z + *b\z * *c\x))+(*a\z * (*b\x * *c\y - *b\y * *c\x))
EndProcedure
;-Matrix Math
Procedure.f MatrixDeterminant(*this.Matrix);returns the determiant of a matrix
ProcedureReturn *this\e11 * *this\e22 * *this\e33 - *this\e11 * *this\e32 * *this\e23 + *this\e21 * *this\e32 * *this\e13 - *this\e21 * *this\e12 * *this\e33 + *this\e31 * *this\e12 * *this\e23 - *this\e31 * *this\e22 * *this\e13
EndProcedure
Procedure.w MatrixTranspose(*this.Matrix, *result.Matrix);returns the transpose of a matrix
*result\e11 = *this\e11
*result\e21 = *this\e21
*result\e31 = *this\e31
*result\e12 = *this\e12
*result\e22 = *this\e22
*result\e32 = *this\e32
*result\e13 = *this\e13
*result\e23 = *this\e23
*result\e33 = *this\e33
EndProcedure
Procedure.w MatrixInverse(*this.Matrix);returns the inverse of a matrix
d.f = MatrixDeterminant(*this)
If d = 0
d = 1
EndIf
*this\e11 = (*this\e22 * *this\e33 - *this\e23 * *this\e32)/d
*this\e21 = -(*this\e12 * *this\e33 - *this\e13 * *this\e32)/d
*this\e31 = (*this\e12 * *this\e23 - *this\e13 * *this\e22)/d
*this\e12 = -(*this\e21 * *this\e33 - *this\e23 * *this\e31)/d
*this\e22 = (*this\e11 * *this\e33 - *this\e13 * *this\e31)/d
*this\e32 = -(*this\e11 * *this\e23 - *this\e13 * *this\e21)/d
*this\e13 = (*this\e21 * *this\e32 - *this\e12 * *this\e31)/d
*this\e23 = -(*this\e11 * *this\e32 - *this\e12 * *this\e31)/d
*this\e33 = (*this\e11 * *this\e22 - *this\e12 * *this\e21)/d
EndProcedure
Procedure.w MatrixAdd(*a.Matrix, *b.Matrix, *result.Matrix);adds 2 matrice together
*result\e11 = *a\e11 + *b\e11
*result\e12 = *a\e12 + *b\e12
*result\e13 = *a\e13 + *b\e13
*result\e21 = *a\e21 + *b\e21
*result\e22 = *a\e22 + *b\e22
*result\e23 = *a\e23 + *b\e23
*result\e31 = *a\e31 + *b\e31
*result\e32 = *a\e32 + *b\e32
*result\e33 = *a\e33 + *b\e33
EndProcedure
Procedure.w MatrixSubtract(*a.Matrix, *b.Matrix, *result.Matrix);subtract 2 matrice together
*result\e11 = *a\e11 - *b\e11
*result\e12 = *a\e12 - *b\e12
*result\e13 = *a\e13 - *b\e13
*result\e21 = *a\e21 - *b\e21
*result\e22 = *a\e22 - *b\e22
*result\e23 = *a\e23 - *b\e23
*result\e31 = *a\e31 - *b\e31
*result\e32 = *a\e32 - *b\e32
*result\e33 = *a\e33 - *b\e33
EndProcedure
Procedure.w MatrixScalarMuiltply(*a.Matrix, Scalar.f, *result.Matrix);muiltplies a matrix to a scalar
*result\e11 = *a\e11 * Scalar
*result\e12 = *a\e12 * Scalar
*result\e13 = *a\e13 * Scalar
*result\e21 = *a\e21 * Scalar
*result\e22 = *a\e22 * Scalar
*result\e23 = *a\e23 * Scalar
*result\e31 = *a\e31 * Scalar
*result\e32 = *a\e32 * Scalar
*result\e33 = *a\e33 * Scalar
EndProcedure
Procedure.w MatrixScalarDivision(*a.Matrix, Scalar.f, *result.Matrix);divides a matrix to a scalar
*result\e11 = *a\e11 / Scalar
*result\e12 = *a\e12 / Scalar
*result\e13 = *a\e13 / Scalar
*result\e21 = *a\e21 / Scalar
*result\e22 = *a\e22 / Scalar
*result\e23 = *a\e23 / Scalar
*result\e31 = *a\e31 / Scalar
*result\e32 = *a\e32 / Scalar
*result\e33 = *a\e33 / Scalar
EndProcedure
;-FrameWork
Procedure AddPointLightObject(*Light.PointLight,*Origin.xyz)
AddElement(ObjectList())
ObjectList()\Type=#ObjectType_PointLight
ObjectList()\Material\SoildColor\Red=*Light\Color\Red
ObjectList()\Material\SoildColor\Green=*Light\Color\Green
ObjectList()\Material\SoildColor\Blue=*Light\Color\Blue
ObjectList()\Origin\x=*Origin\x
ObjectList()\Origin\y=*Origin\y
ObjectList()\Origin\z=*Origin\z
ObjectList()\IsLight=#True
ObjectList()\Primitive=#Null
EndProcedure
;get and set are not required
Procedure AddDirectionalLightObject(*Light.DirectionalLight,*Direction.xyz)
AddElement(ObjectList())
ObjectList()\Type=#ObjectType_PointLight
ObjectList()\Material\SoildColor\Red=*Light\Color\Red
ObjectList()\Material\SoildColor\Green=*Light\Color\Green
ObjectList()\Material\SoildColor\Blue=*Light\Color\Blue
ObjectList()\Direction\x=*Direction\x
ObjectList()\Direction\y=*Direction\y
ObjectList()\Direction\z=*Direction\z
ObjectList()\IsLight=#True
ObjectList()\Primitive=#Null
EndProcedure
;get and set are not required
Procedure.b AddSphereObject(*Material.Material,*Origin.xyz,radius.f)
AddElement(ObjectList())
ObjectList()\Type=#ObjectType_Sphere
ObjectList()\Material\SoildColor\Red=*Material\SoildColor\Red
ObjectList()\Material\SoildColor\Green=*Material\SoildColor\Green
ObjectList()\Material\SoildColor\Blue=*Material\SoildColor\Blue
ObjectList()\Material\Diffuse=*Material\Diffuse
ObjectList()\Material\Reflect=*Material\Reflect
ObjectList()\Origin\x=*Origin\x
ObjectList()\Origin\y=*Origin\y
ObjectList()\Origin\z=*Origin\z
ObjectList()\IsLight=#False
ObjectList()\Primitive=AllocateMemory(4)
PokeF(ObjectList()\Primitive,radius)
EndProcedure
Procedure.b GetSphereStructure(source.l,*destination.Sphere)
*destination\radius=PeekF(source)
EndProcedure
Procedure.b SetSphereStructure(*source.Sphere,destination.l)
PokeF(destination,*source\radius)
EndProcedure
Procedure.b RemoveObject()
If ObjectList()\Primitive<>#Null
FreeMemory(ObjectList()\Primitive)
EndIf
DeleteElement(ObjectList())
EndProcedure
Procedure.l Shade(Type.b,*Intersection.xyz,*Normal.xyz,*Material.Material,*Ambient.Color)
*Old_Element=@ObjectList()
result.l
Color.Color
Light.xyz
Temp.Color
If Type=#Render_IntersectionTest
If t>0
result=#Red
EndIf
ElseIf Type=#Render_Soild
result=RGB(*Material\SoildColor\Red,*Material\SoildColor\Green,*Material\SoildColor\Blue)
ElseIf Type=#Render_Diffuse ;note Lights use material\soildcolor for there emmiting color
For Object=0 To CountList(ObjectList())
SelectElement(ObjectList(),Object)
If ObjectList()\IsLight=#True
VectorSubtract(ObjectList()\Origin,Intersection,Light)
VectorNormalize(Light)
If *Material\Diffuse > 0
angle.f=VectorDotProduct(*Normal,Light)
If angle>0
diff.f=angle**Material\Diffuse
ColorMuilply(*Material\SoildColor,ObjectList()\Material\SoildColor,Temp)
ColorScalarMuilply(Temp,diff,Temp)
ColorAdd(Color,Temp,Color)
EndIf
EndIf
EndIf
Next Object
ColorRangeCheck(Color)
If Color\Red=0 And Color\Green=0 And Color\Blue=0
result=-1
Else
result=RGB(Color\Red,Color\Green,Color\Blue)
EndIf
EndIf
ChangeCurrentElement(ObjectList(), *Old_Element)
EndProcedure
Procedure.f TestSphere(*Origin.xyz,*Direction.xyz,*Sphere.Object)
offset.xyz
VectorSubtract(*Origin, *Sphere\Origin, offset)
radius.f = PeekF(*Sphere\Primitive)
b.f = 2 * (*Direction\x * offset\x + *Direction\y * offset\y + *Direction\z * offset\z)
c.f = offset\x * offset\x + offset\y * offset\y + offset\z * offset\z - radius * radius
d.f = b * b - 4 * c
If d > 0 ;hit the sphere
t.f = (-b - Sqr(d)) * 0.5 ; Could return +ve or -ve number!
EndIf
ProcedureReturn t
EndProcedure
Procedure TraceRay(TraceFor.b,*Origin.xyz,*Direction.xyz,*Ambient.Color,depth.b)
*Old_Element=@ObjectList()
If depth<#MaxChildren
Select TraceFor
Case #TraceFor_Visables
Closesthandle=-1
ClosestT=-1
For Object=0 To CountList(ObjectList())
SelectElement(ObjectList(),Object)
Select ObjectList()\Type
Case #ObjectType_Sphere
t.f=TestSphere(*Origin,*Direction,@ObjectList())
If t>0
If t<ClosestT
Closesthandle=Object
ClosestT=t
EndIf
EndIf
;other cases will be added
EndSelect
Next Object
If ClosestT>=0
t=ClosestT
SelectElement(ObjectList(),Closesthandle)
Intersection.xyz
Normal.xyz
VectorScalarMuilply(*Direction,t,Intersection)
VectorAdd(*Origin,Intersection,Intersection)
If ObjectList()\Type=#ObjectType_Sphere ;normal Calulations are diffrent per object
VectorSubtract(Intersection ,ObjectList()\Origin ,Normal)
VectorScalarDivide(Normal,PeekF(ObjectList()\Primitive),Normal)
;other cases will be added
EndIf
Shade(#Render_IntersectionTest,Intersection.xyz,Normal.xyz,ObjectList()\Material,*Ambient)
EndIf
Case #TraceFor_Lights
; #ObjectType_PointLight
Case #TraceFor_Shadows
; #ObjectType_PointLight
EndSelect
EndIf
ChangeCurrentElement(ObjectList(), *Old_Element)
EndProcedure
Procedure RenderScene(*Scene.Scene,*ViewPort.Camera)
For y = -*Scene\HalfScreenHeight To *Scene\HalfScreenHeight - 1
For x = -*Scene\HalfScreenWidth To *Scene\HalfScreenWidth - 1
*ViewPort\Direction\x = x
*ViewPort\Direction\y = y
*ViewPort\Direction\z = *Scene\Perspective
Color=TraceRay(#TraceFor_Visables,*ViewPort\Origin,*ViewPort\Direction,*Scene\Ambient,0)
Plot(posx, posy, Color)
Next x
Next y
EndProcedure
Procedure TestLoop() ;tester
CallDebugger
Sphere1Mat.Material
Sphere1Center.xyz
Sphere1Radius.f
MainCamera.Camera
MainScene.Scene
Sphere1Center\x=0
Sphere1Center\y=0
Sphere1Center\z=0
Sphere1Mat\SoildColor\Red=0
Sphere1Mat\SoildColor\Green=0
Sphere1Mat\SoildColor\Blue=255
Sphere1Mat\Diffuse=1.0
Sphere1Mat\Reflect=0
Sphere1Mat\Refract=0
Sphere1Radius=100
AddSphereObject(Sphere1Mat,Sphere1Center,Sphere1Radius)
MainCamera\Origin\x=0
MainCamera\Origin\y=0
MainCamera\Origin\z=-256
MainCamera\ViewingAngle\x=0
MainCamera\ViewingAngle\y=0
MainCamera\ViewingAngle\z=0
MainScene\Ambient\Red=32
MainScene\Ambient\Green=32
MainScene\Ambient\Blue=32
MainScene\Perspective=256
MainScene\ScreenWidth=320
MainScene\ScreenHeight=240
MainScene\HalfScreenWidth=MainScene\ScreenWidth/2
MainScene\HalfScreenHeight=MainScene\ScreenHeight/2
InitSprite()
OpenWindow(0,0,0,MainScene\ScreenWidth,MainScene\ScreenHeight,#PB_Window_ScreenCentered,"PBRay - FPS: 0")
OpenWindowedScreen(WindowID(),0,0,MainScene\ScreenWidth,MainScene\ScreenHeight,0,0,0)
start=ElapsedMilliseconds()
Repeat
frame+1
ClearScreen(0, 0, 0)
StartDrawing(ScreenOutput())
RenderScene(MainScene,MainCamera)
StopDrawing()
FlipBuffers(1)
If ElapsedMilliseconds()-start>1000
start=ElapsedMilliseconds()
SetWindowTitle(0,"PBRay - FPS: "+Str(frame))
frame=0
EndIf
Until WindowEvent() = #PB_Event_CloseWindow
EndProcedure
TestLoop()