可以弹出多维数据集DirectX 11多维数据集未显示,仅屏幕被清除

问题描述

我正在尝试制作一个简单的d3d11程序来旋转多维数据集。 但最终似乎没有出现多维数据集。 仅将屏幕清除为蓝色,但不显示多维数据集。 我一直以此为来源:https://docs.microsoft.com/en-us/windows/win32/direct3dgetstarted/getting-started-with-a-directx-game

我的项目结构是 MainClass.cpp,MainClass.h(处理窗口初始化) DeviceResources.cpp,DeviceResources.h(设备资源包括设备,上下文等) Renderer.cpp,Renderer.h(渲染器加载几何和着色器。很可能这是我要出错的地方)

这是我的Renderer.h:

#pragma once
#include <memory>
#include <Windows.h>
#include <directxmath.h>
#include "DeviceResources.h"
class Renderer
{
public:
    Renderer(std::shared_ptr<DeviceResources> deviceResources);
    ~Renderer();
    void CreateDeviceDependentResources();
    void CreateWindowSizeDependentResources();
    void Update();
    void Render();
private:
    HRESULT CreateShaders();
    HRESULT CreateCube();
    void CreateViewAndPerspective();

    bool m_done = false;

    std::shared_ptr<DeviceResources> m_deviceResources;

    typedef struct _constantBufferStruct {
        DirectX::XMFLOAT4X4 world;
        DirectX::XMFLOAT4X4 view;
        DirectX::XMFLOAT4X4 projection;
    } ConstantBufferStruct;
    static_assert((sizeof(ConstantBufferStruct) % 16) == 0,"Constant Buffer size must be 16-byte aligned");

    typedef struct _vertexPositionColor {
        DirectX::XMFLOAT3 pos;
        DirectX::XMFLOAT3 color;
    } VertexPositionColor;

    typedef struct _vertexPositionColorTangent {
        DirectX::XMFLOAT3 pos;
        DirectX::XMFLOAT3 color;
        DirectX::XMFLOAT3 tangent;
    } VertexPositionColorTangent;

    ConstantBufferStruct m_constantBufferData;
    unsigned int m_indexCount;
    unsigned int m_frameCount;

    Microsoft::WRL::ComPtr<ID3D11Buffer> m_pVertexBuffer;
    Microsoft::WRL::ComPtr<ID3D11Buffer> m_pIndexBuffer;
    Microsoft::WRL::ComPtr<ID3D11VertexShader> m_pVertexShader;
    Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pPixelShader;
    Microsoft::WRL::ComPtr<ID3D11InputLayout> m_pInputLayout;
    Microsoft::WRL::ComPtr<ID3D11InputLayout> m_pInputLayoutExtended;
    Microsoft::WRL::ComPtr<ID3D11Buffer> m_pConstantBuffer;
};

这是我的Renderer.cpp代码

#include "Renderer.h"

#include <fstream>
#include <ppltasks.h>
#include <stdexcept>

Renderer::Renderer(std::shared_ptr<DeviceResources> deviceResources) :
    m_deviceResources(deviceResources),m_frameCount(0)
{
    m_frameCount = 0;
}

Renderer::~Renderer() {}

void Renderer::CreateDeviceDependentResources() {
    auto CreateShaderTask = Concurrency::create_task([this]() {CreateShaders(); 
    m_done = true;
    });
    auto CreateCubeTask = CreateShaderTask.then([this]() {CreateCube(); });
}

void Renderer::CreateWindowSizeDependentResources() {
    CreateViewAndPerspective();
}

