Chargement progressif et non bloquant des assets

Généralités sur la programmation 3D
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Chargement progressif et non bloquant des assets

Message par falsam »

j'ai été inspiré par le sujet Flux en France - 3D de Cool Dji.

Le chargement des assets est un peu long. J'ai cherché un moyen de faire un chargement non bloquant (Esc pour quitter en cours de chargement) des données.

Objectif :
- Charger 500 meshs
- Effectuer une rotation sur chacun des axes x y et z de chaque mesh
- Déplacement avec les fléches du clavier et la souris.

Voila ce que ça donne.

Code : Tout sélectionner

EnableExplicit

;Police
Global FontInfo = LoadFont(-1, "Arial", 12)

;Scene [3D] 
Global Camera, MouseX.f, MouseY.f, Light

;Assets & Preload
Global NewMap Material() 
Global NewMap Mesh()
Global NewMap Entity() 

Global CountLoad, MaxLoad = 500, CurrentOperation.b

;Sprite [2D]
;Bottom
Global Bottom 

;Returns a random float in the interval [0.0, Maximum]
Macro RandomFloat(Maximum=1.0)
  ( Random(2147483647)*Maximum*4.6566128752457969241e-10 ) ; Random * 1/MaxRandom
EndMacro

;Returns a random sign {-1, 1}
Macro RandomSign()
  ( Random(1)*2-1 ) 
EndMacro

;Summary
Declare GamePreload()
Declare GameLoad()
Declare RenderGame3D()
Declare RenderGame2D() 
Declare Exit()

GameLoad()

Procedure AddAssets(Id.s, Type, Value)
  If Not CurrentOperation 
    CurrentOperation = #True
    Select Type
      Case 1 ;Material
        Material(Id) = Value
        If Material(Id)
          CountLoad + 1
          CurrentOperation = #False
        EndIf
        
      Case 2 ;Mesh
        Mesh(Id) = Value
        If Mesh(Id)
          CountLoad + 1
          CurrentOperation = #False
        EndIf
        
      Case 3 ; Entity
        Entity(Id) = Value
        If Entity(Id)
          CountLoad + 1
          CurrentOperation = #False
        EndIf
    EndSelect    
  EndIf
EndProcedure
  
