2010-11-28 4 views
5

Attualmente sto scrivendo un gioco di immensa raffinatezza e astuzia, che ti riempirà di meraviglia e vinto- oh, OK, è il 15 puzzle, e mi sto solo familiarizzando con SDL.Come sincronizzare i salti di pagina con ritraccia verticale in un'applicazione SDL con finestra?

Sono in esecuzione in modalità finestra e utilizzo di SDL_Flip come aggiornamento generale della pagina, poiché esegue automaticamente la mappatura su un SDL_UpdateRect dell'intera finestra in modalità finestra. Non l'approccio ottimale, ma dato che questo è solo il 15 puzzle ...

In ogni caso, i movimenti delle tessere stanno accadendo a velocità ridicola. IOW, SDL_Flip in modalità finestra non include alcuna sincronizzazione con i ritraccia verticali. Sto lavorando su ATM di Windows XP, ma presumo che questo sia un comportamento corretto per SDL e si verifichi anche su altre piattaforme.

Passare all'utilizzo di SDL_UpdateRect ovviamente non cambierà nulla. Presumibilmente, ho bisogno di implementare la logica del ritardo nel mio codice. Ma un semplice timer basato sull'orologio potrebbe comportare aggiornamenti che si verificano quando la finestra è semirotta, causando distorsioni visibili (ho dimenticato il nome tecnico).

EDIT Questo problema è noto come "strappo".

Quindi, in un gioco in modalità finestra in SDL, come faccio a sincronizzare i page-flip con il ritraccia verticale?

EDIT Ho visto diverse affermazioni, durante la ricerca di una soluzione, che è impossibile sincronizzare i salti di pagina con la ritraccia verticale in un'applicazione con finestre. Su Windows, almeno, questo è semplicemente falso - ho scritto giochi (con cui intendo cose di livello simile al 15-puzzle) che lo fanno. Una volta ho sprecato un po 'di tempo a giocare con Dark Basic e Dark GDK - sia basato su DirectX che su entrambe le pagine sincronizzate al salto verticale in modalità finestra.

risposta

4

Maggiore Modifica

Si scopre avrei speso più tempo a guardare prima di chiedere. Dalla FAQ SDL ...

http://sdl.beuc.net/sdl.wiki/FAQ_Double_Buffering_is_Tearing

che sembra implicare abbastanza forte che la sincronizzazione con il ritracciamento verticale non è supportato in SDL app-modalità finestra.

Ma ...

La tecnica di base è possibile su Windows, e sto iniziando la pensano SDL lo fa, in un certo senso. Solo non del tutto sicuro ancora.

Su Windows, ho detto prima, la sincronizzazione dei salti di pagina alle sincronizzazioni verticali in modalità finestra è stata possibile fino ai giorni a 16 bit utilizzando WinG. Si scopre che non è esattamente sbagliato, ma fuorviante. Ho scovato un vecchio codice sorgente usando WinG, e c'era un timer che innescava i blit della pagina. WinG funzionerà a una velocità ridicola, proprio come sono stato sorpreso da SDL: le operazioni di flip di pagina blit-to-screen non prevedono attesa per un ritracciamento verticale.

In seguito a un'indagine più approfondita: quando si esegue un blit sullo schermo in WinG, il blit viene messo in coda per un secondo momento e la chiamata termina. Il blit viene eseguito al prossimo ritraccia verticale, quindi speriamo che non ci sia lacrimazione. Se si eseguono ulteriori blit allo schermo (rettangoli sporchi) prima di quello ritracciamento, vengono combinati. Se fai un sacco di blits a schermo intero prima del ritracciamento verticale, stai rendendo i fotogrammi che non vengono mai visualizzati.

Questo blit-to-screen in WinG è ovviamente simile a SDL_UpdateRect. SDL_UpdateRects è solo un modo ottimizzato per combinare manualmente alcuni rettangoli sporchi (e assicurarsi, forse, che siano applicati allo stesso frame). Quindi forse (su piattaforme in cui è possibile tracciare tracce verticali) viene eseguito in SDL, analogamente a WinG: nessuna attesa, ma nessuna lacerazione.

Bene, ho provato a utilizzare un timer per attivare gli aggiornamenti dei frame e il risultato (su Windows XP) è incerto. Potrei ottenere delle lievi e occasionali lacerazioni sul mio vecchio laptop, ma questo potrebbe non essere colpa degli SDL - potrebbe essere che il "raster" superi l'esaltazione. Probabilmente è colpa mia se ho usato SDL_Flip invece di una chiamata diretta a SDL_UpdateRect con un rettangolo sporco minimo - anche se stavo cercando di strapparmi in questo caso, per vedere se potevo.

Quindi sono ancora incerto, ma potrebbe essere che l'SDL in modalità finestra sia immune alla lacerazione come può essere su quelle piattaforme che lo consentono. I risultati non sembrano così male come immaginavo, anche sul mio vecchio portatile.

Ma - qualcuno può offrire una risposta definitiva?

+0

Accettato per chiudere questa vecchia domanda, ma sono ancora disponibile a cambiare se viene visualizzata una risposta definitiva. – Steve314

0

È possibile utilizzare il controllo framerate di SDL_gfx. Guardando il docs della biblioteca, il flusso della vostra applicazione sarà simile a questo:

// initialization code 
FPSManager *fpsManager; 
SDL_initFramerate(fpsManager); 
SDL_setFramerate(fpsManager, 60 /* desired FPS */); 


// in the render loop 
SDL_framerateDelay(fpsManager); 

Inoltre, si può guardare al source code per creare il proprio controllo di framerate.

+0

La domanda è come sincronizzare i fotogrammi con il ritraccia verticale. L'analogia è rappresentata dai vecchi display CRT, che sincronizzano il cambio del frame con un periodo in cui il raggio del CRT è stato spento. Con display moderni, non c'è un raggio, ma è comunque importante sincronizzarsi con il ritracciamento verticale per evitare "[strappo] (http://en.wikipedia.org/wiki/Screen_tearing)". L'impostazione di una frequenza fotogrammi è separata da quella, anche se i frame rate sono perfettamente abbinati, ciò significa che lo strappo è nella stessa posizione in ogni fotogramma. – Steve314

+0

TBH, la mia ultima conclusione provvisoria è stata che SDL * sempre * si sincronizza con la ritraccia verticale se è in grado di farlo. Potrebbe non essere in grado in modalità finestra. È * possibile *: i giochi DirectX in modalità finestra lo fanno sempre, ma ciò non significa che SDL possa supportarlo e potrebbe dipendere dall'utilizzo dell'SDL API sottostante. – Steve314

+0

Ok. Penso che SDL non abbia modo di farlo ancora. Ad ogni modo, deve esserci un modo per farlo. GLFW esegue VSync in modalità finestra su Windows. –

Problemi correlati