Dark BASIC Pro ( DBpro ) Bump Mapper Ported to PlayBASICI found this old optimization source code on my harddrive that does bump mapping in software. The only problem with it's written in another language, so I decided to port it PlayBASIC and see how it'd perform in PlayBASIC V1.65.
Runs fine
[pbcode]
; PROJECT : Bump Mapper Dbpro Port
; AUTHOR : Raven & Kev Picone
; CREATED : 28/05/2020
; EDITED : 30/05/2020
; ---------------------------------------------------------------------
openscreen 512, 512, 32,1
titlescreen "Bump Mapping (Software)"
Type Vector2
X As Float
Y As Float
EndType
Type TimeType
Old As Integer
New As Integer
Due As Integer
Accum As Integer
isValid As Integer ;Boolean
EndType
Type ScreenType
Height As Integer
Width As Integer
EndType
Type tBumpPixelOffsets
x1
y1
x2
y2
EndType
Dim Environment(255, 255) ;As Integer
Dim Bump(GetScreenWidth(), GetScreenHeight()) ;As Integer
` precalc bidirectional normals
Dim BumpNX(GetScreenWidth(), GetScreenHeight()) ;As Integer
Dim BumpNY(GetScreenWidth(), GetScreenHeight()) ;As Integer
Dim Surface(GetScreenWidth(), GetScreenHeight()) ;As Integer
dim Screen As ScreenType
Screen = New ScreenType
Screen.Width = GetScreenWidth()
Screen.Height = GetScreenHeight()
dim Light As Vector2
Light = New Vector2
dim Alpha As Integer
dim Time As TimeType
Time = new TimeType
GoSub __LoadSamples
Size=Screen.width*Screen.Height*4
createbank 1,Size
createbank 2,Size
createbank 3,(Size+1)*2
` Copy To Src Buffer
SrcBufferAddress=getBankPtr(2)
SrcBufferModulo=Screen.width*4
BumpBufferAddress=GetBankPtr(3)
For Y = 0 To GetScreenHeight()-1
RowAddress=SrcBufferAddress+(Y*SrcBufferModulo)
BumpRowAddress=BumpBufferAddress+(Y*(SrcBufferModulo*2))
ScrnWidth=GetScreenWidth()-1
For X = 0 To ScrnWidth
pokeint RowAddress,Surface(X, Y)
inc RowAddress,4
pokeint BumpRowAddress,BumpNX(X, Y)
inc BumpRowAddress,4
pokeint BumpRowAddress,BumpNY(X, Y)
inc BumpRowAddress,4
Next X
Next Y
// ---------- MAIN LOOP ------------------------------
Repeat
Time.isValid = TimeUpdate( 1000 / 30)
Light.X = MouseX()
Light.Y = MouseY()
MapTime=timer()
If 1 ;Time.isValid
Clip_DestX1=LIght.X-128
Clip_DestY1=LIght.Y-128
Clip_DestX2=LIght.X+128
Clip_DestY2=LIght.Y+128
ClippedPixels=1
if Clip_destX1<1
ClippedPixels=1-Clip_destX1
Clip_DestX1=1
endif
Clip_SrcX=ClippedPixels
ClippedPixels=1
if Clip_destY1<1
ClippedPixels=1-Clip_destY1
Clip_destY1=1
endif
Clip_SrcY=ClippedPixels
If Clip_DestX2=>Screen.Width then Clip_DestX2=Screen.Width - 1
If Clip_DestY2=>Screen.Height then Clip_DestY2=Screen.Width - 1
LightX=Light.x
LightY=Light.y
DestBufferAddress=getBankPtr(1)
DestBufferModulo=Screen.width*4
SrcBufferAddress=getbankPtr(2)
SrcBufferModulo=Screen.width*4
BumpBufferAddress=GetBankptr(3)
BumpBufferModulo=(Screen.width*4)*2
For Y=Clip_destY1 To Clip_destY2
DestRowAddress =DestBufferAddress +(y*DestBufferModulo)+(Clip_DestX1*4)
SrcRowAddress =SrcBufferAddress +(y*SrcBufferModulo)+(Clip_DestX1*4)
BumpRowAddress =BumpBufferAddress +(y*BumpBufferModulo)+(Clip_DestX1*8)
Dim Row as tBumpPixelOffsets Pointer
Row = BumpRowAddress
For X=Clip_DestX1 To Clip_DestX2 step 2
SrcX= Row.X1+LightX
SrcY= Row.Y1+LightY
If (SrcX & 0xffffff00) Then SrcX= 0
If (SrcY & 0xffffff00) Then SrcY= 0
Alpha = Environment(SrcX,SrcY)
If Alpha
Pixel=Peekint(SrcRowAddress)
; RgbAlphaMult
pokeint DestRowAddress,rgbAlphaMult(Pixel,Alpha)
/*
r=(alpha * (Pixel >> 16)) >> 7
g=(alpha * ((Pixel >> 8) & 0xff))>> 7
b=(alpha * (pixel & 0xff))>> 7
if r>255 then r=255
if g>255 then g=255
if b>255 then b=255
pokeint DestRowAddress,rgb(r,g,b)
*/
EndIf
inc DestRowAddress,4
inc SrcRowAddress,4
` Unroll one level
SrcX= Row.X2+LightX
SrcY= Row.Y2+LightY
If (SrcX & 0xffffff00) Then SrcX= 0
If (SrcY & 0xffffff00) Then SrcY= 0
Alpha = Environment(SrcX,SrcY)
If Alpha
Pixel=Peekint(SrcRowAddress)
pokeint DestRowAddress,rgbAlphaMult(Pixel,Alpha)
/*
r=(alpha * (Pixel >> 16))>> 7
g=(alpha * ((Pixel >> 8) & 0xff))>> 7
b=(alpha * (pixel & 0xff))>> 7
if r>255 then r=255
if g>255 then g=255
if b>255 then b=255
pokeint DestRowAddress,rgb(r,g,b)
*/
EndIf
Row=int(Row)+SizeOF(tBumpPixelOffsets)
inc DestRowAddress,4
inc SrcRowAddress,4
Next X
Next Y
EndIf
` Lock Pixels
; Lock BackBuffer
LockBuffer
SrcBufferAddress=getBankptr(1)
NullPixel =Point(0,0)
ScreenPointer = GetImagePtr(0)
ScreenPitch = GetImagePitch(0)
For Y = 0 To Screen.Height-1
DestRowAddress =ScreenPointer + (y * ScreenPitch)
SrcRowAddress =SrcBufferAddress +((Screen.Width*4)*y)
copymemory SrcRowAddress,DestRowAddress, Screen.Width*4
Next Y
fillmemory SrcBufferAddress,Screen.Width*Screen.Height , 0 , 4
unlockbuffer
MapTime=timer()-MapTime
Text 10, 10, Str$(FPS())
Text 10, 24, Str$(MapTime)
Sync
Until EscKey()
`/ GC /
// UnDim Environment()
// UnDim Bump()
// UnDim Surface()
End
Function DotProduct2(Vector As Vector2)
;Local Length As Float
Length# = Sqrt(Vector.X * Vector.X + Vector.Y * Vector.Y)
EndFunction Length#
Function TimeUpdate(Check As Integer)
Time.New = Timer()
Time.Due = Time.New - Time.Old
Time.Old = Time.New
Inc Time.Accum, Time.Due
If Time.Accum > Check
Time.Accum = Time.Due
ExitFunction True
EndIf
EndFunction False
function LoadImageToArray(File$,Image(),PixelMask)
LoadFXImage File$, 1
rendertoimage 1
LockBuffer
nullpixel = point(0,0)
iw = GetSurfaceWidth()
ih = GetSurfaceHeight()
iw = minval(iw,GetScreenWidth())
ih = minval(ih,GetScreenHeight())
#print iw
#print ih
For Y = 0 To ih-1
For X = 0 To iw-1
Image(X, Y) = Point(X, Y) & PixelMask ;0xffffff
Next X
Next Y
UnlockBuffer
rendertoscreen
DeleteImage 1
EndFunction
// ------------------------------------------------------------------
__LoadSamples:
// ------------------------------------------------------------------
LoadImageToArray("assets/default_color.png",Surface(), $00ffffff)
LoadImageToArray("assets/default_bump.png" ,Bump() , $000000ff)
Sh=GetScreenHeight()-1
Sw=GetScreenWidth()-1
` pre calc cross directional normals
For Y = 1 To sh-1
For X = 1 To sw-1
BumpNX(X, Y) = Bump(X + 1, Y) - Bump(X - 1, Y)-x+ 128
BumpNY(X, Y) = (Bump(X, Y + 1) - Bump(X, Y - 1))-y+128
Next X
Next Y
unDim Bump()
For Y = 0 To 255
For X = 0 To 255
Light.X = (X - 128.0) / 128.0
Light.Y = (Y - 128.0) / 128.0
local Z# = 1.0 - DotProduct2(Light)
If Z# < 0 Then Z# = 0
local Level=Int(Z# * 256)
Level*=2
if Level<0 then Level=0
if Level>255 then level=255
Environment(X, Y) = rgb(Level,Level,Level)
Next X
Next Y
Return
[/pbcode]
Have fun !
hey kev, this looks pretty good.
do you have the images default_color.png and default_bump.png so i can run the code?
thanks stevmjon
PlayBASIC LIVE - Porting Dbpro Bump Mapper To PlayBASIC V1 65 - (31st May 2020 ) Today we'll look at converting some source code from DBpro to PlayBASIC V1.65. I originally optimized the DBpro back in 2013 for another forum member. Ran into the code again recently and decided it might make a nice little PlayBASIC live video. Then during recording the screen captures with OBS, I kept running into problem after problem, but finally got it recorded. There's a few continuity issues, but it was created over several days..
Credits:
Video By:
Kevin Picone
http://PlayBASIC.com
https://Underwaredesign.com
https://www.underwaredesign.com/forums/ (Forums)
Original Dbpro Source Code:
Raven
Optimized Code Kevin Picone
Pexels Artwork:
Coffee Animation by Kelly Lacy
Clouds Time lapse by Pexels
Music:
Spirit of Fire by Jesse Gallagher
PlayBASIC LIVE PLAYLIST
https://www.youtube.com/playlist?list=PL_dvm0gvzzIVGlAhx34N6z2ce0ffMMOZ8
PlayBASIC BLOG PLAYLIST
https://www.youtube.com/playlist?list=PL_dvm0gvzzIU0Hnr6veV5UvwkSapHCo1J
PlayBASIC on FACEBOOK
http://www.facebook.com/pages/PlayBasic/127905400584274 (Facebook Page)
PlayBASIC on TWITTER
https://twitter.com/PlayBasic