Page 5 sur 10

Publié : dim. 22/mars/2009 10:53
par Anonyme
Dobro , ton code est simple et expose clairement le problème ( que je ne vois pas sous linux au passage :D )
j'ai essayer de mélanger mon code avec ( 1° page de ce post ) , toujours le même problème... pas fluide , des saccades tout les 250ms environs...

Pas top la syncro , a voir en FullScreen ce que ca donne...

Publié : dim. 22/mars/2009 11:28
par Backup
beaucoup plus stable en full screen !! :D
(surtout debugger ON !! 8O )
normal, ya pas les event a gerer !! :D

c'est quand meme pas de l'Atari niveau stabilité !! :?

(touche ESCAPE pour quitter)



Structure sprite
    x.l
    y.l
    vitesse.l
EndStructure
nbr_sprite=1000
Dim sprite.sprite(nbr_sprite)

; Test
EcranX = GetSystemMetrics_ ( #SM_CXSCREEN )
EcranY = GetSystemMetrics_ ( #SM_CYSCREEN )
InitSprite (): InitKeyboard ()

;hwnd=OpenWindow(1,0,0,EcranX,EcranY,"test", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget )
OpenScreen (EcranX,EcranY,32, "Test" )

; *********** prepare les parametres de chaque sprite *****************
For t=0 To nbr_sprite
    sprite(t)\x = Random (EcranX)+1
    sprite(t)\y= Random (EcranY)+1
    sprite(t)\vitesse= Random (4)+1
   CreateSprite (t, sprite(t)\vitesse, sprite(t)\vitesse)
     ; dessine le sprite
StartDrawing ( SpriteOutput (t))
     Box (0,0, sprite(t)\vitesse, sprite(t)\vitesse, RGB ( Random (100)+100, Random (100)+100, Random (100)+100))
StopDrawing ()

Next t
; ***************************************************************
Repeat
     
     For t= 0 To nbr_sprite
         DisplaySprite (t,sprite(t)\x,sprite(t)\y)
        
        sprite(t)\x=sprite(t)\x+sprite(t)\vitesse
         If sprite(t)\x>EcranX
            sprite(t)\x=0
         EndIf
        
     Next t
    
     FlipBuffers ( #PB_Screen_SmartSynchronization )
     ClearScreen (0)
     Delay (1) ;*
     ExamineKeyboard ()
     If KeyboardPushed ( #PB_Key_Escape )
         End
     EndIf
    
ForEver

Publié : dim. 22/mars/2009 11:38
par beauregard
Cpl.Bator a écrit :Dobro , ton code est simple et expose clairement le problème ( que je ne vois pas sous linux au passage :D )
j'ai essayer de mélanger mon code avec ( 1° page de ce post ) , toujours le même problème... pas fluide , des saccades tout les 250ms environs...

Pas top la syncro , a voir en FullScreen ce que ca donne...
Comme nous le rappelle si brillamment Dobro, FlipBuffers est d'une importance capitale. Alors conditionner l'affichage avec un ElapsedMilliseconds, c'est rajouter une couche de, heu, je sais pas quoi, mais bon tu vois.
Il me semble que Fred a amélioré la gestion de FlipBuffers, ce qui est joyeusement enthousiasment, mais nos certitudes acquise avant la 4.30 sont, heu, plus si certaine, hum.

Publié : dim. 22/mars/2009 11:40
par Backup
de memoire on avait quand meme pas autant d'instabilitée en V 3.94 !! :?

Publié : dim. 22/mars/2009 11:41
par beauregard
Dobro a écrit :beaucoup plus stable en full screen !! :D
(surtout debugger ON !! 8O )
en mode plein écran, quel outil utilise-tu pour voir si c'est stable ou pas ?

Publié : dim. 22/mars/2009 11:53
par Buckethead
Dobro a écrit :normal que ça saccade !!

un delay() doit se mettre APRES un flipbuffer ! pas avant ! :)

si vous aviez fait du Stos basic, vous sauriez cela !!

parcequ'en Stos on manipulais directement le buffer de fond des sprites,
buffer video vu, et buffer video calculé ...

le flipbufer c'est un swap entre la memoire video calculé (celle ou se dessine le sprite) , et la memoire video affiché (celle qu'on vois..)

si tu met un delay() avant le swap, c'est normal qu'il y est une petite saccade
puisque tu empeche l'ecran d'apparaitre !! :)

met ton delay apres, tu verra :)
comme ça :

