2013-04-16 2 views
1

Directx 11.0을 배우려고합니다. 오류가 발생했습니다. 이것은 코드입니다.CreateTexture2D 및 CreateDepthStencilView가 실패 함

// 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") 

// define the screen resolution 
#define SCREEN_WIDTH 800 
#define SCREEN_HEIGHT 600 

// global declarations 
IDXGISwapChain *swapchain = NULL;    // the pointer to the swap chain interface 
ID3D11Device *dev = NULL;      // the pointer to our Direct3D device interface 
ID3D11DeviceContext *devcon = NULL;   // the pointer to our Direct3D device context 
ID3D11RenderTargetView *backbuffer = NULL; // the pointer to our back buffer 
ID3D11InputLayout *pLayout = NULL;   // the pointer to the input layout 
ID3D11VertexShader *pVS = NULL;    // the pointer to the vertex shader 
ID3D11PixelShader *pPS = NULL;    // the pointer to the pixel shader 
ID3D11Buffer *pVBuffer = NULL;    // the pointer to the vertex buffer 
ID3D11Buffer *pIBuffer = NULL;    // the pointer to the index buffer 
ID3D11DepthStencilView *pDView = NULL;  // the pointer to depth stencil view 
ID3D11Texture2D *pDStencil = NULL;   // the pointer to depth stencil 

// a struct to define a single vertex 
struct VERTEX{FLOAT X, Y, Z; D3DXCOLOR Color;}; 

// 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 
void InitGraphics(void); // creates the shape to render 
void InitPipeline(void); // loads and prepares the shaders 

// 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.lpszClassName = "WindowClass"; 

    RegisterClassEx(&wc); 

    RECT wr = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT}; 
    AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); 

    hWnd = CreateWindowEx(NULL, 
          "WindowClass", 
          "Our First Direct3D Program", 
          WS_OVERLAPPEDWINDOW, 
          CW_USEDEFAULT, 
          CW_USEDEFAULT, 
          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.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 
    D3D11CreateDeviceAndSwapChain(NULL, 
            D3D_DRIVER_TYPE_HARDWARE, 
            NULL, 
            D3D11_CREATE_DEVICE_DEBUG, 
            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(); 

    //Create depth stencil buffer 
    D3D11_TEXTURE2D_DESC descDepth; 
    descDepth.Width = SCREEN_WIDTH; 
    descDepth.Height = SCREEN_HEIGHT; 
    descDepth.MipLevels = 1; 
    descDepth.ArraySize = 1; 
    descDepth.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 
    descDepth.SampleDesc.Count = 4; 
    descDepth.SampleDesc.Quality = 0; 
    descDepth.Usage = D3D11_USAGE_DYNAMIC; 
    descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; 
    descDepth.CPUAccessFlags = 0; 
    descDepth.MiscFlags = 0; 

    dev->CreateTexture2D(&descDepth, NULL, &pDStencil); 

    // Create the depth stencil view 
    D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; 
    descDSV.Format = descDepth.Format; 
    descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; 
    descDSV.Texture2DMS.UnusedField_NothingToDefine = 0; 

    dev->CreateDepthStencilView(pDStencil, &descDSV, &pDView); 

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

    // 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; 
    viewport.MinDepth = 0.0f; 
    viewport.MaxDepth = 1.0f; 

    devcon->RSSetViewports(1, &viewport); 

    InitPipeline(); 
    InitGraphics(); 
} 


// 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(1.0f, 1.0f, 1.0f, 1.0f)); 

    //clear the depth stencil view 
    devcon->ClearDepthStencilView(pDView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0); 

     // select which vertex buffer to display 
     UINT stride = sizeof(VERTEX); 
     UINT offset = 0; 
     devcon->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset); 

     //set index buffer 
     devcon->IASetIndexBuffer(pIBuffer, DXGI_FORMAT_R32_UINT, 0); 

     // select which primtive type we are using 
     devcon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 

     // draw the vertex buffer to the back buffer 
     devcon->DrawIndexed(9, 0, 0); 

    // 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) 
{ 
    swapchain->SetFullscreenState(FALSE, NULL); // switch to windowed mode 

    // close and release all existing COM objects 
    if(pLayout)pLayout->Release(); 
    if(pVS)pVS->Release(); 
    if(pPS)pPS->Release(); 
    if(pVBuffer)pVBuffer->Release(); 
    if(pIBuffer)pIBuffer->Release(); 
    if(swapchain)swapchain->Release(); 
    if(backbuffer)backbuffer->Release(); 
    if(dev)dev->Release(); 
    if(devcon)devcon->Release(); 
    if(pDStencil)pDStencil->Release(); 
    if(pDView)pDView->Release(); 
} 


