[OK] Redimensionner un sprite

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
microdevweb
Messages : 1802
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Redimensionner un sprite

Message par microdevweb »

Waouww falsam ça déchire. Mais ou est vraiment le rapport avec Pb?
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Redimensionner un sprite

Message par falsam »

microdevweb a écrit :Waouww falsam ça déchire. Mais ou est vraiment le rapport avec Pb?
Aucun.
falsam a écrit :Je sens que je vais lacher 5 minutes lixu pour une démo de ce type
J'ai oublié de préciser que je vais le faire avec PB en 2.5D, C'est à dire utiliser la 3D pour faire de la 2D.

C'est une expérimentation :)
Configuration : Windows 11 Famille 64-bit - PB 6.20 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
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Redimensionner un sprite

Message par blendman »

Bon, j'ai réussi à faire un simili truc de painting sur texture via l'engine 3D, et bien résultat, c'est pas terrible du tout, niveau performance.

Dessiner sur une texture est bien long que de dessiner sur un sprite ^^. Donc, je vais garder mon système actuel qui est bien plus fluide.
En plu, en 3D, c'est vite la galère pour gérer les coordonnées correctement, contrairement aux sprites où un sprite en (0,0) est effectivement en (0,0) par rapport au screen, en 3D, une entity en (0,0) n'est pas en (0,0) par rapport au screen, il est en (0,0) par rapport au repère du monde et comme on regarde le monde par rapport à une caméra qui n'est pas en (0,0), et bien on a le droit à un zoom qu'on ne connait pas, les coordonnées qui ne sont pas en (0,0), mais en (?;?).
Bref, pas convaincu du tout pour le moment ^^.

J'attends l'exemple de falsam pour voir de quoi il retourne.
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Redimensionner un sprite

Message par falsam »

blendman a écrit :J'attends l'exemple de falsam pour voir de quoi il retourne.
Et bien ce n'est pas concluant.

-Gérer les coordonnées des sprites n'est pas évident en fonction de la taille.
-Souci de flickering.

Le résultat avec ce fichier
:arrow: Vache.zip (Sources + assets)

Utilisez les fleches du clavier pour voir le derriere des vaches :p
Configuration : Windows 11 Famille 64-bit - PB 6.20 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
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Redimensionner un sprite

Message par blendman »

je n'ai pas de flickering, mais il arrive que le moulin ou des vaches passent derrière le sol.

Sinon, c'est quand même pas mal.

Mon essai de painting sur des texture et avec la 3D n'est pas concluant du tout (ça rame, et c'est la galère niveau coordonnées).
Bref, à moins de trouver un exemple valable, je laisse tomber de ce coté-là, et je garde les sprites pour dessiner dessus, c'est beaucoup plus rapide :).

Code : Tout sélectionner

; pb 5.30
; 01/07/2015
; blendman : test to use the 3D to draw and paint

IncludeFile "Screen3DRequester.pb"

