[Direct3D9] Rendertarget zonder D3DXCreateRenderToSurface

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
Aangezien ik wil weten wat ik nu eigenlijk aan het doen ben, ben ik eens zelf Render Targets gaan instellen.

Niet nuttig? Eigenlijk best wel, wist namelijk niet eens wat een Render Target was eerst.

Maar de boel werkt niet goed meer (heb dus geen goed idee wat er eigenlijk in die D3DX-functie uit de titel gebeurt).

Eerst de code:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* INIT */
d3ddevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&flipchain);
d3ddevice->CreateTexture(shadowmapsize,shadowmapsize,1,D3DUSAGE_RENDERTARGET,D3DFMT_R32F,D3DPOOL_DEFAULT,&ShadowTex,NULL);
d3ddevice->CreateDepthStencilSurface(shadowmapsize,shadowmapsize,D3DFMT_D24X8,d3dpp.MultiSampleType,d3dpp.MultiSampleQuality,1,&ShadowDepthTopSurface,NULL);
ShadowTex->GetSurfaceLevel(0,&ShadowTexTopSurface); // TODO: hierboven kapt ermee bij kleiner dan d3dpp

/* RUNTIME */
d3ddevice->BeginScene();

d3ddevice->SetRenderTarget(0,ShadowTexTopSurface);
d3ddevice->SetDepthStencilSurface(ShadowDepthTopSurface);
d3ddevice->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
/* Render ernaar met d3ddev */

d3ddevice->SetRenderTarget(0,flipchain);
d3ddevice->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
/* Render ernaar met d3ddev */

d3ddevice->EndScene();


Gaat perfect zolang ShadowTexTopSurface en ShadowDepthTopSurface groter zijn dan of gelijk zijn aan de backbuffer (flipchain).

Jeps, dat staat ook in de docs. Maar ik kan me niet voorstellen dat het niet mogelijk zou zijn om een shadowmap te maken die kleiner is dan het scherm zelf (dan zou de zeer redelijke 1024x1024 niet eens mogelijk zijn als Shadowmap).

Het lamme is dat de Debug niks vermeldt, en dat het renderen (en reageren) gewoon doorgaat. Niks geen real fouten dus. En dat is vaag. Samengevat:
  • Is het mogelijk om een Render Target te maken die kleiner is dan de Back Buffer zonder D3DX?
  • Verder, is het mogelijk om wel AA op de BackBuffer, maar niet op bijv. de ShadowMap te hebben?

  • Het volledige beeld wordt wisselend zwart of standje disco als de shadows kleiner zijn dan de back buffer. Dit is vreemd, want hoe kan de Shadowmap ooit de gehele back buffer beïnvloeden?
  • Ik beheer blijkbaar netjes m'n COM's. Debug meldt dat ik 0 bytes achterlaat.

[ Voor 9% gewijzigd door Orwell op 02-04-2011 20:09 ]


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Volgens mij heb je dat verkeerd begrepen, je depthstencil moet groter of gelijk als je rendertarget zijn (immers, voor elke texel in je target heb je een texel in je depthstencil nodig). Hoe groot je flipchain is heeft daar niets mee te maken.

Maar op regel 15 bind jij je flipchain als RT en je shadow-depthstencil is nog steeds hetzelfde (van regel 11), en dan moet je depthstencil dus wel groter/gelijk aan flipchain zijn, immers, je rendert ermee icm je flipchain :P

Zelfde geld voor AA, die moeten matchen voor je RT en DS als je ze samen gebruikt, maar de flipchain heeft daar niets mee te maken. Er is wel de limitatie dat een texture geen AA kan hebben (immers, dat kan je niet zomaar samplen in een shader, als je een RT met AA wilt, gebruik dan CreateSurface ipv CreateTexture). Jouw depthstencilsurface op regel 4 heeft mogelijk wel AA, dus dat kan fout gaan.

Om kort te gaan, als je rendert, MOET je een rendertarget hebben, en optioneel een depthstencilbuffer. Indien je een depthstencil wilt gebruiken, MOET die groter/gelijk aan je rendertarget zijn, met dezelfde AA settings. Dat alles heeft NIETS te maken met je D3DPRESENT_PARAMETERS.

Andere foutjes:
- Om te renderen naar je flipchain moet je elk frame je backbuffer opnieuw pakken, want die flipt (wisselt) na elke Present(), dus niet in je Init stap doen.
- Ik zie nergens een SetViewport, dat is vrijwel altijd van toepassing bij een SetRenderTarget

