[D3D8] Multisampling und GDI calls

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Fluke
Beiträge: 7
Registriert: 21.05.2010, 02:21

[D3D8] Multisampling und GDI calls

Beitrag von Fluke »

Hi!

Ich möchte bei einem älteren Direct3D8-Spiel (Source nicht vorhanden) gerne multisampling (Anti-Aliasing) aktivieren. Dazu setze ich Hooks. Dies funktioniert auch in Levels (3D), doch leider nicht im Menü (2D) des Spiels. Ist multisampling im Menü aktiv, bleibt der Bildschirm schwarz bzw. in der Farbe von device->Clear()...

Workaround war, beim Laden eines Levels einen device reset zu erzwingen (durch return D3DERR_DEVICENOTRESET in TestCooperativeLevel()), und vor dem device->Reset() die presentation parameters noch entsprechend zu ändern. Und dann bei Rückkehr ins Menü dasselbe.
Gefällt mir jetzt aber nicht so gut (langsam, unsolide), und es gibt auch Probleme mit dem Cursor, der manchmal nach dem reset einfach nicht mehr erscheint.

Nun würde ich das multisampling gerne dauerhaft aktiviert lassen, doch wie gesagt wird das Menü dann nicht angezeigt/nicht aktualisiert.
Im Menü sehen die Aufrufe so aus:

Clear (D3DCLEAR_ZBUFFER)
GetBackBuffer
BeginScene
SetRenderState (D3DRS_FILLMODE / D3DFILL_SOLID)
EndScene
SetTransform (D3DTS_VIEW)
SetTransform (D3DTS_PROJECTION)
TestCooperativeLevel
Present
// Und wieder von vorn

Das Menü wird also mit ziemlicher Sicherheit mit GDI(+) gezeichnet (nur GetBackBuffer(), aber keinerlei DrawPrimitive...() Funktionen).

Warum tritt dieses Problem eigentlich auf? Gibt es denn eine Möglichkeit, multisampling zu unterstützen? Was könnte ich versuchen?

Danke euch!
MfG,
Fluke
Psycho
Establishment
Beiträge: 156
Registriert: 16.09.2002, 14:23

Re: [D3D8] Multisampling und GDI calls

Beitrag von Psycho »

Ich weiß leider nicht, warum der Bildschirm bei eingeschaltetem Multisampling schwarz bleibt.

Allerdings, wenn es nicht zuviel Aufwand ist, könntest Du probieren, die GDI-Aufrufe ebenfalls zu hooken und nach D3D zu "übersetzen".
Solange im Menü nur einige Sprites oder sowas dargestellt werden, sollte das ja möglich sein, aus den BITMAP-Strukturen Texturen zu erzeugen und als zwei Dreiecke zu rendern.
Fluke
Beiträge: 7
Registriert: 21.05.2010, 02:21

Re: [D3D8] Multisampling und GDI calls

Beitrag von Fluke »

Das ist leider zu kompliziert, ist ein ziemlich umfangreiches Menü.
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: [D3D8] Multisampling und GDI calls

Beitrag von Aramis »

Ein Multisampled Backbuffer kann nicht gelockt werden, auch nicht von GDI+. Du koenntest den Rueckgabewert von GetBackBuffer faelschen und stattdessen ein Surface aus einer normalen Textur zurueckgeben. Dieses sollte dann ja von GDI+ gefuellt werden, oder nicht? Beim naechsten Aufruf einer IDirect3DDevice8-Funktion zeichnest du dann zuerst ein bildschirmfuellendes Rechteck mit dieser Textur.
Fluke
Beiträge: 7
Registriert: 21.05.2010, 02:21

Re: [D3D8] Multisampling und GDI calls

Beitrag von Fluke »

Aaaha, ok, habe nun ein wenig experimentiert, bekomme diese Methode aber leider nicht zum laufen.
Die Textur bleibt leer. Beende ich jedoch das Spiel, erscheint noch ganz kurz ein Ladebalken, welcher nicht mit GDI gezeichnet wird. Diesen sieht man dann auch in der Textur.