If InitEngine3D()
 
  InitSprite()
  InitKeyboard()
  InitMouse()
    
  If Screen3DRequester()
          
    MaterialFilteringMode(#PB_Default, #PB_Material_Anisotropic, 8)
    
    ;- Material
    CreateTexture(0,1024,768)  

    CreateMaterial(0, TextureID(0))
    SetMaterialColor(0, #PB_Material_SelfIlluminationColor, RGB(255, 255, 255))
    MaterialBlendingMode(0, #PB_Material_AlphaBlend)
    MaterialFilteringMode(0, #PB_Material_None)
    MaterialCullingMode(0, #PB_Material_NoCulling)
        
    CreateMesh(0)
    CreatePlane(0,1024,768,1,1,1,1) 
    UpdateMeshBoundingBox(0)
    SetMeshMaterial(0, MaterialID(0), 0)
    
    ;-Entity
    CreateEntity(0, MeshID(0), #PB_Material_None,0,0,0)    
    ;ScaleEntity(0, 1, 1, 1)
    
    ;-Camera
    CreateCamera(0, 0, 0, 100, 100)
    Zoom = 100
    MoveCamera(0, 0, 0, Zoom, #PB_Absolute)
    CameraProjectionMode(0, #PB_Camera_Orthographic)
    CameraBackColor(0, RGB(120,120,120))
    RotateEntity(0,90,180,0, #PB_Relative)
    
    Repeat
      
      Screen3DEvents()
            
      ;ExamineMouse()
      ;{ mouse   
      If paint = 1
        mx = WindowMouseX(0) ; -100
        my = WindowMouseY(0)
        Z.d = zoom*0.01
        If mx > 0 And my >0 And mx < ScreenWidth()-1 And my<ScreenHeight()-1
          If StartDrawing(TextureOutput(0))
            DrawingMode(#PB_2DDrawing_AlphaBlend)
            Circle(mx/z,my/z,10)
            StopDrawing()
          EndIf
        EndIf        
      EndIf      
      ;}
            
      ;{ Keyboard
      ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Add)
        If zoom > 10
          Zoom - 10
        ElseIf zoom > 1
          zoom -1
        EndIf
        MoveCamera(0, 0, 0, zoom, #PB_Absolute)
      EndIf
      If KeyboardPushed(#PB_Key_Subtract)        
        zoom +10        
        MoveCamera(0, 0, 0, zoom, #PB_Absolute)
      EndIf
      ;}
      ; RotateEntity(0, 1.1, 0.3, 1.0, #PB_Relative)
      
      RenderWorld()
      
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End
Et le screen3D.pb, adapté du screen3Drequester.pb :

Code : Tout sélectionner

;
; ------------------------------------------------------------
;
;   PureBasic - Common 3D functions
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

#WINDOW_Screen3DRequester = 0

#GADGET_FullScreen        = 1
#GADGET_Windowed          = 2
#GADGET_ScreenModesLabel  = 3
#GADGET_WindowedModes     = 4
#GADGET_Launch            = 5
#GADGET_Cancel            = 6
#GADGET_Logo              = 7
#GADGET_Frame             = 8
#GADGET_ScreenModes       = 9
#GADGET_Antialiasing      = 10
#GADGET_AntialiasingModes = 11


Global Screen3DRequester_FullScreen, Screen3DRequester_ShowStats
Global Paint.a

UsePNGImageDecoder()

Procedure Screen3DRequester()

  OpenPreferences(GetHomeDirectory()+"PureBasicDemos3D.prefs")
    FullScreen          = ReadPreferenceLong  ("FullScreen"        , 0)
    FullScreenMode$     = ReadPreferenceString("FullScreenMode"    , "800x600")
    WindowedScreenMode$ = ReadPreferenceString("WindowedScreenMode", "800x600")
    AAMode              = ReadPreferenceLong  ("Antialiasing"      , 0)
    
  If ExamineDesktops()
    ScreenX = DesktopWidth(0)
    ScreenY = DesktopHeight(0)
    ScreenD = DesktopDepth(0)
    ScreenF = DesktopFrequency(0)
  EndIf
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
    GadgetHeight = 30
  CompilerElse
    GadgetHeight = 20
  CompilerEndIf
   
  If OpenWindow(#WINDOW_Screen3DRequester, 0, 0, 396, GadgetHeight*4 + 155, "PureBasic - 3D Demos", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_Invisible)
   
    Top = 6
   
    ImageGadget  (#GADGET_Logo, 6, Top, 0, 0, LoadImage(0,#PB_Compiler_Home+"examples/3d/Data/PureBasic3DLogo.png"), #PB_Image_Border) : Top+76
   
    FrameGadget(#GADGET_Frame, 6, Top, 384, GadgetHeight*3 +45, "", 0) : Top+20
   
    OptionGadget(#GADGET_FullScreen, 40, Top, 130, GadgetHeight, "Fullscreen")        : Top+GadgetHeight+5
    OptionGadget(#GADGET_Windowed  , 40, Top, 130, GadgetHeight, "Windowed")          : Top+GadgetHeight+5
    TextGadget(#GADGET_Antialiasing, 40, Top+5, 130, GadgetHeight, "Antialiasing mode") : Top - ((GadgetHeight+5) * 2)
   
    ComboBoxGadget (#GADGET_ScreenModes  , 190, Top, 150, GadgetHeight+1)     : Top+GadgetHeight+5
    ComboBoxGadget (#GADGET_WindowedModes, 190, Top, 150, GadgetHeight+1)     : Top+GadgetHeight+5
    ComboBoxGadget (#GADGET_AntialiasingModes, 190, Top, 150, GadgetHeight+1) : Top+GadgetHeight+25
  
    ButtonGadget (#GADGET_Launch,   6, Top, 180, GadgetHeight+5, "Launch", #PB_Button_Default)
    ButtonGadget (#GADGET_Cancel, 200, Top, 190, GadgetHeight+5, "Cancel")
      
    AddGadgetItem(#GADGET_AntialiasingModes,-1,"None")
    AddGadgetItem(#GADGET_AntialiasingModes,-1,"FSAA x2")
    AddGadgetItem(#GADGET_AntialiasingModes,-1,"FSAA x4")
    AddGadgetItem(#GADGET_AntialiasingModes,-1,"FSAA x6")
  
    SetGadgetState(#GADGET_AntialiasingModes,AAMode)
    
    If ExamineScreenModes()
      
      Position = 0
      While NextScreenMode()
        
        Position + 1
        Width       = ScreenModeWidth()
        Height      = ScreenModeHeight()
        Depth       = ScreenModeDepth()
        RefreshRate = ScreenModeRefreshRate()
        
        If Depth > 8
          AddGadgetItem(#GADGET_ScreenModes, -1, Str(Width)+"x"+Str(Height)+"x"+Str(Depth)+"@"+Str(RefreshRate))
          If ScreenX = Width And ScreenY = Height And ScreenD = Depth And ScreenF = RefreshRate
            SetGadgetState(#GADGET_ScreenModes, Position)
            FullScreenMode$ = Str(Width)+"x"+Str(Height)+"x"+Str(Depth)+"@"+Str(RefreshRate)
          EndIf  
        EndIf
       
      Wend        
      
    EndIf
    
    ExamineDesktops()
    NbScreenModes = 7
    
    Restore WindowedScreenDimensions

    Repeat      
      Read.l CurrentWidth
      Read.l CurrentHeight
      
      If CurrentWidth < DesktopWidth(0) And CurrentHeight < DesktopHeight(0)
        AddGadgetItem(#GADGET_WindowedModes, -1, Str(CurrentWidth)+ "x"+Str(CurrentHeight))
        NbScreenModes - 1
      Else
        NbScreenModes = 0
      EndIf
      
    Until NbScreenModes = 0
    
    If FullScreen
      SetGadgetState(#GADGET_FullScreen, 1)
    Else
      SetGadgetState(#GADGET_Windowed  , 1)
    EndIf

    SetGadgetText (#GADGET_ScreenModes  , FullScreenMode$)
    SetGadgetText (#GADGET_WindowedModes, WindowedScreenMode$)
    
    DisableGadget (#GADGET_ScreenModes  , 1-FullScreen)
    DisableGadget (#GADGET_WindowedModes, FullScreen)
    
    HideWindow(#WINDOW_Screen3DRequester, 0)
    
    Repeat
      
      Event = WaitWindowEvent()
      
      Select Event
        
      Case #PB_Event_Gadget
        
        Select EventGadget()
          
        Case #GADGET_Launch
          Quit = 2
          
        Case #GADGET_Cancel
          Quit = 1
          
        Case #GADGET_FullScreen
          DisableGadget(#GADGET_ScreenModes  , 0)
          DisableGadget(#GADGET_WindowedModes, 1)
        
        Case #GADGET_Windowed
          DisableGadget(#GADGET_ScreenModes  , 1)
          DisableGadget(#GADGET_WindowedModes, 0)
                 
        EndSelect
        
      Case #PB_Event_CloseWindow
        Quit = 1
        
      EndSelect
      
    Until Quit > 0
    
    FullScreen          = GetGadgetState(#GADGET_FullScreen)
    FullScreenMode$     = GetGadgetText (#GADGET_ScreenModes)
    WindowedScreenMode$ = GetGadgetText (#GADGET_WindowedModes)
    AAMode              = GetGadgetState(#GADGET_AntialiasingModes)
    
    CloseWindow(#WINDOW_Screen3DRequester)
      
  EndIf
  
  If Quit = 2 ; Launch button has been pressed
  
    CreatePreferences(GetHomeDirectory()+"PureBasicDemos3D.prefs")
      WritePreferenceLong  ("FullScreen"        , FullScreen)          
      WritePreferenceString("FullScreenMode"    , FullScreenMode$)     
      WritePreferenceString("WindowedScreenMode", WindowedScreenMode$) 
      WritePreferenceLong  ("Antialiasing"      , AAMode)  
      
    If FullScreen
      ScreenMode$ = FullScreenMode$
    Else
      ScreenMode$ = WindowedScreenMode$
    EndIf
    
    RefreshRate = Val(StringField(ScreenMode$, 2, "@"))
    
    ScreenMode$ = StringField(ScreenMode$, 1, "@") ; Remove the refresh rate info, so we can parse it easily
    
    ScreenWidth  = Val(StringField(ScreenMode$, 1, "x"))
    ScreenHeight = Val(StringField(ScreenMode$, 2, "x"))
    ScreenDepth  = Val(StringField(ScreenMode$, 3, "x"))
    
    Screen3DRequester_FullScreen = FullScreen ; Global variable, for the Screen3DEvents
    
    Select AAMode
      Case 0:
        AntialiasingMode(#PB_AntialiasingMode_None)
      Case 1:
        AntialiasingMode(#PB_AntialiasingMode_x2)
      Case 2:
        AntialiasingMode(#PB_AntialiasingMode_x4)
      Case 3:
        AntialiasingMode(#PB_AntialiasingMode_x6)
    EndSelect
    
    If FullScreen
      Result = OpenScreen(ScreenWidth, ScreenHeight, ScreenDepth, "3D Demos", #PB_Screen_WaitSynchronization, RefreshRate)
    Else
      If OpenWindow(0, 0, 0, ScreenWidth, ScreenHeight+MenuHeight(), "PureBasic - 3D Demos", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
      
        CreateMenu(0, WindowID(#WINDOW_Screen3DRequester))
          MenuTitle("Project")
          MenuItem(0, "Quit")
    
          MenuTitle("About")
          MenuItem(1, "About...")
              
        Result = OpenWindowedScreen(WindowID(#WINDOW_Screen3DRequester), 100, 0, ScreenWidth-100, ScreenHeight, 0, 0, 0)
      EndIf
    EndIf
    

    
    
  EndIf
     
  ProcedureReturn Result
EndProcedure


Procedure Screen3DEvents()

  If Screen3DRequester_FullScreen = 0 ; Handle all the events relatives to the window..
  
    Repeat
      Event = WindowEvent()
      
      Select Event
      
        Case #PB_Event_Menu
          Select EventMenu()
          
            Case 0
              Quit = 1
          
            Case 1
              MessageRequester("Info", "Windowed 3D in PureBasic !", 0)
              
          EndSelect
          
        Case #WM_LBUTTONDOWN  
          Paint = 1
          
           Case #WM_LBUTTONUP  
          Paint = 0
                    
        Case #PB_Event_CloseWindow
          Quit = 1
        
      EndSelect
      
      If Quit = 1 : End : EndIf  ; Quit the app immediately
    Until Event = 0
    
  EndIf
     
EndProcedure

     
DataSection
  WindowedScreenDimensions:
    Data.l  320, 240
    Data.l  512, 384      
    Data.l  640, 480
    Data.l  800, 600     
    Data.l 1024, 768
    Data.l 1280, 1024
    Data.l 1600, 1200
EndDataSection
A mon sens les fonctions "pures 2D" de n'importe quel Os/Langage n'ont plus aucun intérêt par rapports aux fonctions 3D, surtout quand elles sont aussi facilement utilisables qu'en PB.
En testant, on se rend compte de l'immense intérêt qu'on les fonctions pure 2D par rapport aux fonctions 3D. Certaines sont beaucoup plus rapides en 2D qu'en 3D (dessiner sur un sprite est beaucoup plus rapide que dessiner sur une texture en purebasic)
C'est pour ça qu'on garde les sprites en 2D ;)
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Redimensionner un sprite

Message par blendman »

Salut

Je reviens sur ce sujet-ci, car j'ai trouvé une solution et je voulais avoir votre avis :
- je passe par une map() pour gérer mes sprites

Code : Tout sélectionner

InitSprite()
Structure sSprite
  Sprite.i ; id du sprite
  Image.i ;id de l'image
EndStructure
Global NewMap Sprite.sSprite()

Procedure CreateSprite2(sprite,w,h)
  
  NewSprite = CreateSprite(sprite,w,h,#PB_Sprite_AlphaBlending )
  
  If sprite = #PB_Any
    sprite = newsprite
  EndIf
  
  ; creation of the new sprite
  key$ = Str(Sprite)
  AddMapElement(sprite(), key$)
  Sprite(key$)\Sprite = sprite
  Sprite(key$)\Image = -1

  ProcedureReturn NewSprite 
EndProcedure

Procedure SetSpriteSize(sprite,w,h)
  
  OriginalSpriteId = sprite
  key$ = Str(OriginalSpriteId)
  
  Idsprite = Sprite(key$)\Sprite
  
  FreeSprite(Idsprite)
    
    If OriginalSpriteId > 10000
      sprite = #PB_Any
    EndIf
    
    NewSprite= CreateSprite(sprite,w,h,#PB_Sprite_AlphaBlending) 
    
    If sprite = #PB_Any
      sprite = NewSprite
    EndIf
    
    Sprite(key$)\Sprite = sprite
    
  ; puis on redessine le sprite si besoin
    If Sprite(key$)\Image <> -1
      If StartDrawing(SpriteOutput(sprite))
        ; erase the sprite
        DrawingMode(#PB_2DDrawing_AllChannels)
        Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,0,0))
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        DrawAlphaImage(ImageID(Sprite(key$)\Image),0,0)
        StopDrawing()
      EndIf
    EndIf   
EndProcedure

screenwidth = 640
screenheight = 480
OpenWindow(0, 0, 0, screenwidth, screenheight, "Game", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0),0,0,screenwidth, screenheight)=0
  MessageRequester("Error", "Can't Open Screen!", 0)
  End
EndIf

ui = CreateSprite2(#PB_Any,10,50)
; Change size of the sprite
SetSpriteSize(ui,128,60)

Repeat
  Repeat
    event = WaitWindowEvent(1)
    If  event = #PB_Event_CloseWindow
      End
    EndIf    
  Until event = 0
  DisplayTransparentSprite(ui,100,100)  
  FlipBuffers()
  ClearScreen(RGB(100,100,100))
ForEver
Cela qui signifie que, après un CreateSprite(#pb_any), je ne renvoie plus l'identifiant du sprite, mais celui de l'élément de la map qui contient alors les informations du sprite ^^.
Du coup, je ne peux plus utiliser directement spritewidth(spriteID) par exemple, mais spriteWidth(Sprite(SpriteID)\sprite).
Pour ce que je souhaite faire ce n'est pas un problème au contraire, puisque j'utilise déjà une map() pour gérer mes sprites, mais que pensez-vous de cette méthode ?
Avatar de l’utilisateur
venom
Messages : 3137
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Redimensionner un sprite

Message par venom »

Bravo falsam, je viens de tester ton archive. Le rendu est cool 8)






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