Page 1 sur 1

SetFrameRate et la 3D sur les versions 4.40 et 4.41 [résolu]

Publié : lun. 15/mars/2010 11:47
par Lost_in_PB
Bonjour à tous,

Ayant pris pour base l'exemple "Entity.pb", fourni par défaut avec le PureBasic, je fais quelques expérimentations en 3D. J'ai rajouté un compteur d'images par seconde ( FPS counter ) au code originel, et il s'avère que le résultat tourne autour de 62 FPS, et cela quel que soit l'argument passé à la fonction SetFrameRate.

Alors ma question est la suivante : l'utilisation des fonctions 3D du PureBasic, et notamment RenderWorld(), rend-t-elle inutile la fonction SetFrameRate ?

Tant que j'y suis, j'avais aussi une question subsidiaire : pourquoi mon code marche-t-il sous la version 4.40 et non pas sous la 4.41 ?

Merci pour le temps que vous prendrez à me répondre !

Code : Tout sélectionner

; "test 3D robot entities army.v0.01.pb"
; marche avec PureBasic 4.40, sa librairie "Engine3D.dll" et le dossier "Data" de ses exemples standards
; ne marche pas avec PureBasic 4.41 suite à une erreur avec le compteur de FPS...

Define.f KeyX, KeyY, MouseX, MouseY
  
