Я пишу приложение Windows-UWP на C#, в которое хочу включить трехмерный элемент управления. По этой причине я перенес программу, основанную на примере Visual Studio DirectX UWP, в UWP DLL. Однако при попытке загрузить включенные шейдеры программа завершается ошибкой, поскольку не может найти скомпилированные файлы шейдеров.
Сообщения на форуме, которые я видел до сих пор, предполагают, что ресурсы, такие как шейдеры, не будут доступны внутри контейнера AppX и что основной проект должен включать их. Таким образом, я попытался скопировать скомпилированные шейдеры в основной проект с настройками «Всегда копировать» и «Дополнительные файлы» или «Встроенный ресурс» соответственно, что также не сработало.
Код, в котором я пытаюсь загрузить шейдеры, выглядит так:
void Scene3DRenderer::CreateDeviceDependentResources()
{
// Load shader asynchronously
auto loadVSTask = DX::ReadDataAsync(L"SampleVertexShader.cso");
auto createVSTask = loadVSTask.then([this](const std::vector<byte>& fileData) {
// Creating the vertex shader on the graphics device
});
// some other stuff
}
Хотя это работало в автономном приложении, ожидание завершения loadVSTask
всегда выдает Platform::COMException ^
сообщение о том, что система не может найти указанный файл при использовании в качестве библиотеки для проекта C#.
Как правильно загрузить шейдеры в этом сценарии?
Эй, это кажется отличной идеей! Могу ли я использовать функции D3Dcompiler.h
для компиляции исходного кода в реальный шейдер? (Извините за новый вопрос, я новичок в 3D-разработке...)
Я ничего не знаю о D3Dcompiler.h
, извините.
Не помещайте исходный код шейдера в строку. Компиляция во время выполнения медленна и не нужна. Это просто приведет к резкому увеличению времени загрузки. Кроме того, вы потеряете возможность отлаживать/пошагово выполнять свои шейдеры.
Вы должны сделать выходные файлы заголовков компилятора шейдера вместо файлов .cso. Вы можете сделать это в свойствах отдельных шейдеров в VS:
Затем вы можете просто включить этот шейдер (в данном случае SampleVertexShader.h) и передать эти байты непосредственно в ID3D11Device::CreateVertexShader:
#include "SampleVertexShader.h"
Microsoft::WRL::ComPtr<ID3D11VertexShader> vertexShader;
auto hr = d3dDevice->CreateVertexShader(g_SampleVertexShader, sizeof(g_SampleVertexShader), nullptr, &vertexShader);
if (FAILED(hr))
{
// handle error
}
Шейдеры заголовочных файлов — хорошее решение. Я использую его для Набор инструментов DirectX. Вы, вероятно, захотите использовать /Qstrip_reflect /Qstrip_debug
, чтобы уменьшить размер.
«Как встраивать шейдеры» — нельзя ли было просто поместить исходный код шейдера в константную строку в исходном коде и загрузить его оттуда? Затем строка/шейдер будет встроена в вашу dll или исполняемый файл, сгенерированный из источника.