D3D9 Present() zwei mal aufrufen
-
rapso schrieb:
3. presentation paramenters umstellen dass du blitting haben willst, statt swap.
Bei swap würde er keinen pinken/grünen Bildschirm mit der Debug-Runtime bekommen.
-> er hat vermutlich discard eingestellt.
-
Also ich habe mal versucht den Swapeffekt zu ändern, jedoch scheitern alle Versuche, einen Device zu erstellen, wenn ich kein D3DSWAPEFFECT_DISCARD benutze. Ich habe auch schon ein bisschen mit den PresentationInterval rumprobiert, jedoch bekomme ich es damit auch nicht hin, D3DSWAPEFFECT_COPYoder D3DSWAPEFFECT_FLIP zum laufen zu bringen. Hier mal meine momentanen PresentationParamter:
D3DPRESENT_PARAMETERS d3dpp; std::memset(&d3dpp, 0, sizeof(d3dpp)); d3dpp.BackBufferWidth = width; d3dpp.BackBufferHeight = height; d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; d3dpp.BackBufferCount = D3DPRESENT_BACK_BUFFERS_MAX; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hWnd; d3dpp.Windowed = true; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
-
versuch mal d3dpp.BackBufferCount auf 1 zu stellen. ansonsten sieht es ok aus fuer mich.
-
Im "Windowed" Mode würde ich D3DSWAPEFFECT_COPY empfehlen, das ist der "natürliche" Swap-Effekt für Windowed (d.h. kein zusätzlicher Overhead). Zumindest mit D3D9 ohne Desktop-Composition. Mit D3D > 9 und/oder Desktop-Composition kenn ich mich nicht aus, k.a. ob das da anders läuft.
Und wie rapso schon geschrieben hat, solltest du BackBufferCount auf 1 stellen.
-
Ok, mit BackBufferCount auf 1 funktioniert es, jedoch musste ich gerade feststellen, dass das ganze mit multisampling nicht mehr funktioniert, da meldet mir die Debug-Runtime immer
Direct3D9: (ERROR) :Multisampling requires D3DSWAPEFFECT_DISCARD. ValidatePresentParameters fails. D3D9 Helper: IDirect3D9::CreateDevice failed: D3DERR_INVALIDCALL
Das ist ja dann auch nicht das gelbe vom Ei...
-
MS braucht eben zwingend D3DSWAPEFFECT_DISCARD. Ich wuerde generell immer D3DSWAPEFFECT_DISCARD nehmen, da das auch von der Doku empfohlen wird (erlaubt Optimierungen).
-
Pikkolini schrieb:
Ok, mit BackBufferCount auf 1 funktioniert es, jedoch musste ich gerade feststellen, dass das ganze mit multisampling nicht mehr funktioniert, da meldet mir die Debug-Runtime immer
Direct3D9: (ERROR) :Multisampling requires D3DSWAPEFFECT_DISCARD. ValidatePresentParameters fails. D3D9 Helper: IDirect3D9::CreateDevice failed: D3DERR_INVALIDCALL
Das ist ja dann auch nicht das gelbe vom Ei...
Ok.
Was willst du jetzt von uns?
Du machst was, was mit DISCARD nicht geht. Sagen wir machs halt anders. Das willst du nicht. Sagen wir dir dann nimm halt SWAP. Jetzt sagst du du willst aber doch DISCARD verwenden.
Was jetzt?
Sind wir wieder zurück bei "machs halt anders" (aka. ruf nicht 2x Present auf).
-
Pikkolini schrieb:
Ok, mit BackBufferCount auf 1 funktioniert es, jedoch musste ich gerade feststellen, dass das ganze mit multisampling nicht mehr funktioniert, da meldet mir die Debug-Runtime immer
Direct3D9: (ERROR) :Multisampling requires D3DSWAPEFFECT_DISCARD. ValidatePresentParameters fails. D3D9 Helper: IDirect3D9::CreateDevice failed: D3DERR_INVALIDCALL
Das ist ja dann auch nicht das gelbe vom Ei...
hab die 3 gelb variationen vom ei nochmal erweitert, du hast die freie wahl
du kannst
1. die scene neu zeichnen und darueber deinen text, dann present
2. die scene in ein temporaeres surfaces kopieren und dann vor dem text auf den backbuffer blitten (z.b. mit stretchrect)
3. presentation paramenters umstellen dass du blitting haben willst, statt swap/discard, falls du kein antialiasing verwendest
-
Also obwohl Variante 1 dann wohl wesentlich sinnvoller ist, habe ich mal rein aus Lerneffekt an Variante zwei probiert.
Das ist bisher rumgekommen:LPDIRECT3DSURFACE9 tempSurf = nullptr; if (FAILED(d3dd->CreateOffscreenPlainSurface(screenWidth, screenHeight, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tempSurf, nullptr))) throw std::runtime_error("Pausieren fehlgeschlagen"); if (FAILED(d3dd->GetFrontBufferData(0, tempSurf))) throw std::runtime_error("Pausieren fehlgeschlagen"); LPDIRECT3DSURFACE9 backBuffer = nullptr; if (FAILED(d3dd->GetRenderTarget(0, &backBuffer))) throw std::runtime_error("Pausieren fehlgeschlagen"); RECT rect = {gameX, gameY, gameWidth, gameHeight}; d3dd->UpdateSurface(tempSurf, &rect, backBuffer, nullptr);
Das Problem dabei ist jetzt, dass mein BackBuffer das Format D3DFMT_X8R8G8B8 und GetFrontBufferData das Format D3DFMT_A8R8G8B8.
Deswegen schlägt dann auch UpdateSurface fehl. Gibt es da eine möglichkeit, die beiden Formate ineinander zu überführen, indem man z.B. den Alpha-Wert einfach ignoriert?
Wenn nicht ist auch wurscht, benutze jetzt eh Variante 1.
-
wieso gibst du nicht beiden das selbe format?