// this is the function that creates the shape to render 
void InitGraphics() 
{ 
    // create a triangle using the VERTEX struct 
    VERTEX Vertices[] = 
    { 
     {-0.5f, 0.5f, 1.0f, D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)}, 
     {0.5f, 0.5f, 1.0f, D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)}, 
     {0.5f, -0.5f, 1.0f, D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)}, 
     {-0.5f, -0.5f, 1.0f, D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)}, 
     {0.75f, 0.75f, 0.0f, D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f)}, 
     {0.75f, -0.5f, 0.0f, D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f)}, 
     {0.0f, -0.5f, 0.0f, D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f)}, 
    }; 

    DWORD Indices[]= 
    { 
     0,2,3, 
     4,5,6, 
    }; 

    // create the vertex buffer 
    D3D11_BUFFER_DESC bd,id; 
    ZeroMemory(&bd, sizeof(bd)); 
    ZeroMemory(&id, sizeof(id)); 

    bd.Usage = D3D11_USAGE_DYNAMIC;    // write access access by CPU and GPU 
    bd.ByteWidth = sizeof(VERTEX) * 7;    // size is the VERTEX struct * 4 
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;  // use as a vertex buffer 
    bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // allow CPU to write in buffer 

    id.Usage = D3D11_USAGE_DYNAMIC;    // write access access by CPU and GPU 
    id.ByteWidth = sizeof(DWORD) * 3*3;    // size is the DWORD struct * 2 * 3 
    id.BindFlags = D3D11_BIND_INDEX_BUFFER;  // use as a index buffer 
    id.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // allow CPU to write in buffer 

    dev->CreateBuffer(&bd, NULL, &pVBuffer);  // create the buffer 
    dev->CreateBuffer(&id, NULL, &pIBuffer); 

    // copy the vertices into the buffer 
    D3D11_MAPPED_SUBRESOURCE ms; 
    devcon->Map(pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer 
    memcpy(ms.pData, Vertices, sizeof(Vertices));      // copy the data 
    devcon->Unmap(pVBuffer, NULL);          // unmap the buffer 

    // copy the indices into the buffer 
    D3D11_MAPPED_SUBRESOURCE ims; 
    devcon->Map(pIBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ims); // map the buffer 
    memcpy(ims.pData, Indices, sizeof(Indices));      // copy the data 
    devcon->Unmap(pIBuffer, NULL);          // unmap the buffer 
} 


// this function loads and prepares the shaders 
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); 

    // 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); 

    // create the input layout object 
    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, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, 
    }; 

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

Debug는 CreateDepthStencilView 기능에서 프로그램이 실패하고 "첫 번째 매개 변수가 손상되었거나 null"인 이유를 알려줍니다.

사실, CreateTexture2D는 내 Texture2D COM 객체를 NULL로 남겨 둡니다. 이것이 모든 문제의 원인입니다.

왜 이런 일이 일어날 수 있습니까?

InitD3D()를 참조하십시오. 위에서 언급 한 두 가지 기능이 있습니다.

+0

거의 모든 DirectX 함수는 오류를 나타내는 'HRESULT'를 반환합니다. 코드에서 아무것도 확인하지 않는 것 같으므로 먼저 실패한 * first * 호출을 분리하기 위해 몇 가지 체크를 넣으십시오. –

답변

1

나는 그것을 얻었다! Depth Stencil View에 대한 설명 아래에서 Flags 필드를 설정해야했습니다.

descDSV.Flags = 0;   //0 for it 'not' being read only 

시간 내 주셔서 감사합니다.