Domanda

Sto scrivendo un'applicazione di modellazione 3D in D3D9 che mi piacerebbe fare come ampiamente compatibile possibile. Ciò significa utilizzare alcune funzionalità hardware-dipendente, cioè multicampionamento. Tuttavia, mentre il tempo reale di rendering non ha bisogno di essere impeccabile, ho bisogno di fornire cattura dello schermo piacevole-osservare, che senza multisampling, sembrano abbastanza alias e poveri.

Per produrre le mie catture dello schermo, creo una superficie temporanea in memoria, rendere la scena per una volta, quindi salvarlo in un file. Il mio primo pensiero di come avrei potuto ottenere una cattura antialias è stato quello di creare il mio stencilsurface fuori dallo schermo come multicampionato, ma naturalmente DX non avrebbe permesso che, poiché il dispositivo stesso era stato inizializzato con D3DMULTISAMPLE_NONE.

Per cominciare, ecco un esempio di come esattamente creo lo screencapture. So che sarebbe più semplice per salvare solo il backbuffer di un telaio già reso, però ho bisogno la possibilità di salvare le immagini di dimensioni diverse da quelle della finestra reale di rendering - che è il motivo per cui lo faccio in questo modo. Il controllo degli errori, il codice per il ripristino dello stato, e rilasciando risorse sono omesso qui per brevità. m_d3ddev è il mio LPDIRECT3DDEVICE9.

//Get the current pp
LPDIRECT3DSWAPCHAIN9 sc;
D3DPRESENT_PARAMETERS pp;
m_d3ddev->GetSwapChain(0, &sc);
sc->GetPresentParameters(&pp);

//Create a new surface to which we'll render
LPDIRECT3DSURFACE9 ScreenShotSurface= NULL;
LPDIRECT3DSURFACE9 newDepthStencil  = NULL;
LPDIRECT3DTEXTURE9 pRenderTexture   = NULL;
m_d3ddev->CreateDepthStencilSurface(_Width, _Height, pp.AutoDepthStencilFormat, pp.MultiSampleType, pp.MultiSampleQuality, FALSE, &newDepthStencil, NULL );
m_d3ddev->SetDepthStencilSurface( newDepthStencil );
m_d3ddev->CreateTexture(_Width, _Height, 1, D3DUSAGE_RENDERTARGET, pp.BackBufferFormat, D3DPOOL_DEFAULT, &pRenderTexture, NULL);
pRenderTexture->GetSurfaceLevel(0,&ScreenShotSurface);

//Render the scene to the new surface
m_d3ddev->SetRenderTarget(0, ScreenShotSurface);
RenderFrame();

//Save the surface to a file
D3DXSaveSurfaceToFile(_OutFile, D3DXIFF_JPG, ScreenShotSurface, NULL, NULL);

Si può vedere la chiamata a CreateDepthStencilSurface (), che è dove speravo che potrei sostituire pp.MultiSampleType con cioè D3DMULTISAMPLE_4_SAMPLES, ma che non ha funzionato.

Il mio pensiero successivo è stato quello di creare un LPDIRECT3DDEVICE9 completamente diverso come un D3DDEVTYPE_REF, che sostiene sempre D3DMULTISAMPLE_4_SAMPLES (indipendentemente dalla scheda video). Tuttavia, tutte le mie risorse (mesh, texture) sono stati caricati in m_d3ddev, il mio dispositivo HAL, quindi non ho potuto utilizzare per il rendering della scena sotto il dispositivo REF. Si noti che le risorse possono essere condivise tra i dispositivi sotto Direct3d9ex (Vista), ma sto lavorando su XP. Dato che ci sono un sacco di risorse, ricaricare tutto per rendere questo un fotogramma, poi li scarico, è troppo tempo inefficiente per la mia applicazione.

Ho guardato altre opzioni per antialiasing dell'immagine post-acquisizione (cioè 3x3 filtro di sfocatura), ma tutti generato risultati piuttosto scadente, quindi mi piacerebbe davvero per cercare di ottenere una scena antialias a destra, fuori D3D, se possibile. ...

Qualsiasi saggezza o puntatori sarebbe molto apprezzato ...

Grazie!

È stato utile?

Soluzione

sovracampionamento da una resa ad un buffer più grande e ridimensionamento o combinando i buffer jittered è probabilmente la soluzione migliore. La combinazione di più buffer jittered dovrebbe darvi la migliore qualità per un dato numero di campioni (migliore rispetto alla griglia regolare dalla semplice rendering di un numero equivalente di campioni a un multiplo della risoluzione e ridimensionamento verso il basso), ma ha il sovraccarico della resa multipla passa. Ha il vantaggio di non essere limitata dalla dimensione massima supportata di vostro target di rendering e anche se consente di scegliere o meno un livello arbitrario di AA (anche se dovrete fare attenzione ai problemi di precisione in caso di associazione molti buffer jittered).

L'articolo "Antialiasing con accumulo tampone" a opengl.org descrive come modificare la vostra matrice di proiezione per il campionamento jittered (OpenGL, ma la matematica è fondamentalmente la stessa). Il documento "Interleaved Sampling" di Alexander Keller e Wolfgang Heidrich parla di un'estensione della tecnica che ti dà un modello di campionamento meglio a scapito di passaggi ancora più di rendering. Mi dispiace per non fornire i collegamenti - come nuovo utente posso pubblicare solo link per ogni risposta. Google dovrebbe trovarli per voi.

Se si vuole andare l'itinerario di rendere ad un buffer più grande e giù per il campionamento, ma non vuole essere limitata dalla massima consentita di rendering dimensione finale quindi è possibile generare un'immagine piastrellato con fuori centro matrici di proiezione come descritto qui .

Altri suggerimenti

Si può sempre rendere a una texture che è due volte la larghezza e l'altezza (vale a dire la dimensione 4x) e poi sovracampiona verso il basso.

È vero che ci si ancora ottenere problemi se la carta non può creare una texture 4x la dimensione del buffer di nuovo ...

Modifica:. C'è un altro modo che mi viene in mente

Se si ripete il telaio n-volte con piccoli nervosismi alla matrice vista si sarà in grado di generare il maggior numero di immagini che vuoi, che è quindi possibile aggiungere insieme in seguito per formare un'immagine molto altamente anti-aliasing. Il bonus è che funziona su qualsiasi macchina in grado di rendere l'immagine. Si tratta, ovviamente, più lento però. Ancora 256xAA davvero non guardare bene quando si esegue questa operazione!

In questo articolo http://msdn.microsoft. com / it-it / library / bb172266 (VS.85) aspx sembra implicare che è possibile utilizzare il render stato di bandiera D3DRS_MULTISAMPLEANTIALIAS per controllare questo. Puoi creare il tuo dispositivo con antialiasing attivo ma spegnerlo per il rendering dello schermo e per la resa fuori schermo utilizzando questo rende state flag?

Non ho provato io stesso però.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top