C++ 三角形不显示direct3d11

C++ 三角形不显示direct3d11,c++,direct3d11,C++,Direct3d11,我正在尝试绘制一个三角形,作为我正在开发的游戏引擎的第一步,以下是图形系统的代码: 图形.hpp #pragma once #include "Engine.hpp" #include <type_traits> #include <codecvt> #include "Window.hpp" #include "Shader.hpp" namespace engine::graphics { c

我正在尝试绘制一个三角形,作为我正在开发的游戏引擎的第一步,以下是图形系统的代码:

图形.hpp

#pragma once

#include "Engine.hpp"

#include <type_traits>
#include <codecvt>

#include "Window.hpp"
#include "Shader.hpp"

namespace engine::graphics
{
    class GraphicsData final
    {
    public:
        logger::Logger* logger;

        Window* window;
        const std::string engineName;
        bool fullScreen;
    };

    class Graphics
    {
    public:
        virtual bool createGraphics(const GraphicsData& data) = 0;
        virtual void destroyGraphics() = 0;

        virtual void clearFrame() = 0;
        virtual void drawVertexes(const std::vector<std::any>& vertexes) = 0;
        virtual void presentFrame() = 0;

        virtual Graphics& loadShader(const std::string& shaderName, GraphicsShader* shader) = 0;
    };

#ifdef _WIN32
    struct DxVertex
    {
        DirectX::XMFLOAT3 m_Pos;
    };

    class DxGraphics final : public Graphics
    {
        ID3D11Device* m_Device;
        ID3D11DeviceContext* m_Context;
        IDXGISwapChain* m_Swapchain;
        ID3D11RasterizerState* m_RState;
        ID3D11RenderTargetView* m_RenderTargetView;
        ID3D11InputLayout* m_InputLayout;

        D3D_FEATURE_LEVEL m_FeatureLevel;
        D3D11_VIEWPORT m_Viewport;

        std::map<std::string, GraphicsShader*> m_GraphicsShaders;

        std::shared_ptr<logger::Logger> m_Logger;
        
        DXGI_SWAP_CHAIN_DESC GetDesc(
            Window* window,
            bool windowed
        );

    public:
        bool createGraphics(const GraphicsData& data) override;
        void destroyGraphics() override;

        void clearFrame() override;
        void drawVertexes(const std::vector<std::any>& vertexes) override;
        void presentFrame() override;

        Graphics& loadShader(const std::string& shaderName, GraphicsShader* shader) override;
    };
#endif
}
#pragma一次
#包括“Engine.hpp”
#包括
#包括
#包括“Window.hpp”
#包括“Shader.hpp”
名称空间引擎::图形
{
班级图形数据期末考试
{
公众:
记录器::记录器*记录器;
窗口*窗口;
常量std::字符串引擎名;
全屏;
};
类图形
{
公众:
虚拟布尔createGraphics(常量图形数据和数据)=0;
虚拟图形()=0;
虚空clearFrame()=0;
虚拟虚空绘制顶点(const std::vector&vertex)=0;
虚拟void presentFrame()=0;
虚拟图形和加载着色器(const std::string和shaderName,graphicshader*shader)=0;
};
#ifdef_WIN32
结构顶点
{
DirectX::XMFLOAT3 m_Pos;
};
DxGraphics类期末考试:公共图形
{
ID3D11设备*m_设备;
ID3D11DeviceContext*m_上下文;
IDXGISwapChain*m_Swapchain;
ID3D11光栅化状态*Mrstate;
ID3D11RenderTargetView*m_RenderTargetView;
ID3D11输入布局*m_输入布局;
D3D_特征级m_特征级;
D3D11_视口m_视口;
标准::地图m_图形阴影;
std::共享_ptr m_记录器;
DXGI交换链描述GetDesc(
窗口*窗口,
布尔开窗
);
公众:
布尔createGraphics(常量图形数据和数据)覆盖;
void()覆盖;
void clearFrame()覆盖;
无效绘制顶点(常量标准::向量和顶点)覆盖;
void presentFrame()覆盖;
Graphics&loadShader(const std::string&shaderName,GraphicsShader*着色器)覆盖;
};
#恩迪夫
}
graphics.cpp

#include "Graphics.hpp"