Als tip, elke keer als je van RT veranderd, doe het in een groep met SetRenderTarget(), SetDepthStencilSurface() en SetViewport() in 1x, en zorg dat die bij elkaar passen.


Een flipchain is niets meer dan een setje van 2 (of meer) rendertargets + (optioneel) 1 depthstencilbuffer. Elke keer als je Present() doet op een flipchain, wijst D3D 1 van die rendertargets aan als frontbuffer, en 1 van die rendertargets als backbuffer (in het geval met 2 rendertargets wisselen die dus elke Present(), vandaar de naam "flip"). De depthstencilbuffer is een beetje "verstopt" in de flipchain, aangezien die ook automatisch kan zijn (auto-depthstencil, in D3DPRESENT_PARAMETERS). Als je je backbuffer als rendertarget bind, vergeet dan niet ook de depthstencil buffer uit de flipchain ook te binden, het automatische gedeelte slaat op het aanmaken/releasen, niet op het gebruik.

[ Voor 83% gewijzigd door MLM op 03-04-2011 01:28 ]

-niks-


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
MLM schreef op zondag 03 april 2011 @ 00:56:
Volgens mij heb je dat verkeerd begrepen, je depthstencil moet groter of gelijk als je rendertarget zijn (immers, voor elke texel in je target heb je een texel in je depthstencil nodig). Hoe groot je flipchain is heeft daar niets mee te maken.
Niet verkeerd begrepen. :P

Maar ik denk dat dit dus komt doordat ik die depth van de shadowmap nog gebruik zoals je zegt.

En jeps, ik wist dat in elke texel (pixel op texture) een eigen texel heeft op de depth en op de color (of render zo je wilt).
Maar op regel 15 bind jij je flipchain als RT en je shadow-depthstencil is nog steeds hetzelfde (van regel 11), en dan moet je depthstencil dus wel groter/gelijk aan flipchain zijn, immers, je rendert ermee icm je flipchain :P
(na alles onderin gelezen te hebben) Ik dacht dus dat dat wel geregeld werd met AutoDepthStencilSurface aan.
Zelfde geld voor AA, die moeten matchen voor je RT en DS als je ze samen gebruikt, maar de flipchain heeft daar niets mee te maken. Er is wel de limitatie dat een texture geen AA kan hebben (immers, dat kan je niet zomaar samplen in een shader, als je een RT met AA wilt, gebruik dan CreateSurface ipv CreateTexture). Jouw depthstencilsurface op regel 4 heeft mogelijk wel AA, dus dat kan fout gaan.
(je bedoelt CreateRenderTarget i.p.v. CreateSurface?)

Symptoombestrijding was dat. Ik merkte dat als ik de shadowmap-AA op hetzelfde zette als de main-AA, dat er een flinke boel troep wegging. Dit komt dus blijkbaar ook doordat ik die depthstencil niet verwisselde.
Om kort te gaan, als je rendert, MOET je een rendertarget hebben, en optioneel een depthstencilbuffer. Indien je een depthstencil wilt gebruiken, MOET die groter/gelijk aan je rendertarget zijn, met dezelfde AA settings. Dat alles heeft NIETS te maken met je D3DPRESENT_PARAMETERS.
Dat ontbrak er dus een beetje aan. Danku.
Andere foutjes:
- Om te renderen naar je flipchain moet je elk frame je backbuffer opnieuw pakken, want die flipt (wisselt) na elke Present(), dus niet in je Init stap doen.
Dat was ook bekend. Maar ik dacht dus dat die pointer automatisch bleef wijzen naar de BACK buffer.
- Ik zie nergens een SetViewport, dat is vrijwel altijd van toepassing bij een SetRenderTarget
Daar moet ik dan is naar gaan kijken.
Als tip, elke keer als je van RT veranderd, doe het in een groep met SetRenderTarget(), SetDepthStencilSurface() en SetViewport() in 1x, en zorg dat die bij elkaar passen.
Dan rest de brandende vraag: hoe verkrijg ik de top surface (of texture of wat) van de maindepthstencil?
Een flipchain is niets meer dan een setje van 2 (of meer) rendertargets + (optioneel) 1 depthstencilbuffer. Elke keer als je Present() doet op een flipchain, wijst D3D 1 van die rendertargets aan als frontbuffer, en 1 van die rendertargets als backbuffer (in het geval met 2 rendertargets wisselen die dus elke Present(), vandaar de naam "flip"). De depthstencilbuffer is een beetje "verstopt" in de flipchain, aangezien die ook automatisch kan zijn (auto-depthstencil, in D3DPRESENT_PARAMETERS). Als je je backbuffer als rendertarget bind, vergeet dan niet ook de depthstencil buffer uit de flipchain ook te binden, het automatische gedeelte slaat op het aanmaken/releasen, niet op het gebruik.
Komt weer die vraag boven: enig idee hoe ik een pointer naar de 1ste mip of de gehele texture van die depth kan krijgen?

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Orwell schreef op zondag 03 april 2011 @ 10:02:
[...]


