Ich versuche vertikale synchronisierte Renderings zu machen, so dass pro vertikale Synchronisierung genau ein Rendering durchgeführt wird, ohne irgendwelche Frames zu überspringen oder zu wiederholen. Ich würde dies unter Windows 7 und (in Zukunft) Windows 8 benötigen.Wie man genau ein Rendering pro Vertikalsynchronisation durchführt (keine Wiederholung, kein Überspringen)?
Es würde im Grunde bestehen aus einer Sequenz von QUADS
Zeichnung, die den Bildschirm so passen würde, dass ein Pixel aus den Originalbildern 1: 1 übereinstimmt Pixel auf dem Bildschirm. Der Rendering-Teil ist kein Problem, weder mit OpenGL noch mit DirectX. Das Problem ist die korrekte Synchronisierung.
ich zuvor versucht OpenGL verwenden, mit der WGL_EXT_swap_control
Erweiterung, durch Ziehen und dann
SwapBuffers(g_hDC);
glFinish();
Aufruf habe ich versucht, alle Kombinationen und Permutationen dieser beiden Befehle zusammen mit glFlush(), und es war nicht zuverlässig.
Ich habe dann versucht, mit Direct3D 10, durch Ziehen und dann
g_pSwapChain->Present(1, 0);
pOutput->WaitForVBlank();
Aufruf wo g_pSwapChain
ist ein IDXGISwapChain*
und pOutput
die IDXGIOutput*
zu diesem SwapChain zugeordnet ist.
Beide Versionen, OpenGL und Direct3D, ergeben dasselbe: Die erste Sequenz von, sagen wir, 60 Frames hält nicht, was es sollte (statt etwa 1000ms bei 60Hz, dauert etwa 1030 oder 1050ms), die folgenden scheinen gut zu funktionieren (ungefähr 1000.40ms), aber hin und wieder scheint es einen Rahmen zu überspringen. Ich mache die Messung mit QueryPerformanceCounter
.
Auf Direct3D, eine Schleife von nur WaitForVBlank versuchen, ist die Dauer von 1000 Iterationen konsistent 1000.40 mit wenig Variation.
Also das Problem hier ist nicht genau zu wissen, wann jede der Funktionen zurückgeben, und ob der Austausch während der vertikalen Synchronisierung erfolgt (nicht früher, um ein Reißen zu vermeiden).
Im Idealfall (wenn ich mich nicht irre), um zu erreichen, was ich will, wäre es ein Render durchzuführen, warten Sie, bis die Synchronisierung beginnt, während der Synchronisierung tauschen, warten Sie, bis die Synchronisierung abgeschlossen ist. Wie macht man das mit OpenGL oder DirectX?
Edit: Eine Testschleife nur WaitForVSync
60x konsequent von 1000.30ms zu 1000.50ms nimmt. Die gleiche Schleife mit Present(1,0)
vor WaitForVSync
, mit nichts anderem, kein Rendering, nimmt die gleiche Zeit, aber manchmal schlägt es fehl und dauert 1017ms, als ob ein Frame wiederholt wurde. Es gibt kein Rendering, also stimmt hier etwas nicht.
Ist das auch in DX10 verfügbar? Ich erstelle das Gerät mit 'D3D10CreateDeviceAndSwapChain', was, soweit ich weiß, keine Present-Parameter hat. – slazaro
Ich fürchte, DX10 hat diese Option nicht. Tut mir leid, ich bin nicht sehr in DX10. – miloszmaki
Eigentlich möchten Sie es auch setzen: D3DPRESENT_INTERVAL_ONE ... und D3D10 führt Vsync durch seine aktuelle Methode 'swapChain-> Present (vSync, 0);' – zezba9000