DXGI_SWAP_CHAIN_DESC engine::graphics::DxGraphics::GetDesc(Window* window, bool windowed)
{
    RECT rect{};
    GetClientRect(std::any_cast<HWND>(window->getWindowHandle()), &rect);

    DXGI_SWAP_CHAIN_DESC desc{
        .BufferDesc = DXGI_MODE_DESC{
            .Width = static_cast<unsigned int>(rect.right - rect.left),
            .Height = static_cast<unsigned int>(rect.bottom - rect.top),
            .RefreshRate = DXGI_RATIONAL{
                .Numerator = 60, // TODO: fix this
                .Denominator = 1
            },
            .Format = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM,
            .ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER::DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE,
            .Scaling = DXGI_MODE_SCALING::DXGI_MODE_SCALING_CENTERED
        },
        .SampleDesc = DXGI_SAMPLE_DESC{
            .Count = 1,
            .Quality = 0
        },
        .BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
        .BufferCount = 2,
        .OutputWindow = std::any_cast<HWND>(window->getWindowHandle()),
        .Windowed = windowed,
        .SwapEffect = DXGI_SWAP_EFFECT::DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
        .Flags = 0
    };

    return desc;
}

bool engine::graphics::DxGraphics::createGraphics(const GraphicsData& data)
{
    m_Logger.reset(data.logger);

    unsigned int flags = D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifdef _DEBUG
    flags |= D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG;
#endif // _DEBUG

    D3D_FEATURE_LEVEL featureLevel[] = {
        D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_1
    };

    DXGI_SWAP_CHAIN_DESC desc = GetDesc(data.window, !data.fullScreen);

    HRESULT hr;

    hr = D3D11CreateDeviceAndSwapChain(
        nullptr,
        D3D_DRIVER_TYPE::D3D_DRIVER_TYPE_HARDWARE,
        nullptr,
        flags,
        featureLevel,
        2,
        D3D11_SDK_VERSION,
        &desc,
        &m_Swapchain,
        &m_Device,
        &m_FeatureLevel,
        &m_Context
    );
    if (FAILED(hr))
    {
        *m_Logger << logger::Message{
            .type = logger::Message::Type::CLIENT,
            .severity = logger::Message::Severity::ERR,
            .data = "Failed to create device and swapchain"
        };
        return false;
    }

    ID3D11Texture2D* texture = nullptr;
    hr = m_Swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&texture));
    if (FAILED(hr))
    {
        *m_Logger << logger::Message{
            .type = logger::Message::Type::CLIENT,
            .severity = logger::Message::Severity::ERR,
            .data = "Failed to collect backbuffer used for rendering"
        };
        return false;
    }

    hr = m_Device->CreateRenderTargetView(texture, nullptr, &m_RenderTargetView);

    if (texture)
        texture->Release();

    if (FAILED(hr))
    {
        *m_Logger << logger::Message{
            .type = logger::Message::Type::CLIENT,
            .severity = logger::Message::Severity::ERR,
            .data = "Failed to set render target view"
        };
        return false;
    }

    m_Context->OMSetRenderTargets(1, &m_RenderTargetView, nullptr);

    m_Viewport = {
        .TopLeftX = 0,
        .TopLeftY = 0,
        .Width = static_cast<float>(desc.BufferDesc.Width),
        .Height = static_cast<float>(desc.BufferDesc.Height),
        .MinDepth = 0,
        .MaxDepth = 1
    };

    D3D11_RASTERIZER_DESC rsDesc{
        .FillMode = D3D11_FILL_MODE::D3D11_FILL_SOLID,
        .CullMode = D3D11_CULL_MODE::D3D11_CULL_BACK,
        .FrontCounterClockwise = true,
        .DepthBias = 0,
        .DepthBiasClamp = 1,
        .SlopeScaledDepthBias = 0,
        .DepthClipEnable = true,
        .ScissorEnable = false,
        .MultisampleEnable = false,
        .AntialiasedLineEnable = false
    };

    m_Device->CreateRasterizerState(
        &rsDesc,
        &m_RState
    );

    m_Context->RSSetState(
        m_RState
    );
    m_Context->RSSetViewports(1, &m_Viewport);

    return true;
}

void engine::graphics::DxGraphics::clearFrame()
{
    float color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
    m_Context->ClearRenderTargetView(m_RenderTargetView, color);

    m_Context->RSSetState(m_RState);
    m_Context->RSSetViewports(1, &m_Viewport);

    m_Context->OMSetRenderTargets(1, &m_RenderTargetView, nullptr);
}

