2012-08-14 69 views
1

所以我正在學習DirectX 11,我正在做東西,我遇到了一個調試錯誤(試圖從交換鏈訪問0x00000000),我認爲CreateDeviceAndSwapChain應該修復,但它沒有。這裏是我的代碼:DirectX 11:零交換鏈

#include <windows.h> 
#include <d3d11.h> 
#include <d3dx11.h> 
#include <dxgi.h> 
#include "types.h" 

//globals 
RECT dimensions; 
HWND hwnd; 

//width and height of the window 
uint width; 
uint height; 

//create the driver types 
D3D_DRIVER_TYPE dt[] = { 
    D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_SOFTWARE 
}; 

//create the feature level 
D3D_FEATURE_LEVEL fl[] = { 
    D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_10_1 
}; 

//create the selected drivertype 
D3D_DRIVER_TYPE selectedDT; 

//create the selected feature level 
D3D_FEATURE_LEVEL* selectedFL; 

//create driver types and feature level uints 
uint totalDTs = ARRAYSIZE(dt); 
uint totalFLs = ARRAYSIZE(fl); 

//create the swap chain description 
DXGI_SWAP_CHAIN_DESC scd; 

//create the swap chain 
IDXGISwapChain* swapchain; 

//create the device 
ID3D11Device* dev; 

//create the context 
ID3D11DeviceContext* context; 

//create the render target view 
ID3D11RenderTargetView *rtv; 

//functions 
void init(); 
void initswapchaindesc(); 
void createDevice(); 
void close(); 

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

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
    // window handler 
    HWND hwnd; 
    // this struct holds information for the window class 
    WNDCLASSEX wc; 

    ZeroMemory(&wc, sizeof(WNDCLASSEX)); 

    // fill the struct 
    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 = "WindowClass1"; 

    // register the window class 
    RegisterClassEx(&wc); 

    hwnd = CreateWindowEx(NULL, 
          "WindowClass1", // name of the window class 
          "Our First Windowed Program", // title of the window 
          WS_OVERLAPPEDWINDOW, // window style 
          300, // x-position of the window 
          300, // y-position of the window 
          800, // width of the window 
          600, // height of the window 
          NULL, // we have no parent window, NULL 
          NULL, // we aren't using menus, NULL 
          hInstance, // application handle 
          NULL); // used with multiple windows, NULL 

    // display the window 
    ShowWindow(hwnd, nCmdShow); 

    // enter the main loop: 
    init(); 
    close(); 
    MessageBox(hwnd, "Success!", "A message for you", NULL); 

    // this struct holds Windows event messages 
    MSG msg; 

    // wait for the next message in the queue 
    while(GetMessage(&msg, NULL, 0, 0)) 
    { 
     TranslateMessage(&msg); 

     DispatchMessage(&msg); 
    } 

    return msg.wParam; 
} 

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch(message) 
    { 
     // the quit message 
     case WM_DESTROY: 
      { 
     //quit 
       PostQuitMessage(0); 
       return 0; 
      } 
     break; 
    } 

    // def message 
    return DefWindowProc (hwnd, message, wParam, lParam); 
} 

void init() { 
    GetClientRect(hwnd, &dimensions); 
    width = dimensions.right - dimensions.left; 
    height = dimensions.bottom - dimensions.top; 

    //initialize the swap chain description 
    ZeroMemory(&scd, sizeof(scd)); 
    scd.BufferCount = 1; 
    scd.BufferDesc.Width = width; 
    scd.BufferDesc.Height = height; 
    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 
    scd.BufferDesc.RefreshRate.Denominator = 60; 
    scd.BufferDesc.RefreshRate.Numerator = 1; 
    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 
    scd.OutputWindow = hwnd; 
    scd.Windowed = true; 
    scd.SampleDesc.Count = 1; 
    scd.SampleDesc.Quality = 0; 

    uint creationflags; 

#ifdef _DEBUG 
    creationflags |= D3D11_CREATE_DEVICE_DEBUG; 
#endif 

    HRESULT devcreateres; 
    uint driver = 0; 

    for(driver = 0; driver < totalDTs; ++driver) { 
     devcreateres = D3D11CreateDeviceAndSwapChain(0, dt[driver], 0, creationflags, fl, totalFLs, 
      D3D11_SDK_VERSION, &scd, &swapchain, &dev, 
      selectedFL, &context); 

     if(SUCCEEDED(devcreateres)) { 
      selectedDT = dt[driver]; 
     } 
    } 

    //create the back buffer image 
    ID3D11Texture2D* backbuffer; 

    //error here - line 175 
    swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backbuffer); 
    dev->CreateRenderTargetView(backbuffer, NULL, &rtv); 
    backbuffer->Release(); 
    context->OMSetRenderTargets(1, &rtv, NULL); 

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

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

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

void close() { 
    if(swapchain) 
     swapchain->Release(); 
    if(dev) 
     dev->Release(); 
    if(context) 
     context->Release(); 
    if(rtv) 
     rtv->Release(); 
} 

(順便說一句數據類型UINT被定義爲unsigned int。)

請幫幫忙!

+0

你究竟在哪裏看到這個錯誤(哪條線......)? – jcoder 2012-08-14 14:12:41

+0

@ J99具有GetBuffer功能的行(第175行,我對它發表了評論) – alecrock1 2012-08-14 16:13:15

+0

好的很奇怪。什麼是你得到的錯誤的實際文本(我認爲這是一個D3D調試輸出?) – jcoder 2012-08-14 16:20:42

回答

1

如果仍然適用,我注意到close()被放置在while(main)循環開始之前。它隨後被放置。這是你的代碼段:

// enter the main loop: 
init(); 
close(); 
MessageBox(hwnd, "Success!", "A message for you", NULL); 

// this struct holds Windows event messages 
MSG msg; 

// wait for the next message in the queue 
while(GetMessage(&msg, NULL, 0, 0)) 
{ 
    TranslateMessage(&msg); 

    DispatchMessage(&msg); 
} 

return msg.wParam; 
} 

您需要close()在環路閉合後發生。請注意,放置「循環內」的東西意味着在while循環內部直接放置某些東西。在這裏,你想要它TranslateMessage(&msg);,然後DispatchMessage(&msg);(GetMessage(&msg, NULL, 0, 0)是真的。另外,你想運行你自己的函數在這個循環中發生。

隨着循環一遍又一遍地發生,您希望每次都繪製您的框架。要做到這一點,你可以添加else,一個運行裏面的功能。

即:

// enter the main loop: 
init(); 
MessageBox(hwnd, "Success!", "A message for you", NULL); 

// this struct holds Windows event messages 
MSG msg; 

// wait for the next message in the queue 
while(GetMessage(&msg, NULL, 0, 0)) 
{ 
    TranslateMessage(&msg); 

    DispatchMessage(&msg); 
} 
else 
{ 
    render(); //Your render function. 
} 
close(); //If this is run, the while loop has closed. This is a good opportunity 
     //to run close() before the function returns msg.wParam 
return msg.wParam; 
} 

你可能會得到侵犯,因爲循環開始前的COM對象被釋放。