If InitEngine3D()

  Add3DArchive("Data"           , #PB_3DArchive_FileSystem)
  Add3DArchive("Data/skybox.zip", #PB_3DArchive_Zip)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If OpenWindow(0,0,0,800,600,"test 3D robot entities army v1",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
    If OpenWindowedScreen(WindowID(0),0,0,800,600,0,0,0)
    Else
      MessageRequester("Error", "Can't open windowed screen!", 0)
      End
    EndIf
  EndIf
 
  SetFrameRate(10) ; ne marche apparemment pas !
    
  LoadMesh   (0, "robot.mesh")
    
  CreateMaterial(0, LoadTexture(0, "clouds.jpg"))
  CreateMaterial(1, LoadTexture(1, "r2skin.jpg"))
  
  For m=0 To 4
    For n=0 To 9  
      CreateEntity((m*10+n), MeshID(0), MaterialID(1), 60*n, 0, 60*m)
    Next n
  Next m
    
  For n=0 To 49   
    AnimateEntity(n, "Walk")
  Next n
    
  SkyBox("desert07.jpg")
   
  CreateCamera(0, 0, 0, 100, 100)
  CameraLocate(0,0,0,100)
      
  TimeDelay.l=100       ; FPS counter
  MasterTimer.l=GetTickCount_()    ; FPS counter
      
  Repeat
      
    ClearScreen(RGB(0, 0, 0))
            
    If ExamineKeyboard()
      
      If KeyboardPushed(#PB_Key_Left)
        KeyX = -1
      ElseIf KeyboardPushed(#PB_Key_Right)
        KeyX = 1
      Else
        KeyX = 0
      EndIf
        
      If KeyboardPushed(#PB_Key_Up)
        KeyY = -1
      ElseIf KeyboardPushed(#PB_Key_Down)
        KeyY = 1
      Else
        KeyY = 0
      EndIf
        
      If KeyboardPushed(#PB_Key_PageUp)
        RollZ = 3
      Else
        RollZ = 0
      EndIf
        
      If KeyboardPushed(#PB_Key_Add)
        Frame.f+0.005
      EndIf
        
    EndIf
      
    If ExamineMouse()
      MouseX = -MouseDeltaX()/10 
      MouseY = -MouseDeltaY()/10
    EndIf
      
    RotateCamera(0, MouseY, MouseX, RollZ, #PB_Relative)
    MoveCamera  (0, KeyX, 0, KeyY)
      
    RenderWorld()

    StartDrawing(WindowOutput(0))  ; FPS counter
    FrontColor(RGB(255,0,0))  ; FPS counter      
    DrawText(10, 10, "FPS="+Str(FrameRate.f) )  ; FPS counter 
    StopDrawing()  ; FPS counter

    FlipBuffers()

    TimeDelay=GetTickCount_()-MasterTimer  ; FPS counter
    MasterTimer=GetTickCount_()  ; FPS counter
    FrameRate.f=1000/TimeDelay  ; FPS counter
      
  Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
End

Re: SetFrameRate et la 3D

Publié : lun. 15/mars/2010 12:03
par G-Rom
Bonjour , quel type d'erreur as tu exactement ? un Invalid Access Memory ?

utilise Engine3DFrameRate() pour avoir le framerate du moteur au lieu de l'API win32 , là tu prends le FrameRate de ta boucle
au pire utilise ceci :

Code : Tout sélectionner

FPS_LIMIT = 10

If (ElapsedMilliseconds() > CheckTime + 1000 / FPS_LIMIT)
  CheckTime = ElapsedMilliseconds()
    ; AFFICHAGE ICI ( ClearScreen() / RenderWorld() FlipBuffers() , etc...)
    ; Calcul ton fps ici aussi !
    Else
  Delay(1)
EndIf

Re: SetFrameRate et la 3D

Publié : lun. 15/mars/2010 12:40
par Lost_in_PB
Merci pour ta réponse on ne peut plus rapide, G-Rom !

Concernant l'erreur que j'obtiens, c'est une "Division by zero forbidden", sur la ligne "FrameRate.f=1000/TimeDelay". Bizarrement, elle ne se produit pas à chaque lancement du programme. De plus, elle n'arrive que sur la 4.41, et jamais sur la 4.40. Pour note, je suis sous Windows 7, et j'utilise des versions x86 du PureBasic.

Et merci pour la référence à la fonction Engine3DFrameRate(), qui m'avait complètement échappé dans l'aide... Avec elle, j'obtiens un FPS actuel de 59, avec donc l'argument "#PB_Engine3D_Current".

Sinon, je vais essayer ton code limitateur de FPS plus tard dans l'après-midi.

Re: SetFrameRate et la 3D

Publié : lun. 15/mars/2010 12:45
par Fred
En effet il y avait un probleme avec SetFrameRate() et la 3D. Ce sera corrigé dans la prochaine version.

Re: SetFrameRate et la 3D

Publié : lun. 15/mars/2010 13:47
par MetalOS
Prochaine version ???? :P :P :P :P :P cool.

Re: SetFrameRate et la 3D

Publié : lun. 15/mars/2010 16:13
par Lost_in_PB
Merci à Fred pour la précision.

Sinon, j'ai bien testé ta suggestion de code pour fixer le frame rate, G-Rom. Cela marche pour un FPS fixé à une valeur inférieure à 60, bien que dans ce cas, il semble que la fonction Engine3DFrameRate() ne renvoit rien. Par contre, pour un FPS fixé supérieur à 60, là la fonction Engine3DFrameRate() renvoit une valeur de 59, et cela quel que soit le montant fixé du FPS.

Ma conclusion est que le PureBasic version 4.41 ( ainsi que la 4.40 ) ferait plafonner le FPS à 60 dès lors que l'on utilise des fonctions 3D natives. Cela me convient très bien pour l'usage que j'en fais, même si cela mériterait sans doute d'être davantage documenté. Et en attendant la prochaine version.

En tout cas, merci à vous tous pour votre aide.

Re: SetFrameRate et la 3D

Publié : lun. 15/mars/2010 17:49
par G-Rom
Ma conclusion est que le PureBasic version 4.41 ( ainsi que la 4.40 ) ferait plafonner le FPS à 60
non , c'est ta carte graphique qui fixe ta syncro à 60 , un FPS supérieur au refresh de ton écran ne sert strictement à rien, tu fera "des rendu dans le vide" autant gardé donc les ressources pour faire autre chose ( IA , collision , etc... ). Si tu désactive la syncro verticale de ta CG , le fps va monté en flêche , mais c'est débile d'avoir un FPS de 400 dans un jeu. 50 / 60 ca suffit très largement.

Re: SetFrameRate et la 3D

Publié : lun. 15/mars/2010 21:34
par Lost_in_PB
Intéressantes, toutes ces précisions, G-Rom... Je n'aurais jamais cru la carte graphique de mon PC capable de gérer cette synchronisation. Il faut croire que j'ai vraiment été traumatisé au début des années 2000 par les difficultés pour faire tourner de vieux jeux PC qui n'étaient pas du tout synchronisés et tournaient facilement plusieurs fois trop vite. Ce qui du coup nécessitait des logiciels ralentisseurs comme Moslo, afin de pouvoir y jouer normalement. Et cela jusqu'au développement de la DOSBox, qui a réglé ce problème en même temps que celui de la compatibilité avec les systèmes d'exploitation antédiluviens.

Encore une fois, merci pour tout !