void engine::graphics::DxGraphics::drawVertexes(const std::vector<std::any>& vertexes)
{
    HRESULT hr;

    ID3D11Buffer* buffer;

    D3D11_INPUT_ELEMENT_DESC shaderInputLayout[] = {
        D3D11_INPUT_ELEMENT_DESC{
            .SemanticName = "POSITION",
            .SemanticIndex = 0,
            .Format = DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT,
            .InputSlot = 0,
            .AlignedByteOffset = 0,
            .InputSlotClass = D3D11_INPUT_CLASSIFICATION::D3D11_INPUT_PER_VERTEX_DATA,
            .InstanceDataStepRate = 0
        }
    };
    UINT numLayoutElements = ARRAYSIZE(shaderInputLayout);

    hr = m_Device->CreateInputLayout(
        shaderInputLayout,
        numLayoutElements,
        m_GraphicsShaders.at("vertex")->getShaderCode(),
        m_GraphicsShaders.at("vertex")->getShaderCodeSize(),
        &m_InputLayout
    );
    if (FAILED(hr))
    {
        *m_Logger << logger::Message{
            .type = logger::Message::Type::CLIENT,
            .severity = logger::Message::Severity::ERR,
            .data = "Failed to create input layout"
        };
        return;
    }

    m_Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    m_Context->IASetInputLayout(m_InputLayout);

    UINT byteWidth = sizeof(DxVertex) * vertexes.size();

    D3D11_BUFFER_DESC desc{};
    desc.Usage = D3D11_USAGE::D3D11_USAGE_DEFAULT;
    desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    desc.ByteWidth = byteWidth;
    desc.StructureByteStride = sizeof(DxVertex);

    D3D11_SUBRESOURCE_DATA resource{};
    resource.pSysMem = vertexes.data();

    hr = m_Device->CreateBuffer(
        &desc,
        &resource,
        &buffer
    );
    if (FAILED(hr))
    {
        if (buffer)
            buffer->Release();

        *m_Logger << logger::Message{
               .type = logger::Message::Type::CLIENT,
               .severity = logger::Message::Severity::ERR,
               .data = "Failed to create vertex buffer"
        };
        return;
    }

    UINT strides = sizeof(DxVertex);
    UINT offset = 0;

    m_Context->IASetVertexBuffers(0, 1, &buffer, &strides, &offset);

    m_Context->VSSetShader(static_cast<ID3D11VertexShader*>(m_GraphicsShaders.at("vertex")->getShader()), nullptr, 0);
    m_Context->PSSetShader(static_cast<ID3D11PixelShader*>(m_GraphicsShaders.at("pixel")->getShader()), nullptr, 0);

    UINT numVertexes = vertexes.size();

    m_Context->Draw(numVertexes, 0);

    if (buffer)
        buffer->Release();

    if (m_InputLayout)
        m_InputLayout->Release();
}

void engine::graphics::DxGraphics::presentFrame()
{
    m_Swapchain->Present(0, 0);
}

engine::graphics::Graphics& engine::graphics::DxGraphics::loadShader(const std::string& shaderName, GraphicsShader* shader)
{
    DxGraphicsShaderData data{
        .device = m_Device,
        .context = m_Context
    };
    data.logger = m_Logger.get();
    shader->createShader(data);
    m_GraphicsShaders.insert(std::make_pair(shaderName, shader));

    return *this;
}

