views:

445

answers:

1

I've been having difficulty identifying the correct parameters for the PresentParameters and DirectX device, so that there can be both vertex-level gouraud shading and the use of a z buffer. Some triangle meshes work fine, others have background triangles appearing in front of triangles which are closer-to-camera.

An example of this is found here: http://gallery.me.com/robert.perkins/100045/zBufferGone. The input data is a simple list of vertices in facets. The winding order of the vertices in each facet is nondeterministic (comes from various CAD software export functions) and there is no normals data.

The PresentParameters are being set up right now as follows. I realize this is C# instead of C++ but I think it's descriptive enough, and the parameters pass through to C++ code. This produces the image in the picture; the behavior is the same on the Reference device:

             pParams = new PresentParameters()
                    {
                        BackBufferWidth = this.ClientSize.Width,
                        BackBufferHeight = this.ClientSize.Height,
                        AutoDepthStencilFormat = Format.D16,
                        EnableAutoDepthStencil = true,
                        SwapEffect = SwapEffect.Discard,
                        Windowed = true
                    };
            _engineDX9 = new EngineDX9(this, SlimDX.Direct3D9.DeviceType.Hardware, SlimDX.Direct3D9.CreateFlags.SoftwareVertexProcessing, pParams);

            _engineDX9.DefaultCamera.NearPlane = 0;
            _engineDX9.DefaultCamera.FarPlane = 10;
            _engineDX9.D3DDevice.SetRenderState(RenderState.Ambient, false);
            _engineDX9.D3DDevice.SetRenderState(RenderState.ZEnable, ZBufferType.UseZBuffer);
            _engineDX9.D3DDevice.SetRenderState(RenderState.ZWriteEnable, true);
            _engineDX9.D3DDevice.SetRenderState(RenderState.ZFunc, Compare.Always);
            _engineDX9.BackColor = Color.White;
            _engineDX9.FillMode = FillMode.Solid;
            _engineDX9.CullMode = Cull.None;

            _engineDX9.DefaultCamera.AspectRatio = (float)this.Width / this.Height;

All of my other setup attempts, even on the reference device, return a COM error code ({"D3DERR_INVALIDCALL: Invalid call (-2005530516)"}). What are the correct setup parameters?

EDIT: The C++ class which interfaces with DirectX9 sets defaults like this:

PresentParameters::PresentParameters()
{
    BackBufferWidth = 640;
    BackBufferHeight = 480;
    BackBufferFormat = Format::X8R8G8B8;
    BackBufferCount = 1;

    Multisample = MultisampleType::None;
    MultisampleQuality = 0;

    SwapEffect = SlimDX::Direct3D9::SwapEffect::Discard;
    DeviceWindowHandle = IntPtr::Zero;
    Windowed = true;
    EnableAutoDepthStencil = true;
    AutoDepthStencilFormat = Format::D24X8;
    PresentFlags = SlimDX::Direct3D9::PresentFlags::None;

    FullScreenRefreshRateInHertz = 0;
    PresentationInterval = PresentInterval::Immediate;
}
+1  A: 

Where does it return an invalid call?

Edit: I'm assuming in the new EngineDX9 call? Have you tried setting a device window handle in the present parameters?

Edit 2: Have you turned on the debug spew in the DirectX control panel to see whether it tells you what the error is?

Edit3: You have tried setting backbufferWidth and Height to 0? What is backbuffercount set to? Might also be worth trying "Format.D24S8" on the backbuffer? Its "possible" your graphics card doesn't support 16-bit (unlikely though). Have you checked in the caps that the mode you are trying to create is valid? I asssume, btw, that the CLR language you are using automagically sets the parameters you don't set to 0? I,personally, always prefer to be explicit in such cases ....

PS I'm guessing here because im a native C++ DX9 coder not a CLR SlimDX coder ...

Edit4: I'm sure its the lack of window handle ... I'm probably wrong but thats the only thing i can see REALLY wrong with your setup. A windowed DX9 device requires a window. Btw set width and height to 0 to just use the window you are setting the device too's size ...

Edit 5: I've really been heading down the wrong route here. There is nothing wrong with the creation of the device that produced your "incorrect" device. Do not mess with the present parameters they are fine. The main reason you'll have problems with your Z-Buffering is that you set the compare function to always. This means that, regardless of what the z-buffer contains, pas the pixel and write its z into the z-buffer overwriting whatever is there already. I'd wager therein lies your Z-buffering problem.

Goz
Every other configuration of PresentParameters that I've tried, including setting a device window handle in the struct, has returned an invalid call at the creation of that EngineDX9 object. The internal code creating that object throws the exception if CreateDevice returns a non-success code, such as D3DERR_INVALIDCALL. My problem is that I can't tell which combination of PresentParameters does not result in D3DERR_INVALIDCALL, for the three features I need.
Rob Perkins
And, yes, as a matter of fact, I have the debug spew turned on. It aborts at the D3DERR_INVALIDCALL hresult, with that number above, with no further information. I don't really know what to make of it.
Rob Perkins
I think the problem is that I'm not being as explicit as I should. I'll dig into the C++ backing code and edit the problem to post the other params.The hardware is a GeForce card -- about 2 years old now. But the results are the same when I choose the Reference driver instead of Hardware.
Rob Perkins
OK, the C++ code is added to the question.
Rob Perkins
Well, the code that you see produces the picture in the http link, which looks like culling or zbuffering is fubared. Alterations from that return the invalid call hresult. I will try your Edit4 recommendations right now. Thank you for the tip about width and height.
Rob Perkins
Thank you for your help. I think what I have is a z-fighting problem. I'm going to open up a different question for that.
Rob Perkins