简体   繁体   English

C ++ Directx错误:访问冲突,swapchain为nullptr

[英]C++ Directx Error: Access Violation, swapchain was nullptr

I'm trying to learn 3D Drawing with DirectX and i got this Code in a Tutorial, but every time i try and compile it, my compiler gives out a "Access Violation swapchain was nullptr" Error. 我正在尝试使用DirectX学习3D绘图,并且在教程中获得了此代码,但是每次尝试对其进行编译时,我的编译器都会出现“访问冲突swapchain was nullptr”错误。

Thanks in advance 提前致谢

   // include the basic windows header files and the Direct3D header files
    #include <windows.h>
    #include <windowsx.h>
    #include <d3d11.h>
    #include <d3dx11.h>
    #include <d3dx10.h>

    // include the Direct3D Library file
    #pragma comment (lib, "d3d11.lib")
    #pragma comment (lib, "d3dx11.lib")
    #pragma comment (lib, "d3dx10.lib")

    // global declarations
    IDXGISwapChain *swapchain;             // the pointer to the swap chain interface
    ID3D11Device *dev;                     // the pointer to our Direct3D device interface
    ID3D11DeviceContext *devcon;           // the pointer to our Direct3D device context
    ID3D11RenderTargetView *backbuffer;    // the pointer to our back buffer

    // function prototypes
    void InitD3D(HWND hWnd);    // sets up and initializes Direct3D
    void RenderFrame(void);     // renders a single frame
    void CleanD3D(void);        // closes Direct3D and releases memory

    // the WindowProc function prototype
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


    // the entry point for any Windows program
    int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nCmdShow)
    {
        HWND hWnd;
        WNDCLASSEX wc;

        ZeroMemory(&wc, sizeof(WNDCLASSEX));

        wc.cbSize = sizeof(WNDCLASSEX);
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc = WindowProc;
        wc.hInstance = hInstance;
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
        wc.lpszClassName = L"WindowClass";

        RegisterClassEx(&wc);

        RECT wr = {0, 0, 800, 600};
        AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);

        hWnd = CreateWindowEx(NULL,
                              L"WindowClass",
                              L"Our First Direct3D Program",
                              WS_OVERLAPPEDWINDOW,
                              300,
                              300,
                              wr.right - wr.left,
                              wr.bottom - wr.top,
                              NULL,
                              NULL,
                              hInstance,
                              NULL);

        ShowWindow(hWnd, nCmdShow);

        // set up and initialize Direct3D
        InitD3D(hWnd);

        // enter the main loop:

        MSG msg;

        while(TRUE)
        {
            if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);

                if(msg.message == WM_QUIT)
                    break;
            }

            RenderFrame();
        }

        // clean up DirectX and COM
        CleanD3D();

        return msg.wParam;
    }


    // this is the main message handler for the program
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message)
        {
            case WM_DESTROY:
                {
                    PostQuitMessage(0);
                    return 0;
                } break;
        }

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


    // this function initializes and prepares Direct3D for use
    void InitD3D(HWND hWnd)
    {
        // create a struct to hold information about the swap chain
        DXGI_SWAP_CHAIN_DESC scd;

        // clear out the struct for use
        ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

        // fill the swap chain description struct
        scd.BufferCount = 1;                                    // one back buffer
        scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;     // use 32-bit color
        scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;      // how swap chain is to be used
        scd.OutputWindow = hWnd;                                // the window to be used
        scd.SampleDesc.Count = 1;                               // how many multisamples
        scd.SampleDesc.Quality = 0;                             // multisample quality level
        scd.Windowed = TRUE;                                    // windowed/full-screen mode

        // create a device, device context and swap chain using the information in the scd struct
        D3D11CreateDeviceAndSwapChain(NULL,
                                      D3D_DRIVER_TYPE_HARDWARE,
                                      NULL,
                                      NULL,
                                      NULL,
                                      NULL,
                                      D3D11_SDK_VERSION,
                                      &scd,
                                      &swapchain,
                                      &dev,
                                      NULL,
                                      &devcon);


        // get the address of the back buffer
        ID3D11Texture2D *pBackBuffer;
        swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);

        // use the back buffer address to create the render target
        dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
        pBackBuffer->Release();

        // set the render target as the back buffer
        devcon->OMSetRenderTargets(1, &backbuffer, NULL);


        // Set the viewport
        D3D11_VIEWPORT viewport;
        ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

        viewport.TopLeftX = 0;
        viewport.TopLeftY = 0;
        viewport.Width = 800;
        viewport.Height = 600;

        devcon->RSSetViewports(1, &viewport);
    }


    // this is the function used to render a single frame
    void RenderFrame(void)
    {
        // clear the back buffer to a deep blue
        devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));

        // do 3D rendering on the back buffer here

        // switch the back buffer and the front buffer
        swapchain->Present(0, 0);
    }


