• 热门专题

Directx11教程(30) 如何保证渲染物体不会变形

作者:迈克老狼2012  发布日期:2012-04-10 11:55:49
Tag标签:Directx11  证渲染物体  
  •      在Directx教程(6)中, 我们曾经实现过这个功能,但那时是在SystemClass中,处理WM_SIZE时候,重新调用m_Graphics的初始化函数,这样的话,它的成员变量D3D类还有其它几个成员类,都会重新创建,所以我们的场景等于是从头重新渲染。对于静态场景,这没有问题,但是对于动画场景,我们一改变窗口大小,动画就会从头播放,这显然不是我们所希望的。

         本章中,我们在D3DClass类中新建一个函数,每次改变窗口大小时候,我们就改变framebuffer大小,然后重新建立目标渲染视图、深度模版视图等等。代码是在myTutorialD3D_23的基础上改写的。

        

    最关键的代码就是这一行:

    m_swapChain->ResizeBuffers(1, screenWidth, screenHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0);

     

    D3Class类中增加的函数为:


    bool D3DClass::ResizeBuffer(int screenWidth, int screenHeight) 
        { 
        
        HRESULT result;
    
        //交换链为空直接返回 
        if(!m_swapChain) 
            return false;
    
        //窗口最小化时候为0,会创建缓冲失败 
        if(screenHeight < 1) 
            screenHeight = 1; 
        if(screenWidth < 1) 
            screenWidth = 1;
    
        if(m_renderTargetView) 
            { 
            m_renderTargetView->Release(); 
            m_renderTargetView = 0; 
            } 
        if(m_depthStencilView) 
            { 
            m_depthStencilView->Release(); 
            m_depthStencilView = 0; 
            }
    
        if(m_depthStencilBuffer) 
            { 
            m_depthStencilBuffer->Release(); 
            m_depthStencilBuffer = 0; 
            }
    
        //改变交换链中后后缓冲大小后,重新创建渲染目标视图 
        result = m_swapChain->ResizeBuffers(1, screenWidth, screenHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0); 
        if(FAILED(result)) 
            { 
            HR(result); 
            return false; 
            } 
        // 得到交换链中的后缓冲指针. 
        ID3D11Texture2D* backBufferPtr; 
        result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); 
        if(FAILED(result)) 
            { 
            HR(result); 
            return false; 
            }
    
        // 用后缓冲创建渲染目标视图. 
        result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); 
        if(FAILED(result)) 
            { 
            HR(result); 
            return false; 
            }
    
        //释放后缓冲.(引用计数减1) 
        backBufferPtr->Release(); 
        backBufferPtr = 0;
    
    
        D3D11_TEXTURE2D_DESC depthBufferDesc; 
        D3D11_DEPTH_STENCIL_DESC depthStencilDesc; 
        D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; 
        D3D11_RASTERIZER_DESC rasterDesc; 
        D3D11_VIEWPORT viewport; 
        //创建深度模版视图 
        // 初始化深度缓冲描述. 
        // 初始化深度缓冲描述. 
        ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
    
        //设置深度缓冲描述 
        depthBufferDesc.Width = screenWidth; 
        depthBufferDesc.Height = screenHeight; 
        depthBufferDesc.MipLevels = 1;  //对于深度缓冲为1 
        depthBufferDesc.ArraySize = 1;  //对于深度缓冲为1,对于纹理,这2个参数有更多用途 
        depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; 
        depthBufferDesc.SampleDesc.Count = 1; 
        depthBufferDesc.SampleDesc.Quality = 0; 
        depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; 
        depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; 
        depthBufferDesc.CPUAccessFlags = 0; 
        depthBufferDesc.MiscFlags = 0;
    
        // 创建深度缓冲. 
        result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); 
        if(FAILED(result)) 
            { 
            HR(result); 
            return false;
    
            }
    
        // 初始化深度模版状态描述. 
        ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
    
       // 设置深度模版状态描述. 
        depthStencilDesc.DepthEnable = true; 
        depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;//D3D11_DEPTH_WRITE_MASK_ZERO禁止写深度缓冲 
        depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
    
        depthStencilDesc.StencilEnable = true; 
        depthStencilDesc.StencilReadMask = 0xFF; 
        depthStencilDesc.StencilWriteMask = 0xFF;
    
        // 对于front face 像素使用的模版操作操作. 
        depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; 
        depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    
        // 对于back face像素使用的模版操作模式. 
        depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; 
        depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    
        // 创建深度模版状态,使其生效 
        result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); 
        if(FAILED(result)) 
            { 
            HR(result); 
            return false;
    
            }
    
       // 设置深度模版状态. 
        m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1);
    
        // 初始化深度模版视图. 
        ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
    
        // 设置深度模版视图描述. 
        depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; 
        depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 
        depthStencilViewDesc.Texture2D.MipSlice = 0;
    
        // 创建深度模版视图. 
        result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); 
        if(FAILED(result)) 
            { 
            HR(result); 
            return false; 
            }
    
       // 绑定渲染目标视图和深度缓冲到渲染管线. 
        m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
    
    
        // 设置光栅化描述,指定多边形如何被渲染. 
        rasterDesc.AntialiasedLineEnable = false; 
        rasterDesc.CullMode = D3D11_CULL_BACK; 
        rasterDesc.DepthBias = 0; 
        rasterDesc.DepthBiasClamp = 0.0f; 
        rasterDesc.DepthClipEnable = true; 
        rasterDesc.FillMode = D3D11_FILL_SOLID; //D3D11_FILL_SOLID 
        rasterDesc.FrontCounterClockwise = false; 
        rasterDesc.MultisampleEnable = false; 
        rasterDesc.ScissorEnable = false; 
        rasterDesc.SlopeScaledDepthBias = 0.0f;
    
        // 创建光栅化状态 
        result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); 
        if(FAILED(result)) 
            { 
            HR(result); 
            return false; 
            }
    
        //设置光栅化状态,使其生效 
        m_deviceContext->RSSetState(m_rasterState);
    
    
        // 设置视口,显示全部后缓冲内容 
        viewport.Width = (float)screenWidth; 
        viewport.Height = (float)screenHeight; 
        viewport.MinDepth = 0.0f; 
        viewport.MaxDepth = 1.0f; 
        viewport.TopLeftX = 0.0f; 
        viewport.TopLeftY = 0.0f;
    
        // 创建视口 
        m_deviceContext->RSSetViewports(1, &viewport);
    
        }
    
     
    
       另外一点小变动就是在GraphicsClass中把m_D3D设置为public,还有就是SystemClass中
    
    if(m_Graphics) 
        { 
        bool result = m_Graphics->m_D3D->ResizeBuffer(screenWidth, screenHeight); 
        if(!result) 
            { 
            return false; 
            } 
        } 
    
    
About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规