简体   繁体   English

Directx 11渲染问题,未显示三角形

[英]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. 我正在学习DirectX 11,并且试图呈现一个简单的多维数据集,不幸的是我的代码无法正常工作,它根本无法呈现任何内容…… 没有错误没有警告 ……唯一显示的是窗口具有指定的透明颜色。 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): 这就是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();
}

The VertexShader is really simple, it only does the world-view-projection transformation: 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;
}

The PixelShader is even simpler: 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;
}

As mentioned above the basic components of Directx are created by the super class (DirectxApp), here's the code: 如上所述,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;
}

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... 到渲染管线仅到达一个三角形时, 将执行VertexShader而不是PixelShader ,然后死掉...

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 ). 您可以通过调用XMMatrixTranspose(matrix)来实现。

(I see now that someone already mentioned it) (我现在看到有人已经提到了它)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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