Sign in to follow this  
Bedlamuk

Rendering Backbuffer to a Texture or smaller Surface

Recommended Posts

Bedlamuk    154
Hi all, I'm not getting the results I expected when rendering the backbuffer surface to a texture (I'm trying to create a smaller image copy of the rendered scene onto a texture surface). When I create the texture with a different width/height than the backbuffer surface, the texture image is turning out all scrambled with different color squares (gobblygook). It only works when I create the texture the same size as the backbuffer surface, but I want a smaller copy of the rendered scene (scaled down copy). Here is the main code I am using (sorry, for the delphi syntax :) ): After my BeginScene and EndScene have been called: Global Var (created somewhere else) d3ddevice: IDirect3DDevice8; Procedure MyRenderToTexture(); var d3dbackbuffer: IDirect3DSurface8; d3dtexturesurface: IDirect3DSurface8; d3dtexture: IDirect3DTexture8; filename: string; dispmode: _D3DDISPLAYMODE; surfdesc: _D3DSURFACE_DESC; begin d3ddevice.GetDisplayMode(dispmode); d3ddevice.GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,d3dbackbuffer); d3dbackbuffer.GetDesc(d3dbackbufferdesc); D3DXCreateTexture(d3ddevice, 256, 256, 1, D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, d3dtexture); d3dtexture.GetSurfaceLevel(0,d3dtexturesurface); d3ddevice.SetRenderTarget(d3dtexturesurface,nil); (this part is just example) d3ddevice.Present(nil,nil,nil,nil); filename := 'c:\temp\texture.bmp'; D3DXSaveTextureToFile(PChar(filename),D3DXIFF_BMP,d3dtexture,nil); end; As I say, it works only when I set the texture size in D3DXCreateTexture to the same width/height as the backbuffer surface. Are there any ways of creating a scaled down version of the Backbuffer surface ??? For example: The screensize/backbuffer size is 1024 x 768 and I want to create a surface which is 640 x 480 and render a complete copy of the scene to this surface. From what I have discovered all surface to surface functions only work if they are all the same format. Thanks all.

Share this post


Link to post
Share on other sites
Armadon    1091
Hi there Bedlamuk,
How are you doing?

The Problem
Rendering the back buffer to a texture.

The Solution
It seems you want to do 2 approaches, 1 being to saving the back buffer to a texture and one is to render to texture.
So let me help you by giving you both approaches.

Rendering to Texture using arb sizes of textures
1) First you will create 2 variables. a Texture created with a size of whatever size you want. You then just get the surface level from the texture and place it in parameter 2 being the surface that you created.
e.g.
texture = new Texture(renderer.Device, 128, 128, 1, Usage.RenderTarget, Format.X8R8G8B8, Pool.Default);
surface = texture.GetSurfaceLevel(0);

2) You then begin the rendering to texture. You save the original back buffer to some other surface.
e.g. Surface oldRenderTarget = renderer.Device.GetRenderTarget(0);
3) Set the new back buffer/surface to the rendered to.
e.g. renderer.Device.SetRenderTarget(0, surface);
4) Clear it as per usual and get it ready to be rendered to.
e.g.
renderer.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer,
Color.Black.ToArgb(), 1.0f, 0);
renderer.Device.BeginScene();
5) Render to the surface.
6) Set the render target back to the old render target.
e.g. renderer.Device.SetRenderTarget(0, oldRenderTarget);

You then have a texture that has been rendered too. You can use this texture then to simply render it and see the results or save the texture to a file using D3DXSaveTextureToFile.

Make sure you are clearing the surface before you are rendering to it.
Make sure you are also specifying a valid format for the texture. Try D3DFMT_X8R8G8B8.

I hope this helps buddy.
Take care.

Share this post


Link to post
Share on other sites
Bedlamuk    154
thanks Armadon, I've rechecked my code and applied what was missing and it's now working but not perfectly.

The texture image is not gobblygook anymore and is the correct dimensions, but the image is not rescaled to the texture size. Also the backbuffer surface is not rendering to my application anymore, only the texture surface.

To recap what I am trying to achieve is:
The scene has already been drawn and it is the backbuffer surface image (before it is presented) that I want to render to the texture. Say I want a picture on a wall displaying a copy of what the user sees on screen.

Should I be using CreatRenderTarget anywhere ???

Share this post


Link to post
Share on other sites
Armadon    1091
Hi there Bedlamuk,
How are you doing?

The Problem
Render to surface/texture

The Solution
What you will want to do is plain old render to texture and just displaying the texture to a quad or sprite. You can look at the following tutorial that does just this. Render to Texture. It's C# but the theory still applies and i'm sure it will push you in the right direction.

I hope this helps. Take care buddy.

Share this post


Link to post
Share on other sites
Bedlamuk    154
Thanks for site link...i'm downloading now.

BTW...I do not have access to any of the BeginScene/EndScene drawing routines. I am using a proxy hook to capture these functions.

Is it possible to render to 2 surfaces at the same time ??

I would rather not change the rendertarget but if it is possible to render to an offscreen surface which would be rendered along with the main backbuffer surface.

Share this post


Link to post
Share on other sites
Bedlamuk    154
Ok, I got it working now.

I used D3DXLoadSurfaceFromSurface to load the backbuffer surface into the texture surface. This seems to do all the scaling/color conversion stuff automatically.

Share this post


Link to post
Share on other sites

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