Jump to content
  • Advertisement
Sign in to follow this  

Extracting pixel information from SLimDX Surface

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

I am trying to work out how to extract the pixel color information from a SlimDX Direct3D9 Surface. I have the surface, which I create with Surface.CreateRenderTarget(...). I then use that as a render target. I want to then extract the color information so I can transform it to a texture, which can then be passed to a shader and rendered onto some geometry.

I've tried using the following method:

Surface renderTarget = Surface.CreateRenderTarget(...);

device.SetRenderTarget(0, renderTarget);

// ... perform render operations ...

// Extract information
DataRectangle rect = renderTarget.Lock(LockFlags.None);

using (DataStream stream = rect.Data)
{
// Note: The parameter type <T> has been tried with various structs, such as Color4 and Vector4.
Color4[] result = stream.ReadRange<Color4>((int)stream.Length);
}


For the above code, I get an array with empty values (ARGB: 0, 0, 0, 0).

Does anyone have any ideas on how I might go about achieving my desired result?

Share this post


Link to post
Share on other sites
Advertisement

I am trying to work out how to extract the pixel color information from a SlimDX Direct3D9 Surface. I have the surface, which I create with Surface.CreateRenderTarget(...). I then use that as a render target. I want to then extract the color information so I can transform it to a texture, which can then be passed to a shader and rendered onto some geometry.

I've tried using the following method:

Surface renderTarget = Surface.CreateRenderTarget(...);

device.SetRenderTarget(0, renderTarget);

// ... perform render operations ...

// Extract information
DataRectangle rect = renderTarget.Lock(LockFlags.None);

using (DataStream stream = rect.Data)
{
// Note: The parameter type <T> has been tried with various structs, such as Color4 and Vector4.
Color4[] result = stream.ReadRange<Color4>((int)stream.Length);
}

For the above code, I get an array with empty values (ARGB: 0, 0, 0, 0).

Does anyone have any ideas on how I might go about achieving my desired result?


Which DirectX is this? If its DX11 then just use UnMap and extract it from the array. Otherwise I don't know

Share this post


Link to post
Share on other sites
You can't directly access render target textures on the CPU like that. You need to call GetRenderTargetData and copy the data to a system surface, and then Lock that.

Is this something you're planning on doing every frame? If so, it will be extremely slow.

Share this post


Link to post
Share on other sites
[color="#1C2837"]Which DirectX is this? If its DX11 then just use UnMap and extract it from the array. Otherwise I don't know[/quote]

It's using DirectX 9.

[color="#1C2837"]You can't directly access render target textures on the CPU like that. You need to call GetRenderTargetData and copy the data to a system surface, and then Lock that.[color="#1C2837"]

Is this something you're planning on doing every frame? If so, it will be extremely slow.

[/quote]

I'm trying to use it for a version of Order Independent Transparency that I'm using. I'm creating render targets, which are passed to the graphics device so the shader passes can render to them. I then need to pass the rendered information as a sampler to the shader to be used as a lookup. Any ideas if this is possible and/or how to go about it?

Share this post


Link to post
Share on other sites
Pulling the data back to the CPU and then writing it out to a separate texture will be an incredibly slow operation, yes. Under native D3D9 what you would do is create a texture with D3DUSAGE_RENDERTARGET, then GetSurfaceLevel on that and set the acquired surface using Device::SetRenderTarget. When done, restore the render target to the old back buffer (using SetRenderTarget again, you would of course need to save out the back buffer using GetRenderTarget first...) and then draw a fullscreen quad using the texture. Not sure what the SlimDX equivalent to all of this is, but that should be enough info to go on.

Share this post


Link to post
Share on other sites
I've just taken a look into the SlimDX documentation briefly and it appears as though I should be able to take that approach. I shall try using a texture and it's surface then respond with any findings. Cheers.

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!