DirectXTK: пользовательский шейдер не рисует
Возвращаясь к моим HLSL-экспериментам с DirectXTK, я наткнулся на нечто действительно странное. Прежде всего, мне удалось интегрировать свой класс эффектов в подсистему IEX DirectXTKs следующим образом:
#include "pch.h"
#include "TmgnEffect.h"
using namespace Tmgn3DApp1;
using namespace Windows::Foundation;
using namespace Windows::System::Threading;
using namespace Concurrency;
TmgnEffect::TmgnEffect(const byte* _myVShaderCode, int _myVShaderCodeSize, Tmgn3DApp1Main* _thisRef)
{
myVShaderCode = _myVShaderCode;
myVShaderCodeSize = _myVShaderCodeSize;
myThisRef = _thisRef;
}
// Helper sets our shaders and constant buffers onto the D3D device.
void TmgnEffect::ApplyShaders(_In_ ID3D11DeviceContext* deviceContext)
{
// Set shaders.
auto vertexShader = myThisRef->myVertexShader;
auto pixelShader = myThisRef->myPixelShader;
deviceContext->VSSetShader(vertexShader.Get(), nullptr, 0);
deviceContext->PSSetShader(pixelShader.Get(), nullptr, 0);
#if defined(_XBOX_ONE) && defined(_TITLE)
void *grfxMemory;
mConstantBuffer.SetData(deviceContext, constants, &grfxMemory);
Microsoft::WRL::ComPtr<ID3D11DeviceContextX> deviceContextX;
ThrowIfFailed(deviceContext->QueryInterface(IID_GRAPHICS_PPV_ARGS(deviceContextX.GetAddressOf())));
auto buffer = mConstantBuffer.GetBuffer();
deviceContextX->VSSetPlacementConstantBuffer(0, buffer, grfxMemory);
deviceContextX->PSSetPlacementConstantBuffer(0, buffer, grfxMemory);
#else
// Make sure the constant buffer is up to date.
//dirtyFlags &= ~EffectDirtyFlags::ConstantBuffer;
XMStoreFloat4x4(&myConstantBufferData.view, view);
//XMStoreFloat4x4(&myConstantBufferData.model, world);
XMStoreFloat4x4(&myConstantBufferData.projection, projection);
// Set the constant buffer.
auto context = myThisRef->m_deviceResources->GetD3DDeviceContext();
// Prepare the constant buffer to send it to the graphics device.
CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
DX::ThrowIfFailed(
myThisRef->m_deviceResources->GetD3DDevice()->CreateBuffer(
&constantBufferDesc,
nullptr,
&m_constantBuffer
)
);
context->UpdateSubresource1(
m_constantBuffer.Get(),
0,
NULL,
&myConstantBufferData,
0,
0,
0
);
deviceContext->VSSetConstantBuffers(0, 1, &m_constantBuffer);
deviceContext->PSSetConstantBuffers(0, 1, &m_constantBuffer);
#endif
}
void Tmgn3DApp1::TmgnEffect::Apply(ID3D11DeviceContext * deviceContext)
{
//matrices.SetConstants(dirtyFlags, constants.worldViewProj);
// Set shaders and constant buffers.
ApplyShaders(deviceContext);
}
void Tmgn3DApp1::TmgnEffect::GetVertexShaderBytecode(void const ** pShaderByteCode, size_t * pByteCodeLength)
{
(*pByteCodeLength) = myVShaderCodeSize;
(*pShaderByteCode) = myVShaderCode;
}
void XM_CALLCONV Tmgn3DApp1::TmgnEffect::SetWorld(FXMMATRIX value)
{
world = value;
}
void XM_CALLCONV Tmgn3DApp1::TmgnEffect::SetView(FXMMATRIX value)
{
view = value;
}
void XM_CALLCONV Tmgn3DApp1::TmgnEffect::SetProjection(FXMMATRIX value)
{
projection = value;
}
void XM_CALLCONV Tmgn3DApp1::TmgnEffect::SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection)
{
SetWorld(world);
SetView(view);
SetProjection(projection);
}
К сожалению, модели не нарисованы. Если я заменю фабрику эффектов на BasicEffect, все будет работать. Я уже проверил, никакие исключения не генерируются во время инициализации, и размещение (сложного) бесконечного цикла в Vertex Shader приводит к зависанию программы. Кстати, вот код для этого бесконечного цикла:
float i = 1;
while ( i == 1)
{
i++;
//Real Code here
i--;
}
Короче, у меня такое ощущение, что некоторые данные отсутствуют. Может у кого есть идеи что искать?
РЕДАКТИРОВАТЬ, чтобы добавить шейдеры. Вершинный шейдер:
cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
matrix model;
matrix view;
matrix projection;
};
struct VertexShaderInput
{
float3 pos : SV_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;
}
PIXEL шейдер:
struct PixelShaderInput
{
float4 pos : SV_POSITION;
};
float4 main(PixelShaderInput input) : SV_TARGET
{
return float4(0.1f, 0.1f, 0.1f, 1.0f);
}