void engine::graphics::DxGraphics::destroyGraphics()
{
    for (auto& shader : m_GraphicsShaders)
    {
        shader.second->destroyShader();
        delete shader.second;
    }
    if (m_RenderTargetView)
    {
        m_RenderTargetView->Release();
    }
    if (m_Swapchain)
    {
        m_Swapchain->Release();
    }
    if (m_Context)
    {
        m_Context->Release();
    }
    if (m_Device)
    {
        m_Device->Release();
    }
}
#包括“Graphics.hpp”
DXGI_交换_链_描述引擎::图形::DxGraphics::GetDesc(窗口*窗口,布尔窗口)
{
RECT{};
GetClientRect(std::any_cast(窗口->getWindowHandle()),&rect);
DXGI交换链描述描述{
.BufferDesc=DXGI\u MODE\u DESC{
.Width=静态施法(右正-左正),
.高度=静态铸件(垂直底部-垂直顶部),
.RefreshRate=DXGI\u RATIONAL{
.Numerator=60,//TODO:修复此问题
.分母=1
},
.Format=DXGI_Format::DXGI_Format_R8G8B8A8_UNORM,
.ScanlineOrdering=DXGI\u MODE\u SCANLINE\u ORDER::DXGI\u MODE\u SCANLINE\u ORDER\u PROGRESSIVE,
.Scaling=DXGI\u MODE\u Scaling::DXGI\u MODE\u Scaling\u CENTERED
},
.SampleDesc=DXGI\u SAMPLE\u DESC{
.Count=1,
.质量=0
},
.BufferUsage=DXGI\u USAGE\u RENDER\u TARGET\u输出,
.BufferCount=2,
.OutputWindow=std::任意_转换(窗口->getWindowHandle()),
.Windowed=加窗,
.SwapEffect=DXGI\u SWAP\u EFFECT::DXGI\u SWAP\u EFFECT\u FLIP\u SEQUENTIAL,
.Flags=0
};
返回描述;
}
布尔引擎::图形::DxGraphics::createGraphics(常量图形数据和数据)
{
m_Logger.reset(数据记录器);
unsigned int flags=D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifdef_调试
标志|=D3D11_创建_设备_标志::D3D11_创建_设备_调试;
#endif/\u调试
D3D_功能_级别功能级别[]={
D3D_功能等级::D3D_功能等级11_0,
D3D_功能等级::D3D_功能等级11_1
};
DXGI\u SWAP\u CHAIN\u DESC DESC=GetDesc(data.window,!data.fullScreen);
HRESULT-hr;
hr=D3D11创建设备和交换链(
nullptr,
D3D_驱动程序类型::D3D_驱动程序类型硬件,
nullptr,
旗帜,
功能级别,
2.
D3D11_SDK_版本,
&描述,
&m_Swapchain,
&m_装置,
&m_功能级别,
&m_语境
);
如果(失败(小时))
{
*m_Logger GetBuffer(0,uu uuidof(ID3D11Texture2D),重新解释强制转换(&texture));
如果(失败(小时))
{
*m_Logger CreateRenderTargetView(纹理、nullptr和m_RenderTargetView);
如果(纹理)
纹理->释放();
如果(失败(小时))
{
*m_Logger OMSetRenderTargets(1,&m_RenderTargetView,nullptr);
m_视口={
.TopLeftX=0,
.TopLeftY=0,
.Width=静态施法(描述缓冲描述宽度),
.Height=静态铸件(描述缓冲描述高度),
.MinDepth=0,
.MaxDepth=1
};
D3D11光栅化器描述rsDesc{
.FillMode=D3D11_FILL_MODE::D3D11_FILL_SOLID,
.CullMode=D3D11\u CULL\u MODE::D3D11\u CULL\u BACK,
.front逆时针=真,
.DepthBias=0,
.DepthBiasClamp=1,
.SlopeScaledDepthBias=0,
.DepthClipEnable=true,
.ScissorEnable=错误,
.MultisampleEnable=false,
.AntialiasedLineEnable=false
};
m_设备->CreateRasterizerState(
&rsDesc,
&穆尔斯塔
);
m_Context->RSSetState(
穆尔斯塔
);
m_上下文->RSSETViewport(1,&m_视口);
返回true;
}
void引擎::图形::DxGraphics::clearFrame()
{
浮动颜色[4]={0.0f,0.0f,0.0f,1.0f};
m_上下文->ClearRenderTargetView(m_RenderTargetView,颜色);
m_Context->RSSetState(m_RState);
m_上下文->RSSETViewport(1,&m_视口);
m_Context->OMSetRenderTargets(1,&m_RenderTargetView,nullptr);
}
void引擎::图形::DxGraphics::绘图顶点(常量std::向量和顶点)
{
HRESULT-hr;
ID3D11Buffer*缓冲区;
D3D11_输入_元素_描述着色器布局[]={
D3D11输入元素描述{
.SemanticName=“位置”,
.SemanticIndex=0,
.Format=DXGI\u格式::DXGI\u格式\u R32G32B32\u浮点,
.InputSlot=0,
.AlignedByteOffset=0,
.InputSlotClass=D3D11_输入_分类::D3D11_输入_逐顶点_数据,
.InstanceDataStepRate=0
}
};
#pragma once

#include "Engine.hpp"

#include "Logger.hpp"

namespace engine::graphics
{
    struct GraphicsShaderData
    {
        logger::Logger* logger;
    };

    class GraphicsShader
    {
    public:
        virtual bool createShader(const GraphicsShaderData& data) = 0;
        virtual void destroyShader() = 0;

        virtual const char* getShaderCode() = 0;
        virtual size_t getShaderCodeSize() = 0;

        virtual void* getShader() = 0;
    };

#ifdef _WIN32
    struct DxGraphicsShaderData final : public GraphicsShaderData
    {
        ID3D11Device* device;
        ID3D11DeviceContext* context;
    };

    template<typename T>
    class DxGraphicsShader final : public GraphicsShader
    {
    };

    template<>
    class DxGraphicsShader<ID3D11VertexShader> final : public GraphicsShader
    {
        ID3DBlob* m_Code;
        ID3D11VertexShader* m_Shader;

    public:
        bool createShader(const GraphicsShaderData& data) override
        {
            const DxGraphicsShaderData& dxdata = static_cast<const DxGraphicsShaderData&>(data);

            int flags = D3DCOMPILE_ENABLE_STRICTNESS;
#ifdef _DEBUG
            flags |= D3DCOMPILE_DEBUG;
#endif // _DEBUG
            HRESULT hr;
            ID3DBlob* errBuff;

            hr = D3DCompileFromFile(
                std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes(
                    "vertex.hlsl" // TODO: fix with resource manager
                ).c_str(),
                nullptr,
                nullptr,
                "VMain",
                "vs_5_0",
                flags,
                0,
                &m_Code,
                &errBuff
            );

            if (FAILED(hr))
            {
                if (errBuff)
                {
                    *dxdata.logger << logger::Message{
                        .type = logger::Message::Type::CLIENT,
                        .severity = logger::Message::Severity::ERR,
                        .data = static_cast<char*>(errBuff->GetBufferPointer())
                    };
                    errBuff->Release();
                }

                return false;
            }

            if (errBuff)
                errBuff->Release();

            hr = dxdata.device->CreateVertexShader(
                m_Code->GetBufferPointer(),
                m_Code->GetBufferSize(),
                0,
                &m_Shader
            );
            if (FAILED(hr))
            {
                if (m_Code)
                    m_Code->Release();

                return false;
            }

            dxdata.context->VSSetShader(
                m_Shader,
                nullptr,
                0
            );

            return true;
        }
        void destroyShader() override
        {
            if (m_Shader)
                m_Shader->Release();

            if (m_Code)
                m_Code->Release();
        }

        const char* getShaderCode()
        {
            return static_cast<char*>(m_Code->GetBufferPointer());
        }
        size_t getShaderCodeSize()
        {
            return m_Code->GetBufferSize();
        }

        void* getShader() override
        {
            return m_Shader;
        }
    };

    template<>
    class DxGraphicsShader<ID3D11PixelShader> final : public GraphicsShader
    {
        ID3DBlob* m_Code;
        ID3D11PixelShader* m_Shader;

    public:
        bool createShader(const GraphicsShaderData& data) override
        {
            const DxGraphicsShaderData& dxdata = static_cast<const DxGraphicsShaderData&>(data);

            int flags = D3DCOMPILE_ENABLE_STRICTNESS;
#ifdef _DEBUG
            flags |= D3DCOMPILE_DEBUG;
#endif // _DEBUG
            HRESULT hr;
            ID3DBlob* errBuff;

            hr = D3DCompileFromFile(
                std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes(
                    "pixel.hlsl" // TODO: fix with resource manager
                ).c_str(),
                nullptr,
                nullptr,
                "PMain",
                "ps_5_0",
                flags,
                0,
                &m_Code,
                &errBuff
            );

            if (FAILED(hr))
            {
                if (errBuff)
                {
                    *dxdata.logger << logger::Message{
                        .type = logger::Message::Type::CLIENT,
                        .severity = logger::Message::Severity::ERR,
                        .data = static_cast<char*>(errBuff->GetBufferPointer())
                    };
                    errBuff->Release();
                }

                return false;
            }

            if (errBuff)
                errBuff->Release();

            hr = dxdata.device->CreatePixelShader(
                m_Code->GetBufferPointer(),
                m_Code->GetBufferSize(),
                0,
                &m_Shader
            );
            if (FAILED(hr))
            {
                if (m_Code)
                    m_Code->Release();

                return false;
            }

            dxdata.context->PSSetShader(
                m_Shader,
                nullptr,
                0
            );

            return true;
        }
        void destroyShader() override
        {
            if (m_Shader)
                m_Shader->Release();

            if (m_Code)
                m_Code->Release();
        }

        const char* getShaderCode()
        {
            return static_cast<char*>(m_Code->GetBufferPointer());
        }
        size_t getShaderCodeSize()
        {
            return m_Code->GetBufferSize();
        }

        void* getShader() override
        {
            return m_Shader;
        }
    };
#endif // _WIN32
}