Code : Tout sélectionner


; Test
InitSprite()
hwnd=OpenWindow(1,0,0,800,600,"test", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget  )
OpenWindowedScreen (hwnd,0,0,800,600,0,0,0)

Dim x(120) : Dim v(120)
For y = 0 To 120
    x(y) = Random(800) : v(y) = 1 + Random(4)
Next y

Repeat
    
    
    StartDrawing(ScreenOutput())
        For y = 0 To 120
            x(y) = x(y) + v(y)
            If x(y) > 800 : x(y) = 0 : EndIf
            c = 100 +v(y) * 25
            Box(x(y), 5*y, v(y), v(y) ,RGB(c,c,c))
        Next y
    StopDrawing()
    
    If WindowEvent() = #PB_Event_CloseWindow : End : EndIf
    
   
    
    FlipBuffers(1)
    ClearScreen(0)
     Delay(10) ;*
ForEver 

de plus logiquement on met le clearscreen après l'affichage
puisque après l'affichage on met un coup de balais sur l'écran pour préparer le prochain travail

beaucoup on tendance a commencer par nettoyer avant de dessiner
personnellement je trouve plus logique de balayer ma surface de travail a la fin du travail

parce que c'est pas très malin d'arriver au boulot et de commencer a passer le balais :lol:


autre chose !!

les sprites sont pas la pour faire jolis !!

là tu dessine des box directement a l'écran !!

tu a choisi la technique la plus lente qui soit !!

si tu avait fait des sprites , tu aurai pu voir la difference !! ;)
Ok, maintenant le Delay() est plus efficace, MERCI. Tout de fois mon exemple avec les BOX était pensé pour être un peu lourd, autrement j'aurais été même jusqu'à tout précalculer voir utiliser un autre API, revoir l'algo, et certain auraient utilisé de l'assembleur.
Allons.. Mon systeme est tout à fait capable d'afficher 120 BOX() fluide à 60 FPS, ce n'est rien comparé à ce que nous codons la pluspart du temps.
On peut optimiser ton exemple mais le but du truc c'est de voir si on peut obtenir une animation fluide en mode fenêtre avec un delay(), même juste un point qui scroll horizontalement. (et AUCUN exemples ici ne sont fluide! Le sprite() n'y change rien!!)

Un meilleur exemple serait de mélanger les sprites avec du GrabSprite() et autre pour être proche de la réalité des programmes.

Pour le moment, je ne suis pas convaincu par delay() pour les animations
fluide en mode fenêtré , et pour le fullscreen je l'ai moi même répété plusieurs fois, un petit delay(1) ne fait pas de mal.


Le problème de mon exemple n'est pas un problème d'optimisation mais de synchronisation.

On voit très bien que c'est ce type d'animation qui ne fait pas de cadeau, je me tue à le dire...

Je ne suis pas d'accord avec le Clearscreen(), car c'est la même chose.

Repeat
ClearScreen(0)
...
FlipBuffers(1)
ForEver


ou



Repeat
...
FlipBuffers(1)
ClearScreen(0)
ForEver

Publié : dim. 22/mars/2009 12:12
par beauregard
Buckethead a écrit : Je ne suis pas d'accord avec le Clearscreen(), car c'est la même chose.

Repeat
ClearScreen(0)
...
FlipBuffers(1)
ForEver


ou



Repeat
...
FlipBuffers(1)
ClearScreen(0)
ForEver
oui, certes, c'est une question d'organisation, la recommandation de Dobro n'est toutefois pas inutile.

Publié : dim. 22/mars/2009 12:15
par comtois
C'est à vous de gérer le temps dans un jeu, voir cet article, notamment le chapitre 'Gestion du temps'

Utiliser un delay() sans gérer un cycle n'a pas de sens.

http://www.gnurou.org/writing/linuxmag/sdl/partie3

Enfin bon , tout ça vous le saviez déjà :)

Publié : dim. 22/mars/2009 12:16
par Buckethead
Perso, je préfère effacer l'écran juste àprès le repeat, je ne vois pas le problème d'organisation.

