News:

Function Finder  Find all the functions within source code files

Main Menu

G2D Releases (Open Gl For PlayBASIC Library)

Started by kevin, November 22, 2014, 08:27:48 PM

Previous topic - Next topic

kevin




 G2D - 2D OpenGL library for PlayBASIC V1.64P  
PROTOTYPE #8


 Release Date:  22nd, Nov, 2014

 PlayBASIC version:  For use with PlayBASIC V1.64P (Retail or higher).






What is this?:


   G2D is an alternative / replacement rendering library the uses the OpenGL API rather than the DirectX / Software interface that PlayBASIC normally uses.   The command set is evolving constantly and already supports a range of core 2d primitive drawing functions (Dots, Lines, Boxes,Polygons) through to Image, Sprites, Maps, Fonts / Text,  and many the most recent addition is the programmable particle library.     These functions try to be functionality identical to the internal PlayBASIC equivalent command (where one exists), while only drawing to the OpenGL screen.


    This library was written in PlayBASIC V1.64P2 and converted to a DLL with PlayBASIC2DLL :)




Latest Blog Posts:


    The following is a selection of development blog posts, note the posts may mention pictures / source codes / video that may not be shown in this overview.


 G2d Blog - Particles and all the small things (October 24, 2014)

      Been thinking about adding particle / entity layers to the G2D library.   Personally I tend to find particle libraries can be a hit hit and miss, some things are easy to do and others fall outside the scope of the solution.  Although the same can be said about any library really.

      Particle effects are useful in many situations, but there's a handful that come to mind such as smoke / fire / thrusters / explosions, so they're worth spending a bit more time thinking about, rather than jamming in the same old same old solution in.  

      Control wise different effects need different controls per particle, stuff like controlling speed / gravity / scale / rotation / image / Randomization etc could all be useful in various situations.  So supporting a cross section of controls seems like the way to go, but this does make initializing  them potentially harder for the user.   Not a huge fan of functions that require 20 parameters though, obviously such things could be wrapped down, but still you soon end up with a lot more set up, than solution.  

     In recent years my favorite solution for such problems is a type of generalized solver.  Where the user can define  a set of operations which it runs it's internal logic over the data set.     In particle terms  the user builds a type of particle script (for want of better word) and the solver would apply this logic to each particle in the set.   So the user isn't really hands on in the process, but they have control over how they move / rotate / animate and when they die.      
 
     Even with such customizable control there would still be situations where the user need to roll their own.. But ya get that !



 G2d - Particles Script / Controller Cont. (November 03, 2014)

  The awfully static picture bellow doesn't really give you much of sense of the demo but anyway, the execution engine is taking shape.  You can think of as a special purpose virtual machine for running basically vector operations, a bit like the vector stack stuff from a few years back.   The code are thus far 3d vector only, but the idea is to support 1D,2D,3D vectors and possibly some bare bones integer controls.    Don't wanna have too many opcodes and too much logic getting in the way of the particle execution engine though.  
 
  In this demo the controller runs the Particles.NEW()  function upon creation which is then updated by the Particles.UPDATE() function.   The FREE() code isn't used/defined in this demo,  not too sure how the language will control the particles state.  Currently the execution engine returns an ALIVE/DEAD (true/false) state on this object,  if it's false it's died and needs to be reclaimed.

  In terms of instructions so far we have SET,MOVE,ADD,SUB,DIV,MULT, RANDOMIZE and CMP.   Which gives us just enough controls to create and explosion with gravity.     It's not exactly BASIC, but with a little thought/reshuffling it seems like reasonable start.   You won't be able to 'loop' in script though, so the logic will have to generally solve in order.  Should be able to add some type of conditional branching (IF/ENDIF) styled statement, but it'd be nothing like BASIC..

  Anyway.. here's an approximation of the controller code in our mock up script that creates the explosion attached (Running in just PLayBASIC for now) .    



; start of script block and name of this class.  So scripts can get called by actual NAME
ParticleScript "Explosion"

