对于没有法线数据的三角网格,如何设置DirectX 9以便关闭背面剔除,打开z缓冲,并使用gouraud阴影?

时间:2010-01-17 18:20:04

标签: directx zbuffer

我一直难以识别PresentParameters和DirectX设备的正确参数,因此可以同时使用顶点级gouraud着色和使用z缓冲区。一些三角形网格工作正常,另一些则在三角形前面出现背景三角形,这些三角形更接近相机。

这里有一个例子:http://gallery.me.com/robert.perkins/100045/zBufferGone。输入数据是facet中顶点的简单列表。每个面中顶点的缠绕顺序是不确定的(来自各种CAD软件导出功能),并且没有法线数据。

现在正在设置PresentParameters,如下所示。我意识到这是C#而不是C ++,但我认为它足够描述,参数传递给C ++代码。这会在图片中产生图像;参考设备上的行为是相同的:

             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;

我的所有其他设置尝试,即使在参考设备上,也会返回COM错误代码({“D3DERR_INVALIDCALL:无效调用(-2005530516)”})。什么是正确的设置参数?

编辑:与DirectX9接口的C ++类设置如下默认值:

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 个答案:

答案 0 :(得分:1)

它在何处返回无效通话?

编辑:我在新的EngineDX9电话中假设?您是否尝试在当前参数中设置设备窗口句柄?

编辑2:您是否打开了DirectX控制面板中的调试功能,看它是否告诉您错误是什么?

Edit3:你试过将backbufferWidth和Height设置为0?什么是backbuffercount设置为?可能还值得在后备缓冲区上尝试“Format.D24S8”吗?它“可能”你的显卡不支持16位(不太可能)。您是否已检查了您尝试创建的模式是否有效?我承认,顺便说一下,您使用的CLR语言是否自动设置了未设置为0的参数?我个人总是喜欢在这种情况下明确......

PS我猜这里是因为我是原生的C ++ DX9编码器而不是CLR SlimDX编码器...

Edit4:我确定它没有窗口处理......我可能错了,但这是我唯一能看到你设置的错误。窗口式DX9设备需要一个窗口。顺便说一下,将宽度和高度设置为0,只需使用您设置设备尺寸的窗口......

编辑5:我在这里真的走错了路线。创建生成“不正确”设备的设备没有任何问题。不要乱用现在的参数,他们没事。您的Z-Buffering出现问题的主要原因是您始终将比较功能设置为。这意味着,无论z缓冲区包含什么,请将像素传递并将其z写入z缓冲区,覆盖已存在的任何内容。我打赌其中存在你的Z缓冲问题。