• 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本身就失败了啊)。

  • 相关阅读:
    【JZOJ6409】困难的图论
    学习LCT小结
    jzoj5432. 【NOIP2017提高A组集训10.28】三元组
    jzoj6367. 【NOIP2019模拟2019.9.25】工厂(factory)
    jzoj6366. 【NOIP2019模拟2019.9.25】化学(chem)
    jzoj5433. 【NOIP2017提高A组集训10.28】图
    学习拓展中国剩余定理小结
    jzoj6300. Count
    jzoj3736. 【NOI2014模拟7.11】数学题
    jzoj6276. 【noip提高组模拟1】树
  • 原文地址:https://www.cnblogs.com/lakeone/p/6086928.html
Copyright © 2020-2023  润新知