Sign in to follow this  

D3D render targets

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

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]

Share this post


Link to post
Share on other sites
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;
}


Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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);
}

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Quote:
Original post by Sync Views
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?
Exactly. Each COM object (D3D objects are COM objects) has a reference count, which is incremented whenever a new reference to it is made (Or you call AddRef() on it, which is what happens internally), and is decremented when Release() is called. When the reference count reaches zero, the object is destroyed.
Usually, you'll just call Release() once, then set the pointer to null, since you'll normally have a reference count of one for each pointer you hold to the object.

In this case:
D3D creates the backbuffer, so gives it a reference count of 1.
You call GetBackBuffer(), which returns it, and increments the refcount to 2.
You call SetRenderTarget() with your new target, which causes D3D to Release() the pointer it holds to the old render target (the one it created), and that sets the refcount to 1.
You render, etc
You call SetRenderTarget() to set the old render target back, which increments the reference count to 2.

If you don't then Release() your pointer to the old render target, the reference count will keep going up and up each time you run that code, until the reference count on the backbuffer reaches some silly number, which never has a matching number of Release()s.

Share this post


Link to post
Share on other sites

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