Как сказано в заголовке, я работаю с взаимодействием XAML и DirectX. Все, что мне нужно, — это рендеринг 3D-контента, но сейчас он показывает только фон.
Приложение может отображать фон с помощью ClearRenderTargetView, поэтому я знаю, что это не так. Проблема с неправильным созданием экземпляра Render Target. Точно такая же настройка работает и для моего контента Direct2D, поэтому я не думаю, что я неправильно создаю цепочку обмена. Никаких ошибок или нулевых значений, привязанных к конвейеру, не появляется, и я уже миллион раз проверил BUFFER_DESC для своих буферов. Должно быть, мне что-то не хватает, возможно, что-то специфическое для WinUI 3, поскольку я использовал практически идентичный код в обычном приложении для Windows, и оно могло прекрасно отображать там 3D-контент.
Мое предположение связано с тем, как я получаю информацию о шейдерах. Раньше я использовал файлы .cso, сгенерированные для создания больших двоичных объектов и создания шейдеров, но мой новый проект не мог их найти, что бы я ни пытался, поэтому я переключился на создание переменной заголовка для получения информации. Это единственное существенное отличие от того, как я писал это раньше.
Здесь я демонстрирую все необходимое для рендеринга контента
Как сказано в заголовке, я работаю с взаимодействием XAML и DirectX. Все, что мне нужно, — это рендеринг 3D-контента, но сейчас он показывает только фон. Приложение может отображать фон с помощью ClearRenderTargetView, поэтому я знаю, что это не так. Проблема с неправильным созданием экземпляра Render Target. Точно такая же настройка работает и для моего контента Direct2D, поэтому я не думаю, что я неправильно создаю цепочку обмена. Никаких ошибок или нулевых значений, привязанных к конвейеру, не появляется, и я уже миллион раз проверил BUFFER_DESC для своих буферов. Должно быть, мне что-то не хватает, возможно, что-то специфическое для WinUI 3, поскольку я использовал практически идентичный код в обычном приложении для Windows, и оно могло прекрасно отображать там 3D-контент. Мое предположение связано с тем, как я получаю информацию о шейдерах. Раньше я использовал файлы .cso, сгенерированные для создания больших двоичных объектов и создания шейдеров, но мой новый проект не мог их найти, что бы я ни пытался, поэтому я переключился на создание переменной заголовка для получения информации. Это единственное существенное отличие от того, как я писал это раньше. Здесь я демонстрирую все необходимое для рендеринга контента [code]//global variables winrt::com_ptr p3DFactory = nullptr; winrt::com_ptr p3DDevice = nullptr; winrt::com_ptr p3DSwapChain = nullptr; winrt::com_ptr p3DContext = nullptr; winrt::com_ptr p3DRenderTarget = nullptr; winrt::com_ptr p3DBackBuffer = nullptr;
//descriptor structure DXGI_SWAP_CHAIN_DESC1 swapDesc = {0}; swapDesc.Width = 1250; //change to actually fill screen based on window size later swapDesc.Height = 650; swapDesc.Stereo = false; swapDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; //layout of the pixels swapDesc.Scaling = DXGI_SCALING_STRETCH; swapDesc.SampleDesc.Count = 1; swapDesc.SampleDesc.Quality = 0; swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapDesc.BufferCount = 2; //1 front buffer and 1 back buffer swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapDesc.Flags = 0;
//create device and rendering context winrt::check_hresult(D3D11CreateDevice( nullptr, //adapter D3D_DRIVER_TYPE_HARDWARE, 0, //software driver D3D11_CREATE_DEVICE_BGRA_SUPPORT, //flags featureLevels, //feature level ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, p3DDevice.put(), &supportedFeatureLevel, //where feature level is put into p3DContext.put() ));
//create factory //get device first winrt::com_ptr p3DDXGIDevice{ p3DDevice.as() };//different from the device made just now, it goes above it //then adapter winrt::com_ptr < IDXGIAdapter> p3DDXGIAdapter = nullptr; p3DDXGIDevice->GetAdapter(p3DDXGIAdapter.put()); //then factory p3DDXGIAdapter->GetParent(__uuidof(IDXGIFactory2), (void**)&p3DFactory); p3DFactory.capture(p3DDXGIAdapter, &IDXGIAdapter::GetParent);
//create swap chain winrt::check_hresult( p3DFactory->CreateSwapChainForComposition( p3DDevice.get(), &swapDesc, nullptr, //restricts output to whatvers put here, could be useful later for switching between modes p3DSwapChain.put() ));
//get native interface auto panelNative{ swapChainPanel().as() };
winrt::check_hresult( panelNative->SetSwapChain(p3DSwapChain.get()) //assign swap chain to native interface );
//get back buffer winrt::check_hresult( p3DSwapChain->GetBuffer(0, IID_PPV_ARGS(p3DBackBuffer.put()))); //create render target winrt::check_hresult( p3DDevice->CreateRenderTargetView(p3DBackBuffer.get(), nullptr, p3DRenderTarget.put())); [/code] И вот здесь я создаю настоящий 3D-контент [code]const float color[] = { red, green, blue, 1.0f }; p3DContext->ClearRenderTargetView(p3DRenderTarget.get(), color);
cbuffer CBuff { matrix transform; //matrix keyword implies 4x4 float //hlsl defaults to column-major, but our matrix is row-major so we have to clarify so it isnt messed up };
VSOut main(float4 pos : POSITION, float3 color : Color) { VSOut vso; vso.pos = mul(float4(pos.x, pos.y, pos.z, 1.0f), transform); vso.color = color; return vso; } [/code] Мой пиксельный шейдер [code]float4 main(float3 color : COLOR) : SV_TARGET { return float4(color, 1.0f); } [/code] Оба шейдера имеют их в своих свойствах, откуда берутся g_PixelShader и g_VertexShader. [img]https://i.sstatic.net/U8v0tQED.png[/img]
Заранее спасибо, что прочитали все это, даже если вы ничего не можете понять.