• Directx11学习笔记【四】 封装一个简单的Dx11DemoBase


    根据前面两个笔记的内容,我们来封装一个简单的基类,方便以后的使用。 代码和前面类似,没有什么新的内容,直接看代码吧(由于代码上次都注释了,这次代码就没怎么写注释o(╯□╰)o) Dx11DemoBase.h

    Dx11DemoBase.h

    #pragma once
    #include <d3d11.h>
    #include <D3DX11.h>
    #include <DxErr.h>
    
    class Dx11DemoBase
    {
    public:
        Dx11DemoBase();
        virtual ~Dx11DemoBase();
    
        bool Initialize(HINSTANCE hInstance, HWND hWnd);
        void ShutDown();//释放内存
    
        virtual bool LoadContent();//载入具体的Demo自己的内容,如纹理,几何体,着色器
        virtual void UnLoadContent();//释放具体Demo中的内容
    
        virtual void Update(float dt) = 0;
        virtual void Render() = 0;
    
    protected:
        HINSTANCE m_hInstance;
        HWND m_hWnd;
    
        D3D_DRIVER_TYPE m_driverType;
        D3D_FEATURE_LEVEL m_featureLevel;
    
        ID3D11Device* m_pd3dDevice;
        ID3D11DeviceContext* m_pImmediateContext;
        IDXGISwapChain* m_pSwapChain;
        ID3D11RenderTargetView* m_pRenderTargetView;
    };

    Dx11DemoBase.cpp

    #include "Dx11DemoBase.h"
    
    Dx11DemoBase::Dx11DemoBase() :m_driverType(D3D_DRIVER_TYPE_NULL), m_featureLevel(D3D_FEATURE_LEVEL_11_0),
    m_pd3dDevice(NULL), m_pImmediateContext(NULL), m_pSwapChain(NULL), m_pRenderTargetView(NULL){}
    
    Dx11DemoBase::~Dx11DemoBase()
    {
        ShutDown();
    }
    
    bool Dx11DemoBase::LoadContent()
    {
        return true;
    }
    
    void Dx11DemoBase::UnLoadContent()
    {
    
    }
    
    void Dx11DemoBase::ShutDown()
    {
        UnLoadContent();
        if (m_pRenderTargetView) m_pRenderTargetView->Release();
        if (m_pSwapChain) m_pSwapChain->Release();
        if (m_pd3dDevice) m_pd3dDevice->Release();
        if (m_pImmediateContext) m_pImmediateContext->Release();
    
        m_pRenderTargetView = NULL;
        m_pSwapChain = NULL;
        m_pd3dDevice = NULL;
        m_pImmediateContext = NULL;
    }
    
    //初始化
    bool Dx11DemoBase::Initialize(HINSTANCE hInstance, HWND hWnd)
    {
        HRESULT result;
        m_hInstance = hInstance;
        m_hWnd = hWnd;
        RECT rc;
        GetClientRect(m_hWnd, &rc);
        UINT width = rc.right - rc.left;
        UINT height = rc.bottom - rc.top;
    
        D3D_DRIVER_TYPE driverTypes[] = 
        {
            D3D_DRIVER_TYPE_HARDWARE,
            D3D_DRIVER_TYPE_WARP,
            D3D_DRIVER_TYPE_REFERENCE
        };
        UINT numDriverTypes = ARRAYSIZE(driverTypes);
    
        D3D_FEATURE_LEVEL featureLevels[] =
        {
            D3D_FEATURE_LEVEL_11_0,
            D3D_FEATURE_LEVEL_10_1,
            D3D_FEATURE_LEVEL_10_0
        };
        UINT numFeatureLevels = ARRAYSIZE(featureLevels);
    
        DXGI_SWAP_CHAIN_DESC sd;
        ZeroMemory(&sd, sizeof(sd));
        sd.BufferCount = 1;
        sd.BufferDesc.Width = width;
        sd.BufferDesc.Height = height;
        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.BufferDesc.RefreshRate.Numerator = 60;
        sd.BufferDesc.RefreshRate.Denominator = 1;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.OutputWindow = m_hWnd;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
        sd.Windowed = true;
    
        UINT createDeviceFlags = 0;
    #ifdef _DEBUG
        createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif
    
        for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; ++driverTypeIndex)
        {
            result = D3D11CreateDeviceAndSwapChain(
                NULL,
                driverTypes[driverTypeIndex],
                NULL,
                createDeviceFlags,
                featureLevels,
                numFeatureLevels,
                D3D11_SDK_VERSION,
                &sd,
                &m_pSwapChain,
                &m_pd3dDevice,
                &m_featureLevel,
                &m_pImmediateContext
                );
            if (SUCCEEDED(result))
            {
                m_driverType = driverTypes[driverTypeIndex];
                break;
            }
        }
    
        if (FAILED(result))
        {
            return result;
        }
    
        ID3D11Texture2D *pBackBuffer = NULL;
        result = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
    
        if (FAILED(result))
        {
            return result;
        }
    
        result = m_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &m_pRenderTargetView);
        if (pBackBuffer)
            pBackBuffer->Release();
    
        if (FAILED(result))
        {
            return result;
        }
    
        m_pImmediateContext->OMSetRenderTargets(1, &m_pRenderTargetView, NULL);
    
        D3D11_VIEWPORT vp;
        vp.Height = static_cast<float>(width);//用c++的static_cast转换类型是个好习惯
        vp.Width = static_cast<float>(height);
        vp.MinDepth = 0.0f;
        vp.MaxDepth = 1.0f;
        vp.TopLeftX = 0.0f;
        vp.TopLeftY = 0.0f;
        
        m_pImmediateContext->RSSetViewports(1, &vp);
    
        return LoadContent();
    }

    下面新建一个空白Demo类,这个类没有做什么特别的事,只是用d3d清除了屏幕而已,除了渲染函数,其他所有重写函数都是空的

    BlankDemo.h

    #pragma once
    #include "Dx11DemoBase.h"
    
    class BlankDemo : public Dx11DemoBase
    {
    public:
        BlankDemo();
        virtual ~BlankDemo();
    
        bool LoadContent();
        void UnLoadContent();
    
        void Update(float dt);
        void Render();
    };

    BlankDemo.cpp

    #include "BlankDemo.h"
    
    
    BlankDemo::BlankDemo()
    {
    }
    
    
    BlankDemo::~BlankDemo()
    {
    }
    
    bool BlankDemo::LoadContent()
    {
        return true;
    }
    
    void BlankDemo::UnLoadContent()
    {
    
    }
    
    void BlankDemo::Update(float dt)
    {
    
    }
    
    void BlankDemo::Render()
    {
        if (!m_pImmediateContext)
            m_pImmediateContext = NULL;
        float clearColors[4] = { 0.0f, 0.0f, 0.5f, 1.0f };
        m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, clearColors);
    
        m_pSwapChain->Present(0, 0);
    }

    main.cpp

    #include <windows.h>
    #include <memory>
    #include "BlankDemo.h"
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
    {
        WNDCLASSEX wcex;
        wcex.cbClsExtra = 0;
        wcex.cbSize = sizeof(wcex);
        wcex.cbWndExtra = 0;
        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
        wcex.hIcon = LoadIcon(NULL, IDI_WINLOGO);
        wcex.hIconSm = wcex.hIcon;
        wcex.hInstance = hInstance;
        wcex.lpfnWndProc = WndProc;
        wcex.lpszClassName = L"BlankDemo";
        wcex.lpszMenuName = L"BlankDemo";
        wcex.style = CS_HREDRAW | CS_VREDRAW;
    
        if (!RegisterClassEx(&wcex))
            return -1;
    
        
        RECT rc = { 0, 0, 800, 640 };
        AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false);
    
        HWND hwnd = CreateWindowEx(WS_EX_APPWINDOW, L"BlankDemo", L"BlankDemo", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
            CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);
    
        if (!hwnd)
            return -1;
    
        ShowWindow(hwnd, nShowCmd);
    
        std::auto_ptr<Dx11DemoBase> demo(new BlankDemo());//使用智能指针
    
        bool result = demo->Initialize(hInstance, hwnd);
        if (!result)
            return -1;
    
        MSG msg;
        ZeroMemory(&msg, sizeof(msg));
        while (msg.message != WM_QUIT)
        {
            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            
            demo->Update(0.0f);
            demo->Render();
        }
    
        demo->ShutDown();
        return static_cast<int>(msg.wParam);
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT paintStruct;
        HDC hDc;
        switch (message)
        {
        case WM_PAINT:
            hDc = BeginPaint(hWnd, &paintStruct);
            EndPaint(hWnd, &paintStruct);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }

    运行结果同上次相同

  • 相关阅读:
    网站性能在线评估
    如何测试电梯/伞/桌子/笔?
    apk反编译查看源码
    Jmeter(四)-断言/检查点
    【转】Jmeter(三)-简单的HTTP请求(非录制)
    【转】Jmeter(二)-使用代理录制脚本
    [转]Jmeter(一)-精简测试脚本
    CentOS 安装以及配置Apache php mysql
    centOS静态ip设置
    免费DDOS攻击测试工具大合集
  • 原文地址:https://www.cnblogs.com/zhangbaochong/p/5178566.html
Copyright © 2020-2023  润新知