PlayBASIC V1.64O (Work In Progress) Gallery

Started by kevin, January 27, 2013, 10:50:31 PM

Previous topic - Next topic

kevin

#30
  PlayBASIC V1.64O  Beta 12 - Download

   This revision rounds out the LOAD MEDIA FROM MEMORY functionality.   The support is limited to PNG,BMP,TGA + CRF.     (JPG isn't supported).

     

   Old Download deleted, newer downloads bellow.


kevin


  PlayBASIC V1.64O  Beta 13 - 32bit Power Of 2 and Black Optimizing

       Been taking a peek back into the texture map span rendering library, which is the core behind pretty much anything that's rotated.   Can't remember now, but at some point we added a hand full of short cut routines for some of common render modes.  So if the draw mode was 'simple' we call a dedicated routine to solve this.  This avoids having to falling through the multi pass filler, which is pretty flexible, but can be eat up some render time.

       Rotated Sprites are texture mapped quads in PlayBASIC,  when we draw a rotated image/texture map,  we're fetching pixels from texture in a none linear fashion.  So we  look up each texel (pixel in texture space) by interpolation down the polygon edges and across the strip.  The coordinates might be anywhere in the texture though.    Now since the texture can be any size, we need a multiply in the texel fetch to work out the where in memory the pixel actually is.  Knowing this, we added some power of two  render modes back during some other update.    Now when the mapper routine knows the source texture is a power of two (width), it calls a version of the filler than uses bit shifts rather than mults.    A bit shift is simply faster !   

       What this means is that if you're using image widths that are a nice round power of two, you'll get some extra speed for pretty much nothing.   Not only that, if the mask colour is zero (black = argb(0,0,0,0)), there's some combinations of the span filler that use this knowledge to it's advantage.   Since this allows the inner fill routine to avoid actually comparing texels with a user defined mask colour.  Winning us back some extra through put.   

        OK.. This is all old news, so tonight's little challenge has been to try and peel back the 32bit routines as much as possible with some interesting results.  This morning build of Beta 13 is rendering s the 500 (64*64) sprite test scene  around 20% faster than beta 12 (and older builds)  when the image is power of two and mask colour is zero.  Not only that actually slightly faster across the board.

        Here's the results from the bench mark.
       


--------------------------------------------------
Version:PlayBASIC V1.64O Beta 12
    Date:05 Jun 2013
   Image:gfx/ship.bmp
--------------------------------------------------
Test:1
Sprites[500] Rotated / Transparent=ON
Image=64*64 po2=1 MaskCOlour=0
Ticks=61250.1 Over=100 tests

Test:2
Sprites[500] Rotated / Transparent=OFF
Image=64*64 po2=1 MaskCOlour=0
Ticks=59431.68 Over=100 tests

Test:3
Sprites[500] Rotated / Transparent=ON
Image=64*64 po2=1 MaskCOlour=16711935
Ticks=59031.71 Over=100 tests

Test:4
Sprites[500] Rotated / Transparent=OFF
Image=64*64 po2=1 MaskCOlour=16711935
Ticks=58863.04 Over=100 tests

Test:5
Sprites[500] Rotated / Transparent=ON
Image=65*65 po2=0 MaskCOlour=0
Ticks=65830.69 Over=100 tests

Test:6
Sprites[500] Rotated / Transparent=OFF
Image=65*65 po2=0 MaskCOlour=0
Ticks=64011.32 Over=100 tests

Test:7
Sprites[500] Rotated / Transparent=ON
Image=65*65 po2=0 MaskCOlour=16711935
Ticks=71085.37 Over=100 tests

Test:8
Sprites[500] Rotated / Transparent=OFF
Image=65*65 po2=0 MaskCOlour=16711935
Ticks=64103.31 Over=100 tests



--------------------------------------------------
Version:PlayBASIC V1.64O Beta 13
    Date:05 Jun 2013
   Image:gfx/ship.bmp
--------------------------------------------------
Test:1
Sprites[500] Rotated / Transparent=ON
Image=64*64 po2=1 MaskCOlour=0
Ticks=48223.4 Over=100 tests

Test:2
Sprites[500] Rotated / Transparent=OFF
Image=64*64 po2=1 MaskCOlour=0
Ticks=58496.33 Over=100 tests

Test:3
Sprites[500] Rotated / Transparent=ON
Image=64*64 po2=1 MaskCOlour=16711935
Ticks=48894.36 Over=100 tests

Test:4
Sprites[500] Rotated / Transparent=OFF
Image=64*64 po2=1 MaskCOlour=16711935
Ticks=58264.08 Over=100 tests

Test:5
Sprites[500] Rotated / Transparent=ON
Image=65*65 po2=0 MaskCOlour=0
Ticks=64852.79 Over=100 tests

Test:6
Sprites[500] Rotated / Transparent=OFF
Image=65*65 po2=0 MaskCOlour=0
Ticks=62616.84 Over=100 tests

Test:7
Sprites[500] Rotated / Transparent=ON
Image=65*65 po2=0 MaskCOlour=16711935
Ticks=67575.52 Over=100 tests

Test:8
Sprites[500] Rotated / Transparent=OFF
Image=65*65 po2=0 MaskCOlour=16711935
Ticks=62693.11 Over=100 tests



       If you look closely you'll notice there's a pretty handy reduction in the first four tests when running in Beta13, which all come from the maskcolour and width of the texture is a power of two.   There's not much change in the general routine though (there is some).  Since $ff00ff is a commonly used mask, it might be viable to roll a few variations with that colour also.  Can't be sure, but I'd imagine they'd be somewhere in the middle.   


kevin

#32
  PlayBASIC V1.64O  Beta 13 - Download

   Here's what's looking to be the final beta for the V1.64O  revision.    We strongly recommend you test it with your programs prior to the final is released.    

    Deleted,  Newer download bellow



kevin


  PlayBASIC V1.64O  Beta 14 - Palette Mapping Library

        Earlier this update we looked at some methods for mapping groups of 8bits out as palette mapped pixels.   To test the theory,  an example showed how we can draw mock up commodore 64 screen in 'hires' mode.  But the process is not just the realm of emulation, as such conversions also occur loading/importing image data, 2bit & 4bit windows bitmap files come to mind.

        Since the initial tinker i'd been thinking of dropping some similar functions into a SLIB.  So far there's only four functions,  but they cater for the situations that come to mind.   So we've got a function to take a byte and couple of functions to render splits of bytes/words as palettes mapped horizontal strip.  There's not rect render as this point, but it's similar to something I was testing a number of years ago.   

        For those not sure what palette mapping is, well it's a bit of step back to the old days of 8bit graphics hardware.   A classic 8Bit screen mode, has up to 256 unique colours on screen ( 2^8=256 ) .    Most systems that had 8bit displays had 24bit RGB colours, much like today.   The difference is that rather than the screen representation being an array colours RGB values like it is today,  legacy hardware used a palette indexes.   So each pixel was a index into the palette array.   Each pixel index was one byte.   

       You can visual it like this,

PlayBASIC Code: [Select]
   Dim Palette(256)
Dim Screen(320,200)




       So the hardware would read through the Screen() array, grab the each colour index value and use that value to read from the Palette to get output colour.   ie   OutputRGB =Palette( Screen(Xpos,Ypos))   

       Old systems used palette mapped images because they're very efficient (on memory and cpu).  For example, to draw graphics in 8bit,  the program only has to shift the colour index data in screen(),  which in an 8bit screen mode is 1/4 of we have push around today in 32bit modes.    The down side is that you're very limited in terms of colours.  You literally only have 256 colours to choose from on screen at once and it's difficult to remap/make them at runtime.    Some systems had ways around this (mutli plexing), but it's still pretty limiting.
 
       However, there's a number of neat effects you can do with palettes, probably the one most people are familiar with is colour cycling.  Which you'd often see used to convey motion in water/lava  sprites/pictures in retro games.   Ironically, now days we'd pretty much have to build an animation to achieve to the same thing. 

        Knowing this,  figured one easy way would be to use a function that's designed to take 8bit/16bit arrays and render them as if they're a normal strip/image.   So if you had a colour cycling fragment, you'd scroll the palette,  then render the fragment to a regular PB image and hey presto colour cycling.


        Here's an example of a routine to draw a palette mapped set of strips to an image.   The 8bit image data is just set up as runs of ascending values with the palette set up to scale up from, rgb(0,0,0) to rgb(255,255,255), so we get a  gradient of sorts.   I've randomly changed some of the pixels and the first few colours to make sure it's rendering correctly.

PlayBASIC Code: [Select]
// ----------------------------------------------------------------------------      
// ----------------------------------------------------------------------------
Test_Palette_Mapped_Strips: // (8bit palette map)
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

rendertoimage screen
Lockbuffer
ThisRgb=Point(0,0)
Ypos=0
For ypos =0 to 255
address=GetBankPtr(ScreenBank)+(ypos*320)
DrawPaletteMappedStrip8(xpos,ypos,Address,320,$ff)
next
unLockbuffer

return




     Speed wise it's fine,  the loop executes in about 1/2 a millisecond on my old desk top,   attached is a picture.     Was going to create some a little more interest to look at but couldn't be bothered..  :)


monkeybot

beta 13-No probs running lots of progs.

There are definite speed improvements.


kevin

#35
  
QuoteThere are definite speed improvements.

   That's good to know.


  PlayBASIC V1.64O  Beta 14 - Palette Mapping Library Cont

        Ok.. so dropped some more functions into the palette mapping library and back end.   This is going to be pretty difficult to wrap your minds around, but in the demo bellow we're loading RGB mapped images, converted them to a global palette which is 16bit in size. This gives us a 2^16 possible colours that be used.  The colours can still be 32bit.     Now since we're using 16bit palette, we need to force the loaded images to be 16bit 656 format.  We do this using the CReateFXimagfeEX command.  Which allows you to create an image of any depth (pixel format), regardless of the screen mode.     Then a conversion routine replaces the RGB colour with the palette indexes in the image.

        Now if we create a 'screen' image that's the same depth as the palette mapped sprites (16bit),  we can use the normal image rendering stuff in PlayBASIC to draw them to the conceptually palette mapped buffer.  Once we're done rendering, we draw the screen out as a group of palette mapped strips.     This gives us a 32bit end result, but we've halved the amount of bandwidth that's moved around in the picture.    Plus you can modify the palette.    Raster Bars, Colour cycling  etc

         Here's  a demo showing the basic approach,  the palette mapped scene is actually fading in/out in this demo.  Fading a Palette mapped mode is much less work, since we only have to scale the palette RGB's and not every single pixel.   

