Okay, I've gotten a really cool sprite surface working. Downside? It's possible to load a sprite from an image, but the alpha channel is masked only. If you just use raw textures, alpha works beautifully. Yes, the mechanism is the same one used in the older one I found, but I've basically rewritten the whole thing from scratch to take advantage of OOP methodology, and superior BMax classes. At least, _I_ think BMax classes are better. Anyway, it's pretty cool, so enjoy! :)
Code:
An import you'll need:
And a meager example to download here: http://rattuscanisdev.g0dsoft.com/uploads/dnload/spritesurfacetest.zip Rest assured you can get more out of it than this. I'm just lazy when preparing examples. It should show you how it pretty much works.
Code:
Import Blitz3D.Blitz3DSDK Import BRL.Math Import BRL.LinkedList Import "imagetotex.bmx" Rem Sprite Surface BlitzMax Blitz3D SDK Addon by ninjarat RCD Software (TM) Based upon the sprite surface commands by Syntax Error and Barliesque, but optimized heavily for BlitzMax in these ways: - Uses OOP to keep track of sprites in a more stuctured and easy to understand manner. - Optimized to use textures, not images. Sorry, but I just don't dig the images. Raw textures are faster, and it's easy to use them for variable sized images by just clipping/scaling. End Rem Private Global currhandle=0 Function allochandle() currhandle:+1 Return currhandle End Function Type TSprite Global sprites:TList Global sshow=True Global issurfaceinit=False Global spritepivot Global spritecamera Field handle Field mesh Field x#,y# Field ax#,ay#,az# Field hdlx#,hdly# Field sclx#,scly# Field angle# Field width Field height Field order Field texture Field u#[2],v#[2] Field isvisible Field blend=1 Field alpha#=1 Function InitSpriteSurface(pivotdist#) issurfaceinit=True sprites=New TList bbSetBuffer bbBackBuffer() spritecamera=bbCreateCamera() CreateSpritePivot spritecamera,pivotdist End Function Function CreateSprite:TSprite(width,height,texture,order,u1#,v1#,u2#,v2#) sprite:TSprite=New TSprite sprite.u=[u1,u2] sprite.v=[v1,v2] sprite.texture=texture sprite.order=order sprite.width=width sprite.height=height sprite.x=0 sprite.y=0 sprite.hdlx=0 sprite.hdly=0 sprite.sclx=1 sprite.scly=1 sprite.ax=0 sprite.ay=0 sprite.az=0 sprite.handle=allochandle() smesh=bbCreateMesh(spritepivot) surf=bbCreateSurface(smesh) bbAddVertex surf,0,0,0,u1,v1 bbAddVertex surf,2,0,0,u2,v1 bbAddVertex surf,0,-2,0,u1,v2 bbAddVertex surf,2,-2,0,u2,v2 bbAddTriangle surf,0,1,2 bbAddTriangle surf,3,2,1 If texture Then bbEntityTexture smesh,texture bbScaleEntity smesh,Float(width)/2,Float(height)/2,1 bbEntityFX smesh,1+16 bbEntityOrder smesh,-order bbHideEntity smesh sprite.mesh=smesh sprite.isvisible=False sprite.MidHandle sprites.AddLast sprite Return sprite End Function Method Clone:TSprite() s:TSprite=CreateSprite(width,height,texture,order,u[0],v[0],u[1],v[1]) s.blend=blend s.alpha=alpha s.SetHandle hdlx,hdly,False s.x=x; s.y=y Return s End Method Function UpdateSprites() For curr:TSprite=EachIn sprites curr.Update Next End Function Method Update(frame=-99999,z#=0) If sshow Then If isvisible Then bbShowEntity(mesh) Else bbHideEntity(mesh) Else bbHideEntity mesh End If bbEntityBlend mesh,blend bbEntityAlpha mesh,alpha bbEntityOrder mesh,-order bbPositionEntity mesh,x+.5,.5-y,z bbScaleEntity mesh,Float(width*sclx)/2,Float(height*scly)/2,1 bbRotateEntity mesh,0,0,angle If frame<>-99999 Then bbEntityTexture mesh,texture,frame End Method '(courtesy of FredBorg) Method SetHandle(hx#,hy#,pixpfct) MidHandle If pixpfct Then hx=(hx/width)-1 hy=(hy/height)-1 End If Local surf=bbGetSurface(mesh,1) bbVertexCoords surf,0,bbVertexX(surf,0)-hx,bbVertexY(surf,0)+hy,bbVertexZ(surf,0) bbVertexCoords surf,1,bbVertexX(surf,1)-hx,bbVertexY(surf,1)+hy,bbVertexZ(surf,1) bbVertexCoords surf,2,bbVertexX(surf,2)-hx,bbVertexY(surf,2)+hy,bbVertexZ(surf,2) bbVertexCoords surf,3,bbVertexX(surf,3)-hx,bbVertexY(surf,3)+hy,bbVertexZ(surf,3) hdlx=hx; hdly=hy End Method Method SetScale(sx#,sy#,pixpfct) If pixpfct Then sclx=sx/width scly=sy/height Else sclx=sx scly=sy End If End Method Method Rotate(ang#) angle=-ang If angle>180 Then angle:-360 If angle<-180 Then angle:+360 End Method Method Turn(ang#) angle:-ang If angle>180 Then angle:-360 If angle<-180 Then angle:+360 End Method Method GetAngle#() Return -angle End Method '(courtesy of bot builder) Method MidHandle() ux#=-100000; uy#=-100000; uz#=-100000 lx#=100000; ly#=100000; lz#=100000 surf=bbGetSurface(mesh,1) For vert=0 To 3 vx#=bbVertexX(surf,vert) vy#=bbVertexY(surf,vert) vz#=bbVertexZ(surf,vert) If vx<lx Then lx=vx If vx>ux Then ux=vx If vy<ly Then ly=vy If vy>uy Then uy=vy If vz<lz Then lz=vz If vz>uz Then uz=vz Next ax#=(ux+lx)/2 ay#=(uy+ly)/2 az#=(uz+lz)/2 bbPositionMesh mesh,-ax,-ay,-az End Method Method HandleX#() Return hdlx End Method Method HandleY#() Return hdly End Method Method PixelHandleX#() abshdlx#=hdlx+1 Return abshdlx*width End Method Method PixelHandleY#() abshdly#=hdly+1 Return abshdly*height End Method Function ShowSprites() sshow=True End Function Function HideSprites() sshow=False End Function Method SetVisible(vis) isvisible=vis End Method Method Show() isvisible=True End Method Method Hide() isvisible=False End Method Function GetCamera() Return spritecamera End Function Function CreateSpritePivot(parentcam=0,dist#=1.0) spritepivot=bbCreatePivot(parentcam) aspect#=Float(bbGraphicsHeight())/Float(bbGraphicsWidth()) scale#=2#/bbGraphicsWidth() bbPositionEntity spritepivot,-1,aspect,dist bbScaleEntity spritepivot,scale,scale,scale bbNameEntity spritepivot,"spritepivot" End Function Method FreeBBObjects() bbFreeEntity mesh End Method End Type Public 'get whether the sprite suface is initialized Function IsSpriteSurfaceInit() Return TSprite.issurfaceinit End Function 'initialize the sprite surface Function InitSpriteSurface(pivotdist#=1) TSprite.InitSpriteSurface pivotdist End Function 'load a sprite from a texture Function LoadSprite:TSprite(file$,texflags=0,order=1,u1#=0,v1#=0,u2#=1,v2#=1) tex=bbLoadTexture(file,texflags) Return CreateSpriteFromTex(bbTextureWidth(tex),bbTextureHeight(tex),tex,order,u1,v1,u2,v2) End Function 'create a new sprite with a texture Function CreateSpriteFromTex:TSprite(width=1,height=1,texture=Null,order=1,u1#=0,v1#=0,u2#=1,v2#=1) Return TSprite.CreateSprite(width,height,texture,order,u1,v1,u2,v2) End Function 'create a new sprite with an image 'note that the alpha channel can only do 'a mask blend for the time being Function CreateSpriteFromImg:TSprite(width=1,height=1,image,order=1,u1#=0,v1#=0,u2#=1,v2#=1) tex=ImageToTexture(image,0,0) Return TSprite.CreateSprite(width,height,texture,order,u1,v1,u2,v2) End Function 'create a duplicate of a sprite Function CloneSprite:TSprite(sprite:TSprite) Return sprite.Clone() End Function 'set visibility of sprite Function SetSpriteVisible(sprite:TSprite,vis) sprite.SetVisible vis End Function 'get visibility of sprite Function IsSpriteVisible(sprite:TSprite) Return sprite.isvisible End Function 'show the sprite Function ShowSprite(sprite:TSprite) sprite.Show End Function 'hide the sprite Function HideSprite(sprite:TSprite) sprite.Hide End Function 'set the sprite's position Function PositionSprite(sprite:TSprite,x#,y#) sprite.x=x sprite.y=y End Function 'rotate the sprite Function RotateSprite(sprite:TSprite,ang#) sprite.Rotate ang End Function 'turn the sprite Function TurnSprite(sprite:TSprite,ang#) sprite.Turn ang End Function 'get the sprite's width Function SpriteWidth#(sprite:TSprite) Return sprite.width End Function 'get the sprite's height Function SpriteHeight#(sprite:TSprite) Return sprite.height End Function 'get the sprite's x handle Function SpriteHandleX#(sprite:TSprite,pixpfct=False) If pixfct Then Return sprite.PixelHandleX() Else Return sprite.HandleX() End If End Function 'get the sprite's y handle Function SpriteHandleY#(sprite:TSprite,pixpfct=False) If pixfct Then Return sprite.PixelHandleY() Else Return sprite.HandleY() End If End Function 'set the sprite's order Function SetSpriteOrder(sprite:TSprite,order) sprite.order=order End Function 'set the drawing handle of the sprite Function SetSpriteHandle(sprite:TSprite,hx#,hy#,pixpfct=False) sprite.SetHandle hx,hy,pixpfct End Function 'set the sprite's scale Function ScaleSprite(sprite:TSprite,sx#,sy#,pixpfct=False) sprite.SetScale sx,sy,pixpfct End Function 'set sprite blend Function SetSpriteBlend(sprite:TSprite,blend) sprite.blend=blend End Function 'set sprite alpha Function SetSpriteAlpha(sprite:TSprite,alpha#) sprite.alpha=alpha End Function 'get sprite blend Function SpriteBlend(sprite:TSprite) Return sprite.blend End Function 'get sprite alpha Function SpriteAlpha(sprite:TSprite) Return sprite.alpha End Function 'get sprite angle Function SpriteAngle#(sprite:TSprite) Return sprite.GetAngle() End Function 'get sprite x scale Function SpriteScaleX#(sprite:TSprite) Return sprite.sclx End Function 'get sprite y scale Function SpriteScaleY#(sprite:TSprite) Return sprite.scly End Function 'update all sprites Function UpdateSprites() TSprite.UpdateSprites End Function 'get the sprite camera Function GetSpriteCamera() Return TSprite.GetCamera() End Function 'get the sprites integer handle Function GetSpriteIntHandle(sprite:TSprite) Return sprite.handle End Function 'free a sprite object Function FreeSprite(sprite:TSprite) sprite.FreeBBObjects() sprite=Null End Function 'use a sprite's integer handle to get the sprite Function GetSpriteFromIntHandle:TSprite(handle) For ck:TSprite=EachIn TSprite.sprites If ck.handle=handle Then Return ck Next Return Null End Function 'get amount of memory used by a sprite Function SpriteMemory(sprite:TSprite) Return SizeOf(sprite) End Function 'get amount of memory used by all sprites Function AllSpritesMemory() For curr:TSprite=EachIn TSprite.sprites acc:+SizeOf(curr) Next Return acc End Function
An import you'll need:
Import Blitz3D.Blitz3DSDK Import BRL.Retro Function ImageToTexture(img,texflags=0,mask=$FF00FF) If par=0 Then par=spritepivot imgwid=bbImageWidth(img) imghgt=bbImageHeight(img) texwid=2 Shl (Bin(imgwid-1).Replace("0"," ").Trim().length-1) texhgt=2 Shl (Bin(imghgt-1).Replace("0"," ").Trim().length-1) tex=bbCreateTexture(texwid,texhgt,texflags) bbLockBuffer bbImageBuffer(img) bbLockBuffer bbTextureBuffer(tex) For x=0 To texwid-1 For y=0 To texhgt-1 If x<imgwid><imghgt> currpix=bbReadPixelFast(x,y,bbImageBuffer(img)) If currpix&$FFFFFF=mask Then bbWritePixelFast x,y,0,bbTextureBuffer(tex) Else bbWritePixelFast x,y,currpix,bbTextureBuffer(tex) End If Else bbWritePixelFast x,y,0,bbTextureBuffer(tex) End If Next Next bbUnlockBuffer bbImageBuffer(img) bbUnlockBuffer bbTextureBuffer(tex) Return tex End Function
And a meager example to download here: http://rattuscanisdev.g0dsoft.com/uploads/dnload/spritesurfacetest.zip Rest assured you can get more out of it than this. I'm just lazy when preparing examples. It should show you how it pretty much works.