SwapChain指针是nullptr异常DIRECTX 11

时间:2017-01-14 14:19:44

标签: c++ directx directx-11

所以我是DirectX的总菜鸟,从未做过任何事情。我研究了一些已经编写过的框架,并且还阅读了Frank Luna的一本书(使用DirectX进行游戏编程)来制作一个框架。我对WINAPI也不好,但我认为这不是问题所在。当我运行代码时,我得到这个例外: this-> m_swapChain为nullptr 我怎么解决这个问题?我尝试不将m_swapChain初始化为NULL但没有改变。 这是DirectClass.h文件

#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3dcompiler.lib")

#include <d3d11.h>
#include <directxmath.h>
using namespace DirectX;

class DirectClass {
public:
    DirectClass();
    ~DirectClass();
    ID3D11Device *GetDevice() { return m_device; };
    ID3D11DeviceContext *GetDeviceContext() { return m_deviceContext; };
    IDXGISwapChain*GetSwapChain() { return m_swapChain; };
    HRESULT Initialize(HWND hwnd);
private:

    ID3D11Device *m_device;
    ID3D11DeviceContext *m_deviceContext;

    IDXGISwapChain *m_swapChain;
    DXGI_SWAP_CHAIN_DESC m_swapChainDesc;

    ID3D11Texture2D *m_backBuffer;                  //Back Buffer
    ID3D11Texture2D *m_depthStencilBuffer;          //Depth Stencil Buffer

    D3D11_TEXTURE2D_DESC m_depthBufferDesc;         //Depth Buffer Desc
    D3D11_DEPTH_STENCIL_DESC m_depthStencilDesc;    
    ID3D11DepthStencilView *m_depthStencilView;

    D3D11_DEPTH_STENCIL_VIEW_DESC m_depthStencilViewDesc;   
    D3D11_VIEWPORT m_viewPort;  


    ID3D11DepthStencilState* m_depthStencilState;
    ID3D11RenderTargetView *m_renderTargetView;

    int m_screenHeight;
    int m_screenWidth;

    bool m_windowed;
    //render target
    //render target view

};

这是DirectClass.cpp文件

#include "DirectClass.h"

DirectClass::DirectClass() {
    m_windowed = false;
}
DirectClass::~DirectClass() {

}
HRESULT DirectClass::Initialize(HWND hwnd) {
    HRESULT hr=S_OK;
    m_windowed = true;
    m_screenHeight= GetSystemMetrics(SM_CYSCREEN);
    m_screenWidth = GetSystemMetrics(SM_CXSCREEN);


    //feature levels
    D3D_FEATURE_LEVEL featureLevels[]{
        D3D_FEATURE_LEVEL_9_1,
        D3D_FEATURE_LEVEL_9_2,
        D3D_FEATURE_LEVEL_9_3,
        D3D_FEATURE_LEVEL_10_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_11_0,
    };
    //swap chain
    if (m_windowed) {
        m_swapChainDesc.BufferDesc.Height = 600;
        m_swapChainDesc.BufferDesc.Width = 800;
        m_swapChainDesc.Windowed = true;
    }
    else {
        m_swapChainDesc.BufferDesc.Height = m_screenHeight;
        m_swapChainDesc.BufferDesc.Width = m_screenWidth;
        m_swapChainDesc.Windowed = false;
    }

    m_swapChainDesc.BufferCount = 2;
    m_swapChainDesc.OutputWindow = hwnd; // dopo correggi
    m_swapChainDesc.Flags = 0;
    m_swapChainDesc.SampleDesc.Count = 1;
    m_swapChainDesc.SampleDesc.Quality = 0;
    m_swapChainDesc.BufferUsage = DXGI_USAGE_DISCARD_ON_PRESENT;
    m_swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

    hr=D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, 0, 0, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, 
                                    &m_swapChainDesc, &m_swapChain, &m_device, featureLevels, &m_deviceContext );   //The problem is here. I get an exception like this "this->m_swapChain was nullptr

    m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&m_backBuffer);
    m_backBuffer->Release();
    //Descrizione del depth buffer
    ZeroMemory(&m_depthBufferDesc, sizeof(m_depthBufferDesc));
    if (m_windowed) {
        m_depthBufferDesc.Width = 800;
        m_depthBufferDesc.Height = 600;
    }
    else {
        m_depthBufferDesc.Width = m_screenWidth;
        m_depthBufferDesc.Height = m_screenHeight;
    }

    m_depthBufferDesc.ArraySize = 1;
    m_depthBufferDesc.MipLevels = 1;
    m_depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;  
    m_depthBufferDesc.SampleDesc.Count = 1;
    m_depthBufferDesc.SampleDesc.Quality = 0;
    m_depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;              
    m_depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;     
    m_depthBufferDesc.BindFlags = 0;
    m_depthBufferDesc.CPUAccessFlags = 0;

    m_depthStencilDesc.DepthEnable = true;
    m_depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; 
    m_depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;  

    m_depthStencilDesc.StencilEnable = true;
    m_depthStencilDesc.StencilReadMask = 0xFF;
    m_depthStencilDesc.StencilWriteMask = 0xFF;


    m_depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    m_depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
    m_depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
    m_depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

    m_depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    m_depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
    m_depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
    m_depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

    m_device->CreateTexture2D(&m_depthBufferDesc, 0, &m_depthStencilBuffer); 
    m_device->CreateDepthStencilView(m_depthStencilBuffer, 0, &m_depthStencilView);

    if (m_windowed) {
        m_viewPort.Height = 600;
        m_viewPort.Width = 800;
    }
    else {
        m_viewPort.Height = m_screenHeight;
        m_viewPort.Width = m_screenWidth;
    }
    m_viewPort.MaxDepth = 1.0f;
    m_viewPort.MinDepth = 0.0f;
    m_viewPort.TopLeftX = 0.0f;
    m_viewPort.TopLeftY = 0.0f;

    m_device->CreateRenderTargetView(m_backBuffer, 0, &m_renderTargetView);


    m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
    m_deviceContext->RSSetViewports(1, &m_viewPort);


    return hr;
}

