Closed Annihil closed 7 months ago
I don't have much experience with Xbox Game Bar SDK but I don't see why it wouldn't work
The problem is that it is Win2D, and we can only get a Microsoft::Graphics::Canvas::CanvasSwapChain^
which does not seem to be convertible to a DXGISwapChain*
.
canvasSwapChainPanel->SwapChain = ref new CanvasSwapChain(CanvasDevice::GetSharedDevice(), Width, Height, displayInformation->LogicalDpi);
We cannot call CoreWindow::GetForCurrentThread()
either, so cannot do https://github.com/ahmed605/imgui-uwp/blob/6e131e8de2d13f1824b2e0f32d3382f4c69ec4cd/examples/example_uwp_directx12/main.cpp#L315 to create a swap chain.
Because of that I'm unable to run your example in it.
Would you know how to obtain a DXGISwapChain in Win2D?
CanvasSwapChain can be converted to IDXGISwapChain1, check Win2D Direct2D interop docs.
but why are you using XAML? this backend doesn't support being hosted in XAML yet, it would work but pretty sure input will be broken, proper XAML support is planned tho but in the meantime create a CoreApplication app instead, like shown in samples
also why CoreWindow::GetForCurrentThread()
cannot be called? it should work fine in Xbox Game Bar widgets
CanvasSwapChain can be converted to IDXGISwapChain1, check Win2D Direct2D interop docs.
Thanks for that, will give it another go!
but why are you using XAML? this backend doesn't support being hosted in XAML yet, it would work but pretty sure input will be broken, proper XAML support is planned tho but in the meantime create a CoreApplication app instead, like shown in samples
Because I believe it's the only available option in an xbox game bar widget. Yes input won't work, I just want to be able to draw things.
Because I believe it's the only available option in an xbox game bar widget.
afaik Xbox Game Bar Widgets can be CoreApplication apps too, will give it a try in the future and will upload a sample of that here if I succeeded
Because I believe it's the only available option in an xbox game bar widget.
afaik Xbox Game Bar Widgets can be CoreApplication apps too, will give it a try in the future and will upload a sample of that here if I succeeded
Ah alright, going to check this out too. Amazing, thanks!
You were right, CoreWindow::GetForCurrentThread()
works, it's the same as Window::Current->CoreWindow
, but it returns a Windows::UI::Core::CoreWindow^
and
const auto window = CoreWindow::GetForCurrentThread();
// ...
dxgiFactory->CreateSwapChainForCoreWindow(
m_pd3dCommandQueue.get(),
reinterpret_cast<IUnknown*>(window),
&swapChainDesc,
nullptr,
swapChain1.put()
);
fails 🫤 It seems impossible to create a 3d swapchain in an xgb widget 😒
what's the HRESULT this returns?
btw note that the window needs to be shown for this to work
what's the HRESULT this returns?
E_ACCESSDENIED
btw note that the window needs to be shown for this to work
Yes the window is visible at the time I call it.
I suspect the sandbox forbids calling CreateSwapChainForCoreWindow
.
the sandbox shouldn't be a problem as this function works fine for the samples which are sandboxed too
a rough guess but the compiler might be picking CppWinRT's IUnknown instead of raw one which wouldn't work with CX objects, so can you try using ::IUnknown
instead of IUnknown
for that cast?
Hopefully this is the case, if not I will try to investigate further as soon as I get the time to
DirectX Debug Layer might also help investigating the problem
btw does your app initialize XAML? because if so then that's why, XAML would be already using the CoreWindow so creation of a swapchain over that CoreWindow would fail
the sandbox shouldn't be a problem as this function works fine for the samples which are sandboxed too
Ah alright, well I don't know what's happening then.
a rough guess but the compiler might be picking CppWinRT's IUnknown instead of raw one which wouldn't work with CX objects, so can you try using
::IUnknown
instead ofIUnknown
for that cast?
Interesting, I tried with ::
but same error.
Hopefully this is the case, if not I will try to investigate further as soon as I get the time to
Alright, I'll let you have a look, thanks again.
DirectX Debug Layer might also help investigating the problem
Will check this out
btw does your app initialize XAML? because if so then that's why, XAML would be already using the CoreWindow so creation of a swapchain over that CoreWindow would fail
It does, ah I see, let me have a look!
Ok so I was able to create the swapchain by calling setWindow inside the Widget1
constructor
static void RenderingThread(App& app) {
app.Run();
}
Widget1::Widget1() {
//InitializeComponent();
auto app = App();
app.SetWindow(Window::Current->CoreWindow);
thread RenderThread(RenderingThread, app);
RenderThread.detach();
}
but now I get an error DCOMPOSITION_ERROR_WINDOW_ALREADY_COMPOSED
in ImGui_ImplDX12_NewFrame
this is still conflicting with XAML since it's still initialized
To get XAML not to be initialized you have to add DISABLE_XAML_GENERATED_MAIN
to Preprocessor Definitions then define your own main entrypoint function as shown in the samples in this repo, and avoid using anything in the XAML namespace (e.g Window
class)
To get XAML not to be initialized you have to add
DISABLE_XAML_GENERATED_MAIN
to Preprocessor Definitions then define your own main entrypoint function as shown in the samples in this repo, and avoid using anything in the XAML namespace (e.gWindow
class)
Gave that a try, all the files compile fine but at the very end of the build process it throws an error
error APPX0702: Payload file '...\x64\Debug\WidgetSampleCX\WidgetSampleCX.winmd' does not exist.
Edit: Generate Windows Metadata linker switch to No (/WINMD:NO) fixed this issue
Now it runs but, only if I click play in Visual Studio, not once I run it as a widget using the game bar, which does make sense since I removed the XAML part that initialize the widget...
Now the trick is to figure out how to bootstrap the connection with Game Bar without using XAML 😅 https://github.com/microsoft/XboxGameBarSamples/blob/master/Samples/WidgetSampleCX/App.xaml.cpp#L85 So close yet so far 😊
hm XboxGameBarWidget
requiring a Frame
will be complicating things a bit, I need to figure out how to initialize GameBar without this API in order to workaround this.. in the meantime I guess you can re-enable XAML and use a Frame with a SwapChainPanel as its child and use it to initialize ImGui, it won't give the best experience but should work as a temporary solution
in the meantime I guess you can re-enable XAML and use a Frame with a SwapChainPanel as its child and use it to initialize ImGui, it won't give the best experience but should work as a temporary solution
That's what I've been trying to do initially already, did not manage to do it :/ Did you get the time to try?
@Annihil I added an Xbox Game Bar example to the repo https://github.com/ahmed605/imgui-uwp/tree/master/examples/example_uwp_gamebar_directx12
@ahmed605 impressive work, many thanks! (I added you on discord btw, I'm anni)
Would you be able to setup ImGui in an xbox game bar widget (c++17/CX)? https://github.com/microsoft/XboxGameBarSamples/tree/master/Samples/WidgetSampleCX That would be awesome