; declarations would be expect here (explicit and case sensitive)
 dim Speed as Vector3
 dim SpeedScale as Vector3
 dim SpeedCenter as Vector3

 dim Gravity as Vector3
 dim GravityAccel as Vector3

 dim FloorPosition as Vector3

; function is called after object allocated
function New()
   
  ; set starting position of this particle
  Set(Pos,400,300,0)

  ; Set this vector to speed.x = 20, speed.y=20,  speed.z=0  
  Set(Speed,20,20,0)

  ; Randomly scale speed vector.  So it's this speed.x *= rnd#(1), speed.y*=rnd#(1),  speed.z*=rnd#(1)  
  Randomize(Speed)

  ; Set SpeedCenter. So it's this SpeedCenter.x = -10, SpeedCenter.y=-10,  speedCenter.z=0  
  Set(SpeedCenter,-10,-10,0)

  ; Add SpeedCenter to Speed. So it's this
  ;    Speed.x += SpeedCenter.x,
 ;     Speed.y += SpeedCenter.y
 ;     Speed.z += SpeedCenter.z
  Add(Speed,SpeedCenter)


   Set(SpeedScale,0.99,0.99,0)

   ; force applied to the particle
   Set(Gravity,0,0,0)
   Set(GravityAccel,0,0.20,0)

   ; clipping vector
   Set(FloorPosition,0,600,-1)


EndFunction



; Function  called when objects motion is 'updated'
Function Update()
 
   ; Add current speed to the position
   Add(Pos,Speed)

   ; Add gravity speed to the position
   Add(Pos,Gravity)

   ; increase the force of gravity over time
   Add(Gravity,GravityAccel)

   ; Scale speed over time
   Add(Speed,SpeedScale)

   ; Compare position vector with Floor vector, this set the particles condition code which the execution engine returns.
   ; when a particles position is inside the floor vector, it returns an ok state, otherwise it's dead and needs to be deleted by the controller
   Cmp(POs >= Floor)

EndFunction


EndParticleScript






 G2d Blog - Particles Script Compiler - Local Rotations/Scaling/Animations (November 09, 2014)

      Even though today was my birthday,  still found time to add a branch (IF/ENDIF) block into the script.   This means the script can make comparisons and make simple decisions upon on the result.   Unlike the previous versions of the library the particle will only return a 'dead' state when the script hits the DIE() operator.  Which is basically and END statement.   So script is exited and the status set to dead.  

      So while still rather crude, we've basically arrived at a frame work that can do most common place particle effects.  What we're missing is some way of spawning them relative to a parent.  The current idea for that, is the user set the current parent (passes a structure to the library) and then the new() operator can pull useful stuff from, such as it's position, direction / rotation,  speed.    So if you had a ship that rotating, all you'd do is set the parent structure with that info, then any and all particles generated at that point will use that as they're origin.  Allowing you to attach a thruster, spawn related sparks/explosions that sort of thing.    

      The current Particle VM is a bit naff, I think what i'll do is wrote a post processing converter, which will convert the instruction calling to a more optimal method within the final DLL version (PB2DLL), which would easily be using some type of  ON VARIABLE GOTO/GOSUB structure.   Which yields a fixed cost per instruction.  Moreover I can use the same registering caching method that PB+PB2DLL use when writing opcodes, would allow the compiler to sub faster operations, or use packed methods.   So the scripts should  perform very well.  

      Anyway here's today's little picture..  It's show the particles using different frames, rotations, scales, speeds etc etc...  Check the source code to



; ---------------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------------
; PARTICLE SCRIPT EXAMPLE
; ---------------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------------

; Start if script called "Gravity EXPLOSION"
ParticleScript "Gravity Explosion"

; declarations should be outside of functions and before first usage

 dim Speed as Vector3
 dim SpeedScale as Vector3
 dim SpeedCenter as Vector3

 dim Gravity as Vector3
 dim GravityAccel as Vector3

 dim FloorPosition as Vector3

 dim RotationSpeed as Vector3



; function is called after object allocated.
function New()
   
; set starting position of this particle
Set(Pos,400,300,0 )

; Set this vector to speed.x = 20, speed.y=20,  speed.z=0  
Set(Speed,20,20,0)

; Randomly scale speed vector.  So it's this speed.x *= rnd#(1), speed.y*=rnd#(1),  speed.z*=rnd#(1)  
Randomize(Speed)

; Set SpeedCenter. So it's this SpeedCenter.x = -10, SpeedCenter.y=-10,  speedCenter.z=0  
Set(SpeedCenter,-10,-10,0)

; Add SpeedCenter to Speed. So it's this
;    Speed.x += SpeedCenter.x,
;     Speed.y += SpeedCenter.y
;     Speed.z += SpeedCenter.z
Add(Speed,SpeedCenter)

Set(SpeedScale,0.999,0.999,0)

; Graivty force we'll apply to the particle
Set(Gravity,0,0,0)
Set(GravityAccel,0,0.20,0)

; clipping vector
Set(FloorPosition,-20000,650,-1)


; set the frame to the max possible frames
Set(Frame,15,15,15)

; mult the frame by a random facor to pick a frame
Randomize(Frame)



; set the rotation angle vector  X,y,Z, only Z is used in a 2d scene
Set(Rotation,360,360,360)
Randomize(Rotation)

Set(RotationSpeed,2,2,2)
Randomize(RotationSpeed)


; set the Scale of this particle
Set(Scale,3,3,0)
Randomize(Scale)

EndFunction



; Function  called when objects motion is 'updated'
Function Update()
 
; Add current speed to the position
Add(Pos,Speed)

; Add gravity speed to the position
Add(Pos,Gravity)

; increase the force of gravity over time, so it accels down
Add(Gravity,GravityAccel)

; Scale speed over time
Mult(Speed,SpeedScale)


; Scrink the scale over time
Mult(Scale,SpeedScale)


; Add speed scale to rotation angle to turn the particle
Add(Rotation,RotationSpeed)



; Compare position vector with Floor vector, each field in is compared and MASKED together
; into a 3 bit condition code
Cmp(Pos >= FloorPosition)

; branch on the previous condition code that was set by a previous CMP() operator.
if

; Set this particle to DEAD, so controller can reclaim it
die()
endif

EndFunction


; End of this particle block
EndParticleScript






   

G2d - Programmable Particles - Controller / Emitters (November 14, 2014)

    Wrote the emitter commands yesterday,  the functions turned out pretty much like what's outlined above, with a few subtle changes.   The emitter is the controller or owner of any group of particles.  All particles within the group share common attributes, such as the spawning origin, logic scripts and the texture they use, but each emitter is unique.    The user controls the spawning frequency (particle emission) updating and rendering.   So you have complete control over if/when something is updated, and if it's rendered.     There's no particle level access at all really, but a function to return a pointer to a particles locals could be useful, or perhaps a function to alter the locals of the set.    Which is useful for  adding/changing some global force, like wind for example.  

    The scene bellow is running in a new hacked together testbed.   In the original demo, the code was man handling each particle through a list,  now we've just managing the emitters.   Basically telling them to emitter new particles, when to refresh and when to draw.  Since they're all on screen we're updating all of them all the time.   If and emitter was to do out of view, then of course you'd suspend updating/rendering it.


  Here's an animation created from frame work running in standard PlayBASIC, with any luck the damn thing will play... as it doesn't here !

 





 G2d Blog - Programmable Particles DLL version  (November 20, 2014)

    Up until today, the particle library only existed as a set of PlayBASIC functions and Psubs.   After tonight though, the library has made it's way into the G2D library and now being compiled to machine code DLL using PLayBASIC2DLL.   There was few gremlins with the translation initially and a few spots where I'd been lazy and not manually allocated my types.  Which would make it crash during the script compile, but those seem to be all sorted now.

    For me, the most interesting thing about this isn't actually the rendering at point, it's how fast the Particle VM will execute the byte code, as if there's too much overhead in the particle VM, then there's no much use in them being programmable.   But any fears I may have bad were soon squashed.    With the particle scene controller being able to run 10,000 scripts at over 60fps on my 9 year old Athlon system.   Which can be seen in the rather boring screen shot bellow.

    The library can't render the particles to the OpenGL screen as yet, but even drawing the same FX screen yields a 10+ times performance boost in 4K particle heavy scene, rendering the particles as FX images with alpha addition.   I'd say that with batching them as quads in GL,  rendering should make mince meat of it really.    While in reality it might be able to process 10K particle scripts, I'll be more than happy with rendering 1/2 of that at a reasonable rate.   But that's Fridays little challenge      


