[C# / SlimDX /D3D9] Rendering to multiple windows

Started by
10 comments, last by Barguast 14 years ago
What is the best way to render to multiple windows using SlimDX? I have a single device instance (since all the windows will share the same resources) but I want to be able to render the scene differently (for example, viewed from a different direction) to each window. I had the idea of using SetRenderTarget to draw to an off-screen texture and drawing that to each window, but is there must be another way? If it makes a difference, I want to be able to add windows dynamically without having to reset the device. Windows will also be of varying sizes. Thanks. [Edited by - Barguast on March 31, 2010 5:42:32 PM]
Using Visual C++ 7.0
Advertisement
I tried using a swap chain, but I'm a bit confused about the involvement of a swap chain with normal Direct3D operations. So here are a couple of questions about that;

- When rendering to a swap chain, is it the correct procedure to use SetRenderTarget with the result of SwapChain.GetBackBuffer(0)? If so, do I have to dispose of this Surface when the frame has been completed?

- When the swap chain target (window) size changes, how do I resize the back buffer? Do I call reset? Do I need to dispose of all swap chains and re-create them in order to do this?


Thanks in advance.
Using Visual C++ 7.0
Not to nag (well, maybe a little :p) but I'd be amazed if no-one has worked on this kind of problem before! Any help would be appreciated. :)
Using Visual C++ 7.0
The first two entries from here seem useful. They use C++, but it's probably very similar in SlimDX.
Quote:Original post by Gage64
The first two entries from here seem useful. They use C++, but it's probably very similar in SlimDX.


Thanks but I've read those already and they don't address my questions above. For example, they don't deal with resizing a swap chain, and they Get / Release their back buffer with each render.

I've managed to get an application working, but I still have those questions lingering. I have to dispose of the swap chains before calling Reset, and recreate them afterwards. I'm not sure if that is the required way of doing things?

Also, what is the overhead of calling GetBackBuffer on a swap chain, and Dispose afterwards? I'm doing this every frame at the moment, just for simplicitity, and I don't know if I would be better off just calling GetBackBuffer once and keeping the returned Surface reference around until I close my app?
Using Visual C++ 7.0
Yes, creating a swap chain for each window is the way to do it as you mentioned. You manually handle the resizing of each window and the according swap chain.

When a window resizes, you dispose each render target (if you use MRT) and then your swap chain. After destroying the views, you recreate them with the new dimensions of the client area.

EDIT: after reading your second post of your thread; you use the SwapChain instance itself as the input SetRenderTarget and not the .GetBackBuffer(0) result.
So if one of my windows resizes, I have to reset the entire device in order to resize the swap chain buffers? O_O

Quote:Original post by Xeile
EDIT: after reading your second post of your thread; you use the SwapChain instance itself as the input SetRenderTarget and not the .GetBackBuffer(0) result.


But SetRenderTarget expects a Surface parameter? So I do:
using (Surface backBuffer = swapChain.GetBackBuffer(0)){    device.SetRenderTarget(0, backBuffer);    ...}

The above demonstrates my question about disposal of the back buffer. Should I be doing this once per frame, as above, or should I get the reference on creating the swap chain, and disposing of it after I've finished with it?
Using Visual C++ 7.0
Aaah you are using DX9, somehow I thought DX10. Yes, the way you do it seems approriate.

I do not know the work load you create by calling the GetBackBuffer method each frame, for that should use a profiler is see how big the impact is of the call opposed of the rest of the frame code calls.
Quote:Original post by Barguast

- When the swap chain target (window) size changes, how do I resize the back buffer? Do I call reset? Do I need to dispose of all swap chains and re-create them in order to do this?



If the window is using an additional swap chain (AKA, a swap chain you created manually) then all you have to do is create a new swap chain and dispose of the old one. If the window is using the implicit swap chain (the swap chain created with the device), then you can't destroy it so you have to reset the device.

It's possible to have all windows use additional swap chains and just ignore the implicit swap chain, which means you never have to reset the device for a resize. However if you do this programs that overlay a HUD on your window (NVPerfHUD, PIX, etc.) won't work correctly since they assume that you use the implicit swap chain.

Ah, that's good to know. Indeed, I don't use the implicit swap chain at all anyway! Many thanks. :)

Only question remaining (not a biggy) is whether I should be accessing (GetBackBuffer) and disposing the swap chain back buffers once per frame or not. I'm not really fussed on whether it is performant or not, more if I should be doing it in the first place.

I'm worried that calling Dispose on the GetBackBuffer result is destroying the back buffer, causing it to be recreated every frame (which I'd obviously rather avoid).
Using Visual C++ 7.0

This topic is closed to new replies.

Advertisement