News:

PlayBASIC2DLL V0.99 Revision I Commercial Edition released! - Convert PlayBASIC programs to super fast Machine Code. 

Main Menu

PlayBASIC Vector Blast Processing (2023-06-23)

Started by kevin, June 23, 2023, 07:56:37 AM

Previous topic - Next topic

kevin

 PlayBASIC Vector Blast Processing (2023-06-23)


  This example does batches of vector operations.   In this demo i'm using those batches to move 500000 particles in 2D.  


 



  Video Transcript:


welcome back PlayBASIC coders
I've just titled this product blast
processing or blast Vector processing
it's basically
A variation of what I was hinting at
with shapes it's just doing this job in
raw memory though so in this case here
we're we're creating a simulation of
what
the standard particle demo pretty much
so we've got a bunch of particles being
emitted we'll run the demo
the other version of this which does use
shapes this one does not this is just
dot plotting
so we've got our half million points
at about 10 frames per second in 165.
on my laptop here which is
quite good considering that we're doing
manual
processing of every dot right
and the whole point of
the best way to make programs in PB
quicker
is to eliminate situations where the
user does a lot of Hands-On processing
so which one's trying to get with this
idea about doing
additional vectors
now if we hit enter
we can swap modes
now
what's actually happening is the
the part that does the
addition of the speed Vector to the
current particles position
is shifted across and done in the
background rather than the user doing
that operation manually
so we keep a buffer of all the particles
in each ring what will actually go is
from this spawn point where I'm missing
in this case 5000 particles out from
that location
or randomly from that point so we're
keeping the origin
we head down here for the spawning
function
keeping a list of these particles
so this becomes a group controller
for each ring that's created we have a
particle count
a bank and a spade Bank this is just
buffers of memory just storing vectors
in
floating Point two-dimensional vectors