Procedure GamePreload()
  Static n
  Protected x.f, y.f, z.f
  
  Select CountLoad 
    Case 0 : AddAssets("box", 1, CreateMaterial(-1, TextureID(LoadTexture(-1, "MRAMOR6X6.jpg"))))
    Case 1 : AddAssets("box", 2, CreateCube(-1, 10))
    Case 3 : AddAssets("sinbad", 2, LoadMesh(-1, "sinbad.mesh"))
    Case 4 : AddAssets("sinbad", 3, CreateEntity(-1, MeshID(Mesh("sinbad")), #PB_Material_None))
      
    Case 4,6,7,8,9,10,11,12,13, 14, 15, 16, 17, 18, 19, 20
      x = RandomFloat(100) * RandomSign()
      y = RandomFloat(50) * RandomSign()
      z = RandomFloat(100) * RandomSign()
      n + 1 
      AddAssets("sinbad" + n, 3, CreateEntity(-1, MeshID(Mesh("sinbad")), #PB_Material_None, x, y, z))
      
    Default
      x = RandomFloat(400) * RandomSign()
      y = RandomFloat(100) * RandomSign()
      z = RandomFloat(400) * RandomSign()
      n + 1 
      AddAssets("box" + n, 3, CreateEntity(-1, MeshID(Mesh("box")), MaterialID(Material("box")), x, y, z))
  EndSelect
      
  If CountLoad = MaxLoad
    UnbindEvent(#PB_Event_Timer, @GamePreload())
  EndIf  
EndProcedure

Procedure GameLoad()
  Protected Window 
    
  If InitEngine3D() And  InitKeyboard() And InitSprite() And InitMouse() And InitSound()
    Window = OpenWindow(#PB_Any, 0, 0, 0, 0, "", #PB_Window_Maximize | #PB_Window_BorderLess)
    
    ;-[Screen]
    OpenWindowedScreen(WindowID(Window),0, 0, WindowWidth(Window) , WindowHeight(Window))    
    KeyboardMode(#PB_Keyboard_International | #PB_Keyboard_AllowSystemKeys)
    
    ;-[2D]
    Bottom  = CreateSprite(-1, ScreenWidth(), 150, #PB_Sprite_AlphaBlending)
   
    ;-[3D]
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/textures", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Packs/Sinbad.zip", #PB_3DArchive_Zip)
    Parse3DScripts()
    
    AddWindowTimer(Window, 0, 1)    
    BindEvent(#PB_Event_Timer, @GamePreload())  
        
    ;-Camera
    Camera = CreateCamera(#PB_Any, 0, 0, 100, 100)
    CameraBackColor(Camera, RGB(50, 51, 80))
    MoveCamera(Camera, 0, 0, -50)
    CameraLookAt(Camera, 0, 0, 0)
    
    ;-Light
    Light = CreateLight(#PB_Any, RGB(255, 255, 255), 0, 0, 0, #PB_Light_Point)
    SetLightColor(Light, #PB_Light_SpecularColor, RGB(255, 255, 255))
    SetLightColor(Light, #PB_Light_DiffuseColor, RGB(255, 255, 255))
        
    ;-Loop
    While #True
      Repeat : Until WindowEvent() = 0
      FlipBuffers()  
      RenderGame3D()
      RenderWorld()
      RenderGame2D()
    Wend
  Else
    
  EndIf 
EndProcedure

Procedure RenderGame3D()    
  Protected CameraSpeed.f, CameraLateralSpeed.f
  
  ;-Events Keyboard
  If ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Escape)
      Exit()
    EndIf  
    
    If KeyboardPushed(#PB_Key_Up)
      CameraSpeed = -3
    ElseIf KeyboardPushed(#PB_Key_Down)
      CameraSpeed = 3
    Else
      CameraSpeed = 0
    EndIf
    
    If KeyboardPushed(#PB_Key_Left)
      CameraLateralSpeed = -3
    ElseIf KeyboardPushed(#PB_Key_Right)
      CameraLateralSpeed = 3
    Else
      CameraLateralSpeed = 0
    EndIf
  EndIf
  
  ;-Events Mouse
  If ExamineMouse()
    MouseX = -MouseDeltaX() *  0.05
    MouseY = -MouseDeltaY() *  0.05
  EndIf 
  
  ForEach Entity()
    RotateEntity(Entity(), 1, 1 , 1, #PB_Relative)
  Next
  
  ;-Camera movement
  RotateCamera(Camera, MouseY, MouseX, 0, #PB_Relative)
  MoveCamera(Camera, CameraLateralSpeed, 0, CameraSpeed, #PB_Absolute|#PB_Local)  
EndProcedure

Procedure RenderGame2D()
  Protected Buffer.s = "Loading in progress"
  
  Protected n.f = ((ScreenWidth() - 20) / MaxLoad)
  
  StartDrawing(SpriteOutput(Bottom))
  DrawingFont(FontID(FontInfo))
  Box(0, 0, ScreenWidth(), SpriteHeight(Bottom), RGBA(0, 0, 0, 0))

  DrawingMode(#PB_2DDrawing_AlphaChannel)
  Box(0, 0, ScreenWidth(), SpriteHeight(Bottom), RGBA(0, 0, 0, 110))
  DrawingMode(#PB_2DDrawing_Transparent)
  
  DrawText(10, 10, ". : : Help : : .")
  DrawText(10, 40, "Esc : Exit.")
  DrawText(10, 70, "Keyboard arrows and mouse to move around.")
  
  DrawingMode(#PB_2DDrawing_Default)
  If CountLoad <> MaxLoad
    Box(10, 100, ScreenWidth() - 20, 24, RGB(55, 59, 190))
    Box(10, 100, n * CountLoad, 24, RGB(255, 255, 255))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText((ScreenWidth() - TextWidth(Buffer))/2, 102, Buffer, RGB(0, 0, 0))
  EndIf
  
  StopDrawing()
  
  DisplayTransparentSprite(Bottom, 0, ScreenHeight() - SpriteHeight(Bottom))
EndProcedure

Procedure Exit()
  End
EndProcedure
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: Chargement progressif et non bloquant des assets

Message par Cool Dji »

Wouah !

Great, j'ai pas tout compris car j'ai regardé vite fait mais je vais prendre le temps de comprendre.

J'ai pas vu ton topic plus tôt, dommage car j'ai fait une demo ce midi au boulot et le chargement progressif aurait bien été utile puisqu'en plus des flux j'ai chargé plus de 1000 sprites...
Only PureBasic makes it possible
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Chargement progressif et non bloquant des assets

Message par Ar-S »

En tout cas c'est propre et fluide. 8)
~~~~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
Avatar de l’utilisateur
venom
Messages : 3071
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Chargement progressif et non bloquant des assets

Message par venom »

Bonjour,

Oui c'est fluide et sympa a voir. Bravo falsam 8)






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Répondre