简单的 DirectX 11 程序运行时错误

发布于 2024-11-30 02:30:53 字数 7739 浏览 1 评论 0原文

我是 DirectX 11 的新手,我已经成功地在我的书中找到了绘制三角形章节。 我已经编写了这段代码,但出现运行时错误: “DirectX 11.exe 中 0x00cd14e6 处未处理的异常:0xc0000005:读取位置 0x00000000 时发生访问冲突。”

我的编译器显示错误出在 InitPipeline 函数处,但我找不到那里的错误。 我做错了什么?

代码:

    #include <windows.h>
#include <windowsx.h>

#include <d3d11.h>
#include <D3DX11.h>
#include <D3DX10.h>

#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d3dx11.lib")
#pragma comment(lib,"d3dx10.lib")

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

IDXGISwapChain                  *swapchain;
ID3D11Device                    *dev;
ID3D11DeviceContext             *devcon;

ID3D11InputLayout               *pInputLayout;
ID3D11Buffer                    *pVBuffer;
ID3D11RenderTargetView          *backbuffer;
ID3D11VertexShader              *pVS;
ID3D11PixelShader               *pPS;

// Type
struct VERTEX
{
    FLOAT X,Y,Z;
    D3DXCOLOR Color;
};
//DirectX
void InitPipeline()
{
    // load and compile the two shaders
     ID3D10Blob *VS, *PS;
     D3DX11CompileFromFile("shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0);
     D3DX11CompileFromFile("shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);

     //debug
     if(!dev)
     {
         MessageBox(NULL, "DEV = NULL", "ERROR", NULL);
     }
     if(!devcon)
     {
         MessageBox(NULL, "DEVCON = NULL", "ERROR", NULL);
     }

     if(!VS)
     {
         MessageBox(NULL, "VS = NULL", "ERROR", NULL);
     }
     if(!PS)
     {
         MessageBox(NULL, "PS = NULL", "ERROR", NULL);
     }
     // encapsulate both shaders into shader objects
     dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
     dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);

     // set the shader objects
     devcon->VSSetShader(pVS, 0, 0);
     devcon->PSSetShader(pPS, 0, 0);

    D3D11_INPUT_ELEMENT_DESC ied[] =
    {
        {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,0,D3D11_INPUT_PER_VERTEX_DATA,0},
        {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
    };

    dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pInputLayout);
    devcon->IASetInputLayout(pInputLayout);
}


void InitGraphics()
{
    VERTEX OurVertices[] =
    {
        {1,0,0,D3DXCOLOR(1,0,0,1)},
        {0,-1,0,D3DXCOLOR(1,0,0,1)},
        {0,0,1,D3DXCOLOR(1,0,0,1)},
    };

    D3D11_BUFFER_DESC bd;
    ZeroMemory(&bd, sizeof(D3D11_BUFFER_DESC));
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bd.ByteWidth = sizeof(VERTEX)*3;
    bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    bd.Usage = D3D11_USAGE_DYNAMIC;

    dev->CreateBuffer(&bd, NULL, &pVBuffer);

    D3D11_MAPPED_SUBRESOURCE ms;
    devcon->Map(pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
    memcpy(ms.pData, OurVertices, sizeof(OurVertices));
    devcon->Unmap(pVBuffer, NULL);
}
void RenderFrame()
{
    devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0,0,1,1));

    UINT stride = sizeof(VERTEX);
    UINT offset = 0;
    devcon->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset);
    devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    devcon->Draw(3,0);

    swapchain->Present(0,0);
}
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.BufferDesc.Width = SCREEN_WIDTH;                   // set the back buffer width
     scd.BufferDesc.Height = SCREEN_HEIGHT;                 // set the back buffer height
     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 = 4;                              // how many multisamples
     scd.Windowed = TRUE;                                   // windowed/full-screen mode
     scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;    // allow full-screen switching

     // create a device, device context and swap chain using the information in the scd struct
     if(FAILED(D3D11CreateDeviceAndSwapChain(NULL,
                                   D3D_DRIVER_TYPE_HARDWARE,
                                   NULL,
                                   NULL,
                                   NULL,
                                   NULL,
                                   D3D11_SDK_VERSION,
                                   &scd,
                                   &swapchain,
                                   &dev,
                                   NULL,
                                   &devcon)))
     {
         MessageBox(NULL, "D3D11CreateDeviceAndSwapChain Failed", "ERROR", NULL);
     }




     // 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 = SCREEN_WIDTH;
     viewport.Height = SCREEN_HEIGHT;

     devcon->RSSetViewports(1, &viewport);

    InitPipeline();
     InitGraphics();
 }