I've got a different thing there as well
each particle each group has a color for
the whole group they're all the same
color
and we keep track of how long they've
been updated and what they're expected
lifetime is going to be in this case
they're all given a lifetime of 100
frames
so we're using the lifetime to compute
the what shade of white they're going to
be
just down here somewhere
yeah there is there
sorry this is processing the life the
lifetime just adding
every time we update the positions we
add one to the lifetime account
we and we just check whether it's time
to delete this batch or not
that's returned back to the main Loop
and the deletions that are in the from
the main Loop up here
so we're stepping through all the park
or groups
update again
if it's this group has been uh
in the list for more than 100 frames
uh
we won't draw it we just fall through
here to delete and we'll rip it out of
the out of the list the delete just gets
rid of the buffers that we've allocated
up for it we could do this one
one line but we I just have it in this
case
uh if it if it's um
the particles need to be updated we just
keep drawing them
uh the different aspect of theirs is
that we're storing using a bank
store each of the individual particles
now we could use an array here or if
people would feel more comfortable with
that
the process itself as we
there is there
so when we know how many particles we
need
which is given to the spawn particle up
front I think the default at the
moment's like five thousand so we work
out how many bytes
a two-dimensional Vector of two flights
is going to going to be we multiply that
by the number of parks we need
and we allocate a block of memory in a
bank
and remember this this Bank index for
later
we do it that's for our positions or at
current positions this is for the speeds
of each coordinates so
each once the banks are created they're
both empty they were zeroed out so speed
and position to both zero zero so they
would be up in the top left hand corner
if we were to leave them like that so
grab
when we Define position back down
we gotta pointed to this positions Bank
which is the actual address in memory
where this thing actually is
assigned to a pointer now from here on
that's like a type array
the same thing for speeds
so we can refer to
position.x and that will be
in right in Array terms that would be
index zero within if that was in a rail
the difference is you're going to
manually move to the next one here so
when we step through and initialize the
the vertices we're giving the the origin
point
that the this entire batch of particles
was given we could just actually copy
that into memory actually
and not do it manually like this but you
know
something else to think about
for each particle we're just giving a
random
polar coordinate and a ram speed and
give setting up the
the X and Y components of our Vector
speed vector
then we're stepping to the next one
just manually stepping to the speeds and
position across
and we're just looking through every
vertices and these buffers we created
so the drawing is much the same
all the updates the same we just
Wolverine when we're in manual mode we
just go okay how many vertices we got
give me a pointer to the position Bank
of the speed bank or you just run
through the vertices
one by one and add speeds onto positions
and then move the two pointers forward
until we reach the end of our four next
slope uh drawing's the same we just
grabbed our position Vector pointer we
do a bit of work here to work out
what the color is going to be
um
scales between naught and one we just
multiply it by 255 to give us a an
integer range for our RGB level
here we just this is a clip range 0 to
255 so if it's below zero it'll be
equipped to zero if it's above 255 it'll
be clipped at 255.
and because we're counting from zero to
the number of frames and we actually
want the inverse of that we want to
start out
fully illuminated
or its initial color and then slightly
die away to Black yeah so this malt
Alpha malt here is doing
we're taking this
this grayscale level here and multiplier
buying our current color and that will
give us that will take our original
color and give us
a scaled down
version of that color towards black
and just draw the batch of particles so
that's all my manual processing stuff
that's not the interesting part of the
demo
it's just extra bit of
garbage here
um
over here with a simple
it's about a day allow
got back to two type Vector three type
a very simple job list structure so we
create the idea is that you would create
a list of these jobs that was that would
be in one buffer
and each job has a source and
destination
buffer for the back for the data you
you're using
you can actually give it
just standard floats
or two vectors of three vectors or 40
vectors
um you're just packing these things so
it's just working either as an
individual float a pair a triplet or
four of them that's all you're really
doing
foreign
here I'm just you know have a default
here about how many of these job events
do you want to create in this case I
would just need one
we're adding the speeds to the positions
that's what we're doing
a bank
the bank is sized appropriately for the
number of events we want to create and
the
the size of this structure here
this data here because we're going to
pass a raw pointer to seize the seaside
to do that if it doesn't match it's
going to crash
so we've created a little blasted a
little blast processing
data structure and then we have to fill
it in talk about this very simple
affiliate function here where we've got
what bank
is the job list what's the index of the
job
uh what's the source buffer of the
vertices
or the
your playing Point data what's the
destination that we're writing to most
likely and how many do we do what do you
want to update in this particular case
I've pre-loaded these to
to working uh
in 2D vectors and to default to the
addition there's four modes you can do a
subtraction multiplication division
um
this is the bare bones of the test right
so our actual update code
well in in this execute mode the update
function
all of this part here
is not actually necessary
we're shifting all of that work often to
the runtime
we're updating the live counting here
of course the draw particles are still
just drawn as just dots
all right
back to here
I think the original version of this was
called particle sprinkler that uses
shapes
and the reason it uses shapes is it does
the animation and the plotting with the
built-in functions so we we create this
randomized shape of vertices and then we
scale it each frame
and draw it like that
now let's switch to the blast processing
mode
after million verses
so the bottleneck in this particular
demo is actually not the processing of
the vertices it's just the rendering
we're just calling dot a bunch of times
you know
ideally you'd be better to have you know
a Dot Plot they could do multiple dot
plots
um
because the Dot Plot something clipping
Etc
and yes the buff is a lock so
yeah uh
of course if I was like
yeah if you're running at 10 frames per
second I mean the frame's taking 100
milliseconds to update so that's a lot
of time
but we're about double
they're about 50 millisecond refresh
so I wonder how what our frame rate
would be if we didn't render dots
if we just didn't draw anything
then we would get a much better metric
on
uh
what the processing cost of the demo
actually is we'll try it out
so we're in normal mode here
and half million points and we're
running at 17 frames per second which
means that
a lot of the work is done is being done
or performance is being lost because
we're doing
this manual processing of vertices we'll
switch modes
or up to 130 frames per second
I think that president for it
and this is not optimal at all this is
just something I threw together and went
I think that's a better way of doing it
um the question is is that
I do I do think it's probably better to
have a system where the user isn't aware
of the data structures underneath
and it just
gives you it gives you a simple
interface and you can just kind of
manually do this you know call some
functions do some things to the the
device it just it lies the direct the
way it wants to internally
um
anyway
nonetheless if you want to mess around
with it I'll put this up on the boards
course and you can mess around with all
you like
I don't expect it to be documented much
or don't expect it to be actually uh
in any way shape or form be really
thought through it's just
a manifestation of the idea
it's interesting how long dark line
takes in it
um
so even that you know if you
were saying before about the drawing
stuff
the classic method
is you would do something like this is
you would go
we'll have two draw loops and
so we might go I won't count
and we'll divide that by four
minus one so
and then here we'll go Loop
equals
count
times
so Loop Vehicles Loop times four
start from here to do the end of the
first uh
sorry I'm just talking to myself yeah
what we're going to do is we're going to
unroll this
four times
and the point we're trying to do here is
we're trying to remove the looping
overhead as much as possible without
loading out the code to an enormous
amount that's reasonable particularly if
we don't have to update again
and we don't really
have some difference we make well
oh I think we made a mistake with that
if we move off the end of the frame
buffer we will get that it will break
oh my Lord dough as I go hunk right you
see you don't have hug
there's this
and you have leftovers
so it's a count it's the modulus of this
the terminology of sort of uh quite used
to
so We're looping through the Hunts right
and then at the end of this we do our
leftovers we're going to Loop through
uh
height times four
we don't need leftovers do we
so if we have one hunk yeah
but from here to count yeah it's fine
ah a little crash okay
so yeah do we crush it do we kill it
and we're not saving ourselves much time
for a little bit with maybe one a frame
back considering we're capturing the
science as well so if we go to
um
a little blast mode
not winning much time back there
I mean you'd probably have to go
I mean you could go to fast dot but you
would need to clip of points
so you would need a
um
something inside
the blast processing routine to give you
an idea whether you should draw the dot
or not
um
that would be the best way of doing it
because you know doing comparisons on
five thousand or sorry half a million
points
um it's going to take a bit of time
just saying
the one is a software development
but yeah if you ever wanted about
unrolling things that's pretty pretty
much what I'm talking about there
if you switch to fast start
you would get crashes because the fast
dot does not check if the dot is outside
the frame buffer
um
we'll just do a quick test on on
I didn't check this beforehand so let me
just see if we can we clip it
manually
and still get the thing to run a
reasonable rise faster yeah
that won't like that it was no that will
not like those
uh faster doesn't want you to give it
flying point
like even that actually with the dot
like we knew back some performance
all right so we've read the x coordinate
if we go
growling
just do it
so rather than
800
we are on the buffer we have to step
forward to the next further C regardless
so we don't want to do
uh anything
untoward with that so we have to do that
test out why 600
what do we got
look reasonable
we want to live through all the vertices
so we're not going to do a batch recipe
oh quick save run it
fantastic we're running great so
X Y exit
uh exciting that grow in there yeah
I want to lock the buffer my seating the
buffer or north
I don't remember what optimization
caused that
it's always been a source of
much irritation yeah
yeah
I we assume this would be slower
because we're doing it
half a million verse eclipse
so for vertex are on screen
they're falling through and getting
clipped
um
you'd have you know
my goal is not to make this all about
just dark particles it's about doing
batches of these operations
that you might have for all kinds of
usages
not just doing things like this
anyway
um that'll do for for now uh
I put the example in the form it should
work with any version of PVA actually
so you're welcome to try it out
mess around with it so if we can get to
do I don't know have fun bye
just a chance running in
uh all the versions of PBA
here it is running in 164.
P4 so I've got our half million versus
the rates down to five frames per second
so we're doubling our rate again there's
so much overhead in the old run time
we're not really breaking through that
sort of 20 frames per second barrier
I might try the uh the old learning
condition see if it works on that
there's a little learning Edition
and yeah it works in this out of the
Australia the Box
see how low the rate goes
four frames per second
four frames per second
this is in the 10 year old run time I
don't know what year this was released
now
so enable me
yeah there's a huge update in
performance between
this is one six L and the P revisions
are pretty much Rewritten internally
so even with uh
our dll doing the workload of all of the
vector additions it's too much for this
right clocking seven frames per second
there you go




