2011-08-15 35 views
4

我是新來的DirectX 11,我已經設法在我的書中得到了繪圖三角章。 我已經寫了這段代碼,但是我得到一個運行時錯誤: 「DirectX 11.exe中的0x00cd14e6未處理的異常:0xc0000005:訪問衝突讀取位置0x00000000」。簡單的DirectX 11程序運行時錯誤

我的編譯器顯示錯誤在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; 
} 
+0

在崩潰之前放置一個斷點,然後單步執行調試器中的代碼。在每行之前,查看下一行中使用的每個指針,看看它們中的任何一個是否爲0x00000000 – jcoder

回答

3

該錯誤基本上意味着你使用的是空指針的地方。檢查你所有的指針。我的猜測是某處某個函數無法設置你的指針(或者你的參數順序錯誤)。

+0

嗨!在我的書中,沒有寫關於分配和初始化的任何信息。即使在DirectX教程網頁上,他們也不會初始化它們[鏈接](http://directxtutorial.com/Tutorial11/B-A/BA5.aspx#still) – Janman

+0

@Janman:我相信'D3D11CreateDeviceAndSwapChain'應該初始化它們。正如我所說,檢查你的指針。這是你要找出的唯一方法。 –

+0

我檢查了我的'D3D11CreateDeviceAndSwapChain',並且沒有任何問題(我甚至從網頁粘貼'InitD3D()'函數複製到我的代碼中)。 仍然沒有運氣。 我發現很難找到錯誤。 – Janman

2

您正在使用NULL指針。您定義了8個全局D3D接口指針,並且您在InitPipeline內使用devdevcon,需要分配和初始化它們,然後才能調用其中的任何方法。

+1

嗨! 在我的書中,沒有寫關於分配和初始化的任何內容。 即使在DirectX教程網頁上,他們也不會初始化它們[link](http://directxtutorial.com/Tutorial11/B-A/BA5。aspx#still) – Janman

+0

創建函數返回一個'HRESULT',你應該檢查這個以確保它在使用設備之前成功。我沒有看到代碼段中的哪個位置可以調用任何ID3D創建函數:http://msdn.microsoft.com/zh-cn/library/ff476153(v=VS.85).aspx – AJG85

+0

已添加if(FAILED ()),我向我展示了DeviceAndSwapChain成功。 (更新了問題中的代碼)。 – Janman

2

嘗試設置scd.SampleDesc.Count = 1

這個值告訴Direct3D多的細節應該如何投入抗鋸齒,數值越高越好。 Direct3D 11視頻卡保證最多支持4個,但最低爲1. 也許您的視頻卡不支持Direct3D 11?

相關問題