Jump to content
  • Advertisement
Sign in to follow this  
AlexSenko

SlimDX WPF No Z-Buffer

This topic is 2447 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 spend a lot of time to find why z-buffer don't work in my modified WpfSample10 and then founded information from microsoft site(http://msdn.microsof...4(v=vs.85).aspx):

[color="#2A2A2A"]When a buffer is used as a render target, depth-stencil testing and multiple render targets are not supported.[/quote].

And the only way to use SlimDX in WPF is to use texture as render target?
Is there any way to make Z-buffer working in SlimDX WPF?

Share this post


Link to post
Share on other sites
Advertisement

I spend a lot of time to find why z-buffer don't work in my modified WpfSample10 and then founded information from microsoft site(http://msdn.microsof...4(v=vs.85).aspx):

[color="#2A2A2A"]When a buffer is used as a render target, depth-stencil testing and multiple render targets are not supported.
.

And the only way to use SlimDX in WPF is to use texture as render target?
Is there any way to make Z-buffer working in SlimDX WPF?
[/quote]
As I understand it, the documentation says that a plain d3d10 buffer (and not a texture) can be bound as a RenderTargetView (though I have never tested this kind of bindings) but then you cannot bind any depthstencilviews.

Have you tried in the WPF sample to create a separate render target/depth stencil buffer, render your d3d10 scene to it, and then copy the resulting rendertarget to the shared d3d9 surface?

Share this post


Link to post
Share on other sites

Have you tried in the WPF sample to create a separate render target/depth stencil buffer, render your d3d10 scene to it, and then copy the resulting rendertarget to the shared d3d9 surface?


Yes, I do in such way, this part of code left from sample and it works pretty well except Z-Buffer.


RenderTarget Texture initialization:
var renderTexDesc = new Texture2DDescription()

{
BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
Format = Format.B8G8R8A8_UNorm,
Width = WindowWidth,
Height = WindowHeight,
MipLevels = 1,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default,
OptionFlags = ResourceOptionFlags.Shared,
CpuAccessFlags = CpuAccessFlags.None,
ArraySize = 1
};

SharedTexture = new Texture2D(device, renderTexDesc);
sampleRenderView = new RenderTargetView(device, SharedTexture);


DepthStencil initialization:

var depthDesc = new Texture2DDescription()
{
BindFlags = BindFlags.DepthStencil,
Format = Format.D32_Float,
Width = WindowWidth,
Height = WindowHeight,
MipLevels = 1,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default,
OptionFlags = ResourceOptionFlags.None,
CpuAccessFlags = CpuAccessFlags.None,
ArraySize = 1
};



DepthTexture = new Texture2D(device, depthDesc);
depthStencilView = new DepthStencilView(device, DepthTexture);


var dsDesc = new DepthStencilStateDescription
{
IsDepthEnabled = true,
IsStencilEnabled = false,
DepthWriteMask = DepthWriteMask.All,
DepthComparison = Comparison.Less
};

depthStencilState = DepthStencilState.FromDescription(device, dsDesc);



Rasterizer initialization:

var rasterizerState = new RasterizerStateDescription()
{
CullMode = CullMode.None,
FillMode = FillMode.Solid,
IsFrontCounterclockwise = false,
DepthBias = 0,
DepthBiasClamp = 0,
SlopeScaledDepthBias = 0,
IsDepthClipEnabled = true,
IsScissorEnabled = false,
IsMultisampleEnabled = true,
IsAntialiasedLineEnabled = true
};

device.Rasterizer.State = RasterizerState.FromDescription(device, rasterizerState);



Render:

public void Render(int arg)
{
device.OutputMerger.DepthStencilState = depthStencilState;
device.OutputMerger.SetTargets(depthStencilView, sampleRenderView);

device.Rasterizer.SetViewports(new Viewport(0, 0, WindowWidth, WindowHeight, 0.0f, 1.0f));
device.ClearRenderTargetView(sampleRenderView, new Color4(0.0f, 0.0f, 0.0f));
device.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);


Matrix worldMatrix = GetWorldViewProj(arg);

DataStream ds = new DataStream(worldMatrix.ToArray(), true, false);
SampleEffect.GetVariableByName("WorldViewProj").AsMatrix().SetMatrix(worldMatrix);

EffectTechnique technique = SampleEffect.GetTechniqueByIndex(0);
EffectPass pass = technique.GetPassByIndex(0);

for (int i = 0; i < technique.Description.PassCount; ++i)
{
pass.Apply();
renderDataManager.Render(worldMatrix);
}

device.Flush();

OnSceneRender();
}

Share this post


Link to post
Share on other sites

[quote name='AlexandreMutel' timestamp='1317818122' post='4869367']
Have you tried in the WPF sample to create a separate render target/depth stencil buffer, render your d3d10 scene to it, and then copy the resulting rendertarget to the shared d3d9 surface?


Yes, I do in such way, this part of code left from sample and it works pretty well except Z-Buffer.
[/quote]
Seems not exactly. What I was suggesting is that you create 2 render target buffer: one used with the z-buffer, but that is not shared (no ResourceOptionFlags.Shared on it). One that is shared, and receive a copy of the 1st render target (device.CopyResource between them)

