shade29450

I am trying to render to a texture and then use the texture as a result for subseqeunt passes, I have implemented this in a double buffered fashion. However it gives some un forseen results,
Both textures are identical in size and format, it have no problems with single pass render to texture but there must be a problem in my approach for repetive passes.
Any ideas

LPDIRECT3DSURFACE9 framebuffer = NULL;
DXUTGetD3DDevice()->GetRenderTarget(0, &framebuffer);
LPDIRECT3DSURFACE9 pDestSurf = NULL;
pEffect->SetTechnique(hTechnique);
pEffect->Begin(&uiNumPasses, 0);
uiReadTarget = 1; uiWriteTarget = 0;

// outer loop
for (int i = 0; i < 2; i++)
{
rt[uiWriteTarget]->GetSurfaceLevel( 0, &pDestSurf );
pd3dDevice->SetRenderTarget( 0, pDestSurf );
// inner loop
for (uiPass = 0; uiPass < uiNumPasses; uiPass++)
{
pEffect->SetTexture(hTexResult, rt[uiReadTarget]);
pEffect->SetInt(hCurrentPass, i);
pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_ARGB(0,0,0,0),1.0f,0);

pEffect->BeginPass(uiPass);
DrawQuad();
pEffect->EndPass();
}
pDestSurf->Release();
// switching read and write buffers
uiReadTarget = !uiReadTarget;
uiWriteTarget = !uiWriteTarget;
}
pEffect->End();
// restore framebuffer as render target
hr = pd3dDevice->SetRenderTarget(0, framebuffer);
framebuffer->Release();


Re: Game Technologies: Graphics double buffer render texture

BLANC Guillaume

What content do you expect for rt[uiReadTarget] when i == 0 and uiPass == 0
From my understanding, pixels of that surface are not correct.





Re: Game Technologies: Graphics double buffer render texture

shade

Both floating point textures will initially contain float4(0.0f,0.0f,0.0f,0.0f) which is as expected.

Once the first pass is executed the current write target should contain the results and as I swap read and write at the end I should be able to reuse previous results in an iterative manner. I have previously implemented this painless under OpenGL with the pbuffer extension, however I must obviously be doing something incorrect since the results are not as expected.

I am unsure what your exact point is

What do you mean by pixels of that surface are not correct As mentioned the texels will start as all zero¡¯s nothing wrong in that.






Re: Game Technologies: Graphics double buffer render texture

BLANC Guillaume

So you mean that rt[1] is initialized outside of the code you've post. Because from what I've seen, rt[1] is read before it can be cleared (when i == 0 and uiPass == 0). Is that right





Re: Game Technologies: Graphics double buffer render texture

shade

By initialize I assume you mean Clear(....) I dont clear the results because I wish to reuse the results in consqeuent passes. I create the texture normally as below, which does at start contain nothing but zeroes.

What exactly is it that you think I am doing wrong is there a clear you would add or


I have modified the texture creation code to explicily clear the render texture (surface)
LPDIRECT3DSURFACE9 framebuffer = NULL;
pd3dDevice->GetRenderTarget(0, &framebuffer);
for(int buf = 0; buf<dwNumBuffers; buf++)
{
   hr = md_pd3dDevice->CreateTexture(width,
   height,
   1,
   D3DUSAGE_RENDERTARGET,
   D3DFMT_A32B32G32R32F,
   D3DPOOL_DEFAULT,
   &rt[buf],NULL);
   if(FAILED(hr))  { return hr;  }
           
   rt[buf]->GetSurfaceLevel(0, &surface[buf]);
   pd3dDevice->SetRenderTarget( 0, surface[buf]);         
   pd3dDevice->Clear(.... .....); // usual arguments
}

hr = md_pd3dDevice->SetRenderTarget(0, framebuffer);
framebuffer->Release();

The rendering has been change to use the surfaces associtated with the textures, also I have explicitly disabled z write, since the result is smeared all over the screen once I move the quad around.


    LPDIRECT3DSURFACE9 framebuffer = NULL;
    pd3dDevice->GetRenderTarget(0, &framebuffer);
    md_pEffect->SetTechnique(hTechnique);
    md_pEffect->Begin(&uiNumPasses, 0);
    uiReadTarget = 1;    uiWriteTarget = 0;
    INT iCurrentPass = 0;
    // outer loop
    for (int i = 0; i < 2; i++)
    {
        md_pd3dDevice->SetRenderTarget( 0, surface[uiWriteTarget] );
        md_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE,0);
        // inner loop
        for (uiPass = 0; uiPass < uiNumPasses; uiPass++) 
        {

            md_pEffect->SetTexture(hTexResult, rt[uiReadTarget]);
            md_pEffect->SetInt(hCurrentPass, iCurrentPass);             
            pd3dDevice->Clear(...); // usual arguments
            md_pEffect->BeginPass(uiPass);       
            DrawQuad();
            md_pEffect->EndPass();
         }
        iCurrentPass = iCurrentPass + 1;
        // switching read and write buffers
        uiReadTarget = !uiReadTarget;
        uiWriteTarget = !uiWriteTarget;
    }
    md_pEffect->End();   
    // restore framebuffer as render target
    hr = md_pd3dDevice->SetRenderTarget(0, framebuffer);
    framebuffer->Release();


Could you please specificy in graphics terms what you mean by initialize ....






Re: Game Technologies: Graphics double buffer render texture

BLANC Guillaume

"Initialize" means (in that context) settin all pixels values to default. So ::clear can be the way to initialize surface if all pixels should have the same value.

Got 2 idea:
1. Is'nt it strange that the clear operation is made inside effect begin/end pass (inner) loop Only the last pass of an effect can be seen because all others are cleared! I don't know what you're doing, but I think the ::Clear op should be done just after the ::SetRenderTarget is called and before the inner loop, isn't it

2. I understand you want to keep the result between each pass. But do you need to keep the result of previous frame (object, effect) If yes, then forget what I've said. If not, then since the second frame, the texture you're reading (rt[uiReadTarget == 1]) isn't cleared (initialized) when i==0 and uiPass == 0. That's all I could say from the reading of your code.

As I don't know what the result is and nor what you wanted to do, I cannot imagine what the bug could be. What you need to do is debugging so you should try Pix in order to see what's going on during each pass. You be able so see surfaces for each pass and thus certainly understand and fix your issue.





Re: Game Technologies: Graphics double buffer render texture

shade

Point taken ;-) You are right with the second part. I have more or less completely veryfied that the clearing is the issue. Since as you say than in the frame ahead should have had the previous results cleared.