void CleanD3D()
{
    swapchain->SetFullscreenState(FALSE, NULL);
    dev->Release();
    devcon->Release();
    swapchain->Release();
    pInputLayout->Release();
    pVBuffer->Release();
    backbuffer->Release();
    pVS->Release();
    pPS->Release();
}

// Window
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
}
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
    HWND hWnd;

    WNDCLASSEX wc;
    ZeroMemory(&wc, sizeof(WNDCLASSEX));
    wc.cbSize = sizeof(WNDCLASSEX);
    //wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = (HICON)LoadIcon(NULL, IDI_APPLICATION);
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = "DirectXWindow";
    wc.style = CS_HREDRAW | CS_VREDRAW;

    RegisterClassEx(&wc);

    hWnd = CreateWindowEx(NULL,
        "DirectXWindow",
        "DirectX 11 (June 2010",
        WS_OVERLAPPEDWINDOW,
        0,0,
        SCREEN_WIDTH, SCREEN_HEIGHT,
        NULL,
        NULL,
        hInstance,
        NULL);

    ShowWindow(hWnd, nCmdShow);

    InitD3D(hWnd);
    UpdateWindow(hWnd);

    MSG msg = {0};

    while(msg.message != WM_QUIT)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);

        }
        else
        {
            RenderFrame();
        }
    }
    CleanD3D();

    return msg.wParam;
}

I'm new to DirectX 11, and I have managed to get the Drawing Triangle chapter in my book.
I have written this code, but I get a runtime error:
"Unhandled exception at 0x00cd14e6 in DirectX 11.exe: 0xc0000005: Access violation reading location 0x00000000."

My compiler show that the error is at the InitPipeline function, but I can't find the error there.
What have I done wrong?

Code:

    #include <windows.h>
#include <windowsx.h>

#include <d3d11.h>
#include <D3DX11.h>
#include <D3DX10.h>

#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d3dx11.lib")
#pragma comment(lib,"d3dx10.lib")

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

IDXGISwapChain                  *swapchain;
ID3D11Device                    *dev;
ID3D11DeviceContext             *devcon;

ID3D11InputLayout               *pInputLayout;
ID3D11Buffer                    *pVBuffer;
ID3D11RenderTargetView          *backbuffer;
ID3D11VertexShader              *pVS;
ID3D11PixelShader               *pPS;

// Type
struct VERTEX
{
    FLOAT X,Y,Z;
    D3DXCOLOR Color;
};
//DirectX
void InitPipeline()
{
    // load and compile the two shaders
     ID3D10Blob *VS, *PS;
     D3DX11CompileFromFile("shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0);
     D3DX11CompileFromFile("shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);

     //debug
     if(!dev)
     {
         MessageBox(NULL, "DEV = NULL", "ERROR", NULL);
     }
     if(!devcon)
     {
         MessageBox(NULL, "DEVCON = NULL", "ERROR", NULL);
     }

     if(!VS)
     {
         MessageBox(NULL, "VS = NULL", "ERROR", NULL);
     }
     if(!PS)
     {
         MessageBox(NULL, "PS = NULL", "ERROR", NULL);
     }
     // encapsulate both shaders into shader objects
     dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
     dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);

     // set the shader objects
     devcon->VSSetShader(pVS, 0, 0);
     devcon->PSSetShader(pPS, 0, 0);

    D3D11_INPUT_ELEMENT_DESC ied[] =
    {
        {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,0,D3D11_INPUT_PER_VERTEX_DATA,0},
        {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
    };

    dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pInputLayout);
    devcon->IASetInputLayout(pInputLayout);
}


void InitGraphics()
{
    VERTEX OurVertices[] =
    {
        {1,0,0,D3DXCOLOR(1,0,0,1)},
        {0,-1,0,D3DXCOLOR(1,0,0,1)},
        {0,0,1,D3DXCOLOR(1,0,0,1)},
    };

    D3D11_BUFFER_DESC bd;
    ZeroMemory(&bd, sizeof(D3D11_BUFFER_DESC));
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bd.ByteWidth = sizeof(VERTEX)*3;
    bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    bd.Usage = D3D11_USAGE_DYNAMIC;

    dev->CreateBuffer(&bd, NULL, &pVBuffer);

    D3D11_MAPPED_SUBRESOURCE ms;
    devcon->Map(pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
    memcpy(ms.pData, OurVertices, sizeof(OurVertices));
    devcon->Unmap(pVBuffer, NULL);
}
void RenderFrame()
{
    devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0,0,1,1));

    UINT stride = sizeof(VERTEX);
    UINT offset = 0;
    devcon->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset);
    devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    devcon->Draw(3,0);

    swapchain->Present(0,0);
}
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.BufferDesc.Width = SCREEN_WIDTH;                   // set the back buffer width
     scd.BufferDesc.Height = SCREEN_HEIGHT;                 // set the back buffer height
     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 = 4;                              // how many multisamples
     scd.Windowed = TRUE;                                   // windowed/full-screen mode
     scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;    // allow full-screen switching

     // create a device, device context and swap chain using the information in the scd struct
     if(FAILED(D3D11CreateDeviceAndSwapChain(NULL,
                                   D3D_DRIVER_TYPE_HARDWARE,
                                   NULL,
                                   NULL,
                                   NULL,
                                   NULL,
                                   D3D11_SDK_VERSION,
                                   &scd,
                                   &swapchain,
                                   &dev,
                                   NULL,
                                   &devcon)))
     {
         MessageBox(NULL, "D3D11CreateDeviceAndSwapChain Failed", "ERROR", NULL);
     }




     // 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 = SCREEN_WIDTH;
     viewport.Height = SCREEN_HEIGHT;

     devcon->RSSetViewports(1, &viewport);

    InitPipeline();
     InitGraphics();
 }