PlayBASIC Code: [Select]
      #include "PaletteMapping"

loadFont "verdana",2,24,0,8


Dim Palette($10000)
Dim MasterPalette($10000)
SetPalette(Palette())

; set colour zero as RGB(0,0,0), since the images use that colour as transparent
Palette(0) = $00000000
ColourCount=1


; create 16bit fX image as the palette mapped screen..
Screen=CreateScreen(800,600)


; load some images and remap the RGBS to palette indexes
Ship,ColourCount= LoadAsPaletteMappedImage("gfx\ship.bmp",Palette(),ColourCount)
Bubble,ColourCount= LoadAsPaletteMappedImage("gfx\bubble_64x64.bmp",Palette(),ColourCount)
Logo,ColourCount= LoadAsPaletteMappedImage("gfx\uwlogo.bmp",Palette(),ColourCount)


// Make a copy of the original palette
CopyArray Palette(),MasterPalette()




Do

cls 255

frames++

setcursor 0,0

t=timer()

// -----------------------------------------------
// draw to the 16bit screen
// -----------------------------------------------

rendertoimage Screen
cls 0

gridimage Ship,mousex()-250,mousey()-250,10,10,true

drawrotatedimage Bubble,400,100,angle#,2,2,-32,-32,true
angle#=wrapangle(angle#+2)

