Sign in to follow this  

problem reading back from render target

This topic is 4304 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am creating the render targets after saving the current one. Then I use effects and HLSL to render something into this new target that I created. After I am done with all, I try to read the render target and am not getting the correct value. Here's how I create the textures. REN_TARGET_SIZE is set to 1 (I just need to read 1 value so 1x1 texture). // Save the old render target LPDIRECT3DSURFACE9 pRTOld = NULL; V( pd3dDevice->GetRenderTarget( 0, &pRTOld ) ); //// Create a temporary Surface to render into IDirect3DSurface9 * pSurf; pd3dDevice->CreateRenderTarget(REN_TARGET_SIZE,REN_TARGET_SIZE,D3DFMT_A8R8G8B8,D3DMULTISAMPLE_NONE,0,true,&pSurf,NULL); Then, I set technique in effect. V( g_pEffect->SetTechnique( g_pTech->foo ) ); Then I render to the scene to that target. if( SUCCEEDED( pd3dDevice->BeginScene() ) ) { V( g_pEffect->Begin( &cPass, 0 ) ); for( p = 0; p < cPass; ++p ) { V( g_pEffect->BeginPass( p ) ); for (int iNumMeshes=0; iNumMeshes < NUM_MESHES; iNumMeshes++) { LPD3DXMESH pMesh = g_EnvMesh[iNumMeshes].m_Mesh.GetMesh(); for( DWORD i = 0; i < g_EnvMesh[iNumMeshes].m_Mesh.m_dwNumMaterials; ++i ) { D3DXMatrixMultiply( &mWorldView, &g_EnvMesh[iNumMeshes].m_mWorld, pmView ); V( g_pEffect->SetMatrix( g_hWorldView, &mWorldView ) ); V( g_pEffect->CommitChanges() ); V( pMesh->DrawSubset( i ) ); } } V( g_pEffect->EndPass() ); } pd3dDevice->EndScene(); } V( g_pEffect->End() ); After all this is done, here's how read the texture back. IDirect3DSurface9 *dt = 0; V( DXUTGetD3DDevice()->CreateOffscreenPlainSurface( REN_TARGET_SIZE, REN_TARGET_SIZE, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &dt, 0 ) ); V( DXUTGetD3DDevice()->GetRenderTargetData( pSurf, dt ) ); D3DLOCKED_RECT outRect; if (FAILED (dt->LockRect(&outRect,0,D3DLOCK_READONLY ))) DXUTOutputDebugString( L"Failed to lock the render target dt\n"); DWORD * pBitmap = (DWORD*)outRect.pBits; int vResult[REN_TARGET_SIZE][REN_TARGET_SIZE]; for( int y = 0; y < REN_TARGET_SIZE; y++ ) for( int x = 0; x < REN_TARGET_SIZE; x++ ) vResult[y][x]=0; for( int y = 0; y < REN_TARGET_SIZE; y++ ) for( int x = 0; x < REN_TARGET_SIZE; x++ ){ //iResult[y][x] = 0; vResult[y][x] = ((int *)(outRect.pBits))[y*REN_TARGET_SIZE+ x]; } In my shader I am returning float4 value of (1.0,1.0,1.0,1.0) in pixel shader. So technically I should get 0xffffffff back in vResult[1][1]. I am getting somethign different. Any ideas why? I tried changing DWORD * pBitmap = (DWORD*)outRect.pBits; to unsigned * pBitmap = (unsigned *)outRect.pBits; but that did not work either. Any ideas ?

Share this post


Link to post
Share on other sites
Okay, good catch.
I added a SetRenderTarget call after CreateRender target as follows.

//// Create a temporary Surface to render into
IDirect3DSurface9 * pSurf;
pd3dDevice->CreateRenderTarget(REN_TARGET_SIZE,REN_TARGET_SIZE,D3DFMT_A8R8G8B8,D3DMULTISAMPLE_NONE,0,true,&pSurf,NULL);
V( pd3dDevice->SetRenderTarget( 1, pSurf ) );

I still get random reasults. Anything else I am missing ? or doing incorrectly?

-Rahul

Share this post


Link to post
Share on other sites
I have some questions.

1. Do you create a new render target every frame?
2. Do you use a depth buffer?
3. Have you checked if it renders your meshes to the back buffer in the case you don’t use your render target?

Share this post


Link to post
Share on other sites
> 1. Do you create a new render target every frame?

I do this in OnFrameMove, i.e. only when something needs to be updated in the scene, not every frame. May be I need to CreateRenderTarget only once in OnCreateDevice but switch every update. Right?

> 2. Do you use a depth buffer?

No.

> 3. Have you checked if it renders your meshes to the back buffer in the case you don’t use your render target?

No. I have not. It's not a scene data. I am using this shader for something else other than rendering. For Some computationally heavy task. But I can try. The output won't make any sense visually, but worth a try.

Share this post


Link to post
Share on other sites
Yes you should create your render targets only once after you create device and after a device Reset.

To check what’s happen with your render target you can additionally use PIX.

Share this post


Link to post
Share on other sites
Are you sure you're not using a depth buffer elsewhere in your program? RenderTargets have to be compatible with their depth buffers, so to make sure you're not using a depth buffer you should call SetDepthStencilSurface(NULL) when you do your SetRenderTarget() and then restore the old depth buffer.

Although if that really was your problem, you would get a D3D Error, and you're not getting any of those right?

Share this post


Link to post
Share on other sites

This topic is 4304 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this