D3D render targets

Started by
10 comments, last by SiCrane 16 years, 2 months ago
Basicly I want to create something that I can draw to (instead of the screen) then use later like a texture. Ive been trying to use this to create a surface I can set as the render target but I'm not sure what to use for one of the parameters... IDirect3DDevice9::CreateRenderTarget
Quote: MultiSample [in] Member of the D3DMULTISAMPLE_TYPE enumerated type, which describes the multisampling buffer type. This parameter specifies the antialiasing type for this render target. When this surface is passed to IDirect3DDevice9::SetRenderTarget, its multisample type must be the same as that of the depth-stencil set by IDirect3DDevice9::SetDepthStencilSurface. MultisampleQuality [in] Quality level. The valid range is between zero and one less than the level returned by pQualityLevels used by IDirect3D9::CheckDeviceMultiSampleType. Passing a larger value returns the error, D3DERR_INVALIDCALL. The MultisampleQuality values of paired render targets, depth stencil surfaces, and the multisample type must all match.
I never did use "IDirect3DDevice9::SetDepthStencilSurface" so I'm not sure what to do here... The only two things ive done with the stencil are:

d3d_parameters.EnableAutoDepthStencil = true;
d3d_parameters.AutoDepthStencilFormat = D3DFMT_D16;


Also once ive got my surface and drawn what I want onto it how do I use it? For terxtures i'm useing "d3d_device->SetTexture" but there doesn't seem to be a "SetSurface" to do the same with a surface so I can drawe it useing a quad.... [Edited by - Sync Views on February 17, 2008 9:11:52 AM]
Advertisement
Just use GetSurfaceLevel() on a texture you want to render to and use SetRenderTarget() with that surface.
Don't forget to create the texture with D3DUSAGE_RENDERTARGET specified.
Peter
ok now I'm just getting a completly black window as soon as I try to change the render target...

struct surface_data{	IDirect3DTexture9 *image;	int w, h;};std::vector<surface_data*> surface_list;bool draw_target(int sur){	if(!surface_exists(sur)) return false;	IDirect3DSurface9* surface;	surface_list[sur]->image->GetSurfaceLevel(0, &surface);	d3d_device->SetRenderTarget(0, surface);	return true;}void draw_target_reset(){	cgm::d3d_device->SetRenderTarget(NULL, NULL);}int surface_create(int w, int h){	if (w <= 0 || h <= 0) return -1;	IDirect3DTexture9 * image;	if(FAILED(D3DXCreateTexture		(cgm::d3d_device,		w, h,		1,		D3DUSAGE_RENDERTARGET,		D3DFMT_A8R8G8B8,		D3DPOOL_DEFAULT,		&image))) return -1;	surface_data *surface = new surface_data;	surface->w = w;	surface->h = h;	surface->image = image;	surface_list.push_back(surface);	return surface_list.size()-1;}
This still isn't working for me... Is there any examples around of drawing something onto a texture(eg some lines etc) then rendering that texture?
Mandatory "Any output from the debug runtimes?"
only warning/error is the same one ive always got

Quote:D3D9 Helper: Warning: Default value for D3DRS_POINTSIZE_MAX is 2.19902e+012f, not 1.58456e+029f. This is ok.


The draw functions are returning D3D_OK as well as I just checked but I still get just a black screen. Seeing as the draw function isn't failing I suppose it could be the render target not reseting correctly... I'm asuming that the right way to reset it since there doesn't seem to be a "d3d_device->ResetRenderTarget()" or anything like that....

Suppose I could see if I can find a pointer to the screen somewhere and try setting that as the render target...
o...got it to work by getting a pointer to the render target d3d has to start with and useing that to reset. Problem is 395284 bytes are not being freed but only when these 2 functions are called....

bool draw_target(int sur){	//abort if invalid surface id	if(!surface_exists(sur)) return false;	//get surface pointer from list	IDirect3DSurface9* surface;	cgm::surface_list[sur]->image->GetSurfaceLevel(0, &surface);	//set render target	cgm::d3d_device->SetRenderTarget(0, surface);	//start rendering to surface	cgm::d3d_device->BeginScene();	return true;}void draw_target_reset(){	//stop rendering to surface	cgm::d3d_device->EndScene();	//set target back to the screen	cgm::d3d_device->SetRenderTarget(0, cgm::screen);}
Ah yes. You need to grab the current render target, set the new render target, render, then restore the old render target.

It looks to me like you're never releasing the surface from GetSurfaceLevel(). Every time D3D gives you an interface pointer, you need to release it when you're done with it.

What is cgm::screen? If that's the surface from IDirect3DDevice9::GetRenderTarget(), you need to Release() it once you're done (After you've set it back as the render target).
ah I see... so ->Release() doesn't actually destroy the surface but just decreases some sort of counter so that when I looped through with (*it)->Release() at the end of the program those ones were not freed?

This topic is closed to new replies.

Advertisement