Is there a way to speed up this crude code and difficulty of tons of pixels???
It would be real usefully to know in demo effects such as water and fire ect...
Thanks
[pbcode]
X_Res = 320
Y_Res = 200
Dim Buffer_1#(X_Res,Y_Res)
Dim Buffer_2#(X_Res,Y_Res)
Buffer_1#(X_Res / 2,Y_Res / 2) = 100
Do
Cls
For Y = 1 To Y_Res - 1
For X = 1 To X_Res - 1
Buffer_2#(X,Y) = (Buffer_1#(X - 1,Y) + Buffer_1#(X + 1,Y) + Buffer_1#(X,Y - 1) + Buffer_1#(X,Y + 1)) / 2 - Buffer_2#(X,Y)
Buffer_2#(X,Y) = Buffer_2#(X,Y) * 0.99
Ink RgbFade(Rgb(255,255,255),Buffer_2#(X,Y))
Dot X,Y
Next X
Next Y
Sync
SwapArray Buffer_2#(),Buffer_1#()
Loop
[/pbcode]
lockbuffer and unlockbuffer
The most obvious speeds ups are, locking the buffers, using a more appropriate 'dot' function and removing the redundancy inside the inner loop.
Even at 320*200 there's six 2d array accesses inside the inner loop, all of which have multiples inside them as well as clipping (ie 'play nice' behaviors) inside the debug VM / runtimes. Doing this approximately 64000 times introduces a lot of overhead.
Some others hint that might apply, could be,
* 1D arrays has 30->40% less over head than a 2D array.
* direct access of the array data (Peek/Poke)
* loop unrolling
* variable caching in the diamond filter.
[pbcode]
X_Res = 320
Y_Res = 200
Dim Buffer_1#(X_Res,Y_Res)
Dim Buffer_2#(X_Res,Y_Res)
Buffer_1#(X_Res / 2,Y_Res / 2) = 100
Do
Cls $112233
lockbuffer
ThisRGB=Point(0,0)
For Y = 1 To Y_Res - 1
Yminus1 =Y-1
Yplus1 =Y+1
For X = 1 To X_Res - 1
RGB2# =Buffer_2#(X,Y)
RGB2# = (Buffer_1#(X - 1,Y) + Buffer_1#(X + 1,Y) + Buffer_1#(X,Yminus1) + Buffer_1#(X,Yplus1)) / 2 - RGB2#
Buffer_2#(X,Y) = RGB2# * 0.99
FastDot X,Y,RgbFade(Rgb(255,255,255),RGB2#)
Next X
Next Y
unlockbuffer
if NextDropTime<Timer()
for lp=0 to 10
x=rndrange(1,X_Res-1)
y=rndrange(1,Y_Res-1)
Buffer_1#(X,Y) = 100
next
NextDropTime=Timer()+rndrange(1,10)*10
endif
Sync
SwapArray Buffer_2#(),Buffer_1#()
Loop
[/pbcode]
PB2DLL - Water Demo
Attached you'll find a machine code version of the above demo tweaked up and run through PlayBASIC2DLL .. This version is floating point, it's likely to be even faster converted to pure integer..
woo! much better.
Can you do a version with the pd2dll and show us the difference kev?
you mean like the one attached the previous post ??
Wow! Holy Crap, These speedups are so much better.
Kevin I'm not sure how to run the dll what do I need to do?
Do I need an updated playbasic?
I was gonna ask if anyone knew how to increase the resolution as well but it looks like you did in the dll.
Just do know how to make it work?
I always had the problem from time to time about optimisations so this is really kewl.
Thank for the help people.
as for the texture beneath this puddle of water how about if someone can incorporate this.
X_Offset# = Buffer_2#(X - 1,Y) - Buffer_2#(X + 1,Y)
Y_Offset# = Buffer_2#(X,Y - 1) - Buffer_2#(X,Y + 1)
Shading# = X_Offset#
T# = Texture#(X + X_Offset#,Y + Y_Offset#)
P# = T# + Shading#
Now, Plot every pixel at colour P#
***********************************
I'm working through a old school tutorial that always caught my eye but
had trouble make this all run fast enough.
Some as I remember we a super nice face shot of a women with the water on top also
Some one took it further with tangent function doing ray traced water with reflections and refractions.
But I'm still happy for the help so far So
Thanks!
Quote from: kevin on May 25, 2014, 06:54:36 AM
you mean like the one attached the previous post ??
hmm i suppose my page hadn't refreshed...
impressive stuff!
To my knowledge I also seem to remember how using a pre-calculated colour lookup table/charts
of the pictures pixels elements rangeing from pixels orginal color to darker of lighter could also
possible be a faster optimization.
Back in the days of magic mode 13h or 320x200 was great for something like this so I wondering how
can we possible bring it to lower resolutions now adays with things like double/dual screens interlaced screen modes???
QuoteWow! Holy Crap, These speedups are so much better.
Kevin I'm not sure how to run the dll what do I need to do?
Do I need an updated playbasic?
I was gonna ask if anyone knew how to increase the resolution as well but it looks like you did in the dll.
Just do know how to make it work?
Load and run it V1.64P (http://www.underwaredesign.com/?l=PlayBASIC-V164P-WIP-GALLERY)
Quote
To my knowledge I also seem to remember how using a pre-calculated colour lookup table/charts
of the pictures pixels elements rangeing from pixels orginal color to darker of lighter could also
possible be a faster optimization.
Most effects start out with the naive solution, which is a proof of concept version that's generally accurate, but dead slow. Then to make things faster we're sacrificing something in the method, be it accuracy or some flexibility that can be precomputed out or isn't necessary for the usage.
Kevin, Wow! That speeds up everything!
But Mine seems to crash after running for awhile would you know how to fix this?
And also wheres the tool play2dll to turn basic progs into dlls?
Is it easy to run and create the .dlls?
Any help would be great thanks.
Here's the second speedup with texture added.
Kevin it would nice if you could add this to your .dll
Still waiting for replies.
Quote
And also wheres the tool play2dll to turn basic progs into dlls?
Is it easy to run and create the .dlls?
see-> PB2DLL blogs (http://www.underwaredesign.com/?l=PlayBASIC-To-DLL-Development-Blog)..
[pbcode]
Dim Texture#(X_Res,Y_Res)
LoadImage "women.jpg",1
DrawImage 1,0,0,0
X_Res = 320
Y_Res = 200
Dim Buffer_1#(X_Res,Y_Res)
Dim Buffer_2#(X_Res,Y_Res)
Buffer_1#(X_Res / 2,Y_Res / 2) = 50
Buffer_1#(X_Res / 2 - 1,Y_Res / 2) = 50
Buffer_1#(X_Res / 2 + 1,Y_Res / 2) = 50
Buffer_1#(X_Res / 2,Y_Res / 2 - 1) = 50
Buffer_1#(X_Res / 2,Y_Res / 2 + 1) = 50
Dim Texture#(X_Res,Y_Res)
For Y = 0 To Y_Res
For X = 0 To X_Res
Texture#(X,Y) = Point(X,Y)
Next X
Next Y
[/pbcode]
This is an extremely poor solution to loading the image into an array. Pretty much everything you need to know is in the previous comments above.
Why is the texture array floating point ? when colours are integer.
[pbcode]
FastDot X,Y,RgbFade(Rgb(RgbR(Texture#(X,Y)),RgbG(Texture#(X,Y)),RgbB(Texture#(X,Y))),Buffer_2#(X,Y) + 50)
[/pbcode]
Here you're reading a 2d floating point array 3 times, when all that is needed is once.
[pbcode]
Texel =Texture#(X,Y)
FastDot X,Y,RgbFade(Rgb(RgbR(Texel),RgbG(Texel),RgbB(Texel)),Buffer_2#(X,Y) + 50)
[/pbcode]
Next, why splitting the colour apart to only reconstruct it to get the same result.
ThisRGB = $223355
R=RgbR(ThisRGB)
G=RgbG(ThisRGB)
B=RgbB(ThisRGB)
NewRGB=RGB(R,G,B)
ThisRGB and
NewRGB are the same value.
So this line can be further simplified to,
[pbcode]
Texel =Texture#(X,Y)
FastDot X,Y,RgbFade(Texel,Buffer_2#(X,Y) + 50)
[/pbcode]
The array access
Buffer_2#(X,Y) also isn't needed. So this line can be further simplified to,
[pbcode]
Texel =Texture#(X,Y)
FastDot X,Y,RgbFade(Texel,RGB2# + 50)
[/pbcode]