• Advertisement
Sign in to follow this  

Rendering to textures

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

Hello Can someone please point out the basic steps when using another rendertarget than the screenbuffer (and of other dimensions)? Im a total noob on this one, and im unsure how things like the projection matrix and the z-buffer etc works. Also, how do i create the rendertarget texture? Links to tutorials and other useful sites are very welcome. //Emil

Share this post


Link to post
Share on other sites
Advertisement
Take a look at the HDRCubMap and ShadowMapping samples that come with the SDK. Even though those samples cover more advanced techniques, they do use render target textures to accomplish stuff. So you could just look at how they do the render target code.

First step is to create the render target. This can be done by using IDirect3DDevice9::CreateRenderTarget or D3DXCreateTexture and passing in the appropriate flags.

Next you must set this surface/texture as the render target using IDirect3DDevice9::SetRenderTarget. Your projection matrix will usually change because the size of your new render target may be different from the size of your backbuffer. The depth buffer needs to be at least as large or larger than the render target currently being used. So if your render target is smaller or the same size as your backbuffer, you can continue to use the same depth buffer.

After you've set your render target, you can just draw things as normal. Once you've finished rendering, you can use the results to do other things. Code might look something like this.

// Save the original backbuffer
LPDIRECT3DSURFACE9 pBackBuffer = NULL;
pDevice->GetRenderTarget(0, &pBackBuffer);

// Set new surface as the render target
LPDIRECT3DSURFACE9 pSurfaceTarget = NULL;
pTextureTarget->GetSurfaceLevel(0, &pSurfaceTarget);
pDevice->SetRenderTarget(0, pSurfaceTarget)

pDevice->Clear(...)
pDevice->BeginScene()
...
pDevice->Draw*Primitive(....);

// finished rendering to render target.
pDevice->SetRenderTarget(0, pBackBuffer);
pDevice->Clear(...);
...
// Use render target as input texture for other stuff.
pDevice->SetTexture(0, pTargetTexture);
pDevice->Draw*Primitive(...);
...
pDevice->EndScene();
pSurfaceTarget->Release();
pDevice->Present(...);


Hope this helps,
neneboricua

Share this post


Link to post
Share on other sites
thanks for a fast reply. ill look into those samples.

a question thogh, what is the difference between a texture and a surface?

//emil

Share this post


Link to post
Share on other sites
As far as i know.. a texture is a colection of surfaces

A texture is a list of surfaces that hold the same bitmap but in diferent sizes, for example, if you create a texture of 256x256 pixels, then that texture will have one or various surfaces (depending on the configuration) with sizes 256x256, next 128x128, next 64x64, etc. until you achieve 1x1 pixels that is the last surface

Top-level surface (the more detailed one) is denoted by the index 0, and the rest are generated acording to this one

The surface used to paint polygons is chosed depending on the size of the polygon, so, small polygons (far aways polygons usually) use smaller surfaces of the texture

Share this post


Link to post
Share on other sites
Quote:
Original post by Toack
As far as i know.. a texture is a colection of surfaces
[snip...]

This is true if you enable mipmapping when loading/creating the texture. But it is possible to have a texture with only one level of detail (i.e. one surface). But the idea Toack expressed is correct.

neneboricua

Share this post


Link to post
Share on other sites
Ok, but when i render to the texture i only render to the top level mipmap, so i should disable mipmapping when rendering from the texture, right?

A strange thing: the directx documentation has this definition of SetRenderTarget:

HRESULT SetRenderTarget(
DWORD RenderTargetIndex,
IDirect3DSurface9 * pRenderTarget,
IDirect3DSurface9 * pNewZStencil
);

but the function header in d3d9.h doesnt have this third argument (pNewZStencil). Are the documentation flawed, or am i missing something?

Im using october update sdk

Thanks

//emil

Share this post


Link to post
Share on other sites
Code to define rendertarget



LPDIRECT3DTEXTURE9 g_pRenderTexture = NULL; /// texture to encapsulate surface
LPD3DXRENDERTOSURFACE g_pRenderTarget = NULL;
LPDIRECT3DSURFACE9 g_pRenderSurface = NULL; /// render surface




