2

我正在学习 DirectX 11,我正在尝试渲染一个简单的立方体,不幸的是我的代码不起作用,它根本没有渲染任何内容......没有错误没有警告......唯一显示的是窗口具有指定的清晰颜色。我也非常确定代码已完全执行。

这是我的专业课的标题:

#pragma once
#include "DirectxApp.h"
#include <DirectXMath.h>
#include "DirectxUtils.h"



struct Vertex
{
    DirectX::XMFLOAT3 Position;
    DirectX::XMFLOAT4 Color;
};


struct TransformationMatrix
{
    DirectX::XMMATRIX worldViewProjMatrix;
};


class MyDirectxApp : public DirectxApp
{

private:
    
    ID3D11Buffer* m_vertexBuffer;
    ID3D11Buffer* m_indexBuffer;
    ID3D11Buffer* m_worldViewProjBuffer;
    ID3D11RasterizerState* m_rasterizerState;
    ID3D11InputLayout* m_inputLayout;

    ID3D11VertexShader* m_vertexShader;
    ID3D11PixelShader* m_pixelShader;


    DirectX::XMMATRIX m_worldMatrix;
    DirectX::XMMATRIX m_viewMatrix;
    DirectX::XMMATRIX m_projMatrix;


    TransformationMatrix m_transformationMatrix;


    float m_theta;
    float m_phi;
    float m_radius;

public:

    MyDirectxApp(HINSTANCE hInstance, 
                    int width,
                    int height,
                    LPWSTR windowName = L"",
                    bool enable4xMsaa = true,
                    int xCoord = CW_USEDEFAULT,
                    int yCoord = CW_USEDEFAULT
                    );

    virtual bool Init();
    virtual void OnFrame();



    virtual ~MyDirectxApp(void);
};

而这就是cpp(超类的init方法初始化窗口和DirectX的基本组件,见后文):

#include "MyDirectxApp.h"


using namespace DirectX;




MyDirectxApp::MyDirectxApp(HINSTANCE hInstance, 
                           int width,
                           int height,
                           LPWSTR windowName,
                           bool enable4xMsaa,
                           int xCoord,
                           int yCoord
                           ) : DirectxApp(hInstance, width, height, windowName, enable4xMsaa, xCoord, yCoord)
{

    m_vertexBuffer = 0;
    m_indexBuffer  = 0;
    m_inputLayout = 0;
    m_rasterizerState = 0;
    m_vertexShader = 0;
    m_pixelShader = 0;
    m_worldViewProjBuffer = 0;


    XMMATRIX matrixIdentity = XMMatrixIdentity();
    m_worldMatrix = matrixIdentity;
    m_viewMatrix  = matrixIdentity;
    m_projMatrix  = matrixIdentity;
    m_transformationMatrix.worldViewProjMatrix = matrixIdentity;


    m_theta  = 1.5f * DirectX::XM_PI;
    m_phi    = 0.25f* DirectX::XM_PI;
    m_radius = 5.0f;

}