G2d Blog - Programmable Particles - 17000 particle test scene.(November 21, 2014)

      Well that was much ado about nothing,  as any fears that running particles through  our custom particle VM would be too slow, should now be completely and utterly smashed with the library returning better than expected performance.   The test scene bellow is shown in two states, the scene is made up of a number of elements again all cut and pasted together form the basic 2d demo that comes with the library.   So in this scene we have some sprites an mock up map and depending on how fast you can press the ENTER KEY anywhere between 5K->17K live particles...  Obviously the  demonstration is over the top, but it does prove how efficient the PB Compiler -> PB2DLL process actually is.   Which is VERY !

     Test Machine: AMD64 3000,  GF6600  ( 9 years old)







Download:


    The current build of the G2D library is available through PlayBASIC maintenance area on our forums.

    Download G2d Prototype #8 (login required)





kevin

#1



 G2D - 2D OpenGL library for PlayBASIC V1.64P  
PROTOTYPE #10


 Release Date:  10th, May, 2015

 PlayBASIC version:  For use with PlayBASIC V1.64P2 (Retail or higher).






What is this?:


   G2D is an alternative / replacement rendering library the uses the OpenGL API rather than the DirectX / Software interface that PlayBASIC normally uses.   The command set is evolving constantly and already supports a range of core 2d primitive drawing functions (Dots, Lines, Boxes,Polygons) through to Image, Sprites, Maps, Fonts / Text,  and many the most recent addition is the programmable particle library.     These functions try to be functionality identical to the internal PlayBASIC equivalent command (where one exists), while only drawing to the OpenGL screen.


    This library was written in PlayBASIC V1.64P2 and converted to a DLL with PlayBASIC2DLL :)




Latest Blog Posts:


    The following is a selection of development blog posts, note the posts may mention pictures / source codes / video that may not be shown in this overview.


  G2D Blog - Prototype # 9 Released  (27th, Dec 2014)

      Here's the latest build of the g2d library, this one is something of a catch up release addressing bugs and missing primitive commands that i've noticed through using the library.  The main fixes would be G2DDeleteImage failing and things like the Text command not responding to changes in the current font.    The library doesn't use the PB's current font settings, rather it tracks this internally. So whatever you set in G2DSetFont.  The same goes the GL ink colour.  So commands like G2dDOT, G2dBox will use the current G2d ink colour.  


      The library is of course built with the latest build of PB & PB2DLL for added performance



  G2D - Prototype # 10 - WIP

         Just stopping by to add a few more primitives to the library, namely circles and ellipses.   From memory the original D3D replacements has some extra fill mode flags for these, so the user could toggle if they wanted them to be span rendered or drawn as polygon batch.  The latter is less work for the run time and would generally give a reasonable result, but can get edgy without some type of sampling control.  Since the shape (the circle) is simply drawn a 360 degree ring of polygons.   The less steps in the ring, the faster/less polygons but less accurate the result would be the original shape.    The span version of the routines are integer only and use much the same logic the PB internal engine with the same precision.


        The main additions to library would be Circle/Ellipse (open & filled) rendering functions and a few other missing 2D primitives.




Download:


   The current build of the G2D library is available through PlayBASIC maintenance area on our forums.

   Download G2d Prototype #10 (10th,May,2015) (login required)