DirectX渲染时Clear无效的原因(造成叠影)

 最近在开发D3D程序的过程中,发现一件很奇怪的事情,就是在Render的时候,纹理总是留有“残影”(即上次Render后的帧):

如上图,是一副纹理绕中心点旋转的向日葵,但是可以看到每次Render的时候,都会留下上次Render的帧,即Clear似乎没有起作用。

原来是Clear没调用成功,代码如下:
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 100), 1.0f, 0);
后来经过跟踪代码,发现这其实与Clear函数中的D3DCLEAR_ZBUFFER标志位或者说是创建设备时使用的设备描述参数(深度模板)有关。
在DX SDK中关于Clear的函数返回值有如下描述:
IDirect3DDevice9::Clear will fail if you:
Try to clear either the depth buffer or the stencil buffer of a render target that does not have an attached depth buffer. 
Try to clear the stencil buffer when the depth buffer does not contain stencil data. 

      然后,回到IDevice3D9::CreateDevice的参数D3DPRESENT_PARAMETERS看到我的程序中根本没有设置EnableAutoDepthStencil和AutoDepthStencilFormat这两个参数(即使用默认值EnableAutoDepthStencil=FALSE),所以才导致“残影”的产生。
      从程序逻辑的角度看,就是说我们在创建设备的时候没有使用深度模板缓存,但是我们在Clear的时候却去清除ZBUFFER,导致Clear函数调用失败。如果此时将Clear的参数D3DCLEAR_ZBUFFER去掉,那么就不会有“残影”产生,因为此时就不会去清除深度模板缓存,因此Clear就会返回D3D_OK。
      此外,在创建设备的时候,指定EnableAutoDepthStencil=TRUE(必须同时指定AutoDepthStencilFormat参数才能创建设备成功),那么原来的Clear函数就会成功,而且也不会再产生“残影”了。

bool Direct3D_Init(HWND window, int width, int height, bool fullscreen)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);
    if (!d3d) return false;
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = !fullscreen;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferCount = 1;
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
    d3dpp.BackBufferWidth = width;
    d3dpp.BackBufferHeight = height;
    d3dpp.hDeviceWindow = window;

    d3dpp.EnableAutoDepthStencil = 1;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;

    d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
        D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
    if (!d3ddev) return false;

    d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
    D3DXCreateSprite(d3ddev, &spriteobj);

    return true;
}



正确的渲染:


总结:
      如果创建D3D设备的时候没有指定深度模板缓存,那么Clear的时候就不要去清除这个模板缓存,否则就会造成所谓的“残影”现象(因为Clear本身就失败了啊)。

原文地址:https://www.cnblogs.com/lakeone/p/6086928.html