Sprite Engine

Advanced game related topics
Papala
User
User
Posts: 38
Joined: Wed Sep 12, 2012 5:09 pm

Sprite Engine

Post by Papala »

First of all I would like to say a realy big thank to eddy for his Sprite Engine. I can realy learn a lot, that's an awesome code.
The engine is not over yet but already replace all pb's 2D lib function and more.

I can't test every function so may be unstable. If you find some bug i'm intrested if you can give me a little code that reproduce the bug.
If you have some question i'll do my best to answer you.

Code: Select all

;:=============================Sprite Engine =======================================
;:- Author          : Papala                                                       =
;:- Compiler        : PureBasic 5.70 LTS                                           =
;:- Target OS       : Mac, Linux, Windows                                          =
;:- Goal            : Replace every 2D fonction + Post production + Shader display =
;:==================================================================================

DeclareModule Sprite3D
  #Sprite3D_FlipHorizontal = %1
  #Sprite3D_FlipVertical = %10
  ;---------- View
  Declare CreateView(x.f=0, y.f=0, Width.f=100, Height.f=100,BackColor=0)
  Declare FreeView(View)
  Declare ViewBackColor(View,Color)
  Declare ViewMode(View,RenderMode)
  Declare ViewCameraID(View)
  
  ;---------- Spreet Sheet
  Declare CreateSpriteSheet(Width,Height,Name$="")
  Declare CopySpriteSheet(SpriteSheetID)
  Declare FreeSpriteSheet(SpriteSheet)
  Declare LoadSpriteSheet(File.s,Name$="")
  Declare SpriteSheetOutpout(SpriteSheet)
  Declare SpriteSheetTextureID(SpriteSheet)
  
  ;---------- Layer
  Declare CreateLayer(ViewID,SpriteSheetID,RenderQueue = 0,QueuePriority = 1,BlendingMode = #PB_Material_AlphaBlend, FilteringMode = #PB_Material_Trilinear , DisableLight = #True)
  Declare FreeLayer(Layer)
  Declare LayerMaterialID(Layer)
  Declare SetLayerRenderPriority(Layer,RenderQueue,QueuePriority)
  
  ;---------- Sprite
  Declare CreateSprite3D(Width,Height,LayerID)
  Declare FreeSprite3D(Sprite3D)
  Declare ClipSprite3D(Sprite3D,x,y,Width,Height)
  Declare CopySprite3D(Sprite3D)
  Declare DisplaySprite3D(Sprite3D,x,y)
  Declare FlipSprite3D(Sprite3D,Flag) ;Flag can be #Sprite3D_FlipHorizontal or/and #Sprite3D_FlipVertical
  Declare RenderSprite()
  Declare RestorTransformedSprite3D(Sprite3D)
  Declare RotateSprite3D(Sprite3D,Angle)
  Declare Sprite3DCollision(Sprite3D1,X1,Y1,Sprite3D2,X2,Y2)
  Declare Sprite3DFlip(Sprite3D,Flag)
  Declare Sprite3DWidth(Sprite3D)
  Declare Sprite3DHeight(Sprite3D)
  Declare SetSprite3DColor(Sprite3D,Color,CornerIndex = #PB_All)
  Declare SetSprite3DTransparency(Sprite3D,Transparency, CornerIndex = #PB_All)
  Declare TransformSprite3D(Sprite3D,X1,Y1,X2,Y2,X3,Y3,X4,Y4)
  Declare ZoomSprite3D(Sprite3D,Width,Height)
  
  ;---------- Post Process <<<<<<?????????????????????????????
;   Declare StartRenderToTexture(SpriteSheedID = #PB_Any,RenderMode = #PB_Texture_ManualUpdate)
;   Declare StopRenderToTexture(SpriteSheetID)
  
  ;---------- Shader <<<<<<<<<<<??????????????????????????????
  Declare CreateShaderLayer(ViewID,ScriptMaterialName$,SpriteSheetID,RenderQueue = 0,QueuePriority = 1,BlendingMode = #PB_Material_AlphaBlend,FilteringMode = #PB_Material_None, DisableLight = #True)
  ;Declare CreateShaderSpriteSheet() ;<==== ????????
  
EndDeclareModule

Module Sprite3D
  EnableExplicit
  Structure Coordinate
    x.f[4]
    y.f[4]
  EndStructure
  
  Structure DisplaySpr
    SpriteID.i
    x.f
    y.f
  EndStructure
  
  Structure Sprite3D
    AttachedLayer.i
    u.f[4]
    v.f[4]
    x.f
    y.f
    Width.f
    Height.f
    ZoomedWidth.l
    ZoomedHeight.l
    RotationAngle.w
    Color.i[4]
    FlipState.a
    Transformed.a
    Transform.Coordinate
    Vertices.Coordinate
  EndStructure
  
  Structure Layer
    SpriteSheetID.i
    Mesh.i
    Material.i
    AttachedView.i
    List Sprite.Sprite3D()
    List SpriteDisplayed.Sprite3D()
  EndStructure
  
  Structure View
    Camera.i
    CameraWidth.f
    CameraHeight.f
    Node.i
    List Layer.Layer()
  EndStructure
  
  Macro CalculVertices(Memory,xc,yc,Width,Height)
    Memory\Vertices\x[0] = xc
    Memory\Vertices\y[0] = yc
    Memory\Vertices\x[1] = Width
    Memory\Vertices\y[1] = yc
    Memory\Vertices\x[2] = xc
    Memory\Vertices\y[2] = Height
    Memory\Vertices\x[3] = Width
    Memory\Vertices\y[3] = Height
  EndMacro
  
  Global NewList SpriteEngine.View()
  
  ;---------- View
  Procedure CreateView(x.f=0, y.f=0, Width.f=100, Height.f=100,BackColor=0)
    Protected Entity, ScaleX.f, ScaleY.f
    AddElement(SpriteEngine())
    With SpriteEngine()
      \Camera = CreateCamera(#PB_Any,x,y,Width,Height)
      CameraBackColor(\Camera,BackColor)
      CameraRange(\Camera,0.1,1000)
      CameraProjectionMode(\Camera,#PB_Camera_Orthographic)
      SetOrientation(CameraID(\Camera),1,0,0,0)
      \CameraWidth = CameraViewWidth(\Camera)
      \CameraWidth = CameraViewHeight(\Camera)
      Entity=CreateEntity(#PB_Any, MeshID(CreateCube(#PB_Any, 100)), #PB_Material_None)
      ScaleEntity(Entity, 100, 100, 0.01)
      MoveEntity(Entity,0,0,500)
      
      \Node = CreateNode(#PB_Any)
      AttachNodeObject(\Node,EntityID(Entity))
      
      RenderWorld()
      If MousePick(\Camera, CameraViewX(\Camera), CameraViewY(\Camera))
        ScaleX = Abs(PickX()/(ScreenWidth()/2))
        ScaleY = Abs(PickY()/(ScreenHeight()/2))
      EndIf
      FreeEntity(Entity)
      ScaleNode(\Node,ScaleX,ScaleY,1)
      MoveNode(\Node,PickX(),PickY(),1)
    EndWith
    ProcedureReturn @SpriteEngine()
  EndProcedure
  
  Procedure FreeView(*View.View)
    If ChangeCurrentElement(SpriteEngine(),*View)
      ForEach *View\Layer()
        FreeLayer(@*View\Layer())
      Next
      DeleteElement(SpriteEngine())
      ProcedureReturn #True
    EndIf
    ProcedureReturn #False
  EndProcedure
  
  Procedure ViewBackColor(*View.View,Color)
    CameraBackColor(*View\Camera,Color)
  EndProcedure
  
  Procedure ViewMode(*View.View,RenderMode)
    CameraRenderMode(*View\Camera,RenderMode)
  EndProcedure
  
  Procedure ViewCameraID(*View.View)
    ProcedureReturn *View\Camera
  EndProcedure
  
  ;---------- Spreet Sheet
  Procedure CreateSpriteSheet(Width,Height,Name$="")
    ProcedureReturn CreateTexture(#PB_Any,Width,Height,Name$)
  EndProcedure
  
  Procedure CopySpriteSheet(SpriteSheetID)
    ProcedureReturn CopyTexture(SpriteSheetID,#PB_Any)
  EndProcedure
  
  Procedure FreeSpriteSheet(SpriteSheet)
    FreeTexture(SpriteSheet)
  EndProcedure
  
  Procedure LoadSpriteSheet(File.s,Name$="")
    Protected Texture, Image
    Image = LoadImage(#PB_Any,File)
    If Image
      Texture = CreateSpriteSheet(ImageWidth(Image),ImageHeight(Image),Name$)
      StartDrawing(TextureOutput(Texture))
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      DrawAlphaImage(ImageID(Image),0,0)
      StopDrawing()
      FreeImage(Image)
      ProcedureReturn Texture     
    EndIf
    ProcedureReturn #False
  EndProcedure
  
  Procedure SpriteSheetOutpout(SpriteSheet)
    ProcedureReturn TextureOutput(SpriteSheet)
  EndProcedure
  
  Procedure SpriteSheetTextureID(SpriteSheet)
    ProcedureReturn TextureID(SpriteSheet)
  EndProcedure
  
  ;---------- Layer
  Procedure CreateLayer(*ViewID.View,SpriteSheetID,RenderQueue = 0,QueuePriority = 1,BlendingMode = #PB_Material_AlphaBlend, FilteringMode = #PB_Material_Trilinear , DisableLight = #True)
    AddElement(*ViewID\Layer())
    With *ViewID\Layer()
      \AttachedView = *ViewID
      \SpriteSheetID = SpriteSheetID
      \Material = CreateMaterial(#PB_Any,SpriteSheetTextureID(SpriteSheetID))
      MaterialFilteringMode(\Material,FilteringMode)
      MaterialBlendingMode(\Material,BlendingMode)
      DisableMaterialLighting(\Material,DisableLight)
      \Mesh = CreateMesh(#PB_Any, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
      SetMeshMaterial(\Mesh,MaterialID(\Material))
      MeshVertexPosition(0, 0, 0)
      MeshVertexNormal(0, 0, 0)
      MeshVertexTangent(0, 0, 0)
      MeshVertexTextureCoordinate(0, 0)
      MeshVertexColor(RGBA(255, 255, 255, 255))
      MeshVertexPosition(1, 0, 0)
      MeshVertexPosition(1, 1, 0)
      MeshFace(0, 1, 2)
      FinishMesh(0)
      NormalizeMesh(\Mesh)
      AttachNodeObject(*ViewID\Node,MeshID(\Mesh))
    EndWith
    ProcedureReturn @*ViewID\Layer()
  EndProcedure
  
  Procedure FreeLayer(*Layer.Layer)
    If ChangeCurrentElement(SpriteEngine(),*Layer\AttachedView)
      If ChangeCurrentElement(SpriteEngine()\Layer(),*Layer)
        FreeMaterial(*Layer\Material) 
        DeleteElement(SpriteEngine()\Layer())
        ProcedureReturn #True
      EndIf
    EndIf
    ProcedureReturn #False
  EndProcedure
  
  Procedure LayerMaterialID(*Layer.Layer)
    ProcedureReturn *Layer\Material
  EndProcedure
  
  Procedure SetLayerRenderPriority(*Layer.Layer,RenderQueue,QueuePriority)
    SetRenderQueue(*Layer\Mesh,RenderQueue,QueuePriority)
  EndProcedure
  
  ;---------- Sprite
  Procedure CreateSprite3D(Width,Height,*LayerID.Layer)
    AddElement(*LayerID\Sprite())
    With *LayerID\Sprite()
      \AttachedLayer = *LayerID
      \Width = Width
      \Height = Height
      Protected CornerIndex
      For CornerIndex = 0 To 3
        \Color[CornerIndex] = RGBA(255,255,255,255)
      Next
      ClipSprite3D(@*LayerID\Sprite(),0,0,Width,Height)
      CalculVertices(*LayerID\Sprite(),0,0,Width,Height)
    EndWith
    ProcedureReturn @*LayerID\Sprite()
  EndProcedure
  
  Procedure FreeSprite3D(*Sprite3D.Sprite3D)
    Protected *Layer.Layer = *Sprite3D\AttachedLayer
    ChangeCurrentElement(*Layer\Sprite(),*Sprite3D)
    DeleteElement(*Layer\Sprite())    
  EndProcedure
  
  Procedure ClipSprite3D(*Sprite3D.Sprite3D,x,y,Width,Height)
    Protected *Layer.Layer = *Sprite3D\AttachedLayer, WidthT = TextureWidth(*Layer\SpriteSheetID), HeightT = TextureHeight(*Layer\SpriteSheetID)
    With *Sprite3D
      \u[0] = x/WidthT
      \v[0] = y/HeightT
      \u[1] = (Width+x)/WidthT
      \v[1] = y/HeightT
      \u[2] = x/WidthT
      \v[2] = (Height+y)/HeightT
      \u[3] = (Width+x)/WidthT
      \v[3] = (Height+y)/HeightT
    EndWith
  EndProcedure
  
  Procedure CopySprite3D(*Sprite3D.Sprite3D)
    Protected *Layer.Layer = *Sprite3D\AttachedLayer
    AddElement(*Layer\Sprite())
    CopyStructure(*Sprite3D,@*Layer\Sprite(),Sprite3D)
  EndProcedure
  
  Procedure DisplaySprite3D(*Sprite3D.Sprite3D,x,y)
    Protected *Layer.Layer = *Sprite3D\AttachedLayer
    AddElement(*Layer\SpriteDisplayed())
    CopyStructure(*Sprite3D,*Layer\SpriteDisplayed(),Sprite3D)
    *Layer\SpriteDisplayed()\x = x
    *Layer\SpriteDisplayed()\y = y
  EndProcedure
  
  Procedure FlipSprite3D(*Sprite3D.Sprite3D,Flag)
    Protected i
    *Sprite3D\FlipState ! Flag
    If *Sprite3D\FlipState & #Sprite3D_FlipHorizontal
      For i = 0 To 3
        *Sprite3D\u[i] = - Abs(*Sprite3D\u[i])
      Next
    Else
      For i = 0 To 3
        *Sprite3D\u[i] = Abs(*Sprite3D\u[i])
      Next
    EndIf
    If *Sprite3D\FlipState & #Sprite3D_FlipVertical
      For i = 0 To 3
        *Sprite3D\v[i] = - Abs(*Sprite3D\v[i])
      Next
    Else
      For i = 0 To 3
        *Sprite3D\v[i] = Abs(*Sprite3D\v[i])
      Next
    EndIf
  EndProcedure
  
  Procedure RenderSprite()
    Protected VertexIndex, *Sprite.Sprite3D, i
    ForEach SpriteEngine()
      ForEach SpriteEngine()\Layer()
        VertexIndex = 0
        UpdateMesh(SpriteEngine()\Layer()\Mesh,0)
        ForEach SpriteEngine()\Layer()\SpriteDisplayed()
          *Sprite = SpriteEngine()\Layer()\SpriteDisplayed()
          If *Sprite\Transformed
            For i = 0 To 3
              MeshVertexPosition(*Sprite\Transform\x[i]+*Sprite\x,*Sprite\Transform\y[i]+*Sprite\y,0)
              MeshVertexTextureCoordinate(*Sprite\u[i],*Sprite\v[i])
              MeshVertexColor(*Sprite\Color[i])
            Next 
          Else
            For i = 0 To 3
              MeshVertexPosition(*Sprite\Vertices\x[i]+*Sprite\x,*Sprite\Vertices\y[i]+*Sprite\y,0)
              MeshVertexTextureCoordinate(*Sprite\u[i],*Sprite\v[i])
              MeshVertexColor(*Sprite\Color[i])
            Next
          EndIf
          
          MeshFace(VertexIndex, VertexIndex+3, VertexIndex+1)
          MeshFace(VertexIndex+2, VertexIndex+3, VertexIndex)
          VertexIndex + 4
        Next
        FinishMesh(0)
        ClearList(SpriteEngine()\Layer()\SpriteDisplayed())
      Next
    Next
    
    RenderWorld()
  EndProcedure
  
  Procedure RestorTransformedSprite3D(*Sprite3D.Sprite3D)
;     Protected i
    *Sprite3D\Transformed = 0
;     For i = 0 To 3
;       *Sprite3D\Transform\x[i] = 0
;       *Sprite3D\Transform\y[i] = 0
;     Next
  EndProcedure
  
  Procedure RotateSprite3D(*Sprite3D.Sprite3D,Angle)
    If Angle = #PB_Default Or Angle > 359 : Angle = 0 : EndIf
    Protected rad.f = Radian(Angle), cos.f = Cos(rad), sin.f = Sin(rad), i, Width,Height
    If *Sprite3D\ZoomedHeight : Height = *Sprite3D\ZoomedHeight / 2 : Else : Height = *Sprite3D\Height / 2 : EndIf
    If *Sprite3D\ZoomedWidth : Width = *Sprite3D\ZoomedWidth / 2 : Else : Width = *Sprite3D\Width / 2 : EndIf
    *Sprite3D\RotationAngle = Angle
      *Sprite3D\Vertices\x[0] = (Width + cos * -Width - sin * -Height)
      *Sprite3D\Vertices\y[0] = (Height + sin * -Width + cos * -Height)
      *Sprite3D\Vertices\x[1] = (Width +  cos * Width - sin * -Height)
      *Sprite3D\Vertices\y[1] = (Height + sin * Width + cos * -Height)
      *Sprite3D\Vertices\x[2] = (Width + cos * -Width - sin * Height)
      *Sprite3D\Vertices\y[2] = (Height + sin * - Width + cos * Height)
      *Sprite3D\Vertices\x[3] = (Width + cos * Width - sin * Height)
      *Sprite3D\Vertices\y[3] = (Height + sin * Width + cos * Height)
    ProcedureReturn Angle
  EndProcedure
  
  Procedure Sprite3DCollision(*Sprite3D1.Sprite3D,X1,Y1,*Sprite3D2.Sprite3D,X2,Y2)
    Protected Colide,Width.f,Height.f
    If X1 > X2
      If *Sprite3D2\ZoomedWidth : Width = *Sprite3D2\ZoomedWidth : Else : Width = *Sprite3D2\Width : EndIf
      If X1 - X2 <= Width : Colide = 1 : Else : ProcedureReturn #False : EndIf
    Else
      If *Sprite3D1\ZoomedWidth : Width = *Sprite3D1\ZoomedWidth : Else : Width = *Sprite3D1\Width : EndIf
      If X2 - X1 <= Width : Colide = 1 : Else : ProcedureReturn #False : : EndIf
    EndIf
    If Y1 > Y2
      If *Sprite3D2\ZoomedHeight : Height = *Sprite3D2\ZoomedHeight : Else : Width = *Sprite3D1\Height : EndIf
      ProcedureReturn Bool(Y1 - Y2 <= Height)
    Else
      If *Sprite3D1\ZoomedHeight : Height = *Sprite3D1\ZoomedHeight : Else : Height = *Sprite3D1\Height : EndIf
      ProcedureReturn Bool(Y2 - Y1 <= Height)
    EndIf
  EndProcedure
  
  Procedure Sprite3DFlip(*Sprite3D.Sprite3D,Flag)
    ProcedureReturn *Sprite3D\FlipState & Flag
  EndProcedure
  
  Procedure Sprite3DWidth(*Sprite3D.Sprite3D)
    If *Sprite3D\ZoomedWidth
      ProcedureReturn *Sprite3D\ZoomedWidth
    Else
      ProcedureReturn *Sprite3D\Width
    EndIf
  EndProcedure
  
  Procedure Sprite3DHeight(*Sprite3D.Sprite3D)
    If *Sprite3D\ZoomedHeight
      ProcedureReturn *Sprite3D\ZoomedHeight
    Else
      ProcedureReturn *Sprite3D\Height
    EndIf
  EndProcedure
      
  Procedure SetSprite3DColor(*Sprite3D.Sprite3D,Color,CornerIndex = #PB_All)
    If CornerIndex = #PB_All
      Protected i
      For i = 0 To 3
        If Color = #PB_Default
          *Sprite3D\Color[i] = RGBA(255,255,255,Alpha(*Sprite3D\Color[i]))
        Else
          *Sprite3D\Color[i] = RGBA(Red(Color),Green(Color),Blue(Color),Alpha(*Sprite3D\Color[i]))
        EndIf
      Next
    Else
      If Color = #PB_Default
        *Sprite3D\Color[CornerIndex] = RGBA(255,255,255,Alpha(*Sprite3D\Color[CornerIndex]))
      Else
        *Sprite3D\Color[CornerIndex] = RGBA(Red(Color),Green(Color),Blue(Color),Alpha(*Sprite3D\Color[CornerIndex]))
      EndIf
    EndIf
  EndProcedure
  
  Procedure SetSprite3DTransparency(*Sprite3D.Sprite3D,Transparency, CornerIndex = #PB_All)
    If CornerIndex = #PB_All
      Protected i
      For i = 0 To 3
        If Transparency = #PB_Default
          *Sprite3D\Color[i] = RGBA(Red(*Sprite3D\Color[i]),Green(*Sprite3D\Color[i]),Blue(*Sprite3D\Color[i]),255)
        Else
          *Sprite3D\Color[i] = RGBA(Red(*Sprite3D\Color[i]),Green(*Sprite3D\Color[i]),Blue(*Sprite3D\Color[i]),Transparency)
        EndIf
      Next
    Else
      If Transparency = #PB_Default
        *Sprite3D\Color[CornerIndex] = RGBA(Red(*Sprite3D\Color[CornerIndex]),Green(*Sprite3D\Color[CornerIndex]),Blue(*Sprite3D\Color[CornerIndex]),255)
      Else
        *Sprite3D\Color[CornerIndex] = RGBA(Red(*Sprite3D\Color[CornerIndex]),Green(*Sprite3D\Color[CornerIndex]),Blue(*Sprite3D\Color[CornerIndex]),Transparency)
      EndIf
    EndIf
  EndProcedure
  
  Procedure TransformSprite3D(*Sprite3D.Sprite3D,X1,Y1,X2,Y2,X3,Y3,X4,Y4)
    *Sprite3D\Transformed = 1
    *Sprite3D\Transform\x[0] = X1
    *Sprite3D\Transform\x[1] = X2
    *Sprite3D\Transform\x[2] = X3
    *Sprite3D\Transform\x[3] = X4
    *Sprite3D\Transform\y[0] = Y1
    *Sprite3D\Transform\y[1] = Y2
    *Sprite3D\Transform\y[2] = Y3
    *Sprite3D\Transform\y[3] = Y4
  EndProcedure
  
  Procedure ZoomSprite3D(*Sprite3D.Sprite3D,Width,Height)
    If Width = #PB_Default : *Sprite3D\ZoomedWidth = 0 : Width = *Sprite3D\Width : Else : *Sprite3D\ZoomedWidth = Width : EndIf
    If Height = #PB_Default : *Sprite3D\ZoomedHeight = 0 : Height = *Sprite3D\Height : Else : *Sprite3D\ZoomedHeight = Height : EndIf
    CalculVertices(*Sprite3D,0,0,Width,Height)
    If *Sprite3D\RotationAngle : RotateSprite3D(*Sprite3D,*Sprite3D\RotationAngle) : EndIf
  EndProcedure 
  
  ;---------- Shader
  Procedure CreateShaderLayer(*ViewID.View,ScriptMaterialName$,SpriteSheetID,RenderQueue = 0,QueuePriority = 1,BlendingMode = #PB_Material_AlphaBlend,FilteringMode = #PB_Material_None, DisableLight = #True)
    AddElement(*ViewID\Layer())
    With *ViewID\Layer()
      \AttachedView = *ViewID
      \SpriteSheetID = SpriteSheetID
      \Material = GetScriptMaterial(#PB_Any,ScriptMaterialName$)
      RemoveMaterialLayer(\Material)
      AddMaterialLayer(\Material,SpriteSheetTextureID(SpriteSheetID))
      MaterialFilteringMode(\Material,FilteringMode)
      MaterialBlendingMode(\Material,BlendingMode)
      DisableMaterialLighting(\Material,DisableLight)
      \Mesh = CreateMesh(#PB_Any, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
      SetMeshMaterial(\Mesh,MaterialID(\Material))
      MeshVertexPosition(0, 0, 0)
      MeshVertexNormal(0, 0, 0)
      MeshVertexTangent(0, 0, 0)
      MeshVertexTextureCoordinate(0, 0)
      MeshVertexColor(RGBA(255, 255, 255, 255))
      MeshVertexPosition(1, 0, 0)
      MeshVertexPosition(1, 1, 0)
      MeshFace(0, 1, 2)
      FinishMesh(0)
      NormalizeMesh(\Mesh)
      AttachNodeObject(*ViewID\Node,MeshID(\Mesh))
    EndWith
    ProcedureReturn @*ViewID\Layer()
  EndProcedure
    
EndModule
Example with comment for documentation :

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
  InitEngine3D()
  InitSprite()
  
  OpenWindow(0,0,0,800,600,"test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0),0,20,800,580)
  
  ;Create a new camera, x y width and height are in % of screen size. Default BackColor is black.
  view = Sprite3D::CreateView(0,0,100,100,$FFFF00)
  
  ;Create new texture pages
  Sheet = Sprite3D::CreateSpriteSheet(30,30)
  sheet2 = Sprite3D::CreateSpriteSheet(30,30)
  
  ;Draw something on the textures
  StartDrawing(Sprite3D::SpriteSheetOutpout(Sheet))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  Box(0,0,15,15,RGBA(255,0,150,255))
  Box(15,0,15,15,RGBA(150,0,255,255))
  Box(0,15,15,15,RGBA(255,255,0,255))
  Box(15,15,15,15,RGBA(150,255,0,255))
  StopDrawing()
  StartDrawing(Sprite3D::SpriteSheetOutpout(sheet2))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  Circle(15,15,15,RGBA(38,75,255,255))
  StopDrawing()
  
  ;Create layer and link texture page to theim. Only one texture page can be apply by layer !!!
  layer = Sprite3D::CreateLayer(view,Sheet)
  layer2 = Sprite3D::CreateLayer(view,sheet2)
  
  ;Create some sprite3D linked to a layer. Layer will define the texture page to display to the sprite.
  Spr = Sprite3D::CreateSprite3D(30,30,layer)
  spr2 = Sprite3D::CreateSprite3D(30,30,layer2)
  
  ;Define Z order. Here the sprites linked to the layer 2 will be displayed on top
  Sprite3D::SetLayerRenderPriority(layer2,10,10)
  
  ;Set the #sprite transparency
  Sprite3D::SetSprite3DTransparency(spr2,150)
  
  timer = ElapsedMilliseconds()
  txt = TextGadget(#PB_Any,0,0,100,20,"")
  
  Repeat
    ;Simply display a sprite... Because spr2's layer is ordered, it will be display on top no mater if the sprite is display first.
    Sprite3D::DisplaySprite3D(spr2,305,245)
    
    ;Clip a sprite3d, same way of use than pb's clipsprite function, It define the x y width and heig of the sprite's texture to display.
    Sprite3D::ClipSprite3D(spr,15,0,15,15)
    
    ;Zoom (in pixel to display) the #sprite
    Sprite3D::ZoomSprite3D(spr,50,50)
    Sprite3D::DisplaySprite3D(spr,500,500)
    Sprite3D::ClipSprite3D(spr,0,0,30,30)
    
    ;reset the sprite zoom
    Sprite3D::ZoomSprite3D(spr,#PB_Default,#PB_Default)
    
    ;Apply a rotation to a #sprite
    rotate = Sprite3D::RotateSprite3D(spr,rotate)
    rotate + 1
    
    Sprite3D::SetSprite3DColor(spr,$0000FF)
    Sprite3D::SetSprite3DTransparency(spr,150)
    
    Sprite3D::DisplaySprite3D(spr,100,100)
    
    ;restor color, transparency and rotation to default
    Sprite3D::SetSprite3DColor(spr,#PB_Default)
    Sprite3D::SetSprite3DTransparency(Spr,#PB_Default)    
    Sprite3D::RotateSprite3D(spr,#PB_Default)
    
    Sprite3D::ZoomSprite3D(spr,80,80)
    Sprite3D::DisplaySprite3D(spr,300,200)
    
    ;Test if 2 sprites overlap. /!\ test with the curent with/heigh of each sprite and ignore sprite transformation (Via TransformSprite3D) for fast calculation /!\ 
    Debug Sprite3D::Sprite3DCollision(spr2,305,245,spr,300,200)
    
    ;Flip a sprite. If sprite is already fliped, it will be restor to normal, You can know if the sprite is fliper with Sprite3DFlip(#sprit,flag)
    Sprite3D::FlipSprite3D(spr,Sprite3D::#Sprite3D_FlipHorizontal|Sprite3D::#Sprite3D_FlipVertical)
    
    Sprite3D::ZoomSprite3D(spr,#PB_Default,#PB_Default)
    
    ;Tranform a sprite by giving him new vertice location. A sprite is a combination of 2 triangles, represented like this :
    ;X1/Y1          X2/Y2
    ;   -------------
    ;   |\          |
    ;   |  \        |
    ;   |    \      |
    ;   |      \    |
    ;   |        \  |
    ;   |          \|
    ;   -------------
    ;X3/Y3         X4/Y4
    Sprite3D::TransformSprite3D(Spr,-10,-10,50,-30,-10,50,50,25)
    Sprite3D::DisplaySprite3D(Spr,400,400)
    Sprite3D::FlipSprite3D(spr,Sprite3D::#Sprite3D_FlipHorizontal|Sprite3D::#Sprite3D_FlipVertical)
    
    ;Restor the sprite to normal
    Sprite3D::RestorTransformedSprite3D(spr)
    
    ;Once all display opperation are done, RenderSprite will process to the drawing opperation, must be call just before the flipbuffer
    Sprite3D::RenderSprite()
    FPS + 1
    FlipBuffers()
    If ElapsedMilliseconds() - timer >= 1000
      SetGadgetText(txt,"FPS : "+FPS)
      timer = ElapsedMilliseconds()
      FPS = 0
    EndIf
  Until WindowEvent() = #PB_Event_CloseWindow
CompilerEndIf
Have fun.
Last edited by Papala on Fri Jan 18, 2019 2:53 pm, edited 1 time in total.
User avatar
Fig
Enthusiast
Enthusiast
Posts: 351
Joined: Thu Apr 30, 2009 5:23 pm
Location: Côtes d'Azur, France

Re: Sprite Engine

Post by Fig »

Looks nice, but could you give us an exemple ?
Does sprite collision works with rotated sprite ?
There are 2 methods to program bugless.
But only the third works fine.

Win10, Pb x64 5.71 LTS
Papala
User
User
Posts: 38
Joined: Wed Sep 12, 2012 5:09 pm

Re: Sprite Engine

Post by Papala »

Their is an example with lot of comment.
Does sprite collision works with rotated sprite ?
Collision check don't take care of rotation of the sprite so not really, i'd try to have a really fast collision check, i'll try to have a more precise one (but slower). But not in my priority.
Papala
User
User
Posts: 38
Joined: Wed Sep 12, 2012 5:09 pm

Re: Sprite Engine

Post by Papala »

Update. From now i'm realy not sure about what am i doing... But it seem it work o_O.

Here is a little sample on how to apply shader on layer base on Samuel transparency shader.

Shader

@Samuel : If you have any idea of how can we get the textureID apply on the material when created with GetScriptMaterial() I would realy appreciate this information ^^"
Env
Enthusiast
Enthusiast
Posts: 151
Joined: Tue Apr 27, 2010 3:20 pm
Location: Wales, United Kingdom

Re: Sprite Engine

Post by Env »

This is brilliant! Thank you :)
Thanks!
ultimzeus
New User
New User
Posts: 6
Joined: Thu Sep 20, 2018 12:27 pm

Re: Sprite Engine

Post by ultimzeus »

Hello

Seems to be nice work. thank you

but the problem is : if you combine it with 3D objects like meshs and when you need to change the camera position or direction, all the sprites will be affected.! Seems that you need to draw them with some projection matrix to stay undependant from main camera view
Post Reply