void CleanD3D()
{
    swapchain->SetFullscreenState(FALSE, NULL);
    dev->Release();
    devcon->Release();
    swapchain->Release();
    pInputLayout->Release();
    pVBuffer->Release();
    backbuffer->Release();
    pVS->Release();
    pPS->Release();
}

// Window
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
}
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
    HWND hWnd;

    WNDCLASSEX wc;
    ZeroMemory(&wc, sizeof(WNDCLASSEX));
    wc.cbSize = sizeof(WNDCLASSEX);
    //wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = (HICON)LoadIcon(NULL, IDI_APPLICATION);
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = "DirectXWindow";
    wc.style = CS_HREDRAW | CS_VREDRAW;

    RegisterClassEx(&wc);

    hWnd = CreateWindowEx(NULL,
        "DirectXWindow",
        "DirectX 11 (June 2010",
        WS_OVERLAPPEDWINDOW,
        0,0,
        SCREEN_WIDTH, SCREEN_HEIGHT,
        NULL,
        NULL,
        hInstance,
        NULL);

    ShowWindow(hWnd, nCmdShow);

    InitD3D(hWnd);
    UpdateWindow(hWnd);

    MSG msg = {0};

    while(msg.message != WM_QUIT)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);

        }
        else
        {
            RenderFrame();
        }
    }
    CleanD3D();

    return msg.wParam;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

他夏了夏天 2024-12-07 02:30:53

该错误基本上意味着您在某处使用了空指针。检查你所有的指针。我的猜测是某个地方的某些函数无法设置您的指针(或者您的参数顺序错误)。

That error basically means that you are using a null pointer somewhere. Check all your pointers. My guess is that some function somewhere is failing to set your pointers (or you have the parameters in the wrong order).

孤君无依 2024-12-07 02:30:53

您正在使用 NULL 指针。您定义了 8 个全局 D3D 接口指针,并在 InitPipeline 中使用 devdevcon,它们需要在调用任何方法之前进行分配和初始化在他们身上。

You are using a NULL pointer. You define 8 global D3D interface pointers and you are using dev and devcon within InitPipeline they need to be allocated and initialized before you can call any methods on them.

给妤﹃绝世温柔 2024-12-07 02:30:53

尝试设置 scd.SampleDesc.Count = 1

该值告诉 Direct3D 应将多少细节放入抗锯齿中,数字越高越好。此处保证 Direct3D 11 显卡最多支持 4 个,但最少为 1 个。
也许您的显卡不支持 Direct3D 11?

Try setting the scd.SampleDesc.Count = 1

This value tells Direct3D how much detail should be put into anti-aliasing, the higher the number the better. Direct3D 11 video cards are guaranteed to support up to 4 here, but the minimum is 1.
Perhaps your video card doesn't support Direct3D 11?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文