Share this post


Link to post
Share on other sites
In such way?

Initialization:

var renderTexDescShared = new Texture2DDescription()
{
BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
Format = Format.B8G8R8A8_UNorm,
Width = WindowWidth,
Height = WindowHeight,
MipLevels = 1,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default,
OptionFlags = ResourceOptionFlags.Shared,
CpuAccessFlags = CpuAccessFlags.None,
ArraySize = 1
};

SharedTexture = new Texture2D(device, renderTexDescShared);
sampleRenderViewShared = new RenderTargetView(device, SharedTexture);

var renderTexDesc = new Texture2DDescription()
{
BindFlags = BindFlags.RenderTarget,
Format = Format.B8G8R8A8_UNorm,
Width = WindowWidth,
Height = WindowHeight,
MipLevels = 1,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default,
OptionFlags = ResourceOptionFlags.None,
CpuAccessFlags = CpuAccessFlags.None,
ArraySize = 1
};

renderTexture = new Texture2D(device, renderTexDesc);
sampleRenderView = new RenderTargetView(device, renderTexture);



Render:
public void Render(int arg)
{
device.OutputMerger.DepthStencilState = depthStencilState;
device.OutputMerger.SetTargets(depthStencilView, sampleRenderView);

device.Rasterizer.SetViewports(new Viewport(0, 0, WindowWidth, WindowHeight, 0.0f, 1.0f));
device.ClearRenderTargetView(sampleRenderView, new Color4(0.0f, 0.0f, 0.0f));
device.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);


Matrix worldMatrix = GetWorldViewProj(arg);

DataStream ds = new DataStream(worldMatrix.ToArray(), true, false);
SampleEffect.GetVariableByName("WorldViewProj").AsMatrix().SetMatrix(worldMatrix);

EffectTechnique technique = SampleEffect.GetTechniqueByIndex(0);
EffectPass pass = technique.GetPassByIndex(0);



for (int i = 0; i < technique.Description.PassCount; ++i)
{
pass.Apply();
renderDataManager.Render(worldMatrix);
}


device.Flush();

device.CopyResource(renderTexture, SharedTexture);

OnSceneRender(); }



The same problems :( I'll prepare video in several minutes

Share this post


Link to post
Share on other sites
I ran into the exact same problem. Spent nearly a week to resolve this (using DX11) and utterly failed.
Looking forward to a solution.

EDIT:
I'm using a deferred renderer, thus i already tried the solution that Alexander proposed (copy non-shared mainbuffer to shared surface). No dice. Something screws up the z-buffer. I was already suspecting WPF to somehow interfere with the device. But then again, i have no idea...


EDIT cont:
I just recalled that i tested this without a shared texture. Instead of D3DImage, i used the WinFormsHost control in WPF and rendered directly to the handle (using a swapchain as usual). Now guess what, z-buffer is still broken. That's when i gave up, suspecting WPF to screw with my DX11 device.

If anyone knows anything about this, i'm nervous to get some real answers.

Share this post


Link to post
Share on other sites

EDIT cont:
I just recalled that i tested this without a shared texture. Instead of D3DImage, i used the WinFormsHost control in WPF and rendered directly to the handle (using a swapchain as usual). Now guess what, z-buffer is still broken. That's when i gave up, suspecting WPF to screw with my DX11 device.


It was my last hope :(

Share this post


Link to post
Share on other sites

[quote name='chlerub' timestamp='1317821467' post='4869399']
EDIT cont:
I just recalled that i tested this without a shared texture. Instead of D3DImage, i used the WinFormsHost control in WPF and rendered directly to the handle (using a swapchain as usual). Now guess what, z-buffer is still broken. That's when i gave up, suspecting WPF to screw with my DX11 device.


It was my last hope :(
[/quote]

Yeah, it was my last hope too. And it's extremely puzzling to say the least. Also there's virtually no information about this to be found anywhere.
I wonder if the creators of (for example) SlimDXControl ever tested their code with anything else than a simple triangle - cause it appears they most certainly have not.
(along with a number of other devs that have blogged about WPF/DX10-11 interop)

After testing the hell out of this topic for a week i put in on the shelf with a big sign saying "FUTILE".
I guess there's no need to state how frustrating this is, especially since WPF and DirectX are developed by the same company.

Share this post


Link to post
Share on other sites
I have just tested my code in WinForms, the same result, Z-Buffer do not work. May be any problems with shader?

struct VS_IN
{
float4 pos : POSITION;
float4 col : COLOR;
};


struct PS_IN
{
float4 pos : SV_POSITION;
float4 col : COLOR;
};



float4x4 WorldViewProj : WORLDVIEWPROJECTION;

PS_IN VS( VS_IN input )
{
PS_IN output = (PS_IN)0;

output.pos = mul(input.pos, WorldViewProj);
output.col = input.col;

return output;
}

float4 PS( PS_IN input ) : SV_Target
{
return input.col;
}


technique10 Render
{
pass P0
{
SetGeometryShader( 0 );
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetPixelShader( CompileShader( ps_4_0, PS() ) );
}
}

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!