Sign in to follow this  

render to texture dx9

This topic is 2329 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

Hi,

I want to run a screen space effect on my scene, I think I set up everything correctly for rendering to texture and later drawing it on the entire screen.

I have a texture to render to
[code]LPDIRECT3DTEXTURE9 render_to_tex = NULL;[/code]
and I have two surfaces to set as render targets:
[code]LPDIRECT3DSURFACE9 render_to_tex_surf = NULL, back_buffer = NULL[/code];

I set them up like this:
[code]dx_dev->CreateTexture(screen_width, screen_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &render_to_tex, NULL);
render_to_tex->GetSurfaceLevel(0, &render_to_tex_surf);
dx_dev->GetRenderTarget(0, &back_buffer);[/code]

I have the scene rendered like this:
[code]//begin rendering to texture
dx_dev->SetRenderTarget(0, render_to_tex_surf);
//clear color and z-buffer
dx_dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
dx_dev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

//begin drawing
dx_dev->BeginScene();

//set up matrices (world, projection (perspective), view)
//set up shaders (passing variables etc.)
//drawing triangles (quads)

//end rendering to texture
dx_dev->EndScene();[/code]

and then I run the full-screen effects like this:
[code]//begin rendering to back buffer
dx_dev->SetRenderTarget(0, back_buffer);

//clear color and z-buffer
dx_dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
dx_dev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

//begin drawing
dx_dev->BeginScene();

//set up matrices (world, projection (orthographic), view)
//set up shaders (passing values)
//drawing the full screen quad

//end drawing & swap buffers
dx_dev->EndScene();
dx_dev->Present(NULL, NULL, NULL, NULL);[/code]

The two separately (without rendering to texture) work flawlessly the shaders are fine, if I try to use them together I get a wierd picture (attached)

Any ideas what am I missing?

Best regards,
Yours3!f

Share this post


Link to post
Share on other sites
First thing you need to do is Release the surfaces you obtain from the back buffer and GetSurfaceLevel after you're done with them as the internal reference counts will be increased. You basically have a memory leak here otherwise. The appropriate place would be after your SetRenderTarget call, so change this:[code]dx_dev->SetRenderTarget(0, back_buffer);[/code]
To this:[code]dx_dev->SetRenderTarget(0, back_buffer);

render_to_tex_surf->Release ();
back_buffer->Release ();[/code]
Your clear calls are a little messed up; you don't need two and you only need to clear once - at the very beginning of each frame (even before BeginScene):[code]dx_dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);[/code]
You definitely don't need to clear for the full-screen quad as it's overwriting the entire scene anyway; just disable depth testing and depth writing for it instead.

Your BeginScene/EndScene calls are also a little messed up. Just use one BeginScene/EndScene pair per frame rather each time you switch the rendertarget.

Also add some error checking here. Each of these calls returns a HRESULT and any of them could be failing for any reason, so make sure that you're getting D3D_OK back from them all.

That should get things reasonably correct so far as your code structure is concerned, so assuming that all is fine following this and you still get the same problem, the next step would be to enable the debug runtimes and check for errors there, then run it through PIX and capture draw calls, then step through them in the output viewing what's happening. You should be able to identify where things are going wrong with all of that.

Share this post


Link to post
Share on other sites
Thanks for the reply, I did as you told me, and something still seems to be wrong... I still get the same wierd picture...

I checked the setrendertarget, create texture, get surfacelevel, get rendertarget calls but none of them seem to fail.

However when I release the surfaces and textures I get an access violation error.
[code]render_to_tex->Release();
render_to_tex_surf->Release(); //this line triggers it
back_buffer->Release();[/code]

Share this post


Link to post
Share on other sites
sorry, I was so stupid, I misread what you wrote, so I released the surfaces after the getrendertarget not after the setrendertarget. Now I release them after the setrendertarget, however it now doesn't draw anything, just a white screen. Now I don't get a access violation error, however if I switch to an other rendering mode (different scene, with different draw calls, without render to texture) and I switch back, then I get again an access violation error:
[code]result = dx_dev->SetRenderTarget(0, render_to_tex_surf); //this triggers it.
if(result != S_OK)
{...}[/code]

When I start the VS debugger it says that a heap has been corrupted

Share this post


Link to post
Share on other sites
[quote name='Yours3!f' timestamp='1311685438' post='4840490']
sorry, I was so stupid, I misread what you wrote, so I released the surfaces after the getrendertarget not after the setrendertarget. Now I release them after the setrendertarget, however it now doesn't draw anything, just a white screen. Now I don't get a access violation error, however if I switch to an other rendering mode (different scene, with different draw calls, without render to texture) and I switch back, then I get again an access violation error:
[code]result = dx_dev->SetRenderTarget(0, render_to_tex_surf); //this triggers it.
if(result != S_OK)
{...}[/code]

When I start the VS debugger it says that a heap has been corrupted
[/quote]

Is it possible that anything your using is going out of scope?
Try doing GetBackBuffer() each frame before you call SetRenderTarget on your backbuffer.
http://msdn.microsoft.com/en-us/library/bb174379%28v=VS.85%29.aspx

Share this post


Link to post
Share on other sites
[quote name='yewbie' timestamp='1311719718' post='4840850']
[quote name='Yours3!f' timestamp='1311685438' post='4840490']
sorry, I was so stupid, I misread what you wrote, so I released the surfaces after the getrendertarget not after the setrendertarget. Now I release them after the setrendertarget, however it now doesn't draw anything, just a white screen. Now I don't get a access violation error, however if I switch to an other rendering mode (different scene, with different draw calls, without render to texture) and I switch back, then I get again an access violation error:
[code]result = dx_dev->SetRenderTarget(0, render_to_tex_surf); //this triggers it.
if(result != S_OK)
{...}[/code]

When I start the VS debugger it says that a heap has been corrupted
[/quote]

Is it possible that anything your using is going out of scope?
Try doing GetBackBuffer() each frame before you call SetRenderTarget on your backbuffer.
[url="http://msdn.microsoft.com/en-us/library/bb174379%28v=VS.85%29.aspx"]http://msdn.microsof...v=VS.85%29.aspx[/url]
[/quote]

I don't think so, since the whole app is in one cpp file and all surfaces and textures are on global scope.
I tried, and it is the same.

Share this post


Link to post
Share on other sites
I tried to debug the app frame by frame, and it seems that in the first frame the render_to_tex_surf is correct, but in the following frame it somehow loses the data, and points to wrong memory location, and it cannot be accessed, that's when access violation occur.

Share this post


Link to post
Share on other sites
[quote name='Yours3!f' timestamp='1311750062' post='4840969']
I tried to debug the app frame by frame, and it seems that in the first frame the render_to_tex_surf is correct, but in the following frame it somehow loses the data, and points to wrong memory location, and it cannot be accessed, that's when access violation occur.
[/quote]


That's probably because you're destroying the surface. You shouldn't be releasing the surface after setting it as a rendertarget.
The surface's refcount will increase when you set it as rendertarget ( if I recall correctly ) but it will be decreased again when another rendertarget ( the backbuffer ) is set.
When you call release on the surface you will cause the surface to be destroyed while your app is still running. Assuming you only do GetSurface once you should only release the surface once, at the end of the program.

Share this post


Link to post
Share on other sites
Ok guys I don't really know what was the problem, I just rewrote the app only including the render-to-texture part, and now it works... I think other parts of the app are messed up so I'll try to fix them. Basically there was nothing wrong with the render-to-texture part, but other stuff (might) have made it crash. Anyways thanks for the help!

Share this post


Link to post
Share on other sites

This topic is 2329 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