drawimage logo,100,200,true

rendertoscreen

// draw the palette mapped buffer to actual screen
RenderScreen(Screen,Xpos,Ypos,Palette())
tt#+=Timer()-t


// -----------------------------------------------
// draw what the sprites to
// -----------------------------------------------
drawimage ship,0,500,true
drawimage bubble,64,500,true


setfont 2
lockbuffer
print "Screen Resolution:"+Str$(GetImageWidth(Screen))+"*"+Str$(GetImageHeight(Screen))
print "Palette Size:"+str$(ColourCount)
print "Ticks:"+str$(tt#/frames)
print "Fps:"+str$(fps())
unlockbuffer



// --------------------------------------
// Fade palette in and out
// --------------------------------------
ScaleLevel=128+Cos(angle#)*128
ScaleLevel=ClipRange(ScaleLevel,0,255)

For lp=0 to ColourCount
ThisRgb=MasterPalette(lp)
Palette(lp)=RgbScale(ThisRgb,ScaleLevel)
next

Sync
loop




Psub CreateScreen(Width,Height)
; the
local ThisIMage=GetFreeImage()
CreateFXImageEx ThisImage,Width,Height,16
EndPsub ThisImage




Psub RenderScreen(Screen,Xpos,Ypos,Palette())
if GetImageStatus(Screen) and Screen>0

if GetImageDepth(Screen)=16

SetPalette(Palette())

oldSurface=GetSurface()

rendertoimage Screen
lockbuffer
thisrgb=point(0,0)
Width =GetImageWidth(Screen)
HEight=GetImageHeight(Screen)
Ptr =GetImageptr(Screen)
Modulo=GetImagePitch(Screen)
unlockbuffer

rendertoimage OldSurface

lockbuffer
thisrgb=point(0,0)
For ypos =0 to Height-1
DrawPaletteMappedStrip16(0,ypos,Ptr,Width,$ffff)
ptr+=Modulo
next
unLockbuffer
endif

endif

EndPsub





Psub LoadAsPaletteMappedImage(File$,Palette(),ColourCount)

local TempImage=LoadNewImage(File$,2)

local w=GetIMageWidth(TempImage)
local h=GetIMageHeight(TempImage)

Login required to view complete source code

         

     So bellow we have a shot of what this looks like running..   In the bottom left hand corner you can see the palette mapped SHIP/BUBBLE images drawn directly to screen.  The pixel data in them is no longer RGB's  colour values, but INDEX into the palette array.  So they look all crazy now when drawn to to the normal display..


kevin

#36
  PlayBASIC V1.64O  Beta 14 - Palette Mapping Library Cont #2

     Continued tweaking the library ideas so the following is more a proof of concept.   Previously we had a pretty shallow palette (1200 colour or so),  so I wanted to test out something a bit bigger.   Soon found the Missile Attack  backdrop which is 800*600.   The only issue with converting it, is that the routine the palette maps image data isn't very quick (nested linear searching).  In particular when the image is mostly unique colours like this one,  so it can a take few seconds to map that image..

     Drawing the scene is same as normal, it's a 16bit blit of the palette mapping background to the 16bit screen.  Since there's no pixel format conversions it ends up as a pure memory copy.. What's interesting though, is that you can draw a good 10 layers of 100 transparent images over the top.   Which can rotate also.   What you couldn't do (at least without setting up the palette in very particular way) is blend or filter them.  Since those actions would treat the individual texels in the sprites as  RGB channels and not Indexes, so the mixing them would create all sorts of funky results..   I'll bet there's some very interesting effects that are just waiting to be discovered because of that however.  

     Since the palette data in the test scene is now pretty large (50K colours), sitting in a for/next loop tinting all those colours individually is a lot of dead weight.   So one easy way around this is to the use the BlitImage  functions to do the tinting for us.   To do this, we make a image (32bit) (CreateFxImageEX), plot the palette colours in linear order (from 0 to $ffff).   This gives us a chunk of memory that contains the palette that we blend with.   So just make a second image (same size + depth)  and then blit it across.  This takes advantage of parallel mutilations available in the BlitImage functions.  You could even thread it.  

       
PlayBASIC Code: [Select]
      #Include "BlitImage"
#include "PaletteMapping"

loadFont "verdana",2,24,0

Dim Palette($10000)
SetPalette(Palette())

; set colour zero as RGB(0,0,0), since the images use that colour as transparent
Palette(0) = $00000000
ColourCount=1


; create 16bit fX image..
Screen=CreateScreen(800,600)

print "Palette Mapping Images (slow).. "
sync

; load some images and remap the RGBS to palette indexes
Layer,ColourCount = LoadAsPaletteMappedImage("gfx\layer1.bmp",Palette(),ColourCount)
Ship,ColourCount = LoadAsPaletteMappedImage("gfx\ship.bmp",Palette(),ColourCount)
Bubble,ColourCount= LoadAsPaletteMappedImage("gfx\bubble_64x64.bmp",Palette(),ColourCount)
Logo,ColourCount = LoadAsPaletteMappedImage("gfx\uwlogo.bmp",Palette(),ColourCount)


// Store the Palette Data in an 32bit (256*256) image
MasterPaletteImage=MakePaletteIMage(Palette())

// Make a clone of this image, so we can use blitimage functions to scale the palatte values
PaletteImage=GetFreeImage()
Copyimage MasterPaletteImage,PaletteImage


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

Do

frames++

setcursor 0,0

t=timer()

// -----------------------------------------------
// draw to the 16bit screen
// -----------------------------------------------

rendertoimage Screen
drawimage layer,0,0,false

x=mousex()-250
y=mousey()-250
For lp=0 to 199 step 10
gridimage Ship,x+lp,y+lp,10,10,true
next

drawrotatedimage Bubble,400,100,angle#,2,2,-32,-32,true
angle#=wrapangle(angle#+2)

drawimage logo,100,200,true

rendertoscreen

// draw the palette mapped buffer to actual screen
RenderScreenUserPalette(Screen,Xpos,Ypos,GetImagePtr(PaletteImage))
tt#+=Timer()-t


// -----------------------------------------------
// draw what the images artual contain
// -----------------------------------------------
if spacekey()
drawimage ship,0,500,true
drawimage bubble,64,500,true
drawimage PaletteIMage,GetScreenWidth()-256,GetSCreenHeight()-256,false
endif

setfont 2
lockbuffer
print "Screen Resolution:"+Str$(GetImageWidth(Screen))+"*"+Str$(GetImageHeight(Screen))
print "Palette Size:"+str$(ColourCount)
print "Ticks:"+str$(tt#/frames)
print "Fps:"+str$(fps())
unlockbuffer



// --------------------------------------
// Fade palette in and out
// --------------------------------------
ScaleLevel=128+Cos(angle#)*128
ScaleLevel=ClipRange(ScaleLevel,0,255)


// Copy the Master palette image over the palette image with TINT applied
rendertoimage PaletteImage
BlitImageAlphaMultColour(MasterPaletteImage,0,0,rgb(scalelevel,scalelevel,scalelevel))
rendertoscreen


Sync
loop





Psub CreateScreen(Width,Height)
; the
local ThisIMage=GetFreeImage()
CreateFXImageEx ThisImage,Width,Height,16
EndPsub ThisImage




Psub RenderScreen(Screen,Xpos,Ypos,Palette())
PalettePtr=GetarrayPtr(Palette(),true)
RenderScreenUSerPalette(Screen,Xpos,Ypos,PalettePtr)
EndPsub




Psub RenderScreenUSerPalette(Screen,Xpos,Ypos,PalettePtr)
if GetImageStatus(Screen) and Screen>0

if GetImageDepth(Screen)=16

SetPalettePtr PalettePtr

oldSurface=GetSurface()

rendertoimage Screen
lockbuffer
thisrgb=point(0,0)
Width =GetImageWidth(Screen)
HEight=GetImageHeight(Screen)
Ptr =GetImageptr(Screen)
Modulo=GetImagePitch(Screen)
unlockbuffer

rendertoimage OldSurface

lockbuffer
thisrgb=point(0,0)
Login required to view complete source code


kevin

#37
   PlayBASIC V1.64O  Beta 14 - Download

     Here's beta 14, this version includes the updated palette mapping functions..   Which create a number of interesting possibilities for those creative programmers out there.  

 Download Deleted, newer build bellow.


micky4fun


kevin

#39
  Palette Mapping -> PlayBASIC Image Format ?

        Been messing around the palette mapping routines a bit over the weekend,  mainly trying a few different ways to map larger images quicker.   The current built in solution is a naive solution, that is,  it assumes the image is full of mostly repeated colours.   So it's ok for images with a few colours, but execution time soon blows out when there's lots of colours in the image.

        The core problem with the existing routine is there's lots of dead overhead from the nested linear searching.   Obviously a better solution is to build a structure that's more efficient to search.  One approach is to arrange the colours  so they can be searched quicker, which means keeping the RGBS sorted.    To test the theory, wrote an emulation of the process in regular PlayBASIC code.     So the routine loads the image as normal, then runs though and sorts every pixels RGB value during the first pass, then we compute the indexes from the sorted data.    Being legacy PlayBASIC code, it's slower then existing native built in solution, but not by much..  Which tells us that the method is far more efficient than a built in brute force solution will ever be.    

        One of the most interesting byproducts of the palette mapped images, is the index and rgb table data are pretty compression friendly.   I've been testing a wall paper image that was from somebodies demo,  where the image is 1200*600*32bit pixels.   In BMP format it's 2,813K on disc,  in PNG format it's 935K on disc.     If we take this image and run it through the process above, the resulting none compressed file is 1558K on disc.  

      But when we zip the files,  we get this

      Zipped Palette Mapped (1558k) =  756k

      Zipped BMP (2813k) =  887k

      Zipped PNG (935k) =  934k
 

      So we're getting about a 20% saving in distributing size of the media,  which is a pretty significant saving and has been repeated over a number of test images now.  One further byproduct is there's little to no decompression cost at runtime since the data is raw and in order.  So the chunk is loaded to a buffer and 'drawn' to the destination surface as is, much like a none compressed BMP.   Pngs have to be loaded, decompressed, copied to the target.   I suspect it'd be about the same in real world speed terms.    

      What you could do is roll your own palette mapped image format.  Just load the image, map it and save out the palette and colour index arrays into a file.   Then write a loader to pull the whole file into memory, grab a pointer to the palette and pointer to the index array and draw  the strips to your target surface.   Which you can already this in the Beta 14 above.   Provided your images don't exceed  $10000 (2^16) unique colours that will work fine.   Those with a bit of imagination, will be able to roll their own pack files in a custom format and be able to drive down the distribution size beyond the rest of us..    


       For a long time now, i've been testing various methods that could be used for a PlayBASIC Image Format.  This is handy as PB specific data can stored in the image and restored upon load.  The focus being the format is easy to load into memory while being fairly efficient as possible.    While it might not turn out to be this particular form, supporting a variations of it would be more than useful.


      Update:

       The conversion routine has two main bottle necks, sorting the RGB values and searching the table for matches.    Have moved the sorting & searching into PB, and as expected it's about 10 times (or more) quicker than the brute force solution.  Which is about what i'd expected.    Bellow though the test is running on a 1200*600 sized image.   To test a theory, the sorting in this version is actually just regular PlayBASIC code where the sort routine has been tweaked to use least number of operations per loop.  In this example it's sorting 720,000 values, which is down to around 1750 milliseconds now, which is about 500 or so faster than it was.

       Anyway the attached is piccy of the demo, where it loads the regular image, palette maps it, saves,reloads and displays it.  The display version is scaled down to fit on screen.



  EDIT:  See-> PlayBASIC Image (PBI) Format Development Blog

         
 

kevin

#40
   PlayBASIC V1.64O  Beta 15 - Palette Mapping Round 3

       Been messing around with the palette mapping routines in PB and in the engine, coming up with a better method is always pretty satisfying, in particular when you can get the vanilla PB implementation that runs  quicker than the original brute force version in C.    To map the mountain image the original routine was taking 16->17 seconds.  The alternative version in standard PB does the same job in 3.7 seconds.    Had a feeling the newer method would be faster, but wasn't expecting that.   So by applying the rule of 10, then the same logic  in C should run in about 370 milliseconds,  which wasn't too far off, but It was more like 450.

        But, there's a but.... it's actually not the same method.    The original routine would map all incoming images into a global palette, where as the alternative method just works out the palette for this image.  Which is handy for say image compression, but doesn't slot into what we already had and coming up with a variation on the same theme that was fast, wasn't initially forthcoming.   Luckily while out on the bike,  came up with a reordering/splicing idea to shuffle the new images unique colours into the existing palette and when combined with an idea to cull the original RGB colours as much as possible, the final solution is about 3-times faster again.   Where it's now able to Palette Map the previous demo scene now in 130/140 milliseconds.  

       The interesting thing about this implementation is it gives you 2^16 unqiue 32bit colours within the frame, unlike an 2^8 screen mode in VGA/VSGA / AGA  graphics hardware.      Those with a little bit of creativity will no doubt discover ways of expanding the colour count way beyond that.  


   Related Articles:

    * Palette Mapped / Raster Bar Examples / Glenz Vector Example


kevin

#41
   PlayBASIC V1.64O  Beta 15 - Download

     Here's beta 15, this one includes the updated palette mapping stuff and a MOD fix.

 Download Deleted newer build bellow.

kevin

#42
   PlayBASIC V1.64O  Beta 16 - ZClipper

     This one adds another mini slib library that handles clipping 3D rays down the z axis.

PlayBASIC Code: [Select]
   #include "zclipper"

Projection#=500

Texture=LoadNewIMage("tile.png",2)

x1 =100
y1 =500
z1 =2500

x2 =x1+500
y2 =y1
z2 =250

depth =600

Dim Vert0 as Zclipper_Vertex_Structure pointer
Dim Vert1 as Zclipper_Vertex_Structure pointer
Dim Vert2 as Zclipper_Vertex_Structure pointer

Vert0 =ZClipVertexPtr(0)
Vert1 =ZClipVertexPtr(1)
Vert2 =ZClipVertexPtr(2)


ClipPlane=900

ClipMode=1

Do

cls 0

print "Clip depth:"+Str$(ClipPLane)

//
z=depth+z1
px1 = (x1*Projection#)/z
py1 = (y1*Projection#)/z

// Colour of the polygon
c1=Rgb(10,20,30)
c2=Rgb(255,255,255)

// uv coordinates
u1=0
v1=0

u2=GetImageWidth(texture)
v2=0

v3=GetImageHeight(texture)
v4=v3

//
z=(Depth+z2)
px2 = (x2*Projection#)/z
py2 = (y2*Projection#)/z

if (Depth+z2) < ClipPlane
if (Depth+z1) >= ClipPlane

// intt a pair of vertex
ZClipSetVertex(0,px1, py1,x1,y1,depth+z1,Rgb(10,20,30),U1,V1)
ZClipSetVertex(1,px2, py2,x2,y2,depth+z2,Rgb(255,255,255),U2,V2)

// Clip the vertex pair 0 to 1 and store the result in vertex 2
ZClipRay(ClipPlane,0,1,2)

// Project the clipped point into 2d space
px2 = (vert2.WorldX*Projection#)/vert2.Worldz
py2 = (vert2.WorldY*Projection#)/vert2.Worldz

// get the clipped U/V coords
u2 = vert2.u
v2 = vert2.v

c2 = vert2.thisARGb

print "Clipped Vertx2"

else
print "Behind camera"
goto DontDraw
endif

endif


// draw these in screen space

texturequad Texture, px1+100,300+py1, u1,v1, px2+100,300+py2, u2,v2,_
px2+100,300-py2 ,u2,v3, px1+100,300-py1, u1, v4, 0

gouraudquad px1+500,300+py1, c1, px2+500,300+py2, c2,_
px2+500,300-py2, c2, px1+500,300-py1, c1


line px1+500,300+py1,px2+500,300+py2
line px1+500,300-py1,px2+500,300-py2


DontDraw:

print z1
print z2
print depth
print u1
print u2

print Hex$(c1)
print Hex$(c2)

if UpKey()
Depth-=1
endif

if downKey()
Depth+=1
endif

Sync
loop





 Download

   Get PlayBASIC V1.64O Beta 16 (login required)


kevin

#43
   PlayBASIC V1.64O  Beta 16b - Cross Product Functions

    Dropped in a couple of crossproduct functions in to see how they perform against doing the same thing manually.   In the test code there's about a 30% gain on expressions that containing all floats when calling the float version, and about 10% gain on of integer version.   They're both faster so we'll leave those in.  

PlayBASIC Code: [Select]
   x1#=100
y1#=100

x2#=300
y2#=150

x3#=200
y3#=300


x1=x1#+400
y1=y1#

x2=x2#+400
y2=y2#

x3=x3#+400
y3=y3#

max=5000


do
cls 0

frames++

// Float Versions
print "[ Float Tests ]==================================="
ts=startinterval(0)
For lp =0 to max
result#=(((x2#-x1#)*(y3#-y1#))-((x3#-x1#)*(y2#-y1#)))
next
tt1#+=Endinterval(0)
print result#


ts=startinterval(0)
For lp =0 to max
result#=CrossProduct#(X1#, Y1#,x2#,y2#,x3#,y3#)
next
tt2#+=Endinterval(0)
print result#


print tt1#/frames
print tt2#/frames


print "[ Integer Tests ]==================================="


ts=startinterval(0)
For lp =0 to max
result=(((x2-x1)*(y3-y1))-((x3-x1)*(y2-y1)))
next
tt3#+=Endinterval(0)
print result


ts=startinterval(0)
For lp =0 to max
result=CrossProduct(X1, Y1,x2,y2,x3,y3)
next
tt4#+=Endinterval(0)
print result


print tt3#/frames
print tt4#/frames


line X1#, Y1#,x2#,y2#
line x2#,y2#,x3#,y3#
line x3#,y3#,x1#,y1#

line X1,Y1,x2,y2
line x2,y2,x3,y3
line x3,y3,x1,y1

print fps()
Sync
loop






  Tutorial On CrossProduct
 


 


kevin


  PlayBASIC V1.64O - Resource Binding

       Been stewing on this for a few weeks now and aren't really any closer to an ideal situation.  My preferred solution would see minimal changes to user code when the 'media' is bound into the final exe or loaded from disc.   So a line code like loadimage "gfx\MyPicture.png",1   would work regardless of the context.   If the media is bound into the EXE then the loader process and find this file as an internal resource and load it from memory, if it's not, it attempts to load it from disc.     Which is about as simple as I can make it. 

       But.... there's a but, which comes down to how the programmer tells PlayBASIC to construct the internal binding.    It can't work this from the user code, since anything that's not an literal is virtually impossible to compute at compile time.

     Ie.
PlayBASIC Code: [Select]
      For frame=1 to 10
LoadIMage "gfx\ship"+str$(frame)+".bmp", 100+frame
next



           
      With some messing around you could solve that at compile time, but all it takes is one external unknown and your toast.    So it becomes necessary to tell the compiler what files to bind and what not to bind into the exe.      The lazy solution is to have  recursive include function, that will grab everything in the folder and attached it.   That's a pretty naive solution as users would doubt end with distributing files they had never intended. 

      There needs to be some flexibility in the approach as  binding isn't necessarily just for image files, data files could also be attached.  Those would have to be handled differently for the user than just a loadimage command,  so it introduces another little twist into the process.   It's not uncommon for IDE's to have a 'resource managers' built into them today.   Obviously we can't do that today with PlayWrite, but you could have a tool that does something like that.   So rather than binding the 'files + folders' by hand,  you just attach the previously created pack file.

     Something  to think about anyway.