0

为 OpenGL ES 和 XNA 编程了一段时间后,我现在将我的一些内容更新到 XBOX One 的 DirectXTK。可悲的是,我刚刚遇到了另一个问题——即自定义着色器文件的集成。

特别是,我有以下顶点着色器:

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

struct VertexShaderInput
{
    float3 pos : POSITION;
};

struct PixelShaderInput
{
    float4 pos : SV_POSITION;
};

PixelShaderInput main(VertexShaderInput input)
{
    PixelShaderInput output;
    float4 pos = float4(input.pos, 1.0f);

    pos = mul(pos, model);
    pos = mul(pos, view);
    pos = mul(pos, projection);
    output.pos = pos;

    return output;
}

将其加载到 IEffectFactory 实现中可以正常工作。第一步,我使用 LoadAsync 加载编译后的 hlsl 文件:

void SUS3DApp1Main::SUSCreateDeviceResources()
{
    auto loadVSTask = DX::ReadDataAsync(L"SampleVertexShader.cso");
    auto loadPSTask = DX::ReadDataAsync(L"SamplePixelShader.cso");


    auto createVSTask = loadVSTask.then([this](const std::vector<byte>& fileData) {
        DX::ThrowIfFailed(
            m_deviceResources->GetD3DDevice()->CreateVertexShader(
                &fileData[0],
                fileData.size(),
                nullptr,
                &myVertexShader
            )
        );

        myVShaderCode = fileData.data();
        myVShaderCodeSize = fileData.size();
        myFlagVSUp = true;
    }); //VS hoch
    ...

两个变量 myVShaderCode 和 mVShaderCodeSize 然后被传递到 iEffect 的实际实现中,它像这样使用它们:

void SUS3DApp1::SUSEffect::GetVertexShaderBytecode(void const ** pShaderByteCode, size_t * pByteCodeLength)
{
    (*pByteCodeLength) = myVShaderCodeSize;
    (*pShaderByteCode) = myVShaderCode;
}

可悲的是,这在运行时不起作用。相反,在 SUS3DApp1.exe 中的 0x603520B5 (ucrtbased.dll) 处出现类型为未处理的异常的错误:将无效参数传递给认为无效参数致命的函数。被抛出。调用堆栈如下所示:

>   SUS3DApp1.exe!DirectX::ThrowIfFailed(HRESULT hr) Line 48    C++
    SUS3DApp1.exe!CreateInputLayout(ID3D11Device * device, DirectX::IEffect * effect, ID3D11InputLayout * * pInputLayout, bool skinning) Line 202   C++
    SUS3DApp1.exe!DirectX::Model::CreateFromCMO(ID3D11Device * d3dDevice, const unsigned char * meshData, unsigned int dataSize, DirectX::IEffectFactory & fxFactory, bool ccw, bool pmalpha) Line 796  C++
    SUS3DApp1.exe!DirectX::Model::CreateFromCMO(ID3D11Device * d3dDevice, const wchar_t * szFileName, DirectX::IEffectFactory & fxFactory, bool ccw, bool pmalpha) Line 848 C++
    SUS3DApp1.exe!SUSModel::SUSModel(ID3D11Device * _dev, std::basic_string<char,std::char_traits<char>,std::allocator<char> > & resource, const unsigned char * _myVShaderCode, int _myVShaderCodeSize) Line 15    C++
    SUS3DApp1.exe!SUS3DApp1::SUS3DApp1Main::SetUpShaderDependentResources() Line 62 C++
    SUS3DApp1.exe!SUS3DApp1::SUS3DApp1Main::Render() Line 148   C++

想法,有人吗?我已经检查了 GetVertexShaderBytecode 中成员变量的有效性...

更新:我现在更改了着色器,以及代码的加载。奇怪的是,这部分代码现在通过了 SUSCreateDeviceResources 内部的 CreateInputLayout 阶段: void SUS3DApp1Main::SUSCreateDeviceResources() { auto loadVSTask = DX::ReadDataAsync(L"SampleVertexShader.cso"); auto loadPSTask = DX::ReadDataAsync(L"SamplePixelShader.cso");

    auto createVSTask = loadVSTask.then([this](const std::vector<byte>& fileData) {
        DX::ThrowIfFailed(
            m_deviceResources->GetD3DDevice()->CreateVertexShader(
                &fileData[0],
                fileData.size(),
                nullptr,
                &myVertexShader
            )
        );



        myVShaderCode = &fileData[0];
        myVShaderCodeSize = fileData.size();
        Microsoft::WRL::ComPtr<ID3D11InputLayout>       il;
        DX::ThrowIfFailed(
            m_deviceResources->GetD3DDevice()->CreateInputLayout(VertexPositionNormal::InputElements,
                VertexPositionNormal::InputElementCount,
                myVShaderCode, myVShaderCodeSize,
                &il)
        );
        myFlagVSUp = true;

    }); //VS hoch

然后在创建模型期间出现问题,它再次成为无效参数。这很奇怪,因为之前的创作效果很好。会不会是 myVShaderCode 的值丢失了?

4

0 回答 0