bool MyDirectxApp::Init()
{
    if(!DirectxApp::Init())
    {
        return false;
    }


    HRESULT hResult;
    

    //////////////////////////////////////
    // CreateVertexBuffer
    //////////////////////////////////////

    Vertex cubeVertexArray[] = {
        //          Position                        Color
        {XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, //white
        {XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f)}, //black
        {XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)}, //red
        {XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f)}, //green
        {XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f)}, //blue
        {XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f)}, //yellow
        {XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f)}, //cyan
        {XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f)}  //magenta
    };


    hResult = DirectxUtils::CreateVertexBuffer(m_d3dDevice, &cubeVertexArray, sizeof(cubeVertexArray), &m_vertexBuffer);

    if (FAILED(hResult))
    {
        MessageBox(0, L"CreateVertexBuffer FAILED", 0, 0);
        return false;
    }




    //////////////////////////////////////
    // CreateIndexBuffer 
    //////////////////////////////////////

    UINT indices[] = {
        0, 1, 2, // front face
        0, 2, 3,
        
        4, 6, 5, // back face
        4, 7, 6,

        4, 5, 1, // left face
        4, 1, 0,

        3, 2, 6, // right face
        3, 6, 7,
        
        1, 5, 6, // top face
        1, 6, 2,
        
        4, 0, 3, // bottom face
        4, 3, 7
    };


    hResult = DirectxUtils::CreateIndexBuffer(m_d3dDevice, &indices, sizeof(indices), &m_indexBuffer);

    if (FAILED(hResult))
    {
        MessageBox(0, L"CreateIndexBuffer FAILED", 0, 0);
        return false;
    }




    //////////////////////////////////////
    // CreateVertexShader 
    //////////////////////////////////////

    D3D11_INPUT_ELEMENT_DESC inputLayoutDesc[] = {
        {"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},
    };

    hResult = DirectxUtils::CreateVertexShader(m_d3dDevice, L"VertexShader.hlsl", "main", inputLayoutDesc, 2, &m_vertexShader, &m_inputLayout);

    if (FAILED(hResult))
    {
        MessageBox(0, L"CreateVertexShader FAILED", 0, 0);
        return false;
    }




    //////////////////////////////////////
    // CreatePixelShader
    //////////////////////////////////////

    hResult = DirectxUtils::CreatePixelShader(m_d3dDevice, L"PixelShader.hlsl", "main", &m_pixelShader);

    if (FAILED(hResult))
    {
        MessageBox(0, L"CreatePixelShader FAILED", 0, 0);
        return false;
    }




    //////////////////////////////////////
    // create world\view\proj matrix
    //////////////////////////////////////
        
    XMVECTOR cameraPos    = XMVectorSet(0.0f, 3.0f, -5.0f, 1.0f);
    XMVECTOR cameraTarget = XMVectorZero();
    XMVECTOR cameraUp     = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);

    m_worldMatrix = XMMatrixIdentity();
    m_projMatrix  = XMMatrixPerspectiveFovLH(XMConvertToRadians(45.0f), AspectRatio(), 0.1f, 100.0f);
    m_viewMatrix  = XMMatrixLookAtLH(cameraPos, cameraTarget, cameraUp);


    hResult = DirectxUtils::CreateConstantBuffer(m_d3dDevice, sizeof(TransformationMatrix), &m_worldViewProjBuffer);

    if (FAILED(hResult))
    {
        MessageBox(0, L"CreateConstantBuffer FAILED", 0, 0);
        return false;
    }




    //////////////////////////////////////
    // CreateRasterizerState
    //////////////////////////////////////

    D3D11_RASTERIZER_DESC rasterizerDesc;
    rasterizerDesc.FillMode = D3D11_FILL_SOLID;
    rasterizerDesc.CullMode = D3D11_CULL_BACK;
    rasterizerDesc.FrontCounterClockwise = false;
    rasterizerDesc.DepthClipEnable = true;


    hResult = m_d3dDevice->CreateRasterizerState(&rasterizerDesc, &m_rasterizerState);

    if (FAILED(hResult))
    {
        MessageBox(0, L"CreateRasterizerState FAILED", 0, 0);
        return false;
    }



    return true;


}




void MyDirectxApp::OnFrame()
{
    ///////////////////////////////////
    // update worldViewProj matrix
    ///////////////////////////////////

    XMVECTOR cameraPos    = XMVectorSet(0.0f, 3.0f, -5.0f, 1.0f);
    XMVECTOR cameraTarget = XMVectorZero();
    XMVECTOR cameraUp     = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);

    m_viewMatrix  = XMMatrixLookAtLH(cameraPos, cameraTarget, cameraUp);
    
    m_transformationMatrix.worldViewProjMatrix = m_worldMatrix * m_viewMatrix * m_projMatrix;




    ///////////////////////////////////
    // drawing
    ///////////////////////////////////

    static const FLOAT clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
    

    m_d3dDeviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilBufferView);
    m_d3dDeviceContext->ClearRenderTargetView(m_renderTargetView, clearColor);
    m_d3dDeviceContext->ClearDepthStencilView(m_depthStencilBufferView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

    m_d3dDeviceContext->IASetInputLayout(m_inputLayout);
    m_d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    UINT stride = sizeof(Vertex);
    UINT offset = 0; 
    m_d3dDeviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);
    m_d3dDeviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);

    m_d3dDeviceContext->VSSetShader(m_vertexShader, nullptr, 0);
    m_d3dDeviceContext->PSSetShader(m_pixelShader, nullptr, 0);
    m_d3dDeviceContext->RSSetState(m_rasterizerState);


    m_d3dDeviceContext->UpdateSubresource(m_worldViewProjBuffer, 0, nullptr, &m_transformationMatrix, 0, 0);
    m_d3dDeviceContext->VSSetConstantBuffers(0, 1, &m_worldViewProjBuffer);

    
    m_d3dDeviceContext->DrawIndexed(36, 0, 0);
    m_swapChain->Present(0, 0); 

}


MyDirectxApp::~MyDirectxApp(void)
{
    m_vertexBuffer->Release();
    m_indexBuffer->Release();
    m_inputLayout->Release();
    m_rasterizerState->Release();
    m_vertexShader->Release();
    m_pixelShader->Release();
    m_worldViewProjBuffer->Release();
}

VertexShader真的很简单,它只做世界观投影转换:

cbuffer cbPerObject
{
    float4x4 worldViewProjection;
};



//input data structure
struct VertexInput
{
    float3 iPosition : POSITION;
    float4 iColor    : COLOR;
};

//output data
struct VertexOutput
{
    float4 oPosition : SV_POSITION; //system-value-position is a special semantic name
    float4 oColor    : COLOR;
};




VertexOutput main(VertexInput vertexInput)
{

    VertexOutput vertexOutput;

    //transform world-view-projection
    vertexOutput.oPosition = mul(float4(vertexInput.iPosition, 1.0f), worldViewProjection);
    vertexOutput.oColor = vertexInput.iColor;

    return vertexOutput;
}

PixelShader更简单:

//input data structure
//must match the vertexShader output
struct PixelShaderInput
{
    float4 iPosition : SV_POSITION;
    float4 iColor    : COLOR;
};



float4 main(PixelShaderInput pixelShaderInput) : SV_TARGET //system-value-target means the output must match the renderTarget format
{
    return pixelShaderInput.iColor;
}

如上所述,Directx 的基本组件是由超类(DirectxApp)创建的,代码如下:

bool DirectxApp::InitDirectx()
{
    
    //////////////////////////////////////
    // device creation
    //////////////////////////////////////

    UINT creationDeviceFlags = 0;

#if defined(DEBUG)
    creationDeviceFlags = D3D11_CREATE_DEVICE_DEBUG;
#endif


    D3D_FEATURE_LEVEL featureLevel;
    
    HRESULT hResult = D3D11CreateDevice(0,                              //display adapter
                                        D3D_DRIVER_TYPE_HARDWARE,       //drier type
                                        0,                              //software driver
                                        creationDeviceFlags,            //device flag
                                        0,                              //array of feature levels (NULL means choose the greatest)
                                        0,                              //number of feature levels
                                        D3D11_SDK_VERSION,              //sdk version
                                        &m_d3dDevice,                   
                                        &featureLevel, 
                                        &m_d3dDeviceContext);

    if (FAILED(hResult))
    {
        MessageBox(0, L"D3D11CreateDevice FAILED", 0, 0);
        return false;
    }


    if (featureLevel != D3D_FEATURE_LEVEL_11_0)
    {
        MessageBox(0, L"D3D_FEATURE_LEVEL_11_0 not supported", 0, 0);
        return false;
    }




    //////////////////////////////////////
    // check 4xMSAA
    //////////////////////////////////////
    
    UINT m4xMsaaQuality;
    m_d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);
    assert(m4xMsaaQuality > 0); //m4xMsaaQuality is always > 0
    



    //////////////////////////////////////
    // swap chain creation
    //////////////////////////////////////

    DXGI_SWAP_CHAIN_DESC swapChainDesc;
    swapChainDesc.BufferDesc.Width = m_windowWidth;
    swapChainDesc.BufferDesc.Height = m_windowHeight;
    swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
    swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

    if (m_enable4xMsaa)
    {
        swapChainDesc.SampleDesc.Count = 4;
        swapChainDesc.SampleDesc.Quality = m4xMsaaQuality -1;
    }
    else
    {
        swapChainDesc.SampleDesc.Count = 1;
        swapChainDesc.SampleDesc.Quality = 0;
    }

    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.BufferCount = 1; //means double buffering
    swapChainDesc.OutputWindow = m_mainWindow;
    swapChainDesc.Windowed = true;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    swapChainDesc.Flags = 0;



    IDXGIDevice* dxgiDevice = 0;
    m_d3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));

    IDXGIAdapter* dxgiAdapter = 0;
    dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&dxgiAdapter));

    IDXGIFactory* dxgiFactory = 0;
    dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory));

    HRESULT hResultSwapChain = dxgiFactory->CreateSwapChain(m_d3dDevice, &swapChainDesc, &m_swapChain);

    dxgiDevice->Release();
    dxgiAdapter->Release();
    dxgiFactory->Release();


    if (FAILED(hResultSwapChain))
    {
        MessageBox(0, L"CreateSwapChain FAILED", 0, 0);
        return false;
    }
    



    //////////////////////////////////////
    // render target creation
    //////////////////////////////////////

    ID3D11Texture2D* backBufferTexture2D = 0;
    m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBufferTexture2D));
    HRESULT hResultRenderTarget = m_d3dDevice->CreateRenderTargetView(backBufferTexture2D, 0, &m_renderTargetView);

    backBufferTexture2D->Release();


    if (FAILED(hResultRenderTarget))
    {
        MessageBox(0, L"CreateRenderTargetView FAILED", 0, 0);
        return false;
    }




    //////////////////////////////////////
    // depth-stencil buffer creation
    //////////////////////////////////////

    D3D11_TEXTURE2D_DESC depthStencilBufferTexture2D;
    depthStencilBufferTexture2D.Width = m_windowWidth;
    depthStencilBufferTexture2D.Height = m_windowHeight;
    depthStencilBufferTexture2D.MipLevels = 1;
    depthStencilBufferTexture2D.ArraySize = 1;
    depthStencilBufferTexture2D.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;

    if (m_enable4xMsaa)
    {
        depthStencilBufferTexture2D.SampleDesc.Count = 4;
        depthStencilBufferTexture2D.SampleDesc.Quality = m4xMsaaQuality -1;
    }
    else
    {
        depthStencilBufferTexture2D.SampleDesc.Count = 1;
        depthStencilBufferTexture2D.SampleDesc.Quality = 0;
    }

    depthStencilBufferTexture2D.Usage = D3D11_USAGE_DEFAULT;
    depthStencilBufferTexture2D.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    depthStencilBufferTexture2D.CPUAccessFlags = 0;
    depthStencilBufferTexture2D.MiscFlags = 0;



    HRESULT hResultDepthStencil = m_d3dDevice->CreateTexture2D(&depthStencilBufferTexture2D, 0, &m_depthStencilBufferTexture2D);

    if (FAILED(hResultDepthStencil))
    {
        MessageBox(0, L"CreateTexture2D depthStencil FAILED", 0, 0);
        return false;
    }


    HRESULT hResultDepthStencilView = m_d3dDevice->CreateDepthStencilView(m_depthStencilBufferTexture2D, 0, &m_depthStencilBufferView);

    if (FAILED(hResultDepthStencilView))
    {
        MessageBox(0, L"CreateDepthStencilView FAILED", 0, 0);
        return false;
    }




    //////////////////////////////////////
    // viewport creation
    //////////////////////////////////////

    D3D11_VIEWPORT viewport;
    viewport.TopLeftX = 0;
    viewport.TopLeftY = 0;
    viewport.Width = float(m_windowWidth);
    viewport.Height = float(m_windowHeight);
    viewport.MinDepth = 0.0f;
    viewport.MaxDepth = 1.0f;

    m_d3dDeviceContext->RSSetViewports(1, &viewport);



    return true;
}

我很感激任何解决这个问题的提示!

提前致谢

编辑

到渲染管道只到达一个三角形,执行 VertexShader 但不执行 PixelShader,然后死掉......

4

1 回答 1

1

这可能不是唯一的问题,但您应该在将矩阵发送到着色器之前转置它们。您可以通过调用 XMMatrixTranspose(matrix) 来做到这一点。

(我现在看到有人已经提到了)

于 2013-06-09T19:48:37.230 回答