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;
}

运行结果同上次相同

时间: 2024-10-06 10:13:17

Directx11学习笔记【四】 封装一个简单的Dx11DemoBase的相关文章

DuiLib学习笔记2——写一个简单的程序

我们要独立出来自己创建一个项目,在我们自己的项目上加皮肤这才是初衷.我的新建项目名为:duilibTest 在duilib根目录下面有个 Duilib入门文档.doc 我们就按这个教程开始入门 首先新建一个win32项目 去DuiLib根目录,把目录下DuiLib文件夹拷贝到新建项目的根目录.再把这个项目添加进我们解决方案中. 从教程里面把以下代码粘贴到我们项目的stdafx.h中 // Duilib使用设置部分 #pragma once #define WIN32_LEAN_AND_MEAN

Linux系统学习笔记之 1 一个简单的shell程序

不看笔记,长时间不用自己都忘了,还是得经常看看笔记啊. 一个简单的shell程序 shell结构 1.#!指定执行脚本的shell 2.#注释行 3.命令和控制结构 创建shell程序的步骤 第一步:创建一个包含命令和控制结构的文件 第二步:修改这个文件的权限使它可以执行. 使用chmod u+x 第三步:执行shell sh /test/example.sh Shell变量 变量:是shell传递数据的一种方法,用来代表每个取值的符号名 shell有两类变量:临时变量和永久变量 临时变量是sh

MiZ702学习笔记12&mdash;&mdash;封装一个普通的VGA IP

还记得<MiZ702学习笔记(番外篇)--纯PL VGA驱动>这篇文章中,用verilog写了一个VGA驱动.我们今天要介绍的就是将这个工程打包成一个普通的IP,目的是为后面的一篇文章做个铺垫. 打包成一个普通的IP的目的,可以直接将这个IP粘贴到Block文件中.(和用文本实例化是一个意思).应为我们调用zynq的核的时候一般是用Block的形式,为了zynq和我们的VGA模块更方便的组织起来,就需要这种IP打包方式. 为什么是强调是普通的IP,这个主意是区分带AXI接口的IP,这个在后面介

[原创]java WEB学习笔记12:一个简单的serlet连接数据库实验

本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 ---------------------------------

DirectX11 学习笔记3 - 创建一个立方体 和 坐标轴

这个程序再进一步的将上一个程序 面向对象化. 把模型类独立出来.更加像一个框架. 在此中遇到了一个很逗比的问题,弄了一晚上,看了好几遍其他列子才找到.就是有些函数一定要放在Render里面实时更新,而不是只放到初始化InitModel里面 因为当要渲染多个物体的时候,缓冲区的内容是要随设备变化的. 话不多说直接上代码 主程序main #include "D3DBase.h" #include "Axis.h" #include "Cube.h"

DirectX11 学习笔记3 - 创建一个立方体 和 轴

该方案将在进一步的程序 面向对象. 独立的模型类.更像是一个框架. 其中以超过遇到了一个非常有趣的问题,.获得一晚.我读了好几遍,以找到其他的列子.必须放在某些功能Render里面实时更新,而不是仅仅进入初始化InitModel里边 染多个物体的时候,缓冲区的内容是要随设备变化的. 话不多说直接上代码 主程序main #include "D3DBase.h" #include "Axis.h" #include "Cube.h" class D3

JSP/Servlet Web 学习笔记 DayFour —— 实现一个简单的JSP/Servlet交互

小实例说明: a)实现一个由JSP负责前台显示,Servlet负责后台处理的交互小实例 b)JSP页面由表单获取一个开始数字,一个结束数字,交给Servlet打印响应的乘法表. 未解决的问题: a)跳转貌似不能识别目录中的HTML文件,所以我把源码复制到JSP中,结果能找到. b)Servlet获取到JSP传过来的数据后,如果想在JSP页面out.print相关的JS代码貌似不能实现 目前的效果是:在当前的Servlet页面弹出了JS alert()弹窗 再重定向回之前的JSP页面. 源码: <

Directx11学习笔记【二】 将HelloWin封装成类

我们把上一个教程的代码封装到一个类中来方便以后的使用. 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 MyWindow.h文件 1 /************************************************************************ 2 Directx11学习笔记[2] 将HelloWin封装成类 3 2016.01 by zhangbaochong 4 /

Caliburn.Micro学习笔记(四)----IHandle&lt;T&gt;实现多语言功能

Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能 说一下IHandle<T>实现多语言功能 因为Caliburn.Micro是基于MvvM的UI与codebehind分离, binding可以是双向的所以我们想动态的实现多语言切换很是方便今天我做一个小demo给大家提供一个思路 先看一下效果 点击英文  变成英文状态点chinese就会变成中文                          源码的下载地址在文章的最下边 多语言用的是资源文件建