UnderwareDESIGN

PlayBASIC => Show Case => Topic started by: kevin on June 24, 2014, 02:08:07 PM

Title: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on June 24, 2014, 02:08:07 PM

(http://underwaredesign.com/PlayBasicSig.png)

 G2D - 2D OpenGL library for PlayBASIC  (WIP / BLOG / SCRATCH PAD)

 Project Started:  18th, June, 2014

 PlayBASIC version:  For use with PlayBASIC V1.64P (Beta Edition 42 or higher).


(http://underwaredesign.com/screens/PlayBasic/GL/OpenGL_250.png)





What's this thread ?:


          This is the initial development blog for the library.   So in here you'll find all types of stuff covering the libraries early development.   You know all the bare bones  how's and whys stuff, will a good interjection of  screen shots, code snippets and tips.

          NOTE: I really wouldn't expect the code snippets posted in this thread to work with every version of the library.  The command set names are a fluid thing and subject to change at any time.   If you interested in using the library, then read this stuff very carefully !




What is G2D?:


   G2D is an alternative rendering library the uses the OpenGL API rather than the DirectX / Software interface that PlayBASIC normally uses.   The command set is very minimal at this point, in fact only about a dozen primate operations are supported at all.   Those that are, try to be functionality identical to the internal PlayBASIC equivalent command, while only drawing to the OpenGL screen.

   G2D currently only works with PlayBASIC windowed modes, the library attaches the GL viewport to the PlayBASIC  window.  When we do this,  both the DX and GL screens are being to drawn to the same window.   You can get rid of the DX screen using the ScreenLayout command.   The command gives you a rect (X1,y1,x2,y2) of where the DX screen should be drawn within the window.   To get rid of it,  just position it outside of the window.  


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




G2D FAQ:



   Q. Can I Draw internal PB graphics commands to the GL screen or vice verse ?

                   A.  Nope,  you can't draw between them.  


   Q. Does the Library cache states to optimize draw calls ?

                   A. Nope.   So basically everything we draw is it's own unique draw call.  This is less than optimal, but for now I'm more interested in if it works,  than trying to really optimizing stuff.


VIDEO:


   




DOWNLOADS:


          Get Downloads from the  [plink]Download G2D Release Thread (http://www.underwaredesign.com/forums/index.php?topic=4210.0) [/plink]  



Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on June 24, 2014, 02:37:30 PM
  G2D - Basic Image Support

      Tonight (well this morning it's 5:30AM here) I've been working on getting some basic image commands hooked up.   Since this library is build for use with PB's internal commands, i'm going to try and keep things like images in parallel with each other.  By that i mean when you load a G2D image,  the command loads the pixel data into PlayBASIC (AFX) image at whatever slot you wanted.  Once loaded it then translates this to a format GL understands (a texture).   Rather than kill off the source, It then keeps both versions.    The theory being is we can use PB's internal sprites/collision functions in the background to do pixel based effects.   Haven't test this, but it should work in theory.  


       Anyway bellow here's a look at some test code, there really shouldn't be any surprises for you... If there is, RTFM...


[pbcode]

      Explicit True      

      TitleScreen "G2D - 2D OpenGL Library Test For PlayBASIC V1.64P"

      // First up the open GL library
      Dim GL as tMyGL pointer
      GL=G2DStart(800,600)

      ; push the direct X screen to the bottom (almost off the screen)
      ScreenLayout 0,500,800,600
      
      //
      local lp,lp#,x1,y1,x2,y2,count,c,c1,c2


      g2D_loadImage("media/Brick128by128.bmp",1)
      g2D_loadImage("media/OpenGl_500.png",2)

      Do

         ; -------------------------------------------------            
         ; Draw a nice gradient to clear the GL screen
         ; -------------------------------------------------            
            g2dShadeBox(0,0,800,600,$304050,$304050,$807050,$807050)

      
            x1=g2dMouseX()
            y1=g2dMouseY()

            local xlp,ylp

            // grab a grid of images to the frame buffer
            for ylp=0 to 4
               for xlp=0 to 4
                  g2dDrawImage(1,x1+(Xlp*128),y1+(ylp*128),false)
               next
            next

            // draw a transparent GL image to the frame buffer            
            g2dDrawImage(2,100,100,true)
            

            // SYNC the GL screen
            g2dsync()


         ; -------------------------------------------------            
         ; draw on the Direct X surface at the bottom
         ; -------------------------------------------------            
            boxc 0,0,400,100,true,0
            text 10,10,"Fps:"+str$(fps())+" Count="+str$(Count)
            

            // call PB SYNC too
            sync
      loop spacekey()=true
      
      
      g2dEND()
      

[/pbcode]

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on September 22, 2014, 02:46:17 PM

    G2D - Expanding the core primitives commands

        Fired up the G2D project this evening and have just playing with adding the odd command. Mainly been thinking about ways to build interfaces with the existing internal command sets.   Things like Sprites / Maps are obvious ones.   Rendering a map isn't too difficult, as at least with those all the blocks exist in the same texture.  Sprites are a problem as GL / D3D prefer to render lots of polygons from the same surface/texture. Swapping textures between polygons all the time is really inefficient.  PB sprites support UV mapping, but I don't recall seeing anybody ever use it..

        One way around the problem would be building a GL sprite layer, but then you lose pixel / vector collisions (without rewriting it all in PB).   For now I think I'll just knock up some glDrawAllSprites / glDrawOrderedSprite commands on the GL side and have them try and cache the texture state where possible.   So if the a bunch of sprites fall within a depth use the same texture that should solve most of the texture changing issues, since that state can be held across consecutive textures.   
 
        For maps, i'll prolly just add a glDrawMap routine.  This would compute the output from the PB Map/level you provide, the only different would be it'd have a texture parameter.   A bit like this,glDrawMap Map,Level,Xpos,Ypos,ImageIndex.    So the GL side would look in it's texture index for the surface and if there's a GL texture for this image it'd use that..     This should mean you can use the map collision / occlusion commands etc on the map data completely asynchronously from the GL rendering. 

        Anyway, will think about it in the morning
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on September 23, 2014, 12:34:34 AM
    G2D - g2dDrawAllSprites

     Just dropped in a draw all sprites function into the g2d side,  it's dead simple just wanted to test the basic idea really then worry about jazzing it up if need be later.    So far it works fine even though it's running through the PBVM on the standard test machine (Athlon/6600).  The current version  will draw a 1000 anti aliased (500*248 pixel) GL logos around the 27fps mark with no optimization at all.  Which is a pleasant surprise..    

     The demo code shows we're using the existing PB sprite commands with to manage the sprite scene, then just copying the properties required at the end to the GL using the G2dDrawAllSprites function.   So it's basically the same as regular PlayBASIC. 

    Example code.  

[pbcode]


      Explicit True


      TitleScreen "G2D - 2D OpenGL Library Test For PlayBASIC V1.64P"

      // First up the open GL library
      Dim GL as tMyGL pointer
      GL=G2DStart(800,600)


      ; push the direct X screen to the bottom (almost off the screen)
      ScreenLayout 0,500,800,600
      
      //
      local lp,lp#,x1,y1,x2,y2,count,c,c1,c2

      g2dloadImage("media/Brick128by128.bmp",1)
      g2dloadImage("media/OpenGl_500.png",2)


      local maxsprites,x#
      maxsprites=50

      For lp =1 to maxsprites
            CReateSprite lp
            SpriteImage lp,2
            PositionSprite lp,rnd(800),rnd(600)
      next



      Do

         ; -------------------------------------------------            
         ; Draw a nice gradient  clear the GL screen
         ; -------------------------------------------------            
            g2dShadeBox(0,0,800,600,$304050,$304050,$807050,$807050)

            x1=g2dMouseX()
            y1=g2dMouseY()

            local xlp,ylp

            ; draw a grid of this texture at the mouse coord
            g2dGridImage(1,x1,y1,4,4,false)

            // draw a transparent image to the frame buffer            
            g2dDrawImage(2,100,100,true)
            
            // draw the sprite scene
            g2DDrawAllSprites()

            // move the sprites to the right and clip them to the screen width
            for lp=1 to maxsprites
                  x#=getspritex(lp)+lp*0.123
                  if x#>800 then x#=-800
                  PositionspriteX lp,x#
            next
            

            // SYNC the GL screen
            g2dsync()


         ; -------------------------------------------------            
         ; draw on the Direct X surface at the bottom
         ; -------------------------------------------------            
            boxc 0,0,400,100,true,0
            text 10,10,"Fps:"+str$(fps())+" Count="+str$(Count)
            text 10,30,Scancode()
            
            // call PB SYNC too
            sync
      loop spacekey()=true
      
      
      g2dEND()
      
      flushkeys
            
      print "Yeah"
      sync
      waitkey
      
         
[/pbcode]
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on September 23, 2014, 01:46:31 PM
G2D - Batched Sprite Scenes - DrawRotatedImage

      Been in and out most of the day, even so have been able to drop a few more GL equivalent functions into the library.  Commands that come to mind would be G2dTexturedTri,  G2DTextureQuad,  G2dDrawRotatedIMage as well as some tweaks to sprite scene rendering.  


[pbcode]

      Explicit True

      TitleScreen "G2D - 2D OpenGL Library Test For PlayBASIC V1.64P"

      // First up the open GL library
      Dim GL as tMyGL pointer
      GL=G2DStart(800,600)


      ; push the direct X screen to the bottom (almost off the screen)
      ScreenLayout 0,550,800,600
      
      //
      local lp,lp#,x1,y1,x2,y2,count,c,c1,c2

      g2dloadImage("media/Brick128by128.bmp",1)
      g2dloadImage("media/OpenGl_500.png",2)


      local maxsprites,x#
      maxsprites=100

      For lp =1 to maxsprites
            CReateSprite lp
            SpriteImage lp,2
            PositionSprite lp,rnd(800),rnd(600)
      next


      Do

         ; -------------------------------------------------            
         ; Draw a nice gradient  clear the GL screen
         ; -------------------------------------------------            
            g2dShadeBox(0,0,800,600,$304050,$304050,$807050,$807050)

            x1=g2dMouseX()
            y1=g2dMouseY()

            local xlp,ylp

            ; draw a grid of this texture at the mouse coord
            g2dGridImage(1,x1,y1,4,4,false)

            // draw a transparent image to the frame buffer            
            g2dDrawImage(2,100,100,true)
            
            // draw the sprite scene
            g2DDrawAllSprites()

            // move the sprites to the right and clip them to the screen width
            for lp=1 to maxsprites
                  x#=getspritex(lp)+lp*0.123
                  if x#>800 then x#=-800
                  PositionspriteX lp,x#
            next
            
            g2dTextureTri(2,100,100,500,50,300,300,1)

            g2dTextureQuad(2,400,200,800,200,800,600,400,600,1)
            local angle#
            g2dDrawRotatedImage(2, x1,y1,Angle#,2.5,2.5,-250,-100,true,$8020AA30)

            Angle#=wrapangle(Angle#+1)

            // SYNC the GL screen
            g2dsync()

         ; -------------------------------------------------            
         ; draw on the Direct X surface at the bottom
         ; -------------------------------------------------            
            boxc 0,0,400,100,true,0
            text 10,10,"Fps:"+str$(fps())+" Count="+str$(Count)
            text 10,30,Scancode()
            ;text 10,60,MouseBUtton()
   //         text 10,60,LineCount
            
            // call PB SYNC too
            sync
      loop spacekey()=true
      
      g2dEND()
      
      flushkeys
            
      print "Yeah"
      sync
      waitkey
      
[/pbcode]
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on September 26, 2014, 02:26:00 PM
   G2D - Sprite Scene Testing

    Had something of a set back yesterday after running into some issues with legacy Sprite commands.  The GetSpriteRect() function was crashing and SpriteInRegion as acting funny.   The GetSpriteRect function grabs the bounding box from a sprite, it's ideal for clipping the sprite to a viewport / manual collisions or for things like map translations.  While the issue turned out to be an easy fix, it did take  some time to track down where the issue was coming from.  It turned out the new command set wrapping didn't seem to support the pointer fields correctly, mean it the value it was expecting to be a pointer was almost anything..  So no great surprise it'd crash.

    The other drama was in the SpriteInRegion function which turns out to be wrapper of the Box collision sprite commands.  Not too sure how long that one's been there, but I'm guessing years.  The fix required a behavior change,  as the old solution used the sprites collision mode internally (see->less code), the new solution only checks the bounding box against the rect the user supplies, returning a true/false if they overlap.   Which is how it was meant to work originally.

    These two things caused issue with G2D, as they're were being used to work out if a sprite is visible and where it's bounding rect falls within the g2dDrawAllSprites() function.   I've left the Rect checking out of the they current build of the library, so it'll will work with V1.64P to a degree, but there will be clipping problems with some rotated sprites.

    Yesterdays build of the g2dDrawAllSprites function supports Rotated sprites, Rotation Handles, Visibility checking, Clipping,  Filtering, Tint Colours (ARGB a=Alpha) as well some texture management.  These give you a pretty good amount of control, more than enough to create some interesting stuff.        


[pbcode]

      Explicit True

      TitleScreen "G2D - 2D OpenGL Library Test For PlayBASIC V1.64P"

      // First up the open GL library
      Dim GL as tMyGL pointer
      GL=G2DStart(800,600)


      ; push the direct X screen to the bottom (almost off the screen)
      ScreenLayout 0,600,800,600
      
      //
      local lp,lp#,x1,y1,x2,y2,count,c,c1,c2

      g2dloadImage("media/Brick128by128.bmp",1)
      g2dloadImage("media/OpenGl_500.png",2)


      local maxsprites,x#
      maxsprites=500

      For lp =1 to maxsprites
            CReateSprite lp
            SpriteImage lp,2
            PositionSprite lp,rndrange(-800,1600),rnd(550)
            
            centerspritehandle lp
            
         ;   SpriteTransparent lp,rnd(100)>50
   ;
   ;         Spritefilter lp,true
            ;spritecollisiondebug lp,true
            if rnd(100)>50
                  SpriteDrawMode lp,2
                  rotatesprite lp,45
            endif

            SpriteTint lp,(rndrgb()<<8)| rnd(255)
      next


      local fx=newimage(800,600,2)

      local ScreenModeToggle
      
      local FrameRate


      ; ------------------------------------------------------------------------
      Do
      ; ------------------------------------------------------------------------

         ; -------------------------------------------------            
         ; Draw a nice gradient  clear the GL screen
         ; -------------------------------------------------            
            g2dShadeBox(0,0,800,600,$304050,$304050,$807050,$807050)

            x1=g2dMouseX()
            y1=g2dMouseY()

            local xlp,ylp

            ; draw a grid of this texture at the mouse coord
            g2dGridImage(1,x1,y1,4,4,false)

            // draw a transparent image to the frame buffer            
            g2dDrawImage(2,100,100,true)
            
            
            PositionSprite 1,x1,y1
            centerspritehandle 1
            turnsprite 1,0.25
            
            // draw the sprite scene
            g2DDrawAllSprites()

            // move the sprites to the right and clip them to the screen width
            for lp=1 to maxsprites
                  x#=getspritex(lp)+1+(lp and 3)*0.123
                  if x#>2400 then x#=-1600
                  PositionspriteX lp,x#

                  ; spin it
                  turnsprite lp,lp/10.0
            next
            

            // SYNC the GL screen
            g2dsync()



            // SYNC the PB screen /user input etc
            sync

            if enterkey()
                  if ScreenModetoggle=0
                     ScreenLayout 0,0,800,600
                  else
                     ScreenLayout 0,300,800,600
                  endif
                  
                  ScreenModetoggle=1-ScreenModetoggle
                  flushkeys
            endif

Framerate=fps()

      loop spacekey()=true
      
      g2dEND()



      flushkeys
      ScreenLayout 0,0,800,600
      
      cls
      
      print framerate
      sync
      waitkey
      end            
      
            
[/pbcode]    

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on September 29, 2014, 12:06:34 PM

  G2D - DrawOrderedSprite scenes

        The previous implementation only included an emulation of DrawAllSprites, which is fine if you don't rely upon sprite depths for the output.   But since there's a basic framework to work with, adding scene sorting is the next obvious addition, which gives us a way to implement a g2dDrawOrderedSprite  command in the Open GL side.   The command works much the same as the existing one on the PB side, where if you compare the output against each other visually, they're almost identical.   It's just quicker pushing rendering off onto a second device such as a GPU. 
   
         Here's some test scene code that include a toggle between displaying the GL and DX screens and well as toggle between the the different sprite scene rendering.

[pbcode]
      Explicit True

      TitleScreen "G2D - 2D OpenGL Library Test For PlayBASIC V1.64P"

      // First up, we open GL library after the Pb screen has been created,
      // since it attaches to the window
      Dim GL as tMyGL pointer
      GL=G2DStart(800,600)


      ; push the direct X screen to the bottom (almost off the screen)
      ScreenLayout 0,600,800,600
      
      //
      local lp,lp#,x1,y1,x2,y2,count,c,c1,c2

      g2dloadImage("media/Brick128by128.bmp"   ,1)
      g2dloadImage("media/OpenGl_500.png"      ,2)
      g2dloadImage("media/PlayBasicSig2.png"   ,3)


      local maxsprites,x#
      maxsprites=100


      local Z=1000
      local s#=5
      
      For lp =1 to maxsprites
            CReateSprite lp

            if rnd(100)>50   
               SpriteImage lp,2
               PositionSpriteZ lp, 500
            else
               SpriteImage lp,3
               PositionSpriteZ lp, 100
               Spritefilter lp,true
               
            endif

            PositionSpriteZ lp, z
            z--
            ;rnd(1000)
      
            PositionSprite lp,rndrange(-800,1600),rnd(550)
            centerspritehandle lp

            ScaleSprite lp,2
            s#=s#-0.1

   ;
            ;spritecollisiondebug lp,true
            SpriteDrawMode lp,2
            SpriteTint lp,rndrgb()| $ff000000
            
            
      next


      local fx=newimage(800,600,2)

      local ScreenModeToggle
      
      local FrameRate


      ; ------------------------------------------------------------------------
      Do
      ; ------------------------------------------------------------------------

         ; -------------------------------------------------            
         ; Draw a nice gradient  clear the GL screen
         ; -------------------------------------------------            
            g2dShadeBox(0,0,800,600,$304050,$304050,$807050,$807050)

            x1=g2dMouseX()
            y1=g2dMouseY()

            local xlp,ylp

            ; draw a grid of this texture at the mouse coord
            g2dGridImage(1,x1,y1,4,4,false)

            // draw a transparent image to the frame buffer            
            g2dDrawImage(2,100,100,true)
            
            // Draw a box
;            g2dBOXC(100,100,50,400,0,$ff00ff00)

            
            PositionSprite 1,x1,y1
            centerspritehandle 1
            turnsprite 1,0.25
            
            // draw the sprite scene
   
   
            if functionkeys(1)=false
               g2DDrawOrderedSprites()
            else
               g2DDrawAllSprites()
            endif


            g2dDrawImage(3,GetScreenWidth()/2-(GetImageWidth(3)/2),GetScreenHeight()-GetImageHeight(3),true)


            // move the sprites to the right and clip them to the screen width
            for lp=1 to maxsprites
                  x#=getspritex(lp)+1+(lp and 3)*0.123
                  if x#>2400 then x#=-1600
                  PositionspriteX lp,x#
                  
                  ; spin it
                  turnsprite lp,lp/100.0
            next
            
            // SYNC the GL screen
            g2dsync()

         ; -------------------------------------------------            
         ; Depending on the mode, we draw the same scene to an FX window on the DX window
         ; -------------------------------------------------            

         if ScreenModetoggle

            rendertoimage fx
            ShadeBox 0,0,800,600,$304050,$304050,$807050,$807050

            ; draw a grid of this texture at the mouse coord
            GridImage 1,x1,y1,4,4,false

            // draw a transparent image to the frame buffer            
            DrawImage 2,100,100,true
            

   
            if functionkeys(1)=false
               DrawOrderedSprites
            else
               DrawAllSprites
            endif

            rendertoscreen
            drawimage fx,0,0,false
         endif
         
               
            // call PB SYNC too
            sync

            if enterkey()
                  if ScreenModetoggle=0
                     ScreenLayout 0,0,800,600
                  else
                     ScreenLayout 0,600,800,600
                  endif
                  
                  ScreenModetoggle=1-ScreenModetoggle
                  flushkeys
            endif

Framerate=fps()

      loop spacekey()=true
      
      g2dEND()

[/pbcode]


  To DO list ?

    There's number of things that would be handy building interfaces too, stuff like Maps / Shapes & Fonts are the main ones really.   The G2D side doesn't need a complete implementation of such command sets, just a way of displaying the contents of them on the GL screen.   

    They all have their own little challenges, but fonts could be a bit problematic.  The most obvious solution is build the text into a mesh and render that to the surface, which should work fine.   There is a slight issue with the resolution of the font, and the size of the texture it uses.  Since the font has to be translated to an image and then a GL texture.   If you map all 256 (2^8) characters into a single texture, where each row is 16 character by 16 rows..  Then as long as character width/heights aren't excessive then this should create a texture that's responsible size.    A character width of 16 pixels would give a texture of 256*256 pixels.   Which is peanuts today, but if the characters are 64*64, then that's a 1024*1024 sized texture.   Which will flat out fail on older machines.   

    The texture size stuff is just one of those things you have to get your mind around really,  some of it I can possible hide away within the implementation later,  but initially I think we'll just get working then worry about ways to make it more flexible.
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on September 30, 2014, 12:42:00 PM
    G2D - g2dDrawMap (Solid) Test scene

       So bellow we have a GL version of the DrawMap command.  You set up your map the same as normal, it's recommended you use FX or AFX block graphics.   If you're not running pixel impacts on the map, then you don't really need to put any graphics in them.   The g2dDrawMap command current has an additional texture parameter.    This image / texture should contain the block graphics set out on it in a grid.  Just like the internal loadMapGfx command, the importer maps the tile indexes across then down, starting at index zero.  

      For example, if you had 16 tiles, it's recommended you set them out in a 4 by 4 pattern like this,
     

      [00][01][02][03]
      [04][05][06][07]
      [08][09][10][11]
      [12][13][14][15]


     Always try an avoid block mappings that aren't powers of 2.   So grid of 4*4, 8*8, 16*16, 32*32, 64*64, etc  This is because blocks need to be UV mapped as floats, which can have precision errors in them.   See -> 1/3.0

     The same applies to your  block graphics width and heights.    Your blocks texture should aim to be a power of 2 for the best compatibility.   If it isn't, most drivers will automatically make it a power of 2 (cost you extra memory) or simply fail.  

     Bellow is the test scene code.   The test map builds a level that contains a bunch of copies of the input texture made up of from 32 by 32 size blocks.    Tile zero is the transparent tile so it's removed.

[pbcode]

      Explicit True

      TitleScreen "G2D - G2DDrawMap Map Test"

      // First up, we open GL library after the Pb screen has been created,
      // since it attaches to the window
      Dim GL as tMyGL pointer
      GL=G2DStart(800,600)


      ; push the direct X screen to the bottom (almost off the screen)
      ScreenLayout 0,600,800,600
      
      //
      local lp,lp#,x1,y1,x2,y2,count,c,c1,c2

      g2dloadImage("media/Brick128by128.bmp"   ,1)
      g2dloadImage("media/OpenGl_500.png"      ,2)
      g2dloadImage("media/PlayBasicSig2.png"   ,3)
      g2dloadImage("media/skin_g.bmp"         ,4)

   

      local maxsprites,x#
      maxsprites=200

      local Z=2000
      local s#=5
      
      For lp =1 to maxsprites

            CReateSprite lp

            SpriteDrawMode lp,2

            PositionSpriteZ lp, z
            z-=10

            if rnd(100)>50   
               SpriteImage lp,2
               PositionSpriteZ lp, 500

            else
               SpriteImage lp,3
               PositionSpriteZ lp, 100
            endif

            PositionSprite lp,rndrange(-800,1600),rnd(550)
            centerspritehandle lp

            SpriteTint lp,rndrgb()| $ff000000
            
      next

      local fx=newimage(800,600,2)

      local ScreenModeToggle
      
      local FrameRate

      local ThisMap=NewMap(10)
      CreateMapGFX  ThisMap,32,32,64,0,2

      Local ThisLevel=NewLEvel(ThisMap,100,32)

      local TIle,Xlp,Ylp

      Local ThisLevelBLock=NewLEvel(ThisMap,7,7)

      Tile=0
      for ylp=0 to 7
            for xlp=0 to 7
                  PokeLevelTile ThisMap,ThisLevelBlock,xlp,ylp,TIle and 63
                  TIle++
            next      
      next   
      
      for ylp=0 to 10
         for xlp=0 to 10
            PasteLevel ThisMap,ThisLEvelBlock,ThisMap,ThisLEvel,xlp*8,ylp*8,1111
         next
      next
   

      ; ------------------------------------------------------------------------
      Do
      ; ------------------------------------------------------------------------

         ; -------------------------------------------------            
         ; Draw a nice gradient  clear the GL screen
         ; -------------------------------------------------            
            g2dShadeBox(0,0,800,600,$304050,$304050,$807050,$807050)

            x1=g2dMouseX()
            y1=g2dMouseY()

            local xlp,ylp

            ; draw a grid of this texture at the mouse coord
            g2dGridImage(1,x1,y1,4,4,false)

            // draw a transparent image to the frame buffer            
            g2dDrawImage(2,100,100,true)
            
            // Draw a box
            
            PositionSprite 1,x1,y1
            centerspritehandle 1
            turnsprite 1,0.25
            
            // draw the sprite scene
            if functionkeys(1)=false
               g2DDrawOrderedSprites()
            else
               g2DDrawAllSprites()
            endif

            g2dDrawMap(ThisMap,ThisLevel,x1,y1,4)
            g2dDrawImage(4,0,0,false)

            g2dDrawImage(3,GetScreenWidth()/2-(GetImageWidth(3)/2),GetScreenHeight()-GetImageHeight(3),true)

            
            // move the sprites to the right and clip them to the screen width
            for lp=1 to maxsprites
                  x#=getspritex(lp)+1+(lp and 3)*0.123
                  if x#>2400 then x#=-1600
                  PositionspriteX lp,x#
                  ; spin it
                  rotatesprite lp,lp   ;lp/100.0
            next
            
            
            // SYNC the GL screen
            g2dsync()

         ; -------------------------------------------------            
         ; draw on the Direct X surface at the bottom
         ; -------------------------------------------------            

            // call PB SYNC too
            sync

      loop spacekey()=true
      
      g2dEND()


[/pbcode]


    G2D - Compute Relative Cord From Sprite

        Hadn't noticed it before but there seems to be missing a way to compute a rotated/scaled/centered position from a sprite, so just knocked up a few functions as test.  This would be useful when attaching items to a character.    

        The second picture shows the result of test loop. The loop runs through and computes cords across the sprites width/height which are then translated to the final world position relative to the sprite...    The code just draws a box to highlight the coordinate in the scene


[pbcode]


            for ylp=0 to 100 step 20
               for xlp=0 to 100 step 10
            
                     x1=GetSpriteWidth(1)*(xlp/100.0)         
                     y1=GetSpriteHeight(1)*(ylp/100.0)         
            
                     X1,y1=ZZZ_ComputeSpriteCord(1,x1,y1)
                     g2dBoxC(x1-3,y1-3,x1+3,y1+3,1,$ffff0000)
   
               next         
            next


[/pbcode]



     G2D - Sprite To Sprite Alignment (Limbs)

         Here's another little handy function, this one lets you position a sprite relative to it's parent sprite, in other words you can create sprite limb structures.

         The third picture is show the GL logo with some legs sticks out it spinning around it.  Each leg has 3 limbs, make the object consume over a 100 sprites.. It's not pretty, but hopefully you get the idea.

[pbcode]
            local index =2
            local ParentSprite

            for xlp=0 to 359 step 10

               ; -------------------------------------
               ; Position first sprite in limb
               ; -------------------------------------

               ParentSprite=Index
               x1=GetSpriteWidth(1)/2   +(cos(xlp)*180)
               y1=GetSpriteHeight(1)/2   +(sin(xlp)*60)
               
               spriteimage index,5
               scalespritexy index,1,0.5
               spritehandle Index,0,GetSpriteHeight(Index)/-2
               AlignSpriteToSprite 1,Index,x1,y1,xlp

               positionspritez Index,2

               index++
               ; -------------------------------------
               ; Position second sprite in limb to the end of the previous limb
               ; -------------------------------------

               spriteimage index,5
               scalespritexy index,1,0.5
               spritehandle Index,0,GetSpriteHeight(Index)/-2
               AlignSpriteToSprite ParentSprite,Index,128,16,30
               
               positionspritez Index,5
               ParentSprite=Index

               index++
               ; -------------------------------------
               ; Position third sprite in limb to the end of the previous limb
               ; -------------------------------------

               spriteimage index,5
               scalespritexy index,1,0.5
               spritehandle Index,0,GetSpriteHeight(Index)/-2
               AlignSpriteToSprite ParentSprite,Index,128,16,30
               
               positionspritez Index,6

               index++
            next

[/pbcode]


 

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 01, 2014, 08:49:39 PM
  G2D - Prototype # 4 Released

       Here's today build og he G2D library, it includes more Sprite/Image and Map commands.  For stuff like maps all we needed is a way to render a map to the GL screen, which is what the g2dDrawMap function does.  The only difference to the internal command (DrawMap) is that the g2D version currently requires a texture index to be passed to it as the block graphics.  (See previous post about how that)  
 
       Command wise, this build includes some new sprite commands such as  AlignSpriteToSprite(parentsprite,limbsprite,limbx,limby,limbangle#)  and the x#=GetAlignedSpriteCordX(thissprite,cordx)  (there's also a Y version)  which are used to compute the location of point that's attached to a sprite.  Handy for gun turrets. limbs, particles that sort of thing.  
 
       There's also a few new Image functions such as.  

         MakeAlphaChannel(imageindex,maskcolour)   ; This function builds an Alpha channel for images that use MASK COLOUR based transparency. The image can then be converted to a texture use us in a GL scene.

        g2dConvertToTexture(index)    ; This function creates an FX/AGX image to a GL texture for this image.

       What these functions allow us to do is convert existing image media so that's got and alpha channel, which you need for GL

       
       While updating the test/demo with the dll version I did notice the G2DDrawOrderedSprites function seemed to be broken in this build, not too sure why, the g2dDrawAllSprites is working.  




 G2D - Prototype #4 Released

  [plink]Get G2D Prototype #4 (http://www.underwaredesign.com/forums/index.php?topic=4210.msg28488#msg28488)[/plink]



Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 03, 2014, 12:06:59 PM

G2D - Fonts & Text rendering

      In the previous builds Font/Text rendering is missing, so that's been the order of the today's sessions.     For fonts we need to keep a parallel data on the library side,  much that same images.  For each font we need to build a texture of the character set.    The character set is a 16*16 grid, i've included a debug function to actually draw a fonts character set texture to the GL surface, just so I can verify it.   see-> g2ddrawfontimage(Index,Xpos,Ypos,DrawMode)     

      To load a font we use the g2dLoadFont(FontName$,Index,Size,Style), this function wraps the LoadFont function, so in other words first it loads the font using normal LoadFont on the PB side, then from this, is built the character set image/texture and then stores the data in parallel structure on the GL side.    Be warned, any media you load like this, need to be released using the appropriate g2d Delete function. (G2dDeleteImage, G2dDeleteFOnt etc)   - The G2dLoadFont function behaves almost the same as the standard command, with one key difference, which is the command changes the current font on the GL side for the time being.  Will most like change that to match PB's normal behavior.   To make porting DX based renders to GL easier.     

     The only text rendering commands we have at this time is g2dText(Xpos,Ypos,Message$) which is not at optimal in this version, but gets the jobs done.


     The scene bellow shows the scene rendered to GL (TOP) / DX (Bottom) side by side so i can make check the output is

[pbcode]

      Explicit True

      TitleScreen "G2D - G2DDrawMap Map Test"

      // First up, we open GL library after the Pb screen has been created,
      // since it attaches to the window
      Dim GL as tMyGL pointer
      GL=G2DStart(800,600)


      ; push the direct X screen to the bottom (almost off the screen)
      ScreenLayout 0,300,800,600
      
      //
      local lp,lp#,x1,y1,x2,y2,count,c,c1,c2

      g2dloadImage("media/Brick128by128.bmp"   ,1)
      g2dloadImage("media/OpenGl_500.png"      ,2)
      g2dloadImage("media/PlayBasicSig2.png"   ,3)
      g2dloadImage("media/skin_g.bmp"         ,4)
      g2dloadImage("media/block.png"         ,5)


      
      ; Load the ship image into memory
      loadImage  "media/ship.bmp",6,8
      
      ; build alpha channel from the Mask colour
      MakeAlphaChannel(6,argb(0,0,0,0))

      ; now create a texture from it
      g2dConvertToTexture(6)



      local maxsprites,x#
      maxsprites=110

      local Z=2000
      local s#=5
      
      For lp =1 to maxsprites

            CReateSprite lp

            SpriteDrawMode lp,2

            PositionSpriteZ lp, z
            z-=10

            if rnd(100)>50   
               SpriteImage lp,2
               PositionSpriteZ lp, 500

            else
               SpriteImage lp,3
               PositionSpriteZ lp, 100
            endif

            PositionSprite lp,rndrange(-800,1600),rnd(550)
            centerspritehandle lp

;            s#=s#-0.1

   ;         spritecollisiondebug lp,true
   ;      spritecollisionmode lp,1
            
         ;   SpriteTint lp,rndrgb()| $ff000000
            
      next
      
      SpriteImage 1, 2
      PositionSpriteZ 1, 1

      local fx=newimage(800,600,2)

      local ScreenModeToggle
      
      local FrameRate

      local ThisMap=NewMap(10)
      ;CreateMapGFX  ThisMap,32,32,64,0,2
      loadMapGfx  "media/skin_g.bmp",ThisMap,32,32,0,2   ;         ,4)
      
      Local ThisLevel=NewLEvel(ThisMap,100,32)

      LevelDrawMode  ThisMap,ThisLevel, 2   
      local TIle,Xlp,Ylp
   /*
      for ylp=0 to GetLevelHeight(ThisMap,ThisLEvel)
            for xlp=0 to GetLevelWidth(ThisMap,ThisLEvel)
                  PokeLevelTile ThisMap,ThisLevel,xlp,ylp,TIle and 63
                  TIle++
            next      
      next   
   */
      Local ThisLevelBLock=NewLEvel(ThisMap,7,7)

      Tile=0
      for ylp=0 to 7
            for xlp=0 to 7
                  PokeLevelTile ThisMap,ThisLevelBlock,xlp,ylp,TIle and 63
                  TIle++
            next      
      next   
      
      for ylp=0 to 10
         for xlp=0 to 10
            PasteLevel ThisMap,ThisLEvelBlock,ThisMap,ThisLEvel,xlp*8,ylp*8,1111
         next
      next
   
      local MapScrollX            
   
   ;   SetFPS 60
   
   
   
      local FontIMage=   g2dLoadFont("veranda",10,48,0)
      
      Local Message$="Hello World Hell World []"

      ; ------------------------------------------------------------------------
      Do
      ; ------------------------------------------------------------------------

         ; -------------------------------------------------            
         ; Draw a nice gradient  clear the GL screen
         ; -------------------------------------------------            
            g2dShadeBox(0,0,800,600,$304050,$304050,$807050,$807050)

            x1=g2dMouseX()
            y1=g2dMouseY()

            local xlp,ylp

            g2dDrawMap(ThisMap,ThisLevel,MapScrollX,100,4)
            g2dDrawMap(ThisMap,ThisLevel,MapScrollX+2000,100,4)

            MapScrollX-=1
            If MapScrollX<-1000
               MapScrollX+=1000
            endif


            PositionSprite 1,x1,y1
            centerspritehandle 1
            turnsprite 1,0.25
            
            // draw the sprite scene
            if functionkeys(1)=false
               g2DDrawOrderedSprites()
            else
               g2DDrawAllSprites()
            endif

         ;   g2dGridImage(4,0,0,3,3,false)

            g2dDrawImage(3,GetScreenWidth()/2-(GetImageWidth(3)/2),GetScreenHeight()-GetImageHeight(3),true)

            
            // move the sprites to the right and clip them to the screen width
            for lp=1 to maxsprites
                  x#=getspritex(lp)+1+(lp and 3)*0.123
                  if x#>2400 then x#=-1600
                  PositionspriteX lp,x#
                  ; spin it
               ;   turnsprite lp,0.10   ;(lp and 63)/100.0
            next
            
            
;            SpriteCollisionDebug 1,true

         ;   for ylp=0 to 100 step 20
         ;      for xlp=0 to 100 step 10
            
            ;         x1=GetSpriteWidth(1)*(xlp/100.0)         
            ;         y1=GetSpriteHeight(1)*(ylp/100.0)         
            
               ;      X1,y1=ZZZ_ComputeSpriteCord(1,x1,y1)
               ;      g2dBoxC(x1-3,y1-3,x1+3,y1+3,1,$ffff0000)
   
         ;      next         
         ;   next

;            spriteimage 1,2

            local index =2
            local ParentSprite

            for xlp=0 to 359 step 10

               ; -------------------------------------
               ; Position first sprite in limb
               ; -------------------------------------

               ParentSprite=Index
               x1=GetSpriteWidth(1)/2   +(cos(xlp)*180)
               y1=GetSpriteHeight(1)/2   +(sin(xlp)*60)
               
               spriteimage index,5
               scalespritexy index,1,0.5
               spritehandle Index,0,GetSpriteHeight(Index)/-2
               AlignSpriteToSprite 1,Index,x1,y1,xlp

               positionspritez Index,2

               index++
               ; -------------------------------------
               ; Position second sprite in limb to the end of the previous limb
               ; -------------------------------------

               spriteimage index,5
               scalespritexy index,1,0.5
               spritehandle Index,-5,GetSpriteHeight(Index)/-2
               AlignSpriteToSprite ParentSprite,Index,128,16,30
               
               positionspritez Index,5
               ParentSprite=Index

               index++
               ; -------------------------------------
               ; Position third sprite in limb to the end of the previous limb
               ; -------------------------------------
               spriteimage index,5
               scalespritexy index,1,0.5
               spritehandle Index,-5,GetSpriteHeight(Index)/-2
               AlignSpriteToSprite ParentSprite,Index,128,16,30
               
               positionspritez Index,6

               index++
            next

            ;g2ddrawfontimage 10,g2dmousex(),g2dMousey(),rightmousebutton()
            
            
            G2dText(g2dmousex(),g2dMousey(),Message$)
            

            // SYNC the GL screen
            g2dsync()

         ; -------------------------------------------------            
         ; draw on the Direct X surface at the bottom
         ; -------------------------------------------------            
         ;   boxc 0,0,400,100,true,0
      ;      text 10,10,"Fps:"+str$(fps())+" Count="+str$(Count)
      ;      text 10,30,Scancode()
            ;text 10,60,MouseBUtton()
   //         text 10,60,LineCount
            

            // call PB SYNC too
;         if ScreenModetoggle
            rendertoimage fx
            ShadeBox 0,0,800,600,$304050,$304050,$807050,$807050

            ; draw a grid of this texture at the mouse coord
;            GridImage 1,x1,y1,4,4,false

            // draw a transparent image to the frame buffer            
;            DrawImage 2,100,100,true

            DrawMap ThisMap,ThisLevel,MapScrollX,100
            DrawMap ThisMap,ThisLevel,MapScrollX+2000,100


   
            if functionkeys(1)=false
               DrawOrderedSprites
            else
               DrawAllSprites
            endif

            DrawImage 3,GetScreenWidth()/2-(GetImageWidth(3)/2),GetScreenHeight()-GetImageHeight(3),true

            rendertoscreen
            drawimage fx,0,0,false
;         endif
         
      ;   drawimage FontIMage,0,0,false
            setfont 10
            text g2dmousex(),g2dmousey(),Message$
            
            sync

            if enterkey()
                  if ScreenModetoggle=0
                     ScreenLayout 0,0,800,600
                  else
                     ScreenLayout 0,600,800,600
                  endif
                  
                  ScreenModetoggle=1-ScreenModetoggle
                  flushkeys
            endif

            Framerate=fps()

      loop spacekey()=true
      
      g2dEND()
   
[/pbcode]
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 06, 2014, 07:36:03 PM
   G2D - Prototype # 5 Released  - Fonts / Text Rendering

    So here's the latest build of the library, there's some fixed functionality with the g2dDrawOrderedSprite command now working as well as the addition of the Font & Text commands.     The bug in the g2dDrawOrderedSprite command was one of the face palm mistakes that only shows up in the translated machine code version, since the runtime have write allocation protection on every write.

    The offending code looked a bit like this,

[pbcode]

  ; some code to run through and transfer the sprites settings to a structure for sorting
     For lp=1 to maxSprites

           ; check if there's a structure at this position
           if Array(lp)
                    ; alloc one  
                    Array(lp) = new MySprite
           endif

           ; write into this structure
           Array(lp).x  = Xpos
           Array(lp).y  = Ypos

  ;   etc
      next

[/pbcode]

   The code was meant to alloc a new type if  one wasn't present (if a cell inside an array was zero), but instead it'd only allocated types when it already existed.    So in DLL the cell would be null and boom it'd crash..


     To fix it, the IF statement needed a compare with ZERO, since it's looking for empty cells in the array

[pbcode]

  ; some code to run through and transfer the sprites settings to a structure for sorting
     For lp=1 to maxSprites

           ; check if there's a nothing at this position in the array
           if Array(lp)=0
                    ; alloc one  
                    Array(lp) = new MySprite
           endif

           ; write into this structure
           Array(lp).x  = Xpos
           Array(lp).y  = Ypos

  ;   etc
      next

[/pbcode]


Fonts

    To load a font for g2d we use the g2dLoadFont(FontName$,Index,Size,Style) function.  This function works much the same the LoadFont in the PB command set,in fact it wraps it.   The only real difference is the g2d version covers the vector system font to a texture for rendering in a GL screen.   The g2dLoadFont currently only supports converting system fonts, so if you loaded a CRF bitmap font, then it'll try and convert the character into a texture which loose all the pixel data.     Not big deal, given nobody even uses then.

    For text rendering commands we've g2dPrint and g2dText,  the only difference to native PB command is they require strings.   Where as Print/Text in PB can handle String/Integer/Float fields.  


 
Download

   [plink] G2D - 2D OpenGL library for PlayBASIC V1.64P PROTOTYPE #5 (http://www.underwaredesign.com/forums/index.php?topic=4210.msg28495#msg28495)[/plink]

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 07, 2014, 05:52:32 PM
 G2D - Draw Ordered Sprites Extended plus Viewer/Camera Control

     One of the missing components from the G2D library at this point is some way of rendering a 'captured' camera scene to the GL screen.   Most PB programs/games seem to use either all sprites/images for the scene or a sprite/map combination.    Creating your own camera routines are not out of the question, but internally it's managing the draw state for you..  Which is one of those "it just magically happens" things you're better off not knowing about.   The GL side is no different,  the rendering routines have to try and manage the device state the best it can to avoid state changes which slow things down.    

     If you think about most map / sprite scenes you've generally got a background, a tile layer or two and sprites either in front or behind the layers.  The internal camera would clip/sorts all the rects then draws the visible rects using painters, but we can duplicate that behavior fairly easily, by using a adding a MinZ and MaxZ range to a variation of the g2dDRawOrderedSprite command.     The new command is called  g2dDRawOrderedSpriteEx  (Ex is for Extended BTW)  

     
    So to draw a scene of 3 layers (Sprites with Z from 500 to 1000), a map layer, then foreground sprites 0 to 499

[pbcode]
            ; draw sprites behind map
            g2DDrawOrderedSpritesEx(CameraX,CameraY,500,1000)

            ; draw checker board map layer
            g2dDrawMap(ThisMap,ThisLevel,MapScrollX,100,4)
            g2dDrawMap(ThisMap,ThisLevel,MapScrollX+2000,100,4)

            ; draw sprites in front of map
            g2DDrawOrderedSpritesEx(CameraX,CameraY,0,499)

[/pbcode]

    You'll notice there's camera parameters for the command, which i'm trialing at the moment, they do as you'd expect and allow you view the screen sprite from a relative position in 2d space.    Surely those who've ever messed around with the FX prototypes can probably guess what other little ideas I've got in that regard.


    Anyway, the messy show bellow shows the scene, easy as
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 09, 2014, 06:41:03 PM
  G2D - Perspective Ordered Sprites Scene Test

        Haven't had much time for any projects the past few days (not that there's any interest anyway), was away at a wedding over the weekend and have been trying to catch up on some news / house work (Mowing) ever since...  

        This morning i've have been tweaking the sprite scene routines to support perspective rendering of the scene.  Which just means the final sprites size is the result of perspective projection between the viewer and the sprite.  Which means sprites closer to the viewer (those with a smaller Z) will be larger than those with a bigger z..    

        The pic's bellow just show the mock up scene in two states (near  and far), the scene Z is being controlled internally for the time being.  Will just have to wrap up all the necessary setting functions to make it user controllable.    


 EDIT #1 Added a 3rd picture as it's easier to see the scene is sorted and perspective projected.  

 EDIT #2 Added a 4th picture, in this one we see the camera can rotate it's view down the Z axis.    So the sprite aren't rotating, the viewer is.

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 12, 2014, 06:23:47 PM
    G2D - Alpha Addition Sprite Draw Modes with Perspective Ordered Sprites Scene Test

       It's hot unseasonable warm here the past few days so I've been out on the bike trying to catch up some last minute training for next weekend Around the bay event.    It's only a fun ride, but the preparation can really eat into my free time.   Will be glad when it's over that's for sure.

        Anyway,  during the last session on the library i was toying with dropping in some support for Pb sprite drawmodes / camera rotations.  Unfortunately the GL 1.0x spec is pretty limited when it comes to blend modes,  we can do the most common stuff from PB, such as Alpha blending / Tinting / Additive modes, but some of other would require multiple passes & or special textures..   For the time being it's no big deal..  


       I think what i'll do today is hack together some camera controls and throw up a version of library again...


Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 13, 2014, 05:36:15 PM
  G2D - Zooming Bubble Field

    Those full members of the forums (others won't even be aware it exists) with long memories might remember this demo from the previous GL library for PBFX runtimes.   Basically it's just manually drawing a bunch of zooming bubbles (2500 rects) all alpha bended over each other with shaded backdrop.     It's a bit slower than the optimized PBFX version, as this version is test isn't compiled to DLL (it's just running in normal PB code).  The FX engine is much more optimized than this at this point, but they should run about the same in the end.
   
    The routine bellow draws the scene is bellow..  

[pbcode]
      optExpressions  1+2
      
      Type tSprite
            X#,Y#,Z#
            SpeedX#,SpeedY#
            TintColour
      endtype

      Dim Sprites(2500) as tSprite



Function Render_Sprites(ThisIMage)

   local ProjectX#=400
   local ProjectY#=400
   
   local Width   =getImageWidth(ThisIMage)
   local Height=getImageHeight(ThisIMage)
   local Width2=Width/2
   local Height2=Height/2

   local ScreenWidth=GetScreenWidth()
   local ScreenHeight=GetScreenHeight()
   
   local scx=ScreenWidth/2
   local scy=ScreenHeight/2
   
   local Pad=50            
   
   local lp, MaxZ=3000
   
   Local Speed=8
   Local Sx#,Sy#
   For lp =0 to GetArrayElements(Sprites())
   
         if Sprites(lp)=0
            Sprites(lp)= New tSprite
            
            Sprites(lp).x = rndrange(Pad,screenWidth-Pad)-scx
            Sprites(lp).y = rndrange(Pad,screenHeight-Pad)-scy
            Sprites(lp).z = rnd(MaxZ)
            
            Sprites(lp).TintColour =rnd($ffffff)|(rnd(128)<<24)
            repeat
               sx# = rndrange(-Speed,speed)
               sy# = rndrange(-Speed,speed)
            until sx#<>0 and sy#<>0
            Sprites(lp).SpeedX=sx#
            Sprites(lp).SpeedY=sy#
            
         endif
   
         local z#=Sprites(lp).z-5

         if z#<pad
            z#=MaxZ
            Sprites(lp).x = rndrange(Pad,screenWidth-Pad)-scx
            Sprites(lp).y = rndrange(Pad,screenHeight-Pad)-scy
            Sprites(lp).z = z#
         endif
         Sprites(lp).z=Z#

         local x#=Sprites(lp).x
         local y#=Sprites(lp).y
         
         local Scaler#=ProjectX#/z#
         
         local x1#=(((x#-Width2))*Scaler#)
         local x2#=(((x#+Width2))*Scaler#)
         local y1#=(((y#-Height2))*Scaler#)
         local y2#=(((y#+Height2))*Scaler#)

         g2dDrawScaledImage( ThisImage,scx+x1#,scy+y1#,scx+x2#,scy+y2#, Sprites(lp).TintColour,1+8)
   next
      
EndFunction
      
[/pbcode]

      Obviously there's a lot of work for the runtime to do driving all the objects from the debug runtimes,  so converting it to a perspective sprite scene should get rid of a lot of that, in particular when this build G2D is compiled to DLL.  


   Edit #1

       Ok, it's mid afternoon now and i've just built the DLL version of the library and have discovered something I'd hoped would happen, but didn't want to preempt it..   Which is that today's build of the G2D DLL through PB2DLL is faster, than PBFX GL DLL built from VisualStudio  (pro edition) - This is surprising as I was expect them to be about the same, but this comes as a very pleasant surprise !

       The second picture is show "test #13" from the basic 2d demo that comes with the G2d proto's.   Obviously the  machine code dll version is quicker than running the test code through the PB runtimes..  The previous picture was drawing something like 2000 sprite rects at 30fps.. (on 9 year old computer :) ) .  The machine code version lets us run 5000 sprites in the perspective scene (Z sorted) at 42/43 fps on the same system.   Which is about 8% quicker than what the same demo runs in PBFX and original GL library..  



    Edit #2 - Released

          Uploaded the 6th generation of the library..    Have fun..

   [plink]  G2d Download (http://www.underwaredesign.com/forums/index.php?topic=4210.msg28506#msg28506)[/plink]


Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 15, 2014, 11:47:21 PM

  G2D - Perspective Map Rendering

        Today's little exercises have been two fold,  first issue was to clean up the map drawing code so it's a bit more modular and can be reused a little more easily and then introduce a perspective map rendering method (G2dDrawMapToCamera) .    The routine builds/draws a version of the mesh from the camera perspective / rotation. 

        In attachments bellow the grey looking thing is actually a map that's being drawn relative to the viewer with all the bubble scene stuff in the background.   There's a few odds and ends to clean up with the code, but with allow you you use the G2d camera and follow a character,  zoom in/out and of course rotate the camera view. Rotation is only support in perspective mode for the time being, but it should work the same in Flat mode also..   

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 21, 2014, 12:26:38 AM
 G2D - Perspective Sprite & Map Rendering (Continued)

     Back toying with the G2d library this afternoon after doing some mowing,  when I last looked at the code it was basically set up and running but there was some magic numbers and some strange differences between the sprite rotations and the map rotations, which seem to have been worked out now.  While messing around with a few little math tweaks here and there to remove unwanted divisions and strip any magic numbers from inner loops, but nothing too major.

     In terms of tweaking, I haven't really been focusing on it,  much rather get it worked and be easy to modify,  than have to get round some optimization that might make something else cumbersome to implement later on.    There's some obvious things to do though, for example,  map render code doesn't current have any clipping, or stuff like reducing the number of draw calls for example..    

     Feature wise there's a number of little tidbits that come to mind, such as particle batching,  Text formatting / batching / rotation through to higher level entity controller stuff.    But given the lack of interest thus far, I can't say they'll make an appearance or not..    

    Attached: Perspective Map & Sprite
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: monkeybot on October 21, 2014, 12:12:24 PM
is this G2D malarky to enable the transition to web based output?
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 22, 2014, 07:01:22 PM
  
Quoteis this G2D malarky to enable the transition to web based output?

    Sorta..  Although It's not directly intended for that, it's more a stepping stone towards going GL.    Obviously having a GL rendering option opens lots of doors that DX doesn't.  

   The method i've been tinkering with to translate PB-> JS/HTML5 doesn't require GL at all.   The concept is much the same though, there's a high level set of functions that the user builds their program against, and then a translator builds the equivalent JS from the ByteCode.   There's a some structural issues that are by product of JS's , but you get that.    


  G2D - Prototype # 7 Released  - Tweaks and things
   
    My main computer was crashing a lot yesterday,  I think it's overheating again as my office gets pretty hot, even this time of year.    None the less ,dumped yesterdays build of the library, which has some camera changes (new commands) and few little opt's and tweaks from the previous builds.    Interestingly, it runs the bubble demo another 5 fps faster.  Making it substantially quicker than the PBFX library on the same hardware.  

    Will try hooking up some more draw modes this afternoon.

   [plink] Download G2D Revision #7 (http://www.underwaredesign.com/forums/index.php?topic=4210.msg28520#msg28520)[/plink]

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 24, 2014, 07:28:13 PM

  G2d - Particles and all the small things

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

       Particle effects are useful in so 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 solution in.   

       Control wise different effects need different controls per particle, stuff like controlling speed / gravity / scale / rotation / image / Randomization etc would 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. 

      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 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.       
   
      Even with such control there would still be situations where the user need to roll their own.. But ya get that !

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 02, 2014, 10:14:37 PM
  G2d - Particles Script / Controller
 
   Now things are on a more even plane I can get back to particles, or more importantly particle scripting.   So far I've got a very crude frame work for creating the script code and executing it.   The current concept is that while each particle is it's own entity, the controller script is uniform to the set.   So the user therefore has to initialize the particle with it's default values.   You know giving it a position, speed.. that sorta thing.    Now given that scripts allow you to add extra local variables to the particle structure, this could get pretty confusing to set up.  So what've been thinking above is that each script has a type of creation/deletion script that user defines.  

   At this point, I've absolutely no idea what a script could look like are even what operations are requires beyond things like move + math operations.  Code wise they'd most likely be single operation per line stuff.   Which you may not be familiar with, but it's easier to parse and quicker to put together.  Don't particular want to invest a lot of time in it.

   Mock up script ideas:



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

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


; function is called after object allocated
function New()
   
  ; set the objects starting position from that of the parent
  move(pos, Parent.pos)

  ; set our speed vector to  X=0, Y =1
  set(Speed, 0,1)

  ; randomize this vector, So each field is   X=X*rnd(1), Y =Y*Rnd(1)
  Randomize(Speed)


  ; set vector to 0,0.99
  set(SpeedScale, 0,0.99)


EndFunction



; Function  called when objects motion is 'updated'
Function Update()
 

    ; Adds the Speed vector to Position vector
   Add(Pos,speed)

    ; Scale the speed vector down by our scaling vector, so the object appears to slow down over time.
   Mult(speed,SpeedScale)


EndFunction



; Function  called when object is deleted
Function Free()
 

EndFunction

EndScript







Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 03, 2014, 09:35:04 PM
 G2d - Particles Script / Controller Cont.

   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


Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 04, 2014, 06:59:34 PM

  G2d - Particles Script  Compiler

        Started work on the particle script compiler last night and by started work,  I mean began moving some existing code around to do the job, in this case the DTAB SCRIPT lexer.   DTAB script is a mini language built into DTAB for parsing text documents, that language is cut into three parts a lexical scanner (Tokenizer), a compiler and the VM / Runtime.   I don't need all of it, just the lexical scanning part, could write it again, but this code is mature enough to be considered stable.    I'm sure there will be issues from  porting the code from VB to PB, but it seems to work the same from my tests so far.

         The lexical scanner just builds a token representation of the input source code, the tokens are pretyped so the compiler process can focus on applying syntax rules to the set. 
       
        The following junk document lex's in about 80 milliseconds when running the library in plain PlayBASIC, which is plently fast enough as is really when you consider the side of this junk document, but really the Machine code version will further stomp on that, so it's pretty reassuring!   
 


; ------------------------------
;  Global variables
; ------------------------------
;    PageURL = The full URL of this page
;    RawPage = THe entire document
;  PageTitle = The Title string from the page

;-----------------------------
;  Return Variables
;-----------------------------
;     SongName = The Number of the name
;   ArtistName = The Number of the name
;   TabberName = The Number of the name


; -------------------------------------------
var VectorType,Vector_X,Vector_Y,Vector_Z
; -------------------------------------------

; Allocate the Data Structure
VectorType=NewType("Vector3D")

; Append fields to the structure
Vector_X=AddField(VectorType,"X","INT")
Vector_Y=AddField(VectorType,"Y","INT")
Vector_Z=AddField(VectorType,"Z","INT")

; -------------------------------------------
; -------------------------------------------
; -------------------------------------------


Var MyArray,lp  ; -------------------------------------------


MyArray=NewArray("CoolStuff",VectorType)

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next



; ------------------------------------
; Display the contents of the array
; ------------------------------------

For lp=1 to 20
print("#"+lp)

; check if allocated
if (Get(MyArray,0,lp))
print(Get(MyArray,Vector_X,lp))
print(Get(MyArray,Vector_Y,lp))
print(Get(MyArray,Vector_Z,lp))
endif
next

print(Vector_X)
print(Vector_Y)
print(Vector_Z)




  var StartPos,EndPos,TabbedByStart,TabbedByEnd,Tag
   
        ;---------------------------------------------------------------------------------------
        ;Bring Me To Life Drum Tab by Evanescence | Tabbed by Billabongpro |  MXTabs.net
;Eye Of The Tiger Drum Tab by Cky | Tabbed by bjork |  MXTabs.net
        ;-------------------------------------------- -------------------------------------------
        ;-------------------------------------------- -------------------------------------------
        If (InStr(PageTitle, "MXTabs.net",1)>0)
        ;---------------------------------------------------------------------------------------
        ;-------------------------------------------- -------------------------------------------

    print("Max Tabs Page")
           

            Tag = "drum tab by"

            EndPos = InStr(PageTitle, Tag,1)

            If (EndPos>0)
                EndPos = EndPos - 1
                StartPos = 1
                SongName = Trim(left(PageTitle, endpos))
                Print( "Song:" + SongName)
            EndIf


    if (Html_LocateTags(PageTitle, Tag, "|", 1,StartPos,EndPos)==1)
                StartPos = StartPos + Len(Tag)
                ArtistName = Mid(PageTitle, StartPos, EndPos - StartPos)
                ArtistName = Trim(ArtistName)
                Print( "Artist:" + ArtistName)
    endif

            Tag = "Tabbed by"

            TabbedByStart = InStr(PageTitle, Tag,1 )
            If (TabbedByStart > 0)
                TabbedByEnd = InStr( PageTitle, "|",TabbedByStart)
                If (TabbedByEnd > TabbedByStart)
                    TabbedByEnd = TabbedByEnd - 1
                    TabbedByStart = TabbedByStart + Len(Tag)
                    TabberName = Mid(PageTitle, TabbedByStart, TabbedByEnd - TabbedByStart)
                    TabberName = Trim(TabberName)
                EndIf
            EndIf

    goto Done

endif



done:


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next



For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

print(lp)
For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next



For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next


For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next



For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

print(lp)
For lp=0 to 10
; turn this structure on
Set(MyArray,0,lp,1)

; fill in the fields
Set(MyArray,Vector_X,lp,1000+lp)
Set(MyArray,Vector_Y,lp,2000+lp)
Set(MyArray,Vector_Z,lp,3000+lp)
next

print("End of Program")



   

   NOTE: The Particle scripts won't look like this, since I'm not porting the DTAB compiler, rather going to knock up one which will most like be operation based like the previous examples.



Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 05, 2014, 11:06:29 PM

  G2d - Particles Script Compiler Cont.

            Well put a bit more time into the compiler parse and have got it to point where's it's able to parse and understand the basic operations in the particle script.    Speed wise it's constantly  doing this in  4->5 milliseconds without even converting the library to machine code, I'd say it'll probably max out at about 10->15 milliseconds per script when it's also generating the particle byte code.   That's faster by a factor of 20 times than the VB version when running it from the PlayBASIC.    But no big surprises there though.   

            Anyway, bellow we have pic showing the text document in notepad and the parsers  results in the PB window...  Not pretty to look at, but progress.  I'd say that later on tonight the code generation will be in and it'll be able to compile and run the scripts in the Particle VM.. 




; ---------------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------------
; 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




         
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 07, 2014, 07:42:57 AM
  G2d - Particles Script Compiler Running.

       This morning was spent pulling all the little threads together, so now a very crude and raw version of the parser/compiler is up and running.  Which means in the test bed demo the user can alter the external script, hit space to recompile the script and see the new behavior.   The compiler has some limited error checking but nothing like what you'd find in PlayBASIC itself.    Speed wise it'll load/compile the test script in about 5->6 milliseconds on average.    Which is obviously fast enough, but there's plenty of room left for opt'ing if scripts get bigger.. In other words there's lots of string thrashing that can be removed pretty easily.
 
       The language is action/operator based, so far there's only support for one variable type, which is vector3.   All actions are preformed on user variable or internally defined variables. In the current build of the test bed, each particle has it's own Position & Scale, Rotation.   The last two aren't used in demo since we're drawing the particles as regular PB dots (DOT Particle.X,Particle.Y).   In G2D though, we'll be drawing them as batches of quads. As such, we'll need control over the current frame.   It's really bad performance wise to use different textures for each particle (doesn't batch), so particle frames would need to be UV mapped from the same source image.  Which just means putting the frames in the row by column format.  

       It might be working but there's still a number of issues to iron out of course, from stuff like what instructions scripts need (bare minimum) through to the bigger picture stuff like how the users controls particle groups.    The current test bed demo (main loop bellow) it's a little too low level for most people, as i'm actually calling the methods and drawing the dots manually.   In theory such an interface could be exposed, but It'd be better if all the magic happened inside the library.      

[pbcode]

      local Filename$ ="Scripts/Particle-Test-Script.txt"

      local SourceCode$=LoadFileToString(Filename$)   

      if len(SOurceCode$)<1
            Print "Can't find file:"+Filename$
            print "press any key to exit"
            sync
            waitkey
            end         
      endif
      

      dim MyScript as Particle_Controller_BYTE_CODE pointer

      Dim objects as PB_USerParticle list

      local lp,FireTime
      
      local SpawnFreq,SpawnCount
      
      SpawnFreq   =100
      SpawnCount   =50
      
      ; --------------------------------------------------------------------------------
      ; --------------------------------------------------------------------------------
      ; --------------------------------------------------------------------------------
      ; --------------------------------------------------------------------------------
      ; --------------------------------------------------------------------------------

      Do
            ; draw shaded backdrop
            shadebox 0,0,getscreenwidth(),getscreenHeight(),$304050,$304050,$806030,$806030
            setcursor 0,0

            if int(MyScript)=0 or spacekey()=true or EnterKey()=true

                     ; redim the particle objects list
                     Dim objects as PB_USerParticle list
                     ink -1            

                     print "Compiling Source Code:"
                     local t=timer()

                        local SourceCode$=LoadFileToString(Filename$)   
                        MyScript=Particle_Script_Compiler(SourceCode$)
                     print "Compile Time:"+STR$(timer()-t)
                     print "Press any key"
   
                     sync
                     flushkeys
                     waitkey
                     waitnokey

            endif
            
            if int(MyScript)
      
               if MyScript.Status
   
                  if FireTime<Timer()
                        FireTime=Timer()+rndrange(SpawnFreq*0.1,SpawnFreq)

                        for lp=1 to rndrange(SpawnCount *0.1,SpawnCount)
                              Objects = new PB_USerParticle
                              ; init the particle structure with out script
                              Paricle_Execute_Script(MyScript.NewFunctionPtr, GetLIstPtr(Objects()))
                        next
   
                  endif

                  lockbuffer
                  ink -1
                  For each Objects()
                        if Paricle_Execute_Script(MyScript.UpdateFunctionPtr, GetLIstPtr(Objects()))
                              ;centertext Objects.Pos.x   ,   Objects.pos.y   ,   "
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 09, 2014, 09:31:18 AM

  G2d - Particles Script Compiler - Local Rotations/Scaling/Animations

       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 rottaiotn 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






   
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 12, 2014, 07:23:51 PM
  G2d - Particles Script Compiler - Classes & Controller / Emitters

       Since touching base last time, I've been mulling over the structure of the components in the library.   The initial versions could only load a single particle script from a document, this has been updated to load as many particle classes from the one file as need be.   If there's an error at any point, it'll stop and give you some type of generic WTF error.   It's reasonably fussy about the structure, but you can still get away with a lot at the moment.    Previously the compile script function would return a pointer a last compiled class, it no longer does this, in favor of returning the ERROR STATUS. So if there was an error you'll get some none zero value..    Then you'll most like use some type of query error functions to work out what and where the error was.  These don't currently exists as it just bumps this to the screen.. :)

       The class structure is the particle behaviors, next we need something to control the groups of particles spawned through any emitter and it's orientation.   There's still a bit of grey area here, but the general idea is the user will create an emitter of a certain class, which you can selectively render , update, kill off or ignore at will.    If you think about it, some types of emitters only need to be active when visible in the scene.    Since you control what's visible the library can't magically know this for you.  

       Function set wise we'll probably end up with something like this.


 
       ParticleGroupIndex = NewParticles(ClassName$)    ; Create Emitter

       DeleteParticles ParticleGroupIndex    ;  Kill emitter

       ParticlesImage ParticleGroupIndex, TextureImage    ;  Set the Image/Texture ID this group will be using.

       Status=GetParticleStatus(ParticleGroupIndex)   ; Is this emitter alive ?


       SpawnParticles ParticleGroupIndex,  ParentStructure, Count   ;  Spawn a batch of new particles. These call the Classes NEW() function and would use the parentstucture to set the particles defaults  (Not 100% sure on this yet !) - The count is the number of new particles should be created per call.  

       UpdateParticles ParticleGroupIndex    ;  Step forward the particles uses the Classes logic.

       DrawParticles ParticleGroupIndex    ;  Draw this group as quads using the groups texture to screen.

        DrawParticlesToCamera ParticleGroupIndex, Camera    ;  Draw this group as quads using the groups texture to camera.



       So the whole idea is to remove the user from man handling particle data on a one to one basis, all you'd be doing creating emitters, calling the spawner and telling it render this batch if need be.    You could also render a batch yourself, for that we'd have some functions to query the quantity of particles within a group.  Then step through and grab pointers to the 'public' variables from each particle object.   There's nothing stopping you from accessing the private variables really, it's just the pre-defined structure can only define the particles known interior at compile time.

       Anyway.. Today's little task is set up some emitter functions and see if we can get this running.  I suspect it'll take a few revisions to tweak out the command set, but I think of lot of that can be done as it's integrated in the main library.   

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 14, 2014, 09:04:42 PM
 G2d - Programmable Particles - Controller / Emitters

    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.


[pbcode]


      local Filename$ ="Scripts/Particle-Test-Script.txt"

      local SourceCode$=LoadFileToString(Filename$)   

      if len(SOurceCode$)<1
            Print "Can't find file:"+Filename$
            print "press any key to exit"
            sync
            waitkey
            end         
      endif
      
;
      local lp
      
      Dim BallImages(16)
      local BallImage =CreateBallImage(16)
      
      for lp=0 to 16
            BallImages(lp)=CreateBallImage(24)
      next
      
      Global FXScreen = NewImage(GEtScreenWidth(),GetScreenHeight(),2)
      
      Local Filter=1+8
      
      
      
      
      Type tSpawner
            ParticlesHandle      
            SpawnFreq
            SpawnRate
            NextSpawnTime   
            ThisImage
      EndTYpe
      

      Dim SPawners as tSpawner list
      
      
      Local COmpileParticleScripts = true
      
      
      ; --------------------------------------------------------------------------------
      ; --------------------------------------------------------------------------------
      ; --[MAIN LOOP]------------------------------------------------------------------------------
      ; --------------------------------------------------------------------------------
      ; --------------------------------------------------------------------------------

      Do

            ; draw shaded backdrop
            rendertoimage FXSCREEN
            shadebox 0,0,getscreenwidth(),getscreenHeight(),$304050,$304050,$806030,$806030
            setcursor 0,0

            ; -----------------------------------------------------------------
            ; -----------------------------------------------------------------
            ; -----------------------------------------------------------------
            if   COmpileParticleScripts = true
            
                     ink -1            
                     print "Compiling Source Code:"
                     local t=timer()

                        local SourceCode$=LoadFileToString(Filename$)   
                        
                        ; remove all existing controllers
                        DeleteAllParticleClasses()
                        
                        print Particle_Script_Compiler(SourceCode$)

                        print "    Compile Time:"+STR$(timer()-t)
                        print "PRess any key"
   
                        Show()   

                     local myParticles=NewParticles("Gravity Explosion")
                     ParticlesSpawnPosition(MyParticles,rnd(800),rnd(600))

                     ; create 10 spawners
                     for lp=1 to 5
                           local Handler=NewParticles("Gravity Explosion")
                           if Handler
                              SPawners = new tSpawner
                              Spawners.ParticlesHandle=Handler
                              Spawners.SpawnFreq = rndrange(50,150)
                              Spawners.SpawnRate = rndrange(10,20)
                              Spawners.ThisImage = CreateBallImage(20)
                              ParticlesSpawnPosition(Handler,rnd(800),rnd(600))
                           endif
                     next

                     COmpileParticleScripts = false
                     
                     flushkeys
                     waitkey
                     waitnokey

            endif
            
            ; -----------------------------------------------------------------
            ; -----------------------------------------------------------------
            ; -----------------------------------------------------------------

                  if Spacekey()=true
                        COmpileParticleScripts = true
                        flushkeys
                  endif
                                       

                  lockbuffer
                  inkmode 1+64
                     For each Spawners()
                           if Timer()>Spawners.NextSpawnTime
                              Spawners.NextSpawnTime=Timer()+rndrange(Spawners.SpawnFreq*0.1,Spawners.SpawnFreq)
                              SpawnParticles( Spawners.ParticlesHandle,0,rndrange(Spawners.SpawnRate*0.1,Spawners.SpawnRate))
                           endif

                           UpdateParticles(Spawners.ParticlesHandle)
                           
                           RenderParticles(Spawners.ParticlesHandle,Spawners.ThisIMage)
                     next


                        Dim Spawner as PB_Particle pointer
         
                     SpawnParticles( MyParticles,0,10)
                     UpdateParticles(myParticles)
                     RenderParticles(myParticles,BallImage)
                     ParticlesSpawnPosition(MyParticles,mousex(),mousey())

                        Spawner=GetParticlesSpawnPtr(MyParticles)
                        inkmode 1+32
                        circlec Spawner.pos.x,Spawner.pos.y,10,true,$ff30ff
                        inkmode 1                                                

                  inkmode 1
                     

                  ink $ffff0000
            
                  print "Spawners In Scene #"+Str$(GetLIstSize(Spawners()) )
                  ink -1
                  For each Spawners()
                        print "Handle#"+str$(Spawners.ParticlesHandle)+ "   ClassName:"+GetParticlesClass(Spawners.ParticlesHandle)
                        print " Used ["+str$(GetParticlesUSed(Spawners.ParticlesHandle))+"] - Free ["+str$(GetParticlesFree(Spawners.ParticlesHandle))+" ]"
                        print ""
                        
                        
                        Spawner=GetParticlesSpawnPtr(Spawners.ParticlesHandle)
                        inkmode 1+32
                        circlec Spawner.pos.x,Spawner.pos.y,10,true,$ff3020
                        inkmode 1                                                
                  next
                     
                  ink -1
                  unlockbuffer

               ShowParticleClasses(GetScreenWidth()-250,2)
      
      
      
      
               if GetScreenFocus()=false
                     repeat
                        wait 200      
                              sync   
                     until GetScreenFocus()=true
               else
                     Show()
            endif
      loop      






Psub Show()
               RenderToScreen
               DRawImage FXSCREEN,0,0,false
               Sync
               rendertoimage FXSCREEN
EndPsub





Psub ShowParticleClasses(Xpos,Ypos)

      local Ypos,YRow=GetFontHeight(GetCurrentFont())
      local lp
   
      ink $ffff0000
      Text XPos,Ypos,"Particle Classes"      
      ink -1
      
      for lp =1 to GetParticleClassQuantity()
            if GetParticleClassStatus(lp)
               Ypos+=YRow

               Text Xpos,Ypos,"# "+str$(lp)+" ="+GetParticleClassName$(lp)
            endif            
      next

EndPsub



[/pbcode]


     This is just plain old PlayBASIC code..  Will start migrating it into G2D over the weekend I think..  



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

 



Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 18, 2014, 11:22:50 AM

G2d - Programmable Particles - Optimizing the Particle VM

     Now the the library seems to be working pretty well it's time to expand the instruction set and data types.   The existing versions of the particle VM is written in PlayBASIC and running in PlayBASIC, so it's not necessarily written to be fast at all, just easy to put together.   Which means the VM inner loop is basically a select/case statement.  Where it grabs an opcode, falls through to find the opcode case - performs the action, then repeats the process.  If a particle script contains 10 operations then it's doing this 10 times per particle.   So when there's a few 1000 particles on screen a lot of overhead was being lost in just good old lazyness. 

     The  Select CASE are fine generally, but a better solution is to use the ON GOTO /GOSUB caller block, since those are fixed cost per instruction.    Which means the PlayBASIC VM can call any opcode from the table in the same time, where it can't for select case statements. 

     So a mock up VM using ON GOTO looks a bit like this





; -----------------------------------------------------------------------
do
; -----------------------------------------------------------------------
DecodeINstruction:
opcode=Instruction.OPcode

; Jump to the this opcodes decoder

on Opcode goto OPcode_END ,OPcode_SetVector3 ,OPcode_MOveVector3 ,_
OPcode_AddVector3 ,OPcode_SubVector3 ,OPcode_MultVector3 ,OPcode_DivVector3,_
OPcode_CMP ,OPcode_RANDOMIZE ,OPcode_SetSTatus ,OPcode_BNE,OPcode_JMP


; -----------------------------------------------------------------------
; ERROR UNKNOWN OPCODE
; -----------------------------------------------------------------------

print "FAILED Opcode#"+str$(opcode)+"  PC#"+Str$(SpriteByteCodePtr)+" Is undefined"


; -----------------------------------------------------------------------
; END OF SCRIPT
; -----------------------------------------------------------------------
Opcode_END:

#print "End PC:"+Str$(int(instruction))

exitdo



Opcode_SetVector3:

           ;code to solve this operation goes here,  then you GOTO back to the START to keep decoding

             ; move opcode pointer forward to the next instruction, so this opcode uses 12 bytes of data
             Instruction+=12

              goto DecodeINstruction



Opcode_MoveVector3:

             ; move opcode pointer forward to the next instruction, so this opcode uses 16 bytes of data
             Instruction+=16

              goto DecodeINstruction

etc etc
; -----------------------------------------------------------------------
Loop
; -----------------------------------------------------------------------




     So our program is not wasting a single PlayBASIC VM cycle doing superfluous operations. Speed wise this loop is about 4->5 times faster than original.   But that's not the best thing, PlayBASIC2DLL includes this special optimization in it, mean it's running many times faster again. 


Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 20, 2014, 10:41:18 AM
  G2d - Programmable Particles DLL version

    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      

   Screen Shot:

     IN the picture we're seeing a scene with 90 particle emitters which in total are controlling over 10,000 individuals particles.  Each particle is running the Gravity Script shown previously.  


[pbcode]

Function Render_Test_Particle_Scene()

                  if enterkey()
                  
                     ; create 10 spawners
                     local SpawnTime=Timer()
                     for lp=1 to rndrange(1,5)
                     #print "Doing this"
                           local Handler=NewParticles("Gravity Explosion")
                           if Handler
                              SPawners = new tSpawner
                              Spawners.ParticlesHandle=Handler
                              Spawners.SpawnFreq = rndrange(50,150)
                              Spawners.SpawnRate = rndrange(20,100)
                              Spawners.ThisImage = CreateBallImage(16)
                              
                              Spawners.StartTime = timer()+(lp*250)   ;rndrange(1000,5000)
                              Spawners.EndTime = Spawners.StartTime+rndrange(1000,5000)
                              ParticlesSpawnPosition(Handler,rnd(800),rnd(600))
                           endif
                     next

                     #print "SPAWN TIME:"+STR$(TImer()-SpawnTime)
                     flushkeys                  
                  
                  endif                                    


                  rendertoimage FXScreen
                  
                  cls 0

                  lockbuffer
                  inkmode 1+64
                  local CurrentTime=Timer()
                  
                  
                     For each Spawners()

                           if CurrentTime>Spawners.StartTime
                              if CurrentTime>Spawners.NextSpawnTime
                                 if CurrentTime<   Spawners.EndTime and Spawners.SpawnRate>0
   
                                       Spawners.NextSpawnTime   =CurrentTime+rndrange(Spawners.SpawnFreq*0.1,Spawners.SpawnFreq)
                                       SpawnParticles( Spawners.ParticlesHandle,rndrange(Spawners.SpawnRate*0.1,Spawners.SpawnRate))

                                       Spawners.SpawnFreq+=10
                                       Spawners.SpawnRate-=2
                                 else
                                       if GetParticlesUsed(Spawners.ParticlesHandle)<1
                                          DeleteParticles(Spawners.ParticlesHandle)
                                          DeleteIMage Spawners.ThisIMage
                                          Spawners = Null
                                       endif

                                 endif
                              endif

                              UpdateParticles(Spawners.ParticlesHandle)
                           
                              ;RenderParticles(Spawners.ParticlesHandle,Spawners.ThisIMage)
                              
                           endif
   
                     next
               inkmode 1         
               unlockbuffer


                  Local TotalParticlesInScene=0
                  setcursor 0,50
                  ink -1
                  
                  Dim Spawner as Pb_Particle pointer
                  For each Spawners()
                        if CurrentTime>Spawners.StartTime
                  
                           print "Handle#"+str$(Spawners.ParticlesHandle)+ "   ClassName:"+GetParticlesClass(Spawners.ParticlesHandle)
                           print " Used ["+str$(GetParticlesUSed(Spawners.ParticlesHandle))+"] - Free ["+str$(GetParticlesFree(Spawners.ParticlesHandle))+" ]"
                           print ""
                        
                           TotalParticlesInScene+=GetParticlesUsed(Spawners.ParticlesHandle)
                           
                           Spawner=GetParticlesSpawnPtr(Spawners.ParticlesHandle)
                           inkmode 1+64
                           circlec Spawner.pos.x,Spawner.pos.y,20,true,$ff3020
                           inkmode 1                                                
                        endif
                  next

                  setcursor 0,0
                  print "      Spawners In Scene #"+Str$(GetLIstSize(Spawners()) )
                  print "Total Particles In Scene#"+str$(TotalParticlesInScene)
                     
                  ink -1
                  unlockbuffer


               rendertoscreen
               drawimage FXscreen,0,0,false
               sync
EndFunction

[/pbcode]
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 21, 2014, 08:27:00 PM

G2d - Programmable Particles - 17000 thousand test scene.

       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)

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on December 27, 2014, 10:01:17 AM
   G2D - 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

    Get Update (http://www.underwaredesign.com/forums/index.php?topic=4210.msg28606#msg28606)


Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on May 07, 2015, 12:12:12 PM
   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.



  Idea Pad

         One of the ideas I've been kicking around in the down time is about introducing some type of FRAME settings to either PB sprites or just the G2D library.   The concept is that the frame list houses common properties together within it.    Those being the source texture ( image) as well as the coordinates within that image that a particular frame exists.  This would mean we could load an image that contains many frames and use the frame definitions to define individual images within the original image (aka a texture atlus).     Now this  could be part of the image, but then there's limitation on custom properties.   Like if you wanted the frames in a different palette you'd need to load a second copy of the texture.    

         Now of course i dunno what such a command set(s) would look like, but it could mean you'd simply use a SpriteFrame styled command to set a sprites, Image / UV's / colouring/handles/scales from that defined frame in one go.    So to make an animation, you step through the frame sequences you want.      Alternatively you load an image and tell it to define a sequential run of frames from it at some evently spaced interval,  Or just have that as separate command for that.


        ; normal image load as
         FrameSheetImage=LoadNewIMage("exploision.png")

       ; where in the global frame heap to store this set of frames
         FrameIndex = 100

       ; run through source image and make a frames from the source image.  
         FrameIndex=CreateFramesFromIMage(FrameIndex,FrameSheetImage, FrameWidth,FrameHeight)



       so a frame is really just a list of properties about a section of the source image,  and since groups of frames can be defined with a single or across images this is more optimal for hardware acceleration, as ideally then we can use large atlus textures with lots and lots of frames on them, rather than lots of seperate images.  Which is fine in direct draw/software rendering world, but not so for open GL.  Although even with separate textures it still works very well..  


      Edit: added screen shot of circles and ellipses

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on May 15, 2015, 01:03:02 AM
  G2D - Prototype # 11 - Mapping Fixes- Xenon 2000 Open GL

      Been fiddling with G2D a bit and figured I'd try and remake a openGL version of the original legacy Xenon 2000 tech demo.  For those that don't remember, that's one of the very first PlayBASiC demos ever made and uses the Bitmap brothers artwork form their Xenon reboot back into 2000.   The PlayBASIC tech demo wasn't a game, more a proof of concept and included a bunch of standard PB features some of which are G2d friendly and some that probably aren't, but the only way to find that stuff out is by actually doing something.  

      The first task was to create a new project and copy the media from the legacy demo across (just search for Xenon), next we copy the G2D files into the folder (Dll and bindings include) and we're done.   Once we've made a project ,  then we can kick on to show a  g2D represent get the map.  The original demo uses a couple of map layers for parallax backdrops,  so O simply skimmed  through the old code and pulled out the map loading code.   Jazzed the code up a little, since it was written back in the dawn of PlayBASIC and the mapping commands have changed somewhat over the past decade.   But really the changes are just simple things like using dynamic media allocations and building a FX map directly from the input image in memory, rather than the legacy method of from the video device (see slow, RTFM for why)

      So initially when using the prototype #10 of G2D, the code wasn't running the same as the internal PB command set, so the two would produce a different output completely, namely in what blocks  G2D library would treat as being transparent, solid or empty.   This turned out to be a by product of the per block transparency stuff that was added to PB a bunch of years ago which the G2D library wasn't bothering to utilize when the drawing a map/layer,  but after adding some tweaks we get the same output.  

      Bellow is the current code as well as the  standard testing screenshot for such demos.  So on top we see the OPEN GL version and bellow the DirectDraw version.   Since we're drawing both together,  it's impacting on the frame rate a lot,  as the GL demo runs about 550-600fps (10 year old system)  so it's inside a 2 millisecond refresh.    But it's handy for testing  stuff like this.  



[pbcode]


/* -----------------------------------------------------------------------------      
  -----------------------------------------------------------------------------      
      ----------------->> XENON 2000 mock up in G2D <<--------------------      
  -----------------------------------------------------------------------------      
  -----------------------------------------------------------------------------      

      This demo is another recreation of the Xenon 2000 demo but this time using the
   G2D for the rendering.  The purpose of the demo si to wedd out as many differences
   in the library as possible.
   
  -----------------------------------------------------------------------------      
*/

      // include the G2D library
      #include "G2D_Library.pba"

      // set the screen title
      TitleScreen "G2D - Xenon 2000"


      // First up, we open GL library.. With our screen size and
      Dim GL as tMyGL pointer
      GL=G2DStart(GetSCreenWidth(),GEtScreenHeight())
      if int(GL)   

            ; push the direct X screen to the bottom (almost off the screen)
;            ScreenLayout 0,GetSCreenHeight(),GetScreenWidth(),GetSCreenHeight()+1
            ScreenLayout 0,GetSCreenHeight()/2,GetScreenWidth(),GetSCreenHeight()+1

            // clear the OPenGL Screen
            g2dCls($304050)

            // flip GL buffer (back to front)
            g2dsync()


            // load the map and level raw level block data                                 
            ThisMap,XenonMapBlockImage=Load_And_Prepare_Map()




            // the maps are huge as set the offset to come place we can see something
            Global MapY_Starting_Position=1000*32

            local ypos#=(-MapY_Starting_Position)


            G2dLOadFont("Veranda",10, 24,0)

            setfont 10
            G2dSetFont 10


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

                  CurrentFPS=fps()

                  // ----------------------------------------------------------
                  ; clear Open GL screen
                  // ----------------------------------------------------------
                  g2dCls($304050)

                  ; draw thew map blocks to gl screen, mouse toggle transpraent/solid
                  g2ddrawimage XenonMapBlockImage,50,50,mousebutton()

                  ; draw the map level             
                  g2ddrawmap ThisMap,0,00,ypos#,XenonMapBlockImage

                  g2dprint(Str$(CurrentFPS))

                  g2dsetcursor 0,0
                  g2dprint("G2D display (OPEN GL)")            
                  g2dsync()


                  // ----------------------------------------------------------
                  ; draw direct draw version
                  // ----------------------------------------------------------
                  cls $5544   
                  drawmap ThisMap,0,000,ypos#
                  print("Direct Draw ")            

                  sync
                  Ypos#+=1            
            loop

            sync
            waitkey

            g2dEnd()
      
      endif



      


   // --------------------------------------------------------------------------
   // --------------------------------------------------------------------------
   // --------------------------------------------------------------------------
   // --------------------------------------------------------------------------

Function Load_And_Prepare_Map()

   ` *========================================================================*
   `                 CREATE And LOAD MAP GFX / level Data
   ` *========================================================================*

      ; ===================================================
      ; CReate Map & And MAP Levels/Layers      
      ; ===================================================

      ThisMap=NewMap(2)

      ThisImage=Loadnewimage("Media\Blocks.bmp",2)
      
      MakeMapGFX   ThisMap,ThisImage,32,32,1024,$ff00ff,2

         ; ===============
         ; Create Layer #1
         ; ================
      
         CreateLevel ThisMap,0,20,2000
         LevelTransparent ThisMap,0,000
         LoadLevelTiles("Media\Levels\Xenon2000_layer1.Mar",ThisMap,0,20,3000)

         ; ===============
         ; Create Layer #2
         ; ===============

         CreateLevel ThisMap,1,20,1000
         LevelTransparent ThisMap,1,000
         LoadLevelTiles("Media\Levels\Xenon2000_layer2.Mar",ThisMap,1,20,3000)


         
         
            // since this image used mask colour transparency, we we'll need this image is
            makealphachannel(THisImage,$00ff00ff)

            // make this image into a parallel Open GL texture for G2D output
            g2dconverttotexture(ThisImage)


endfunction ThisMap,Thisimage





Function LoadLevelTiles(filename$,ThisMap,Layer,Width,Height)
  Chan=ReadnewFile(filename$)
  if Chan  
         ;row$=""
         Repeat
            Blk=ReadWord(chan)/32
            If Xpos=<GetLevelWidth(thismap,layer)
               If ypos=<GetLevelHeight(thismap,layer)
                  PokeLevelTile ThisMap,Layer,Xpos,Ypos,blk
                  ;row$+=digits$(blk,4)+","
               EndIf
            EndIf
            Inc xpos
            If Xpos=>Width
               Xpos=0
               Inc Ypos
               
               ;#print row$
               row$=""
               If Ypos=>Height Then ExitRepeat
            EndIf      
         Until EndOfFile(Chan)=True
      CloseFile Chan
   endif
EndFunction




[/pbcode]
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on May 16, 2015, 12:49:12 PM
  G2D - Prototype # 11 - Map fixes + few missing commands

         So in release 11 of G2D, we've tweaked up map rendering somewhat they should generally behave much the same as regular (cough) built in maps,  plus there's a sprinkling of missing commands and a few little back end behaviors aligned with the core command set.   For example previous if you used g2dCLS()  is didn't reset the cursor position.

     So if you had a look like,

[pbcode]
     Do
          g2dCLS 255  
          g2dPRINT "stuff"  
          g2dPRINT "stuff"  
          g2dPRINT "stuff"  

          g2dsync
     loop
[/pbcode]


       The text would move off the screen, so you'd have to reset the g2dcursor position.



Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on May 18, 2015, 01:49:35 PM

   G2D - Prototype # 12 - Map Clipping

       Most of the coding time recently has been writing a math library to help out with clipping/interesections in G2D, some stuff I can use build in commands for, but I can't access all the internal lowlevel functions  from an external DLL so I've got to build versions of the functions in PlayBASIC.   Given that all the PB is translated to machine code via PB2DLL it's boarding upon irrelevant now in terms of performance. 

        Much of the library at this point is pretty vanilla, by that i mean, the code is simple and straight to the point, so it's easy to change without having to sift through a mountain of abstract optimizations.  For maps, we need to made sure we're no creating meshes for the parts of the map level that are impossible to see. For example in both camera modes, the view can rotate.  Now normally we can just clip the blocks scanning to the nearest bounds of the viewport,  effectively skipping 99.99% of stuff that's outside of the frame.   When things rotate we need to first do some high clips to see if the level needs to be drawn as it might completely outside of the view,  if it passes that initial test we work out the region of the map that camera is looking at and build a mesh from it.

      Alternatively it could use the size of the viewport and map block sizes to compute potentially visible zones, so it'd break into 32*32 tile meshes..  even so it's still possible for the mesh generation to build polygon lists of rects that aren't visible.  Which would have negative impact on the performance of the rendering, but would be quicker than the current 'render everything' implementation when drawn through a camera     You could this manually,   just by  breaking big levels down into a smaller grids of 'display levels' which would do much the same thing.   So if you have a level that's 1000 tiles wide by 50 tiles high or something, then you cut up the big level into smaller chunks of say 50 by 50 tiles.   You'd still run collision on the bug map, just draw the smaller chunks, if that makes any sense.. 


     
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on May 20, 2015, 01:17:08 PM
   G2D - Prototype # 12 - Xenon Mock

            So far I've been most playing with the library rather than writing anything with it,  so tonight's session has been get some of the xenon demo up and running.   The original code supports various cameras this version doesn't,  so I've been dragging the code over and making some mods to remove the camera stuff..   So far we've the maps loading/ backdrop and the aliens which are just randomly shoved into the scene in the original demo and are here as well..  

            The pics show us the scene with and without programmable particles in the scene.   The stock scene in a window runs at 600 fps on my 9 year old althon system, so in other words it's a sub 2 millisecond refresh.     Since the GPU is doing the blending in the background to the primary surface you can blend particles too, which comes at cost but even with completely over the top numbers of particles it's still well inside 16.7 millisecond refresh in a window.  

 

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on May 21, 2015, 12:27:31 PM

  G2D - Prototype # 12 - Xenon Mock - Player + Bullets + collisions

        Here's tonight's little 'as is' screenie,  this one is actually used the G2dDrawAllSprites() function to draw the sprite scene, where as yesterdays was manually drawing the sprite images, which isn't a huge difference, appear from the fact that we lose draw modes.  unfortunately we can't replicate all PB draw modes in GL or D3D without moving to shaders, since we're trying to stay GL1.0.     The only area where this impacts this demo is the use the colour addition mode.  Which takes the input texture RGB colours from the sprites image and adds the user defined colour as it's output to the screen,  which is handy when creating coloured flashes on objects when there's an impact.    You could emulate it, but I can't think of way without using a second grey scale texture for the time being. 

        In the screen we see the samey scene with random asteroids, the player and bullets with pixel level collisions.    We don't need to write G2D versions of the collision stuff for sprites/map commands, we just use the built in stuff on FX surfaces and we can run collisions as per normal..  The particle stuff is still included in the demo but isn't used in this shot,  but what I think I'll do is attach an emitter to the explosion to throw a bunch  fugly junk on screen.    The code is basically dragged directly from the original demo (dunno what version of it) and stream lined a little, there's one strange error with that's not reclaiming sprites that leave the screen though, which ends up in crash. The crash is prolly some missing code that's no resizing a buffer correctly, but i'm bit suss about the sprite clipping though, dunno why that's happening.


     
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on May 23, 2015, 02:37:39 PM
 G2D - Prototype # 13 - Xenon Mock - Player + Bullets + collisions + Micheal Bay Explosions yarda yarda

     Slowly wading through tweaking the library and demo in turn, the demo was crashing again drawing sorted sprite scene and I couldn't work out why for most of the day.  After some back tracing it turned out to be that PB2DLL wasn't passing a pointer parameter correctly to the internal command set call when calling the GetSpriteRect command, making it do some odd stuff from crashing immediately through to some bizarre clipping.  Which I guess was just pot luck data on the system stack..

     So in this scene we have working player / bullets / aliens and explosions (with attached PB particle generation) running with depth sorting.  The frame rate is more than ample even on this old clunker.  

   
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on May 25, 2015, 12:39:43 PM

  G2D - 2D OpenGL library for PlayBASIC V1.64P3 Beta 5 and above

  PROTOTYPE #12

  Release Date:  25th,  May, 2015



Download

   Old release deleted, newer versions bellow
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on May 25, 2015, 01:23:49 PM
 G2D Xenon 2000 Mock Up Version 001

     Here's the current build of the xenon 2000 mock up that uses G2D as the display library.    The demo includes maps/sprites/collisions and particles.  The demo is running upcapped (no vsync here),  but it actually depends on what your driver is set to,  most drivers will default to a capped vsynced refresh.   So you'll have to turn that off to get some idea..


Video




Old Video


 

Download

 [plink]G2D Xenon 2000 Mock Up Version 001 (http://underwaredesign.com/requestfile.php?file=G2DXENON2000a25ksxasf534) [/plink] (25th,May,2015)


Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on October 27, 2015, 10:49:28 PM
 G2D - Prototype # 14 - Map Clipping Updates

      With the various tweaks being made to PlayBASIC lately i've been tweaking the G2D libraries also.  One thing i noticed a while back was some strange slow down when rendering map levels to cameras.   Which initially I assumed was the cost of overdraw, but when timing the routine it seemed to bounce around a lot more than one would expect.   Not 100% sure on why,  but it's probably a combination of overdrawing and over rotation of the mesh (pre-cache hits when fetching memory) when it's being set up, due to lack of any real clipping.

     ok now the scene is set, so about a month ago I started coming up with different ways to improve the clipping for those meshes, which was somewhat more challenging than i'd expected.    The initial test was done in plain old PlayBASIC when the scene was drawn from an imported image which you could project and rotated.  The result being drawn as a polygon mesh via drawing QUADs.   Initially it'd choke regardless of how much of the scene was on screen running about 1fps or less.   Then as the clipping got better, the performance started to shoot up, now ranging between 200fps dropping down to 60fps (on the 10 year old althon).   Means the clipping cost has been largely removed and the bottleneck is now the software rendering behind QUAD.    If you have 1000's of quads that's a huge amount of edge translation/clipping etc and final rendering of then spans.

     So last night's little task was to convert the new logic into the G2D, which meant rewriting the Map rendering functions.    The result so far is the map rendering cost in the test scene doesn't seem to have the same impact on frame rate running from standard PB (the library is written in PLAYBASIC btw).   Hopefully, that speed up will translate into the final machine code version also, but I can't see why not at this point.  

     

    (Added later on - just testing video)

 



Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 02, 2015, 11:11:31 PM

G2D - Prototype # 15 - Rotated Map Support 2D Cameras.

    It's taken a few extra sessions to get this working, but g2d cameras now support Map rotation with clipping.  Rotation is supported in both camera modes (flat & perspective) without breaking the clipper, which was the reason for the delays.   The clipping worked fine in the mock up, but there was some order of operation issues when dropping it into the library,  which took some time to weed out where the difference was coming from.   But that's done now.     

    anyway, here's the standard Xenon 2000 map layers drawn from a camera. In previous editions of the library would drop down into about 100fps (so a 10millisecond refresh), where it'll now draw in 450fps (2.2 millisecond refresh) with  backdrop on the Athlon 3000 system (10 year old system)

    The current build of the library only supports rotated maps from cameras in flat camera modes,  in the process of tweaking the sprite rendered to rotate also.    Making it bit more flexible.


Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 05, 2015, 10:20:02 PM
  G2D - Prototype # 15b - Updating Sprite Rotation in 2D Camera modes.
   
        In the original release the G2D cameras have two modes, one was a clone of the PB camera so you can view the scene from a point of view, but the view can't rotate.  The other is perspective mode with supports zooming/rotating, so if you alter the Z that alters the projection of the sprite when in perspective mode.

       Using OpenGLL, we're pushing the rendering off the CPU/system memory onto the video card so there's less noticable difference in render performance,  making it more viable to post rotate/zoom a scene.     Therefore in the newer version of camera code both modes can rotate what's in view.   Unlike PB internal command sets, there's no high level scene collection mechanic so you have to construct the scene yourself.  But given most people tend use sprites for everything in the scene  (if you don't, you should.. ie RTFM for why)   

       So this afternoons annoying little task has been to tweak up the sprite rendering routines so they work in both camera modes.  Which means updating the clipping and state management.   The clipping is working well now and those little math difference between the sprites/maps seem to now have been ironed out.   There's a bit of strange crash in the tests at the moment, but hopefully that be ironed over the weekend so we can get a new version of thise thing out.
Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 13, 2015, 09:18:39 PM

  G2D - 2D OpenGL library for PlayBASIC V1.64P3 Beta 18 and above

  PROTOTYPE #15

  Release Date:  15th,  Nov, 2015



Download

  Get current version from Release Area  (http://www.underwaredesign.com/forums/index.php?topic=4210.msg28961#msg28961)





 

 G2D Xenon Camera Perspective Camera Test 15th,Nov,2015


    This short video (no music) shows the perspective 2D camera mode in the G2D (open GL) graphics library for PlayBASIC. The mock up scene consists of a mix of elements mostly from Xenon 2000.    In view is 2000 rotating sprites and the various map layers with filler backdrop.

    The capture of the demo is rather awful (very framey), but it actually runs 200fps plus on the 10 year old althon 64 test system with 6600 gpu. 


   



Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on November 17, 2015, 09:31:07 PM

  G2D - Prototype # 16 - Particles Updates

    Since the camera has been updated added a function to draw particles into a camera scene, rather than the screen.   Have added some future controls to the particle render to control individual particle colours as well as the intensity allowing them to in/fade out when drawn alpha addition.   It still doesn't support frames though.. 

   anyway, here's a version of the xenon perspective scene with a  bunch of spawns in the world

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on April 19, 2025, 12:23:45 AM
G2D - Can you run Wolf3D demos in Opengl ?

  Yes and no...

  I tried the latest build of the prototype, but it's missing UV controls for the TextureTRI and TextureQUAD commands. These are essential for subdividing not just floors and walls, but also objects.

So, off I go digging through old backups trying to find the G2D source code from 10 years ago. After a bit of hunting, I found what claims to be revision #15—good enough for now! All I really need to do is add UV support to those functions. They won't render in the correct order on screen yet, but at least it should give a sense of what's possible.

How do we build this? 
Good question. I fired up PlayBASIC V1.64P4, since G2D was written in PlayBASIC and built into machine code using PlayBASIC2DLL (for PB V1.64P revisions). The project is half demo, half library—and mostly a mess around, to be honest. But yep, I eventually tracked down what I believe is revision #15 of the source.

Skimming through the code, I found the original TextureTri and TextureQuad implementations. Instead of replacing them, I renamed them to G2dTextureTri2 and G2dTextureQuad2 and made those the base for the updates.

 Adding the new functions was one thing, but how do I turn this into a DLL? 
Well, I had written a PlayBASIC project loader ages ago that does a bit of preprocessing to generate the DLL. This was all covered in a blog post somewhere that no one read, of course...

 Basically, it loads the project and all its includes into one giant blob, scans through the code, and strips out anything tagged with `[removedme]` comments. That's needed because the project's built from various sub-libraries. (Smaller projects don't usually need this.)

  Once the builder was working, I just fired up PlayBASIC2DLL and compiled the merged source (`merged-source.pba`). The tool runs PB to compile and optimize the code in PlayBASIC space, which is then converted to assembly and passed off to the assembler. Boom—seconds later, we've got a DLL and a library of public function names.

 So now what? How does this hook into the WOLF3D demo?
Just include the library, call `G2dSTART()` to kick things off, and replace the old DX-style drawing commands with G2D equivalents. So, `TriC` becomes `G2dTriC`, `TextureTri` becomes `G2dTextureTri`, and so on.

 Then you hit run and hope! And—surprise, surprise—it actually works. Sort of.

 There are rendering issues though. Since we're drawing polygons out of order and expecting the PlayBASIC camera to sort everything from back to front, things get drawn incorrectly. Also, the wall perspective looks off because I'm only subdividing columns, not the full surface.

  But hey, you get that.

 

  Related Links:

      - PlayBASIC Project Loader + Source Code Merger (https://www.underwaredesign.com/forums/index.php?topic=4167.0)

      - PlayBASIC To DLL Blog (https://www.underwaredesign.com/forums/index.php?topic=4105.0)

      - Yet Another Wolfenstein 3D Demo (Texture Mapped Floors & Ceiling) (https://www.underwaredesign.com/forums/index.php?topic=4836.0)
 

      - [plink]Download G2D Library (https://www.underwaredesign.com/forums/index.php?topic=4210.0)[/plink]

Title: Re: G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
Post by: kevin on April 21, 2025, 01:48:21 PM

Wolf 3D Ported G2D Library Tech Demo

   This is variant of the Wolf 3D affine texture mapping demo that's been ported to the use the G2d library for PlayBASIC V1.64 editions.   G2d was an open gl  prototype written in conjunction with PlayBASIC2DLL (a conversion tool for converting PlayBASIC code to machine code dll's) 

   The library provides a list of basic primitives and some emulations of the built in features from sprites / fonts / maps..  To get this code working has working this well has meant updating the legacy g2d library and updating the wolf 3d code..  These fix the perspective, but there's no z sorting of the faces in this build.  Which is required since this is 2D rendering using affine texture mapped polygons.  The faces are subdivided to hold perspective in the scene.