Code to initialize the render-target

HRESULT hRes;
hRes = D3DXCreateTexture( pd3dDevice, // device
512, // width
512, // height
1, // Mipmap levels
D3DUSAGE_RENDERTARGET, // rendertarget
D3DFMT_A8R8G8B8, // 32 bit RGBA format
D3DPOOL_DEFAULT, // default pool, it'll be allocated in VRAM
&g_pRenderTexture); // texture

if (FAILED(hRes))
{
// couldn't create it.
return hRes;
}

// get the surface description
D3DSURFACE_DESC desc;
// get the only mipmap
g_pRenderTexture->GetSurfaceLevel(0, &g_pRenderSurface);
// get description
g_pRenderSurface->GetDesc(&desc);

// create the render-target information
hRes = D3DXCreateRenderToSurface( pd3dDevice, // device
desc.Width, // get info from descriptor
desc.Height, // get info from descriptor
desc.Format, // get info from descriptor
true, // does it have a depth/stencil buffer ?
D3DFMT_D24S8, // if so, this is the format for that buffer
&g_pRenderTarget); // pointer to target



This is the code to render to it


D3DVIEWPORT9 Viewport;
Viewport.X = 0;
Viewport.Y = 0;
Viewport.Width = 512;
Viewport.Height = 512;
Viewport.MinZ = 0;
Viewport.MaxZ = 1;


HRESULT hRes = g_pRenderTarget->BeginScene(g_pRenderSurface, &Viewport);
assert(SUCCEEDED(hRes) && "Failed to begin scene for Camera with render surface");

hRes = pd3dDevice->Clear(
0, NULL, // clear whole rendertarget
D3DCLEAR_TARGET | // clear the framebuffer
D3DCLEAR_STENCIL | // clear stencil buffer
D3DCLEAR_ZBUFFER, // clear zbuffer
D3DCOLOR_RGBA(100, 0, 0, 60), // Color ARGB
1.0f, // clear Z to 1.0 (far clip)
0); // clear stencil to 0

// SETUP CAMERA
// DRAW YOUR STUFF HERE
// ....

// end rendertarget frame.
hRes = g_pRenderTarget->EndScene(D3DX_FILTER_NONE);
// apply a different filter mode?
assert(SUCCEEDED(hRes) && "Failed to end scene for Camera.");



Don't forget to handle Reset, Lost and Destroyed events as well


HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
///.....
// reset the render target
g_pRenderTarget->OnResetDevice();


void CALLBACK OnLostDevice( void* pUserContext )
///....
g_pRenderTarget->OnLostDevice();



void CALLBACK OnDestroyDevice( void* pUserContext )
///....
SAFE_RELEASE( g_pRenderTexture );
SAFE_RELEASE( g_pRenderTarget );
SAFE_RELEASE( g_pRenderSurface);




Hopefully that helps!

Allan

Share this post


Link to post
Share on other sites
Quote:
Original post by cannonicus
Ok, but when i render to the texture i only render to the top level mipmap, so i should disable mipmapping when rendering from the texture, right?

I'm not even sure if you can create a render target texture that has mipmaps generated. But if you do, you're correct in that you only render to the top level mipmap. You could then use IDirect3DTexture9::GenerateMipSublevels to fill the rest of the chain. But often times this isn't necessary and just degrades performance.
Quote:
Original post by cannonicus
A strange thing: the directx documentation has this definition of SetRenderTarget:

HRESULT SetRenderTarget(
DWORD RenderTargetIndex,
IDirect3DSurface9 * pRenderTarget,
IDirect3DSurface9 * pNewZStencil
);

but the function header in d3d9.h doesnt have this third argument (pNewZStencil). Are the documentation flawed, or am i missing something?

Im using october update sdk

This is a doc bug and I have it on good authority that it will be fixed in the next SDK release. The function does NOT accept a depth stencil surface as a parameter because there is a seperate function (IDirect3DDevice9::SetDepthStencilSurface) that will do that.

neneboricua

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement