Una delle possibilità che DirectX offre ormai da molte versioni è la possibilità di effettuare il rendering di una scena su di una texture che possiamo poi utilizzare per altri scopi (un esempio è la possibilità di visualizzare una scena che contiene un monitor con all'interno un'altra scena).
La tecnologia di rendering sulle texture è diventata a partire dalla versione DirectX9 qualcosa di fondamentale per la computer grafica. Tramite il rendering sulle texture sono possibili effetti come riflessione e rifrazione delle superfici, post processing (ad esempio la profondità di campo) e tutta una serie di tecniche che fanno la differenza. Ad oggi non esiste prodotto che non fa uso di questa tecnologia.
In Direct3D10 il render to texture è stato reso molto più semplice e potente. Potrete infatti utilizzare fino ad 8 render target contemporaneamente ed indirizzare grafica differente ad ognuno di essi. In questo tutorial vi illustrerò come implementare una scena con un render target.
Per prima cosa dovrete creare una texture da utilizzare come bersaglio della rendering.
D3D10_TEXTURE2D_DESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.Width = width;
desc.Height = height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = format;
desc.SampleDesc.Count = 1;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
ID3D10Texture2D* targetTex;
device->CreateTexture2D(&desc,NULL,&targetTex);
Come potete vedere la risorsa creata ha come bindFlags Render_Target e Shader_Resource. Questo perchè vogliamo utilizzare la texture sia come bersaglio che come texture per un modello 3D. Ora dobbiamo creare il RenderTargetView
ID3D10RenderTargetView* view;
D3D10_RENDER_TARGET_VIEW_DESC DescRT;
DescRT.Format = format;
DescRT.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D;
DescRT.Texture2DArray.MipSlice = 0;
device->CreateRenderTargetView( targetTex, &DescRT, &view);
Avete già visto questo oggetto. Il device infatti vi ha richiesto di crearne uno e qui non abbiamo fatto altro che crearne uno simile ma collegato alla texture.
Infine si crea uno ShaderResourceView che ci servirà per essere utilizzato dallo shader.
ID3D10ShaderResourceView* resource;
D3D10_SHADER_RESOURCE_VIEW_DESC srDesc;
srDesc.Format = desc.Format;
srDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
srDesc.Texture2D.MostDetailedMip = 0;
srDesc.Texture2D.MipLevels = 1;
device->CreateShaderResourceView( targetTex, &srDesc, &resource );
Avete ora creato le risorse che vi servono, il targetView da utilizzare per passarlo al device come destinazione di rendering e lo ShaderResourceView da passare allo shader come risorsa. Qui potrete anche distruggere la texture (la variabile targetTex) in quanto non più necessaria.
Ora per utilizzare il nuovo target dovrete semplicemente passarle alla funzione OMSetRenderTargets
device->OMSetRenderTargets( 1, &view,ZBuffer);
La variabile ZBuffer, eventualmente anche NULL, è una superficie ID3D10DepthStencilView che va creata in modo identico a quanto fatto per il Device. L'unica differenza sarà la dimensione che dovrà essere uguale a quella utilizzata per il target (sempre come il Device). Al momento dell'inserimento dovrete modificare anche il viewport per porlo uguale a quello della texture.
Dal momento in cui avrete inserito i target ogni oggetto sarà renderizzato sulla texture anzichè sullo schermo. Al termine non dovrete far altro che rimettere come target il backbuffer e lo ZBuffer originari. Qui potrete utilizzare lo ShaderResourceView come texture per un modello 3D o uno sprite.
Nei prossimi tutorial vi mostrerò come utilizzare i render target multipli. Vi lascio al demo.
Demo
I commenti sono disabilitati.