FlipBuffers oder ähnliches in Threads

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
KTX82
Beiträge: 95
Registriert: 31.08.2004 00:11
Wohnort: Mannheim
Kontaktdaten:

FlipBuffers oder ähnliches in Threads

Beitrag von KTX82 »

Hallo Leute!

Da man ja DX-Befehle nicht in Threads verwenden soll, aber ich unbedingt eine Technik bräuchte um unabhängig vom Hautcode einen ScreenBuffer zu flippen, meine Frage: Ist soetwas in Threads überhaupt möglich.

Nun die genaue Erklärung. Ich möchte im Prinzip 3 Buffer, einen Front-Buffer (das was sichtbar ist auf dem Monitor), einen Backbuffer (wo immer nur fertig gerenderte Bilder drin liegen, welche durch einen Thread regelmäßig auf den Frontbuffer gelegt werden), und dann den ZeichenBuffer, auf den im Hauptcode gezeichnet wird. Wenn das Bild fertig gerendert ist, soll es im Hauptcode in den Backbuffer geschoben werden, so dass sofort mit dem nächsten Renderdurchgang begonnen werden kann, ohne auf den eigentlichen ScreenFlip warten zu müssen, da dieser Threadgesteuert wäre.

Weiß jemand für so etwas eine Lösung, fals dies in PB ohne größere Probleme realisierbar ist?

Oder fungiert sogar FlipBuffers(2) nach diesem Prinzip?
Pharmacie populaire www.viagrasansordonnancefr.com aide aux malades
Stefan
Beiträge: 125
Registriert: 29.08.2004 10:51
Kontaktdaten:

Beitrag von Stefan »

So sollten die Sprite-Befehle eigentlich auch im MT-modus funktioniren:

Code: Alles auswählen


Procedure _PB_DDrawBase()
!extrn _PB_DDrawBase
!MOV EAX,[_PB_DDrawBase]
ProcedureReturn
EndProcedure

;Procedure _PB_Screen_Windowed()
;!extrn _PB_Screen_Windowed 
;!MOV EAX,[_PB_Screen_Windowed]
;ProcedureReturn
;EndProcedure

#DDSCL_EXCLUSIVE=16
#DDSCL_FULLSCREEN=1
#DDSCL_MULTITHREADED=1024
#DDSCL_NORMAL=8

Global UseDX7Mutex.l

Procedure MTLockDX7Mutex()
LockMutex(UseDX7Mutex)
EndProcedure

Procedure MTUnLockDX7Mutex()
UnlockMutex(UseDX7Mutex)
EndProcedure

Procedure MTOpenWindowedScreen(hWnd,x,y,width,height,AutoStretch,ROffset,BOffset)
Result=OpenWindowedScreen(hWnd,x,y,width,height,AutoStretch,ROffset,BOffset)
If Result=0:ProcedureReturn 0:EndIf
UseDX7Mutex=CreateMutex()
*DD.IDirectDraw7=_PB_DDrawBase()
;*DD\SetCooperativeLevel(ScreenID(),#DDSCL_EXCLUSIVE|#DDSCL_FULLSCREEN|#DDSCL_MULTITHREADED)  ; Fullscreen
*DD\SetCooperativeLevel(ScreenID(),#DDSCL_NORMAL|#DDSCL_MULTITHREADED)
ProcedureReturn Result
EndProcedure

Procedure MTClearScreen(Color)
LockMutex(UseDX7Mutex)
Result=ClearScreen(Color)
UnlockMutex(UseDX7Mutex)
ProcedureReturn Result
EndProcedure

Procedure MTFlipBuffers(Flags)
LockMutex(UseDX7Mutex)
Result=FlipBuffers(Flags)
UnlockMutex(UseDX7Mutex)
ProcedureReturn Result
EndProcedure




Procedure MyRepaint(dummy)
Repeat
MTFlipBuffers(0)
Delay(15)
ForEver
EndProcedure


InitSprite()
OpenWindow(1,0,0,320,240,"TEST")
MTOpenWindowedScreen(WindowID(1),0,0,320,240,0,0,0)

CreateSprite(1,100,100)

StartDrawing(SpriteOutput(1))
Circle(100,100,100,#Red)
StopDrawing()


TRepaint=CreateThread(@MyRepaint(),0)
Repeat

Delay(50)

MTLockDX7Mutex()
ClearScreen(RGB(255,0,255))
RandomSeed(100)
For C=0 To 100
DisplaySprite(1,Random(200),Random(200))
Next
MTUnLockDX7Mutex()

Until WindowEvent()=#PB_Event_CloseWindow
KillThread(TRepaint)
KTX82
Beiträge: 95
Registriert: 31.08.2004 00:11
Wohnort: Mannheim
Kontaktdaten:

Beitrag von KTX82 »

Wow, Danke, das wäre schon mal die Lösung für Threads, jetzt fehlt nur noch etwas für einen 3. Screenbuffer, das auch wirklich nur fertig gerenderte Bilder in den Frontbuffer kommen. Ich meine da mal was gelesen zu haben, kann mich auch irren... werde nochmal suchen.
Aber vielen Dank @Stefan :allright:

Code: Alles auswählen

;
;                  Thread
;                  +------------------------------------+
; Hauptschleife    |                                    |
; +----------------+---------------+                    |
; | Zeichnen       | Fertiges Bild |                    |
; |                |               |                    |
; |    |           |               | -> FrontBuffer (3) |
; |                |               |                    |
; | Buffer 1   ->  |   Buffer 2    |                    |
; +----------------+---------------+                    |
;                  |                                    |
;                  +------------------------------------+
;
;
; Buffer 1: Hier wird nur gezeichnet
; Buffer 2: Bekommt von der Hauptschleife nach fertig zeichnen das fertig gerenderte Bild
; Buffer 3: Der Thread holt aus dem Buffer 2 das fertige Bild in den Buffer 3 (Monitorbild)
Zuletzt geändert von KTX82 am 16.03.2006 22:08, insgesamt 1-mal geändert.
Pharmacie populaire www.viagrasansordonnancefr.com aide aux malades
Stefan
Beiträge: 125
Registriert: 29.08.2004 10:51
Kontaktdaten:

Beitrag von Stefan »

Zu was brauchst du 3 Buffer, du kannst das Mutex doch auch solange sperren, bis alles dargestellt wurde ?
KTX82
Beiträge: 95
Registriert: 31.08.2004 00:11
Wohnort: Mannheim
Kontaktdaten:

Beitrag von KTX82 »

Das die Hauptschleife nicht auf FlipBuffers warten muss, da dieses ja immer auf den Sync wartet. Und da Sync schon nicht fehlen sollte, braucht man einen dritten Buffer aus dem unabhängig von der Hauptschleife ein Thread immer das FlipBuffers (in diesem Fall muss es ein eigener Befehl werden) ausführt.
Ich glaube das nennt man Tripplebuffering /:-> http://de.wikipedia.org/wiki/Tripplebuffering
Pharmacie populaire www.viagrasansordonnancefr.com aide aux malades
Antworten