HRESULT Renderer::CreateShaders() {

    HRESULT hr = S_OK;

    ID3D11Device* device = m_deviceResources->GetDevice();
    FILE* vShader,* pShader;
    BYTE* bytes;

    size_t destSize = 4096;
    size_t bytesRead = 0;

    bytes = new BYTE[destSize];

    fopen_s(&vShader,"cubeVertexShader.cso","rb");
    bytesRead = fread_s(bytes,destSize,1,4096,vShader);
    hr = device->CreateVertexShader(
        bytes,bytesRead,nullptr,&m_pVertexShader
    );

    D3D11_INPUT_ELEMENT_DESC iaDesc[] =
    {
    { "POSITION",dxgi_FORMAT_R32G32B32_FLOAT,D3D11_INPUT_PER_VERTEX_DATA,0 },{ "COLOR",12,};

    hr = device->CreateInputLayout(iaDesc,ARRAYSIZE(iaDesc),bytes,&m_pInputLayout);
    delete bytes;

    bytes = new BYTE[destSize];
    bytesRead = 0;
    fopen_s(&pShader,"cubePixelShader.cso",pShader);
    hr = device->CreatePixelShader(bytes,&m_pPixelShader);

    CD3D11_BUFFER_DESC cbDesc(sizeof(ConstantBufferStruct),D3D11_BIND_CONSTANT_BUFFER );
    hr = device->CreateBuffer(&cbDesc,&m_pConstantBuffer);
    if (Failed(hr))
        throw std::exception("Failed to Create Constant Buffer");
    fclose(vShader);
    fclose(pShader);
    return hr;
}

HRESULT Renderer::CreateCube() {
    HRESULT hr = S_OK;
    ID3D11Device* device = m_deviceResources->GetDevice();
    VertexPositionColor CubeVertices[] =
    {
    {DirectX::XMFLOAT3(-0.5f,-0.5f,-0.5f),DirectX::XMFLOAT3(0,0),},{DirectX::XMFLOAT3(-0.5f,0.5f),1),0.5f,{DirectX::XMFLOAT3(0.5f,DirectX::XMFLOAT3(1,};

    unsigned short CubeIndices[] =
    {
    0,2,// -x
    1,3,4,5,6,// +x
    5,7,// -y
    0,// +y
    2,// -z
    0,// +z
    1,};
    m_indexCount = ARRAYSIZE(CubeIndices);

    CD3D11_BUFFER_DESC vbDesc(sizeof(CubeVertices),D3D11_BIND_VERTEX_BUFFER);
    D3D11_SUBRESOURCE_DATA vData;
    ZeroMemory(&vData,sizeof(D3D11_SUBRESOURCE_DATA));
    vData.pSysMem = CubeVertices;
    vData.SysMemPitch = 0;
    vData.SysMemSlicePitch = 0;
    hr = device->CreateBuffer(&vbDesc,&vData,&m_pVertexBuffer);

    CD3D11_BUFFER_DESC ibDesc(sizeof(CubeIndices),D3D11_BIND_INDEX_BUFFER);
    D3D11_SUBRESOURCE_DATA iData;
    ZeroMemory(&iData,sizeof(D3D11_SUBRESOURCE_DATA));
    iData.pSysMem = CubeIndices;
    iData.SysMemPitch = 0;
    iData.SysMemSlicePitch = 0;
    hr = device->CreateBuffer(&ibDesc,&iData,&m_pIndexBuffer);


    return hr;
}

void Renderer::CreateViewAndPerspective() {
    // Use directxmath to create view and perspective matrices.
    DirectX::XMVECTOR eye = DirectX::XMVectorSet(0.0f,0.7f,1.5f,0.f);
    DirectX::XMVECTOR at = DirectX::XMVectorSet(0.0f,-0.1f,0.0f,0.f);
    DirectX::XMVECTOR up = DirectX::XMVectorSet(0.0f,1.0f,0.f);
    DirectX::xmstoreFloat4x4(
        &m_constantBufferData.view,DirectX::XMMatrixTranspose(
            DirectX::XMMatrixLookAtRH(
                eye,at,up
            )
        )
    );
    float aspectRatio = m_deviceResources->GetAspectRatio();
    DirectX::xmstoreFloat4x4(
        &m_constantBufferData.projection,DirectX::XMMatrixTranspose(
            DirectX::XMMatrixPerspectiveFovRH(
                DirectX::XMConvertToradians(70),aspectRatio,0.01f,100.0f
            )
        )
    );
}

void Renderer::Update() {
    DirectX::xmstoreFloat4x4(
        &m_constantBufferData.world,DirectX::XMMatrixTranspose(
            DirectX::XMMatrixRotationY(
                DirectX::XMConvertToradians(
                    (float)m_frameCount++
                )
            )
        )
    );
    if (m_frameCount == MAXUINT) m_frameCount = 0;
}

void Renderer::Render() {
    while (!m_done) {

    }
    ID3D11DeviceContext* context = m_deviceResources->GetDeviceContext();
    ID3D11rendertargetView* rendertarget = m_deviceResources->Getrendertarget();
    ID3D11DepthStencilView* depthStencil = m_deviceResources->GetDepthStencil();
    context->UpdateSubresource(m_pConstantBuffer.Get(),&m_constantBufferData,0);

    const float blue[4] = { 0.2f,0.3f,0.8f,1.0f};
    context->ClearrendertargetView(rendertarget,blue);
    context->ClearDepthStencilView(depthStencil,D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,0);

    context->OMSetrendertargets(1,&rendertarget,depthStencil);
    UINT stride = sizeof(VertexPositionColor);
    UINT offset = 0;
    context->IASetVertexBuffers(
        0,m_pVertexBuffer.GetAddressOf(),&stride,&offset
    );
    context->IASetIndexBuffer(m_pIndexBuffer.Get(),dxgi_FORMAT_R16_UINT,0);
    context->IASetPrimitivetopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    context->IASetInputLayout(m_pInputLayout.Get());
    context->VSSetShader(m_pVertexShader.Get(),0);
    context->VSSetConstantBuffers(0,m_pConstantBuffer.GetAddressOf());
    context->PSSetShader(m_pPixelShader.Get(),0);
    //context->DrawIndexed(m_indexCount,0);
    context->Draw(3,0);
}

有关更多信息,请参见以下着色器:- 顶点着色器

cbuffer ModelViewProjectionBuffer : register(b0)
{
    matrix model;
    matrix view;
    matrix projection;
};

float4 main(float3 Position:POSITION,float3 Color:COLOR) : SV_POSITION// main is the default function name
{
    float4 pos = float4(Position,1.0f);
    // Transform the position from object space to homogeneous projection space
    pos = mul(pos,model);
    pos = mul(pos,view);
    pos = mul(pos,projection);
    
    return pos;
}

像素着色器:

float4 main(float4 position:SV_POSITION) : SV_TARGET
{
    return float4(0.9f,0.4f,0.2f,1.0f);
}

Image of the output

请帮助我分析我要去哪里。 此外,我正在使用Visual Studio 2019。

编辑:有些人要求提供完整的复制品,因此这是Visual Studio解决方https://drive.google.com/file/d/1jt6fQgbRElpc9AYpbhYOyp-HCQL3WmEF/view?usp=sharing

解决方法

在读取顶点和像素缓冲区时,您正在执行无效的内存访问。

此外,在我的计算机上,两个着色器都有十几个KB,而您正在读取的着色器的内存缓冲区只有4096个字节。

要解决您的问题,请增加用于从磁盘读取着色器字节码的内存缓冲区的大小,并且不要忘记更新fread_s()中的elementcount。

例如

Renderer.cpp @ 35

    size_t destSize = 1024 * 1024; // CHANGE THE SIZE OF YOUR MEMORY BUFFER HERE
    size_t bytesRead = 0;

    bytes = new BYTE[destSize];

    fopen_s(&vShader,"cubeVertexShader.cso","rb");
    bytesRead = fread_s(bytes,destSize * sizeof(BYTE),sizeof(BYTE),destSize,vShader);
    hr = device->CreateVertexShader(
        bytes,bytesRead,nullptr,&m_pVertexShader
    );

在读取像素着色器的地方做同样的事情。

专业提示:注意调试输出,您将看到来自d3d调试层的重要消息,就像一个告诉您两个着色器均创建失败的消息:)