Fullscreen dual screen

how to get two seperate renderports with good performance and shared assets?
or are you setting up two separate OF apps?

To use 2 monitors/beamers at once (each at a resolution of 1024x768), this is what you need to do (Windows only, I do not have a Mac so I can’t give advice about that):

(1) If running on a videocard that supports SPAN MODE, you can simply use:

  
ofSetupOpenGL(&window, 2048, 768, OF_FULLSCREEN);  

In the NVidia control panel, horizontal span mode can be found at the “Set up multiple displays” tab. The setting is called “As one large horizontal desktop”.

On ATI it is a much more hidden feature that I sometimes got working, but only when using DVI cables and not the standard analog VGA cables. More often than not, however, it took me hours trying to configure the displays before giving up.

(2) When using a Matrox DualHead2Go, you can do the same. Windows will only see 1 very wide monitor with a resolution of 2048x768, which is basically the same as span mode.

(3) If span mode is not available, I can confirm the solution in this thread works like a charm:

  
ofSetupOpenGL(&window, 2048, 768, OF_WINDOW);  
ofSetWindowPosition(0, 0);  

This will properly run your app “fullscreen” on 2 monitors. You can even easily switch between windowed and full screen mode with this code in testApp.cpp:

  
  
void testApp::keyPressed(int key){  
	int screenWidth = ofGetScreenWidth();  
	int screenHeight = ofGetScreenHeight();  
  
	switch(key){  
		case OF_KEY_PAGE_UP:  
			// set window to full screen dual view  
			if( ofGetWindowMode() == OF_WINDOW ){  
				ofSetWindowShape(2 * screenWidth, screenHeight);  
				ofSetWindowPosition(0, 0);  
			}  
			break;  
		case OF_KEY_PAGE_DOWN:  
			// set window to windowed mode (choose an appropriate window size)  
			if( ofGetWindowMode() == OF_WINDOW ){  
				ofSetWindowShape(1200, 450);  
				ofSetWindowPosition((screenWidth - 1200)/2, (screenHeight - 450)/2);  
			}  
			break;  
	}  
}  
  

I hope this answers a few of the questions here. And thanks to the genius who found out you don’t need span mode at all… could have saved me hours of frustration and many a euro had I discovered this thread earlier :slight_smile:

To keep content from appearing on the incorrect monitor
Use OpenGL’s scissor functionality before drawing your content:

  
  
glEnable(GL_SCISSOR_TEST);  
glScissor(x, y, w, h);  
  
... do your drawing here ...  
  
glDisable(GL_SCISSOR_TEST);  
  

This will make sure nothing is drawn outside your scissor rectangle. Note: the rectangle is specified in window coordinates and is insensitive to any translation, rotation or scaling done prior to calling the “glScissor” function. In other words: you can’t specify a rotated scissor rectangle, let alone a triangle or trapezium shape.

But what if my content is not rectangular?
In that case I would recommend rendering to an FBO texture (browse these forums for more info). But ehm, this has little to do with multiple monitor setups.

Is there a performance difference between running fullscreen and windowed?
Yup, a substantial one in my case (Intel Quad Core CPU, NVIDIA Quadro FX 550). Using a fullscreen window clearly has a lower framerate than running the same application as OF_FULLSCREEN in span mode. There is also a chance the Windows taskbar is visible on top of your fullscreen content. Meh.

possible to run as two seperate renderports?

ideally I want to be able to render to two seperate contexts within the same application. it’s something that i’m familiar with in vvvv and performs quite well (generally can mix and match whatever monitor/triplehead setup and keep your 60fps). but vvvv uses directx, so there could be a big difference there.

i presume in oF you’d need to set up two threads, each running an ofRunApp
then have some static classes to perform communications between the two. is there anything else you’d need to do? since OpenGL isn’t very object oriented, it seems like there could also be issues with OpenGL knowing which bit of the app renders to which viewport?

a more basic requirement is to run fullscreen on the second monitor (only 1 renderer, mainscreen for dev, second screen is render context going out on a projector). any ideas on that without using windowed mode?

back in the days of using MaxMSP I was having hell with these issues (ended up having about 20fps to run 2 projectors off one computer with mainscreen as interface). which worries me that it’s a general OpenGL issue… :frowning: ?

Ain’t there a way do enable it by code?

I’m on a mac but i can’t see the glut preferences. Is it removed?

yes we are not using glut anymore if you want to have fullscreen on several monitor now you have to do in main.cpp:

#include "ofAppGLFWWindow.h"

int main(){
    ofAppGLFWWindow window;
    window.setMultiDisplayFullscreen(true);
    ofSetupOpenGL(&window,1024,768,OF_FULLSCREEN);
    ofRunApp(new testApp);
}
5 Likes

on osx, I’ve had luck hacking with the GLFW window directly to make it borderless and on on top of everything else – I’ve put some code here in a gist but can make a small sketch. Having low level access to the window is pretty helpful and I think it could be useful to get the full screen work well across multiple monitors, etc:

2 Likes

one quick note on the code above, you’ll need to force xcode to compile the .cpp files as objective-c++ if you want to mix objective c code in your .cpp file. you can do this in the sidebar:

and this at the top of your h file:

#include <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h>

hope this helps,
zach

1 Like