Grid Sprite : using mesh 3D & entity

Share your advanced PureBasic knowledge/code with the community.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Grid Sprite : using mesh 3D & entity

Post by eddy »

handy for :
- sprite deformation
- material fx
- sprite vertex color
- sprite shape
- sprite Zorder

Code: Select all

EnableExplicit
Structure gs_Sprites
   Entity.i
   Mesh.i
   Material.i
   sx.f
   sy.f
EndStructure
Global NewList gs_Sprites.gs_Sprites()

Procedure gs_FoundSprite(Sprite)
   ForEach gs_Sprites()
      If gs_Sprites()\Entity=Sprite
         ProcedureReturn @gs_Sprites()
         Break
      EndIf
   Next
EndProcedure
Procedure gs_CreateCamera(Camera, x, y, Width, Height, BackgroundColor=$000000)
   Protected w=Width/2
   Protected h=Height/2
   Protected result=CreateCamera(Camera, x, y, Width, Height)
   If Camera=#PB_Any : Camera=result : EndIf
   
   CameraFOV(Camera, ATan(1.0/10.0)*360.0/#PI)
   CameraRange(Camera, 1, w*h)
   CameraLocate(Camera, 0, 0, -10*h)
   RotateCamera(Camera, 180, 0, 0)
   MoveCamera(Camera, w, -h, 0)
   
   CameraBackColor(Camera, BackgroundColor)
   
   ProcedureReturn result
EndProcedure
Procedure gs_CreateMeshSprite(Sprite, Material, Mesh)
   Protected result=CreateEntity(Sprite, MeshID(Mesh), MaterialID(Material))
   If Sprite=#PB_Any : Sprite=result : EndIf
   
   AddElement(gs_Sprites())
   gs_Sprites()\Entity=Sprite
   gs_Sprites()\Material=Material
   gs_Sprites()\Mesh=Mesh
   gs_Sprites()\sx=1.0
   gs_Sprites()\sy=1.0
   
   ProcedureReturn result
EndProcedure
Procedure gs_CreateGridMesh(Mesh, Width, Height, Columns=1, Rows=1)
   If Columns<1 Or Rows<1 : ProcedureReturn : EndIf
   
   Protected result=CreateMesh(Mesh, 1000)
   If Mesh=#PB_Any : Mesh=result : EndIf
   
   Protected maxVertUV=(Columns+1)*(Rows+1)
   Protected maxFace=(2*Columns*Rows)
   Dim msVertUV.f(maxVertUV-1, 4)
   Dim msFace.w(maxFace-1, 2)
   
   Protected n, k, i, j, fd
   Protected x.f, y.f, z.f
   Protected dx.f=Width/Columns
   Protected dy.f=Height/Rows
   Protected u.f, v.f
   Protected du.f=1.0/Columns
   Protected dv.f=1.0/Rows
   
   For j=0 To Rows
      For i=0 To Columns
         ;{/// MESH FACES
         If i<Columns And j<Rows
            msFace(k, 2)=n
            msFace(k, 1)=n+1
            msFace(k, 0)=n+1+(Columns+0)
            k+1
            msFace(k, 2)=n+1
            msFace(k, 1)=n+1+(Columns+1)
            msFace(k, 0)=n+1+(Columns+0)
            k+1
         EndIf
         ;}
         
         ;{/// MESH VERT & UV
         msVertUV(n, 0)=x
         msVertUV(n, 1)=y
         msVertUV(n, 2)=z
         msVertUV(n, 3)=u
         msVertUV(n, 4)=v
         u+du
         x+dx
         n+1
         ;}
      Next
      v+dv : u=0
      y+dy : x=0
   Next
   
   SetMeshData(Mesh, #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate, @msVertUV(), maxVertUV)
   SetMeshData(Mesh, #PB_Mesh_Face, @msFace(), maxFace)
   
   ProcedureReturn result
EndProcedure
Procedure gs_CreateGridSprite(Sprite, Material, Width, Height, Columns=1, Rows=1)
   Protected Mesh=gs_CreateGridMesh(#PB_Any, Width, Height, Columns, Rows)
   ProcedureReturn gs_CreateMeshSprite(Sprite, Material, Mesh)
EndProcedure
Procedure gs_CloneSprite(Sprite, NewSprite, x=#PB_Ignore, y=#PB_Ignore, z=#PB_Ignore)
   Protected result=CopyEntity(Sprite, NewSprite)
   If NewSprite=#PB_Any : NewSprite=result : EndIf
   
   gs_FoundSprite(Sprite)
   Protected Material=gs_Sprites()\Material
   Protected Mesh=gs_Sprites()\Mesh
   Protected sx.f=gs_Sprites()\sx
   Protected sy.f=gs_Sprites()\sy
   
   AddElement(gs_Sprites())
   gs_Sprites()\Entity=NewSprite
   gs_Sprites()\Material=Material
   gs_Sprites()\Mesh=Mesh
   gs_Sprites()\sx=sx
   gs_Sprites()\sy=sy
   
   If x=#PB_Ignore : x=EntityX(Sprite) : EndIf
   If y=#PB_Ignore : y=EntityY(Sprite) : EndIf
   If z=#PB_Ignore : z=EntityZ(Sprite) : EndIf
   EntityLocate(NewSprite, x, y, z)
   
   ScaleEntity(NewSprite, sx, sy, 1)
   
   ProcedureReturn result
EndProcedure
Procedure gs_SpriteLocate(Sprite, x, y, z=#PB_Ignore)
   If z=#PB_Ignore : z=EntityZ(Sprite) : EndIf
   EntityLocate(Sprite, x, y, z)
EndProcedure
Procedure gs_MoveSprite(Sprite, x, y, z=#PB_Ignore)
   If z=#PB_Ignore : z=0 : EndIf
   MoveEntity(Sprite, x, y, z)
EndProcedure
Procedure gs_ScaleSprite(Sprite, sx.f, sy.f)
   ScaleEntity(Sprite, sx, sy, 1)
   
   gs_FoundSprite(Sprite)
   gs_Sprites()\sx=sx
   gs_Sprites()\sy=sy
EndProcedure
Procedure gs_CreateMaterial(Material, TextureID)
   CreateMaterial(Material, TextureID)
   DisableMaterialLighting(Material, #True)
EndProcedure
Procedure gs_GetSpriteMesh(Sprite)
   gs_FoundSprite(Sprite)
   ProcedureReturn gs_Sprites()\mesh
EndProcedure



Procedure DeformMesh(Mesh, Width, Height, Columns=1, Rows=1)
   Protected maxVertUV=(Columns+1)*(Rows+1)
   Protected maxFace=(2*Columns*Rows)
   Dim msVertUV.f(maxVertUV-1, 4)
   
   Protected n, k, i, j, fd
   Protected x.f, y.f, z.f
   Protected dx.f=Width/Columns
   Protected dy.f=Height/Rows
   Protected u.f, v.f
   Protected du.f=1.0/Columns
   Protected dv.f=1.0/Rows
   
   Static DeformTime.f
   DeformTime+#PI/100
   
   For j=0 To Rows
      For i=0 To Columns
         ;{/// MESH VERT & UV
         msVertUV(n, 0)=x
         msVertUV(n, 1)=y+10*Cos(2*#PI/Columns*i+DeformTime)
         msVertUV(n, 2)=z
         msVertUV(n, 3)=u
         msVertUV(n, 4)=v
         u+du
         x+dx
         n+1
         ;}
      Next
      v+dv : u=0
      y+dy : x=0
   Next
   
   SetMeshData(Mesh, #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate, @msVertUV(), maxVertUV)
EndProcedure


InitSprite()
InitSprite3D()
InitEngine3D()
InitKeyboard()

#w=800
#h=600
OpenWindow(0, 0, 0, #w, #h, "GRID SPRITE - PB4.30", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, #w, #h, 0, 0, 0)

UsePNGImageDecoder()
Add3DArchive(".", #PB_3DArchive_FileSystem)

gs_CreateCamera(1, 0, 0, #w, #h, #White)
gs_CreateMaterial(2, LoadTexture(200, "a.png"))
gs_CreateMaterial(3, LoadTexture(200, "alpha.png"))
AddMaterialLayer(2, LoadTexture(200, "a.png"), #PB_Material_Add)
ScrollMaterial(2, 0.1, 0.1, #PB_Material_Animated, 1)
;AmbientColor(RGB(255, 255, 255))

gs_CreateGridSprite(10, 2, 400, 300, 6, 6)
gs_CloneSprite(10, 11, 400, 0)
gs_CloneSprite(10, 12, 0, 300)
Global SpriteDeformMesh=gs_GetSpriteMesh(10)

gs_CreateGridMesh(4, 100, 100, 1, 1)
gs_CreateMeshSprite(20, 3, 4)
gs_ScaleSprite(20, 0.5, 0.5)
Global SpriteClones
For SpriteClones=21 To 29
   gs_CloneSprite(20, SpriteClones)
   gs_SpriteLocate(SpriteClones, 50*(SpriteClones-20), 50*(SpriteClones-20))
Next

Repeat
   DeformMesh(SpriteDeformMesh, 400, 300, 6, 6)
   RenderWorld()
   FlipBuffers()
Until WaitWindowEvent(10)=#PB_Event_CloseWindow
Last edited by eddy on Tue Mar 10, 2009 4:35 am, edited 1 time in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1285
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Post by Paul »

Not sure how you had this code running?!

Cut and paste into PB4.30 and it gives...
Error line: 154
InitEngine3D() has to be called before InitSprite()


Also you didn't include a.png or alpha.png
Image Image
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

Updated
- I added a mesh deformation function.

Image
Last edited by eddy on Tue Mar 10, 2009 4:38 am, edited 1 time in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

Paul wrote:Not sure how you had this code running?!

Cut and paste into PB4.30 and it gives...
Error line: 154
InitEngine3D() has to be called before InitSprite()

Also you didn't include a.png or alpha.png
... because I used DirectX9 as default subsystem for my last tests. 3D init is different.

I didn't include any files. You can replace them.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
Post Reply