可能有更多的错误比我要求的(如果你发现一些不好或缺少的东西告诉我,没有问题)在代码中,但我自己做了这个并通过在线查看一些例子(复制的东西) ,但了解大部分内容)

这是MainClass.h文件(从这里复制https://msdn.microsoft.com/en-us/library/windows/desktop/dn643742(v=vs.85).aspx

#pragma once
#include "DirectClass.h"
#include<Windows.h>
#include <string>
class MainClass
{
public:
    MainClass();
    ~MainClass();

    HRESULT CreateDesktopWindow();

    HWND GetWindowHandle() { return m_hWnd; };

    static LRESULT CALLBACK StaticWindowProc(
        HWND hWnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam
    );

    HRESULT Present(IDXGISwapChain *swapChain);

private:
    HMENU     m_hMenu;
    RECT      m_rc;
    HWND      m_hWnd;
};

static HINSTANCE m_hInstance;
static std::wstring m_windowClassName;

和MainClass.cpp文件一样,这确实没有错误

包括&#34; MainClass.h&#34;

MainClass::MainClass()
{
    m_windowClassName = L"Direct3DWindowClass";
    m_hInstance = NULL;
}
MainClass::~MainClass(){}
//-----------------------------------------------------------------------------
// Create a window for our Direct3D viewport.
//-----------------------------------------------------------------------------
HRESULT MainClass::CreateDesktopWindow()
{
    // Window resources are dealt with here.
    HRESULT hr=S_OK;
    if (m_hInstance == NULL)
        m_hInstance = (HINSTANCE)GetModuleHandle(NULL);

    HICON hIcon = NULL;
    WCHAR szExePath[MAX_PATH];
    GetModuleFileName(NULL, szExePath, MAX_PATH);

    // If the icon is NULL, then use the first one found in the exe
    if (hIcon == NULL)
        hIcon = ExtractIcon(m_hInstance, szExePath, 0);

    // Register the windows class
    WNDCLASS wndClass;
    wndClass.style = CS_DBLCLKS;
    wndClass.lpfnWndProc = MainClass::StaticWindowProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.hInstance = m_hInstance;
    wndClass.hIcon = hIcon;
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = m_windowClassName.c_str();

    if (!RegisterClass(&wndClass))
    {
        DWORD dwError = GetLastError();
        if (dwError != ERROR_CLASS_ALREADY_EXISTS)
            return HRESULT_FROM_WIN32(dwError);
    }

    m_rc;
    int x = CW_USEDEFAULT;
    int y = CW_USEDEFAULT;

    // No menu in this example.
    m_hMenu = NULL;

    // This example uses a non-resizable 640 by 480 viewport for simplicity.
    int nDefaultWidth = 800;
    int nDefaultHeight = 600;
    SetRect(&m_rc, 0, 0, nDefaultWidth, nDefaultHeight);
    AdjustWindowRect(
        &m_rc,
        WS_OVERLAPPEDWINDOW,
        (m_hMenu != NULL) ? true : false
    );

    // Create the window for our viewport.
    m_hWnd = CreateWindow(
        m_windowClassName.c_str(),
        L"Cube11",
        WS_OVERLAPPEDWINDOW,
        x, y,
        (m_rc.right - m_rc.left), (m_rc.bottom - m_rc.top),
        0,
        m_hMenu,
        m_hInstance,
        0
    );

    if (m_hWnd == NULL)
    {
        DWORD dwError = GetLastError();
        return HRESULT_FROM_WIN32(dwError);
    }

    return hr;
}
HRESULT MainClass::Present(IDXGISwapChain *swapChain) {
    HRESULT hr;
    hr = S_OK;
    swapChain->Present(1, 0);
    return hr;
}

LRESULT CALLBACK MainClass::StaticWindowProc(
    HWND hWnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
)
{
    switch (uMsg)
    {
    case WM_CLOSE:
    {
        HMENU hMenu;
        hMenu = GetMenu(hWnd);
        if (hMenu != NULL)
        {
            DestroyMenu(hMenu);
        }
        DestroyWindow(hWnd);
        UnregisterClass(
            m_windowClassName.c_str(),
            m_hInstance
        );
        return 0;
    }

    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

主要

#include "DirectClass.h"
#include "MainClass.h"

#include <memory>

INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    HRESULT hr = S_OK;

    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
    std::shared_ptr<MainClass> winMain = std::shared_ptr<MainClass>(new MainClass());
    // Create a window.
    hr = winMain->CreateDesktopWindow();

    std::shared_ptr<DirectClass> directClass = std::shared_ptr<DirectClass>(new DirectClass());

    HWND hwnd = winMain->GetWindowHandle();
    directClass->Initialize(hwnd);

    IDXGISwapChain *sC = directClass->GetSwapChain();

    if (SUCCEEDED(hr))
    {
        winMain->Present(sC);
    }
}

对不起,如果这是写得不好,愚蠢,废话和糟糕的优化。 也许通过解决该异常,我可以尝试改进此代码,谢谢。

0 个答案:

没有答案