Ich zeichne die Textur immer knapp vor EndScene(), vielleicht finden die GDI-Calls aber erst irgendwann danach statt?

Hmm...
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: [D3D8] Multisampling und GDI calls

Beitrag von Aramis »

Naja, tendentiell finden sie direkt vor Present statt.
Fluke
Beiträge: 7
Registriert: 21.05.2010, 02:21

Re: [D3D8] Multisampling und GDI calls

Beitrag von Fluke »

Hmm, hab jetzt mal direkt vor Present gezeichnet (wusste gar nicht, dass das geht. Dachte, man müsste innerhalb Begin/EndScene bleiben), hat aber leider nichts verändert.
Es befinden sich lediglich ein paar Artefakte in der Textur.

Code: Alles auswählen

// Initialisierung
direct3dDevice8->CreateTexture(800, 600, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1); // Selbes Format wie der back buffer
tex1->GetSurfaceLevel(0, &sur1);

// MyGetBackBuffer()
*ppBackBuffer = sur1;
return S_OK;
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: [D3D8] Multisampling und GDI calls

Beitrag von Aramis »

Doch, du musst schon innerhalb Begin und End zeichnen - Aenderungen direkt am Backbuffer koennen aber (afaik!) auch außerhalb erfolgen. D.h. du muesstest in dem Fall den tatsaechlichen Aufruf von End verzoegern bis du dein Quad gezeichnet hast, und den Programm-eigenen Aufruf ignorieren.

Nicht dass es was aendern wuerde, denke ich.

Edit: Solltest du die Textur nicht im D3DPOOL_MANAGED erstellen, damit sie lockbar ist? Instinktiv haette ich sie außerdem auf D3DFMT_A8R8G8B8 gesetzt.
Fluke
Beiträge: 7
Registriert: 21.05.2010, 02:21

Re: [D3D8] Multisampling und GDI calls

Beitrag von Fluke »

Hab das nun alles gemacht, leider hat sich wieder nix getan...
Helmut
Establishment
Beiträge: 237
Registriert: 11.07.2002, 15:49
Wohnort: Bonn
Kontaktdaten:

Re: [D3D8] Multisampling und GDI calls

Beitrag von Helmut »

Hi,
hat dein Grafiktreiber keine Option, um Multisampling zu erzwingen? Das sollte eigentlich jeder aktuelle Treiber können. Ansonsten kannst du auch 3d analyze ausprobieren, das funktioniert mit dem gleichen Ansatz.

Ciao
Fluke
Beiträge: 7
Registriert: 21.05.2010, 02:21

Re: [D3D8] Multisampling und GDI calls

Beitrag von Fluke »

Ich möchte den Treiber nicht nutzen, sondern es in Direct3D selbst einstellen (Ich erstelle ein Tool).
Fluke
Beiträge: 7
Registriert: 21.05.2010, 02:21

Re: [D3D8] Multisampling und GDI calls

Beitrag von Fluke »

Hmm, jetzt hab ich mal einen Hook auf IDirect3DSurface8 gesetzt, um zu sehen, ob Lock/Unlock aufgerufen wird und funktioniert oder fehlschlägt.

Wenn die Textur im D3DFMT_X8R8G8B8 ist, wird GetDesc + Lock + Unlock zwei mal hintereinander aufgerufen, dann noch einmal GetDesc + Lock und dann stürzt das Spiel ab (Vermutlich in einer (spieleigenen) Funktion "I3D_Driver::ImportBGRAtoBackBuf", hab mit einem Debugger geguckt).

Wenn die Textur im D3DFMT_A8R8G8B8 ist, wird Lock + Unlock gar nicht aufgerufen! (Allerdings wird ständig GetDesc() aufgerufen).

(Natürlich mit meiner erstellten Textur/Surface getestet. Mit dem normalen backbuffer wird GetDesc + Lock + Unlock ganz normal ständig aufgerufen)

:?
Antworten