2012-06-20 83 views
1

我現在正在學習DirectX 11,並試用了「Beginning DirectX 11 programming」一書中的演示之一。我遵循書籍的指導原則來創建一個處理窗口創建和銷燬的基類(包括d3d11設置)。所有其他演示都基於這個類。所以我寫了三角形演示,其目的是繪製一個二維三角形。下面是三角形類的實現:DirectX Demo不會在屏幕上繪製任何東西

#include "Triangle.h" 


Triangle::Triangle(void): mVertexShader(0), mPixelShader(0), mInputLayout(0), mVertexBuffer(0) 
{ 
} 


Triangle::~Triangle(void) 
{ 
} 

void Triangle::Update(float deltaTime){ 

} 

void Triangle::UnloadContent(){ 
    if(mVertexShader) 
     mVertexShader->Release(); 

    if(mPixelShader) 
     mPixelShader->Release(); 

    if(mInputLayout) 
     mInputLayout->Release(); 

    if(mVertexBuffer) 
     mVertexBuffer->Release(); 

    mVertexBuffer = 0; 
    mPixelShader = 0; 
    mVertexShader = 0; 
    mInputLayout = 0; 
} 

bool Triangle::LoadContent(){ 
    //Load Vertex Shader and make it active 
    ID3DBlob* vsBlob = 0; 

    if(!CompileShader(L"shaders.fx", "VS_Main", "vs_4_0", &vsBlob)){ 
     MessageBox(0, L"Error Loading Vertex Shader", L"Compile Error", MB_OK); 
     return false; 
    } 
    HRESULT hr; 
    if(FAILED(hr = mDevice->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), 0, &mVertexShader))){ 
     if(vsBlob) 
      vsBlob->Release(); 

     return false; 
    } 

    D3D11_INPUT_ELEMENT_DESC vertexLayout[] = { 
     { 
      "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 
     } 
    }; 

    unsigned int layoutSize = ARRAYSIZE(vertexLayout); 

    if(FAILED(mDevice->CreateInputLayout(
      vertexLayout, 
      layoutSize, 
      vsBlob->GetBufferPointer(), 
      vsBlob->GetBufferSize(), 
      &mInputLayout 
     ))){ 
      vsBlob->Release(); 
      return false; 
    } 

    vsBlob->Release(); 

    ID3DBlob* psBlob = 0; 

    if(!CompileShader(L"shaders.fx", "PS_Main", "ps_4_0", &psBlob)){ 
     MessageBox(0, L"Error Loading Pixel Shader", L"Compile Error", MB_OK); 

     if(psBlob) 
      psBlob->Release(); 

     return false; 
    } 

    if(FAILED(mDevice->CreatePixelShader(
      psBlob->GetBufferPointer(), 
      psBlob->GetBufferSize(), 
      0, 
      &mPixelShader 
     ))){ 
      psBlob->Release(); 
      return false; 
    } 

    psBlob->Release(); 


    //vertex buffer creation 
    VertexPos vertices[] = 
    { 
     XMFLOAT3(0.5f, 0.5f, 0.5f), 
     XMFLOAT3(0.5f, -0.5f, 0.5f), 
     XMFLOAT3(-0.5f, -0.5f, 0.5f) 
    }; 

    D3D11_BUFFER_DESC vertexDesc; 
    ZeroMemory(&vertexDesc, sizeof(vertexDesc)); 

    vertexDesc.Usage = D3D11_USAGE_DEFAULT; 
    vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 
    vertexDesc.ByteWidth = sizeof(VertexPos) * 3; 

    D3D11_SUBRESOURCE_DATA subresourceData; 
    ZeroMemory(&subresourceData, sizeof(subresourceData)); 
    subresourceData.pSysMem = vertices; 

    if(FAILED(mDevice->CreateBuffer(
      &vertexDesc, 
      &subresourceData, 
      &mVertexBuffer 
     ))){ 
      return false; 
    } 

    return true; 
} 

bool Triangle::CompileShader(wchar_t* filePath, char* entry, char* shaderModel, ID3DBlob** buffer){ 
    DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; 

#if defined(DEBUG) || defined(_DEBUG) 
    shaderFlags |= D3DCOMPILE_DEBUG; 
#endif 

    ID3DBlob* errorBuffer = 0; 
    HRESULT result; 

    result = D3DX11CompileFromFileW(
      filePath, 
      0,0, 
      entry, 
      shaderModel, 
      shaderFlags, 
      0,0, 
      buffer, 
      &errorBuffer, 
      0 
     ); 

    if(FAILED(result)){ 
     if(errorBuffer != 0){ 
      OutputDebugStringA((char*) errorBuffer->GetBufferPointer()); 
      errorBuffer->Release(); 
     } 
     return false; 
    } 
    if(errorBuffer) 
     errorBuffer->Release(); 

    return true; 
} 


void Triangle::Render(){ 
    float clearColor[4] = { 1.0f, 0.0f, 1.25f, 1.0f }; 
    mDeviceContext->ClearRenderTargetView(mRenderTarget, clearColor); 

    unsigned int stride = sizeof(VertexPos); 
    unsigned int offset = 0; 

    mDeviceContext->IASetInputLayout(mInputLayout); 
    mDeviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &offset); 
    mDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 

    mDeviceContext->VSSetShader(mVertexShader, 0, 0); 
    mDeviceContext->PSSetShader(mPixelShader, 0, 0); 
    mDeviceContext->Draw(3, 0); 

    mSwapChain->Present(0, 0); 

} 

現在,當我運行這個清屏並採用了色彩我指定,但沒有被繪製在屏幕上。只是爲了確保我編譯了本書提供的源代碼,並且它工作得很好。使用的着色器也是一樣的。我的電腦確實支持directx 11.我認爲大部分名稱都是不言自明的,但您可以問我是否令人困惑。我已經用其他演示測試了我的框架,它工作正常。我似乎無法找到我的代碼中的錯誤。

+0

我做了一個快速瀏覽,輸入佈局指定位置數據爲DXGI_FORMAT_R32G32B32A32_FLOAT(float4),其中頂點數組的位置爲f​​loat3。這可能會導致我不記得的問題。 因此,無論是製作數組XMFLOAT4還是更改佈局和着色器代碼都如此恰當。 (最快的是交換到XMFLOAT4和(a,b,c,1) 雖然可能需要着色器代碼來識別真實問題。 – wookey

回答

4

位置需要在標準歐幾里德空間座標,三元組或四維同構座標中傳遞,第四個元件設置爲1(一個4元組)(因爲它們是點)。當您在輸入元素描述過,你的頂點數據的佈局,你在設置DXGI_FORMAT_R32G32B32A32_FLOAT

D3D11_INPUT_ELEMENT_DESC vertexLayout[] = 
{ 
    { 
     "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 
    } 
}; 

但只有經過在3D頂點:

VertexPos vertices[] = 
    { 
     XMFLOAT3(0.5f, 0.5f, 0.5f), 
     XMFLOAT3(0.5f, -0.5f, 0.5f), 
     XMFLOAT3(-0.5f, -0.5f, 0.5f) 
    }; 

有人可能會在第一次猜你w座標被初始化爲0,並且它以某種方式混淆了頂點着色器中的變換,但是線性內存佈局和承諾GPU將如何獲取其數據會發生什麼。你說它得到了一個32位的4元組,它只獲得了32位的3元組。現在,由於它們相鄰,它們似乎被第一眼泵入錯誤的插槽。但是,HLSL嚴格禁止打破邊界類型,因此它會死亡。

如何解決?

簡單,更改爲DXGI_FORMAT_R32G32B32_FLOAT和調整你的HLSL代碼加分的第四部分,並將其設置爲1.0象個float4(POS,1.0),並與世界,視圖,投影您已經構造矩陣相乘CPU也記得HLSL是列主要的,而C++是行主要的。這意味着您需要將所有轉到HLSL的內容轉換爲合理的計算。

快樂編碼。

相關問題