PlayBASIC Code: [Select]
; PROJECT : Blast-Vector-Processing
; AUTHOR : Kev Picone - https://playbasic.com
; CREATED : 22/06/2023
; EDITED : 23/06/2023
; ---------------------------------------------------------------------

global TEST_MODE=0


Type tParticle
Count
Positions_Bank
Speed_Bank

Blaster
Colour
Life_Count
Life_Time
EndType

Dim Particles as tParticle list


ParticleCount = 5000

do
Cls

// emit another bunch of particles
Angle#=wrapangle(Angle#,2)
x#=(GetSCreenWidth()/2) +cos(Angle#)*200
y#=(GetSCreenHeight()/2) +sin(Angle#)*200
SpawnParticles(ParticleCount, x#,y#)

lockbuffer
ThisRGB = point(0,0)
count=0
for each particles()
if UpdateParticles(Particles)=false
DrawParticles(Particles)
else
DeleteParticles(Particle)
Particles = null
endif
count++
next
unlockbuffer

text 10,10,"Particle Count:"+str$(Count*ParticleCount)
text 10,30,"Mode:"+str$(TEST_MODE)+" Fps:"+str$(Fps())


if enterkey()<>0
TEST_MODE=1-TEST_MODE
flushkeys
endif

Sync
loop spacekey()




function SpawnParticles(Count, x#,y#)

// Size of buffer
Particles = new tParticle

Particles.Count = Count
Particles.Life_Time = 100
Particles.Colour = -1


BufferSize = sizeof(Vector2) * Count
Particles.Positions_Bank = newbank( BufferSize )
Particles.Speed_Bank = newbank( BufferSize )

dim Position as Vector2 pointer
Position=getbankPtr(Particles.Positions_Bank)

dim Speed as Vector2 pointer
Speed=getbankPtr(Particles.Speed_Bank)


// New Blaster
BlasterBank=NewBlast(1)
SetBlasterPointers(BlasterBank,0,int(Speed),int(POsition),Count )
Particles.Blaster = BlasterBank


OriginX#=x#
OriginY#=y#

// init the Speeds
for lp =0 to Count-1

Position.X#=OriginX#
Position.Y#=OriginY#

Angle#=rnd#(360)
Speed#=rndrange#(1,10)

Speed.X = cos(angle#)*SPeed#
Speed.Y = sin(angle#)*SPeed#

Speed = int(Speed) + sizeof(Vector2)
Position = int(Position) + sizeof(Vector2)
next

EndFunction



Function UpdateParticles(Me as tParticle)

if int(me)

if TEST_MODE=0

Count=Me.count

dim POsition as Vector2 pointer
Position=getbankPtr(Me.Positions_Bank)

dim Speed as Vector2 pointer
Speed=getbankPtr(Me.Speed_Bank)


// Move the particles
for lp =0 to Count-1
Position.X+=Speed.X
Position.Y+=Speed.Y
Speed = int(Speed) + sizeof(Vector2)
Position = int(position) + sizeof(Vector2)
next

endif

if TEST_MODE=1
ExecuteBlaster(Me.Blaster,1)
endif

//
Me.Life_Count++
Status =Me.LIfe_Count>=Me.Life_Time

endif
EndFunction Status
Login required to view complete source code



Download

      Code attached to post bellow.    Press ENTER to toggle between manual vector processing and blast vector processing.  

kevin

#1
  PlayBASIC Vector Blast Processing V002 - (2023-08-06)


 



 
welcome back to play music artists let's
check out blast processing
so it does batches of
dirty
we actually can do addition subtraction
multiplication
between vectors and you can do it
with a constant as well uh you can
normalize the vectors into a few other
things there too you can set them Etc so
let's just have a quick look through
let's put this demo is actually doing
is each frame we create a batch of 5000
particles they're all given the same
color
and each each particle has a position
and a speed and the gravity value as
well and the set or the same position at
least anyway and then a gravity Supply
Edge frame
those in a second
so this is just the Central Loop
grabbing the center of the screen for
spawning a set of particles every update
we
every frame in other words
so to process the the list of particles
because we've got so each
our particle list has these batches of
5000 particles each so we
we do an update
which uh in this mode in there's two
modes in the demo that's got the the
manual mode which is we're going through
uh adding the speeds on to each particle
with PB directly
or we're calling the the pre-built blast
processing run function which is made
when they're when they're spawned so
when we spawn a batch we add a new
particles that particles to the to our
list it's a batch of five thousands one
it's one item to the list but has these
containers of these five thousand um
vertices
so stuff story I'll count
we have uh each set will last 100 frames
so after 100 frames they'll be deleted
and across 100 frames then the color is
fading down to Black
this guy so just giving it a random RGB
so all the particles in this set are
that color
uh then we allocate uh our bank of
vectors so we've got the number of uh
number of
individual vectors we want and the type
we want as well as the ah this is
actually a type name
up in here
so I've wanted one of them to be Vector
3D I would use Vector three today
back to four Etc
let me go back to here
so really it's just allocating a a bank
but this is just a more convenient or
comfortable way of doing it we don't
have to worry about the size the number
of bytes we can just call a function
that does that for us but we end up with
a bank anyway just a block a memory
here we're growing a pointer to this
Bank the first buy unit in other words
that would be Vector zero
if that was a right
we've got a pointer to the positions
appointed to the speeds
um setting up our gravity value
getting it pointer to to here
now we're creating our a little script
for our little blast processing thing
so we call BP create and we
we're going to be working in 2D vectors
so we we tell it what kind of vectors
we're going to be using though we don't
need to set that for each operation
after that we can just set it once and
we're done
and we're adding a job
and this does a vector addition between
the speed
the current position and then outputs
the result in position so it's
effectively doing
think like this we're going to position
equals position plus speed
but for every individual particle in
that block
so we're adding all the speeds to the
positions to move all of the particles
and then we're doing we're applying our
gravity this is so we're doing it we're
adding a value which is going to be just
an individual two-dimensional vector
set up here
so kind of simulating gravity also
might get a bit larger so I can see the
impact so the particles of all kind of
Arc
be on a rather than having a a linear
trajectory they'll be they'll sort of
Arc down as if they're being pulled down
by gravity
uh this one here we do the same thing we
go
give me a point to our Vector a buffer
of vectors
give me a point to this individual
gravity
and this this is just going to add the
same Vector to all of these speeds and
the output is going to be into speed
here
since we've got a source and a
destination we can actually operate on
the same structure and output the same
position or we could have do an
operation between something and put it
output it to a different buffer and then
do something else to that buffer
and that's how two jobs at this
batch of particles have applied to them
next we initialize the parcel starring
positions which is this which is stored
in these positions over here because
because by default they'll all be
that memory will be all be zeros so
every particle will have a position of
just zero zero which would be the top
left hand corner
so what I'm doing here is I'm
initializing a 2d Vector called position
creating another blast processing
function
having a job to do a set which is gonna
grab this
vector and store it in the in every
position output
so they all have been having this this
position stored in them for their
starting position so we're going to
start at the same coordinate
then I'm calling the run to do this job
now and then delete this
this little job here so we don't need
this to be done after this process
but to the speeds I've
we haven't got there's no way for the
library to do this at the moment
so I'm running through it manually and
doing the 5000 speeds for each speed
yeah so we just go hey give me a random
Direction a polar coordinate give me a
random speed
uh let's give cause and sign for our for
our vector and then once we have those
things
so
because inside of giving us the the
amount of movement on along the x-axis
so the amount of movement along the
y-axis
so that does there and we're stepping to
the next one
and because we're stabbing a 2d Vector
so we've got to make sure we move
the right correct number of bytes
and that's all we need to do
that's our initialization so when we do
when we call update the drawer a bunch
of these particles up here
uh this is the that's the manual mode
but pivot run is just all with all we
call like so so when we initialize each
batch of particles we saved the Blaster
index which is just a little
The Blasters are stored as these
structures and inside the structures got
these little there's little job lists
that we pass off to the dll to do to do
the actual processing work itself
so the updating in here is really just
very simple it's just
was making sure with password
maintenance exists
and when we're in Blast mode we just
call BP run and then
I'm adding on to the live counter
because after 100 frames each batch of
particles gets deleted and we use that
at life and current Cows as a way of
shading the particles when they're drawn
which is done down here
so when we draw a batch
we'll grab our position which is in the
our pointer to our positions because we
need to run through and read those
positions out of memory
and we work out what kind of color it's
going to be based on how long these
particles have been uh been updating for
if they're just created them they should
be at the brightest intensity
if they're almost dead they'll almost be
faded out to Black
so update Loop is we're just running
through the batch of 5000. getting out
grabbing each x-coordinate checking if
it's inside the frame if it's not we
just step to the next one
and loop again
so if the x is legal
if the wire is legal we just call fast
Dot and here I've actually got a bit of
extra logic
just checking if if
we have a situation where all of the
particles have left the screen but their
intensity isn't has not yet reached
their end of life point we just go okay
they're all outside the frame
uh let's set the life counter to the end
of life and then the next time this
batch is updated for being drawn they'll
be deleted
so the functions themselves are here
we've got a an allocate vectors which
looks a bit weird I guess so we're
passing in our our actual type name into
into here
we're using kind of a an oddity of PB is
that you can get a numeric
representation of each each Vector is
like an index
so if you pass this type in here it'll
give you a numerical representation of
this type name it'll it'll match against
this type name here as well so
I wouldn't
you can well you can see it up here
actually I was testing this before
so you can do something like this
uh Vector 1D now this won't work
it'll complain about that thing oh no
sorry
165's accepting that
yeah
What's Happening Here is when the
phraser sees this
is it runs through and it gives that a
uh and it just treats it like it's a
constant it goes okay you've used the
you use the a type name inside an
expression or just output it's it's uh
it's indexed in the type stack
in this case it's two it's two because
the first type is this one here
and they've got type one type type two
that would be type three type four so if
we put another type before this just a
bit of junk
I call a different name I was a little
client
get a different index
once you know that you can go okay
I can I can get
an index base from here so that's why
I'm using vector vector bass Type 4
actually
sort of going what's the difference
between this type and that type and that
will always give me an index of one
so if I substitute you know back to two
I'll get to
because they declared uh in a Serial
fashion so two is after one three four
so if you know that about your code you
can actually do some shortcuts with that
stuff because if you didn't know this
you can do a new
and use that uh that number as the data
type
structure type
so really the functions here I've got
some constants about how the internal
Library wants to treat things we've got
different operations we can do we can do
a
addition subtraction multiplication
division between vectors of the same
type to the same type
so if you've got if you're working in
Vector threes you can do ignition to
Vector three and a big batch
if you can do a static Edition
so you're adding one uh one vector
to the whole set of vectors in the in
the source and output
normalize them if you want to
or can you can do a direct write so you
can initialize them as well you probably
need things like you know min max and
probably floors and those kind of stuff
there
um
and you can kind of string some you know
reasonably powerful uh logic together
and do batches of this stuff outside of
the normal processing
um
yeah there's some problems with this
about some of the structure types where
but anyway yeah
so
this this allocates a vector buffer we
give it the the type name
leave it back to 1D 2D through to our
four day in there it'll work out the
Stars we need for this buffer
uh it does a deletion of these
if you want to create a job list this is
blast processing we just we call create
we've got a Max of 128 jobs
it's adding this to an internal array
storing this the structure in there in
that array and then
remember it remembers how many jobs I've
got and allocates a buffer of memory as
a bank
for this job list to be passed to the
dll to do the actual Grant work
so initially that that job list is empty
it's got nothing in it
but it's pre-sized based on the max
number of jobs
then we set the the the data type that
we're going to be working with with this
uh this batch
and passed in up here
and it doesn't make the library a bit
more convenient so we we create
something and Returns the index of the
thing we created
a bit like you're calling New Image or
whatever creates a structure and we then
we refer to it back
to that thing by its index
in successive functions
like add for example it uses the current
thing we just created to then add new
jobs onto and here I've chosen to do
this by I have a string with the name of
the operation in it to make it a little
bit more readable I guess you know a bit
of an experiment there actually
um
so you pass this in if you if I create
something and I add a job to it like
it's done over here
uh
yeah we have another add gravity to it
again if we wanted to so this would
it's effectively like doubling what
whatever this this Vector here is twice
but
now it kind of looks a bit more like
micro the particles were being affected
by gravity
uh
if I switch back to
um normal mode that won't do the same
thing it that code is just the original
particles just moving out in a linear
fashion
in any direction
back to blast processing mode
right
locked actually actually uh the other
day was just to give each batch a random
random speed and that makes it more
obvious about what's actually happening
just in case you're wondering well won't
double it up we'll just just have that
Edition made made once
they're probably moving too fast now
you can see that each batch has being
applied this movement vector and if
you're all moving in the same direction
they're all move off in that same
direction so and each batch has has a
color for the whole batch
it's much more obviously like that isn't
it
actually it makes a nice effect when you
switch between the two
modes
yeah it's kind of weird
it runs pretty fast like that because
you've got the clipping helping us out
there too once the batch of particles of
all left the screen they'll be clipped
from the particle list and they don't
need to be updated train so our actual
number of particles in this scene is
only about seventy thousand
age
but they're going to be manually drawn
you know that's that's one of the that's
probably the slowest part of the route
the actual program now is probably the
initialization is probably the slow one
of the slow parts and the drawing is
slow
if we had something that ran through we
could do
I could draw a DOT
on the standard buffer and clip it to
the current frame size
that would be probably the best the best
outcome
um
but ideally you want to have something
that we could do like you know
this is kind of a you know a parallel
way of thinking about the shape thing I
was talking about a few weeks ago about
how shapes really really just bursi
buffers with meshes
and That Could That Could evolve into it
being a mesh and then that mesh could be
rounded two-dimensionally or
three-dimensional
which is what effects actually already
does but um
I like that transition because it kind
of fits into what we already have so if
you already sort of understand the
terminology of what we already have we
don't have to introduce new command sets
that kind of do the same thing as these
other things you know
um
anyway
making a bit slower it's a bit fast like
that
it's kind of cool
but you can see they're all doing the
same
basic thing
because I'm using a pointer to this
structure
I'd have to have a second
um
I'll do that
so
treat grow either way it is now but
we'll have like a group
group speed and we'll do that with our
randomization stuff
it's a group speed will be what we're
adding this this random
um
Vector to all of our
current positions and gravity will be
just something all we use to pull down
the y-axis
over time so I'll do it maybe 0.25
this job
we probably need to actually anyway
particles.gravity
just we've got a couple of like this is
declared we don't really need that to be
declared
so groups feed so our gravities to our
Spades but we'll also add this group
speed
as a separate batch
well I mean obviously the air what you
could do is you could just add gravity
directly to group speed each frame and
that would
save us one pass over the whole buffer
but now I've got three uh these jobs
that have been done with each vertices
buffer
uh
in between where it gets updated
see how we go
sorry it's gonna be group speed wasn't
it
it's all randomly Go in different
directions that's better
if we make that much less than that just
one random range of that
pretty weird isn't it
maybe if we shift make gravity stronger
than that
you're very pretty ounce pull down
looks more like uh
what a fire hose or something like that
uh
yeah sprinkling away
anyway
all right very basic kind of structure I
hope people can get wrap their heads
around this
kind of testing this Theory out a bit
and
anyway
it's a bit of an overview of it today so
I'll leave that there and uh
have you enjoy
you're coding and I'll see you next time
bye
 



 
PlayBASIC Code: [Select]
      global TEST_MODE=1

Type tParticle
Count
Positions_Bank
Speed_Bank

Blaster
Colour
Life_Count
Life_Time
Position as Vector4D
GroupSpeed as Vector4D
Gravity as Vector4D
EndType

Dim Particles as tParticle list

ParticleCount = 5000


// -----------------------------------------------------
do
// -----------------------------------------------------

Cls

// emit another bunch of particles
Angle#=wrapangle(Angle#,2)
x# =(GetSCreenWidth()/2) +cos(Angle#)*200
y# =(GetSCreenHeight()/2) +sin(Angle#)*200

SpawnParticles(ParticleCount, x#,y#)

lockbuffer
ThisRGB = point(0,0)
count=0
for each particles()
if UpdateParticles(Particles)=false
DrawParticles(Particles)
else
DeleteParticles(Particle)
Particles = null
endif
count++
next
unlockbuffer


text 10,10,"Particle Count:"+str$(Count*ParticleCount)
text 10,30,"Mode:"+str$(TEST_MODE)+" Fps:"+str$(Fps())


if enterkey()<>0
TEST_MODE=1-TEST_MODE
flushkeys
endif

Sync

loop spacekey()




function SpawnParticles(Count, x#,y#)

// Size of buffer
Particles = new tParticle

Particles.Count = Count
Particles.Life_Time = 100 // 100 frames
Particles.Colour = rndrgb() // Random RGB colour
Particles.Positions_Bank = AllocVectors(Count,Vector2D)
Particles.Speed_Bank = AllocVectors(Count,Vector2D)

dim Position as Vector2D pointer
Position=getbankPtr(Particles.Positions_Bank)

dim Speed as Vector2D pointer
Speed=getbankPtr(Particles.Speed_Bank)


// dim Gravity as Vector2D pointer
Particles.GroupSpeed.x = rndrange#(-1,1)
Particles.GroupSpeed.y = rndrange#(-1,1)

Particles.Gravity.x = 0
Particles.Gravity.y = 2.25



// Create the blaster to do the brute force vector operations
Blaster = BP_Create(Vector2D)
Particles.Blaster = Blaster

// Add Speeds to the position
BP_AddJob("ADD" ,int(SPEED) ,int(POsition),int(POsition),Count )

// Add the gravity value to the speed vectors
BP_AddJob("ADDVALUE" ,int(SPEED),int(Particles.Gravity),int(SPEED),Count )

// Add the gravity value to the speed vectors
BP_AddJob("ADDVALUE" ,int(SPEED),int(Particles.GroupSpeed),int(SPEED),Count )


// Init our position vector
Particles.Position.x =X#
Particles.Position.y =Y#

// Set up a blaster to initialize a the vertex to common starting positin
InitPosition= BP_Create(Vector2D)
BP_AddJob("SET",int(Particles.POsition),0, int(POsition),Count )
BP_Run(InitPosition) ; run it
BP_Delete(InitPosition) ; delete once its done

// init the Speeds
for lp =0 to Count-1

Angle# = rnd#(360)
Speed# = rndrange#(1,10)

Speed.X = cosradius(angle#,SPeed#)
Speed.Y = sinradius(angle#,SPeed#)

Speed = int(Speed) + sizeof(Vector2D)
next


EndFunction



Function UpdateParticles(Me as tParticle)

if int(me)

if TEST_MODE=0

Count=Me.count

dim POsition as Vector2D pointer
Position=getbankPtr(Me.Positions_Bank)

dim Speed as Vector2D pointer
Speed=getbankPtr(Me.Speed_Bank)
Login required to view complete source code



 Download Source Code

    Attached bellow