Niet verkeerd begrepen. :P

Maar ik denk dat dit dus komt doordat ik die depth van de shadowmap nog gebruik zoals je zegt.

En jeps, ik wist dat in elke texel (pixel op texture) een eigen texel heeft op de depth en op de color (of render zo je wilt).


[...]


(na alles onderin gelezen te hebben) Ik dacht dus dat dat wel geregeld werd met AutoDepthStencilSurface aan.


[...]


(je bedoelt CreateRenderTarget i.p.v. CreateSurface?)
Inderdaad, was uit mijn hoofd :P
Symptoombestrijding was dat. Ik merkte dat als ik de shadowmap-AA op hetzelfde zette als de main-AA, dat er een flinke boel troep wegging. Dit komt dus blijkbaar ook doordat ik die depthstencil niet verwisselde.


[...]


Dat ontbrak er dus een beetje aan. Danku.


[...]


Dat was ook bekend. Maar ik dacht dus dat die pointer automatisch bleef wijzen naar de BACK buffer.


[...]


Daar moet ik dan is naar gaan kijken.


[...]


Dan rest de brandende vraag: hoe verkrijg ik de top surface (of texture of wat) van de maindepthstencil?


[...]


Komt weer die vraag boven: enig idee hoe ik een pointer naar de 1ste mip of de gehele texture van die depth kan krijgen?
De automatisch depthstencil van je D3DPRESENT_PARAMETERS (van je device) kan je opvragen met GetDepthStencilSurface() direct nadat je device gemaakt is (het is de standaard waarde). Een texture is een verzameling surfaces (de mip levels). Alleen bij het renderen naar texture heb je een "top-level" surface nodig. De depthstencilsurface is gewoon een surface, dus je hebt geen "top-level" :P

-niks-


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
MLM schreef op zondag 03 april 2011 @ 12:33:
[...]

Inderdaad, was uit mijn hoofd :P

[...]


De automatisch depthstencil van je D3DPRESENT_PARAMETERS (van je device) kan je opvragen met GetDepthStencilSurface() direct nadat je device gemaakt is (het is de standaard waarde). Een texture is een verzameling surfaces (de mip levels). Alleen bij het renderen naar texture heb je een "top-level" surface nodig. De depthstencilsurface is gewoon een surface, dus je hebt geen "top-level" :P
Wat zijn die API's toch leuk. Als je een bepaalde functie niet kent, ben je nergens meer. Maar da's nu weer een beetje meer verleden tijd. Dankuzeer!

De winst van het weglaten van D3DX in dit stukje is niet heel erg jottem, maar het is wel te merken: CPU-gebruik ging bij een bepaalde bench omlaag van 31% naar 29%. Dit komt waarschijnlijk doordat D3DXCreateBlaBla de oude rendertarget en depth opslaat en die weer set na RenderToSurface->EndScene().

Verder zit het wel best met de viewports, die defaulten volgens de docs naar de gehele rect, dus daar doen we niet moeilijk meer over.

Klein ding is de back/front-pointer. Volgens mij verhuist deze constant mee naar het adres van de BACK. Ja toch?

Rest nog het punt van de AA: deze werkt nu wel aardig, maar zou het mogelijk kunnen zijn om wel op de main, maar niet op de shadowmap AA te doen? Kan het niet echt voor mekaar krijgen.

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Orwell schreef op zondag 03 april 2011 @ 20:29:
[...]

...
Verder zit het wel best met de viewports, die defaulten volgens de docs naar de gehele rect, dus daar doen we niet moeilijk meer over.
Ik heb wel eens een keer gehad dat ik een half uur heb lopen debuggen met een zwart scherm, omdat de viewport niet goed was. Het is een soort reflex geworden daardoor :P
Klein ding is de back/front-pointer. Volgens mij verhuist deze constant mee naar het adres van de BACK. Ja toch?
Probeer het. Als het werkt zonder hem opnieuw op te halen, dan verhuist hij mee. Als je flikkerend scherm hebt, dan verhuist het niet ;P

-niks-

Pagina: 1