Publié : dim. 22/mars/2009 12:33
par Backup
Buckethead a écrit :Perso, je préfère effacer l'écran juste àprès le repeat, je ne vois pas le problème d'organisation.
tu fais bien comme tu veux !!

faudrait pas confondre de débat !

d'ailleurs beaucoup font comme toi :)

c'est pas le problème !

simplement de mon point de vue, je trouve mieux organisé de mettre
le nettoyage d'écran a la fin du travail , plutôt qu'au début

ma logique est ainsi faite, je code comme je vis , et si je me rase, c'est parce que j'ai des poils !! :)

et non pas parce que je me rase que j'ai des poils !! :D

je nettoie mon écran parce qu'il y a quelque chose dessus
et non pas , je met quelque chose dessus parce que mon écran est propre


évidement si tu ne saisi pas la nuance de ceci, tu ne peut me comprendre ..

mais cela peut révéler aussi de futur problèmes de mise au point de tes codes , si tu pense a l'envers ...

car un code s'exécute de haut en bas !!

mais cela n'est que mon avis hein , n'y vois rien d'agressif :)

comtois a écrit :C'est à vous de gérer le temps dans un jeu, voir cet article, notamment le chapitre 'Gestion du temps'
ton article est intéressant, cependant c'est pas le problème que nous démontrons !!

en effet le problème ici c'est que quoique tu fasse mode fenêtré ou pas
il n'y a pas de stabilité a partir du moment ou l'on code des sprites qui se déplacent , on aperçois le hachage due aux interruptions intempestif de windows !!

a croire que depuis la version 4.30

nos programme ne sont pas capable de réserver du temps machine de façon régulière !!

il me semble qu'en V3.94 on avait pas ce problème

essaye le dernier code coloré et regarde bien le déplacement des étoiles
il n'es pas toujours très régulier !!

c'est encore plus évident sur mon petit NC10 !! :)

Publié : dim. 22/mars/2009 12:38
par Buckethead
C'est comme dire à un gaucher qu'il code à l'envers, dans la routine la permutation entre les 2 instructions sont identiques:

ClearScreen(0)
code
FlipBuffers(1)
ClearScreen(0)
code
FlipBuffers(1)
ClearScreen(0)
code
FlipBuffers(1)

Publié : dim. 22/mars/2009 12:45
par Backup
Buckethead a écrit :C'est comme dire à un gaucher qu'il code à l'envers, dans la routine la permutation entre les 2 instructions sont identiques:

ClearScreen(0)
code
FlipBuffers(1)
ClearScreen(0)
code
FlipBuffers(1)
ClearScreen(0)
code
FlipBuffers(1)
bon laisse tomber ...

Publié : dim. 22/mars/2009 12:46
par Ollivier
Donc, en résumé, le code de Comtois:
-----------------------------------------------

- Prend 2% de CPU chez Beauregard;
- En mode fenêtré (non optimisé)
- A 60 Hz (sous XP) ou plus (sous Linux)
- N'étouffe pas XP (Delay(1) )

>> Fiabilité et fluidité sont réunis. Sujet clos pour pour moi ! ! !

Au passage, je vois que Beauregard ne comprend pas pourquoi Cpl.Bator utilise le chrono., etc...
... PARCE QUE LINUX VA TROP VITE !!!!

Bande de travail Linux : 1000 Hz
Bande de travail XP : 60 Hz

Avec une telle liberté sous Linux, il vaut mieux en effet mettre un chrono...

Publié : dim. 22/mars/2009 12:47
par Anonyme
Dobro a écrit :
Buckethead a écrit :C'est comme dire à un gaucher qu'il code à l'envers, dans la routine la permutation entre les 2 instructions sont identiques:

ClearScreen(0)
code
FlipBuffers(1)
ClearScreen(0)
code

FlipBuffers(1)
ClearScreen(0)
code
FlipBuffers(1)
bon laisse tomber ...
@Buckethead , les instructions sont effectué dans le même ordre , ca n'a pas d'importance , juste une manière de faire.

Publié : dim. 22/mars/2009 12:53
par Buckethead
Je comprend bien, mais il y a aussi un interet a effacer juste après le repeat: si on a predessiné des trucs avant le repeat, on épargne 1 instruction clearscreen