// this is the function that cleans up Direct3D and COM
void CleanD3D(void)
{
    // close and release all existing COM objects
    swapchain->Release();
    backbuffer->Release();
    dev->Release();
    devcon->Release();
}

When programming COM APis like Direct3D, it's critical that you check the return value of all functions that return an HRESULT . 当像Direct3D一样对COM AP进行编程时,检查返回HRESULT的所有函数的返回值至关重要。 If it's safe to ignore the return value, then it will return void . 如果可以安全地忽略返回值,则它将返回void

This means using the SUCCEEDED or FAILED macros on every HRESULT. 这意味着在每个HRESULT上使用SUCCEEDEDFAILED宏。 You should avoid doing == S_OK or != S_OK as there are success results other than S_OK . 您应该避免执行== S_OK!= S_OK因为除了S_OK之外还有成功的结果。 With modern C++, an even better option is to use ThrowIfFailed for 'fatal fast fail' scenarios where your program cannot recover from a failure. 使用现代C ++,更好的选择是将ThrowIfFailed用于“致命的快速失败”方案,在这种情况下程序无法从失败中恢复。

Your code is also failing to check for a failure in the call to RegisterClassEx or CreateWindowEx which could result in the hWnd being null before you really get started. 您的代码也无法检查对RegisterClassExCreateWindowEx的调用是否失败,这可能会导致hWnd在您真正开始之前为null。

You should also consider using nullptr instead of NULL . 您还应该考虑使用nullptr而不是NULL You are passing NULL in places that actually take a UINT which only compiles since you are using the old-school preprocessor define for 0. 您正在实际使用UINT位置传递NULL ,因为您使用的是老式的预处理器定义0,所以该位置只能编译。

Once you are checking the return values, the next step is to enable the debug device. 一旦检查了返回值,下一步就是启用调试设备。 See Anatomy of Direct3D 11 Create Device and Direct3D SDK Debug Layer Tricks . 请参见Direct3D剖析11创建设备Direct3D SDK调试层技巧 The debug layer will provide additional information in the debug output window when returning common failures like E_INVALIDARG . 当返回诸如E_INVALIDARG常见故障时,调试层将在调试输出窗口中提供其他信息。

Note that BufferCount needs to be at least 2. Anything below 1 is treated as 2 anyhow. 请注意, BufferCount必须至少为2。无论如何,低于1的值都将被视为2。

Since you are new to Direct3D 11 programming, I recommend you take a look at the DirectX Tool Kit tutorials . 由于您是Direct3D 11编程的新手,因此建议您看一下DirectX Tool Kit教程

You should also initialize all variables. 您还应该初始化所有变量。

IDXGISwapChain *swapchain = nullptr;
ID3D11Device *dev = nullptr;
ID3D11DeviceContext *devcon = nullptr;
ID3D11RenderTargetView *backbuffer = nullptr;

You should really avoid using 'raw' pointers for COM objects. 您应该真正避免对COM对象使用“原始”指针。 A better choice is to use a COM smart-pointer like ComPtr . 更好的选择是使用ComPtr之类的COM智能指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 读取访问冲突。 _Mycont在C ++中将udp数据转换为向量时出现nullptr错误 - Read access violation. _Mycont was nullptr error while getting udp data into vectors in C++ 抛出C ++异常:读取访问冲突。 这是nullptr - C++ Exception thrown: read access violation. this was nullptr C ++-引发异常:读取访问冲突。 变量为nullptr - C++ - Exception thrown: read access violation. Variable was nullptr 抛出异常:写访问冲突。 这是 nullptr (C++) - Exception thrown: write access violation. this was nullptr (C++) DirectX10交换链和设备指向0x00000000(导致运行时错误)(C ++) - DirectX10 swapchain and device point to 0x00000000 (causing runtime error) (c++) C ++ DirectX11:使用DirectX工具包的NullPtr错误 - C++ DirectX11: NullPtr error using DirectX tool kit C++ 访问冲突错误 - C++ Access Violation Error 读取访问冲突,这是nullptr错误,未正确初始化? - Read Access Violation this was nullptr error, initilized incorrectly? C ++ Battle4Zion项目引发未处理的异常:读取访问冲突。 **这**是nullptr。 发生了 - C++ Battle4Zion project Unhandled exception thrown: read access violation. **this** was nullptr. occurred (SDL渲染问题)C ++异常抛出:读取访问冲突。 这是nullptr - (SDL Render Problem) C++ Exception Thrown: read access violation. THIS was nullptr
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM