• Advertisement
Sign in to follow this  

Multi-Monitor Rendering

This topic is 3633 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've checked around and tried my best at reading (and doing my best to interpret) the Direct3D Devices guide and how they work. Hopefully I can sum this up into a simple question: How do I grab a rendering from 1 device (or swap chain) and render it to another device? This is for a multi-monitor setup, and in order to have 2 full screen displays, each adapter needs it's own device. I've figured out the swap chain (rendering to 2 windows), but when it comes to making it full screen: it won't work (I assume the 2nd device is locking something) I would prefer to do ALL the graphics processing on device one (unless it's recommended not) for speed and memory reasons, otherwise I believe you would have to load 2 meshes/textures/etc.: 1 for each device to display a similar scene with a different perspective, which means duplicating everything. Ie: D3DX.CreateTextureFromFile(D3DDevice,) I can still see possible issues with 1 monitor device stencil/format not matching the other device and causing issues. So if there's any better recommended implementations please provide your insight. Thank you very much, and I appreciate all your time and effort.

Share this post


Link to post
Share on other sites
Advertisement
i dont know if this is what you were looking for... but i was having similar issues with my program. here is what i figured out (in C#).


using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace DXMultiMonitor2
{
class DXwindow : Form
{
Device DXdevice1; // my first device
Device DXdevice2; // my second device
PresentParameters DXprams = new PresentParameters();
Format DXformat = Format.R5G6B5;


public DXwindow()
{
//constructor
//todo: Add constructor code here.
}
public void tUpdate(double time)
{
//todo: Add Update code here.
}
public void InitGraphics()
{

bool Fullscreen = true;
//todo: Add Graphics Init code here.
DXprams.EnableAutoDepthStencil = false;
DXprams.BackBufferCount = 1;
DXprams.DeviceWindow = this;
DXprams.PresentationInterval = PresentInterval.Immediate;
DXprams.SwapEffect = SwapEffect.Discard;
DXprams.Windowed = !Fullscreen;
if (Fullscreen)
{
DXprams.BackBufferWidth = 800;
DXprams.BackBufferHeight = 600;
DXprams.BackBufferFormat = DXformat;
}
else
{
DXprams.BackBufferWidth = this.Width;
DXprams.BackBufferHeight = this.Height;
DXprams.BackBufferFormat = Format.Unknown;
}
DXdevice1 = new Device(0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, DXprams);
DXdevice2 = new Device(1, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, DXprams);

//when the resolution is changed on both monitors you will
//lose atleast one device. just reset them both before moving on.
DXdevice1.Reset(DXprams);
DXdevice2.Reset(DXprams);
}
public void Render()
{

//render to device1 here (adapter 0)

DXdevice1.Clear(ClearFlags.Target, Color.CornflowerBlue, 1.0f, 0);
DXdevice1.BeginScene();

DXdevice1.EndScene();
DXdevice1.Present();

//render to device2 here (adapter 1)
DXdevice2.Clear(ClearFlags.Target, Color.Green, 1.0f, 0);
DXdevice2.BeginScene();

DXdevice2.EndScene();
DXdevice2.Present();
}

public void graphicsDespose()
{
//todo: Despose Graphics here.
}

protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
}
}
}




i guess that you coult tell your first device to render to a surfice before presenting the scene and telling the second device to use that surfice.

Share this post


Link to post
Share on other sites
Thank you for a quick response. I'll take note of the reset portion.

It seems though that I can beginscene > endscene and enter my rendering appropriately on both screens, but it assumes I load each texture/etc. into each device. When all I want is an alternate view of the same scene on the other monitor. I can get everything I want rendered on the second swap chain from the first device, but I just can't seem to grab the backbuffer from that swap chain and move it to the other device.

So is there a certain way to setup "SetRenderTarget" to get this to work, or is there a way to use a "LoadSurfaceFromMemory" type of function where it copies the backbuffer (which means 2 buffers if not 3) is my big question, to help keep readability of code instead of adding extra code for each monitors render (which I'm planning on making at least 3 monitors, if not more).

Perhaps I worded the question a bit wrong:
How do I grab the backbuffer from 1 device (or swap chain) and render it to another device?

Thank you

Share this post


Link to post
Share on other sites
You can't without going via the CPU. The two devices are totally seperate, they could be two different graphics cards. There's no way they can communicate without going via the CPU.

So it'd be a case of rendering to a texture on device 1, then locking that texture, reading it into a buffer, locking a texture on device 2, and then displaying that texture.

Share this post


Link to post
Share on other sites
Hmm, thanks for the insight

I understand why you can't SetRenderTarget that way now.

I thought it was more of a case where anything you rendered ended up being a surface in the backbuffer, then all you had to do was load the backbuffer into a D3D surface, and take that and move it across to the other devices backbuffer > present. Is that still possible at least? Since the surface is considered local to D3DX and not the device.(?)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement