简体   繁体   中英

Directx 11 rendering issue, no triangle displayed

I'm learning DirectX 11 and I'm trying to render a simple cube, unfortunately my code doesn't work, it simply doesn't render nothing... no errors , no warnings ... The only thing displayed is the window with the specified clear color. I'm also very sure that the code is executed entirely.

This is the header of my specialized class:

#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);
};

And this is the cpp (the init method of the super class initializes the window and the basic components of DirectX, see later):

#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();
}

The VertexShader is really simple, it only does the world-view-projection transformation:

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;
}

The PixelShader is even simpler:

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

As mentioned above the basic components of Directx are created by the super class (DirectxApp), here's the code:

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;
}

I appreciate any hint to solve this problem!

Thanks in advance

EDIT

To the rendering pipeline arrives only one triangle, the VertexShader is executed but not the PixelShader , and then dies...

It may not be the only problem, but you should transpose the matrices before sending them to the shader. You can do that by calling XMMatrixTranspose( matrix ).

(I see now that someone already mentioned it)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM