Sprite Engine

Programmation avancée de jeux en PureBasic
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Sprite Engine

Message par boby »

Tout d'abord un GRAND merci à Eddy (du forum US). Je n'avais jamais touché à la 3D jusque là et j'ai pu apprendre vraiment beaucoup grâce à son Sprite Engine.

Encore en cours de dev, mais remplis déjà toutes les fonctions de la lib 2D de pure et même plus.

"J’espère qu'avec les différentes lib que j'ai récemment posté vous comprendrais que mon but et envie est d'essayer de faire avancer les choses et non pas juste critiquer gratuitement les choses de façon non constructive."

J'avoue que je n'ai pas encore trop réfléchi à comment m'y prendre pour l'application des shader ou le postprocess, mais ça va venir.
En attendant je n'ai pas pu testé toutes les fonctions (notamment la libération de mémoire) il n'est donc pas impossible de se retrouver avec des memoryleek ou autre invalide memory acces, je suis preneur de vos retour si vous trouvez des soucis !! (Si possible avec un exemple qui reproduit le problème)

J'ai commenté un max l'exemple pour servir de doc. Si certains points reste floue, j'essaierai de répondre aux éventuel questions.

Code : Tout sélectionner

;:=============================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.f,y.f,Width.f,Height.f)
  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.f,y.f,Width.f,Height.f)
    Protected *Layer.Layer = *Sprite3D\AttachedLayer, WidthT = TextureWidth(*Layer\SpriteSheetID), HeightT = TextureHeight(*Layer\SpriteSheetID)
    ;x+0.5 : y+0.5 : Width - 0.5 : Height - 0.5
    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
Exemple avec commentaire servant de documentation :

Code : Tout sélectionner

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 !
Dernière modification par boby le jeu. 24/janv./2019 13:35, modifié 3 fois.
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Sprite Engine

Message par boby »

MAJ : Les shaders arrivent ! Soyons franc... Je n'ai pas la moindre idée de ce que je fais et je tâtonne pas mal... Mais il semblerait que ça fonctionne !

Shader demo Basé sur le shader de transparence de Samuel
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Sprite Engine

Message par Ar-S »

J'ai essayé vite fait ton exemple. ça tourne très bien.
Faudra que je me penche dessus quand j'airai terminé ma radio (et surtout quand j'aurai du temps pour coder)
Merci pour ce partage.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Sprite Engine

Message par boby »

Merci d'avoir pris le temps de tester Ar-S, si tu fait des essais avec, tes retours m'interesse (bug trouvé, idée d'amélioration ou même si certains fonction ne t'on pas semblé naturel à utiliser...)
(Pour le moment je suis pas mal en galère sur les shaders... donc je n'avance plus beaucoup dessu)
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Sprite Engine

Message par Ar-S »

Je le note mais ne t'impatiente pas c'est pas pour demain :)
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Sprite Engine

Message par boby »

Ok laisse tomber Ar-S, le module n'est pas utilisable.
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Sprite Engine

Message par Ar-S »

Ah ? Pourquoi donc ?
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Sprite Engine

Message par boby »

MAJ : Correctif d'un "bug" du ClipSprite3D().
@Ar-S Par-ce que je suis obligé de bricoler pour que les valeurs soit correcte... Ca va forcément finir par foirer à un moment ou un autre... Je tente de faire un tetris avec... Ca permettra de se faire une idée si ça marche a peut près ou pas du tout...

Edit : Ça ne corrige rien du tout, retour en arrière sur ce que j'ai fait...
Dernière modification par boby le jeu. 24/janv./2019 13:35, modifié 1 fois.
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Sprite Engine

Message par Thyphoon »

très très bon mondule ! merci du partage ... :wink:
Répondre