We’re trying to output apps at a pretty bizarre resolution (3360x2100) across two graphics cards for a hardware test of an upcoming installation. 4 monitors (@ 1680 x 1050) are set up stacked like this:
| 1 | 2 |
| 3 | 4 |
I’ve tried just about every configuration I can think of, and have hit a bit of a wall. Here’s what I’ve tried so far:
1) fullscreen GLUT spanning the whole resolution
- this is the closest to what we’d like to do, but as expected the app takes a giant performance hit (60 fps cut down to 5-10fps) once we span across both cards
2) two GLUT windows in one app
- I don’t have a lot of experience doing this, but I was able to get a second window up and running + using the same draw loop, but could only get the window you have focus on to actually run (the other would just freeze on a frame)
3) two separate apps
- this runs at an acceptable speed, but I can’t seem to find a way to run the apps both in fullscreen mode (with extended desktop). best i’ve gotten is one app spanning the bottom two screens, while the other is stuck with the title bar. i’ve been trying to find a way to do fullscreen with two apps both with extended desktop turned on, but to no avail.
4) cocoa windows
- i just started rolling the ofAppCocoaWindow stuff into our app, but it didn’t seem to want to play nicely will ofxOsc. this definitely has potential, though: I was able to span a straight cocoa app across all displays and play a quicktime video across it, but am not sure if i’ll get the same performance out of OF. is this an avenue worth pursuing?
i’ve also considered creating 4 apps, one for each corner, but this solution isn’t totally scalable either. any suggestions as far as topics to research, other potential solutions, etc, would be incredibly helpful. thanks!
can you post your hardware specs?
one thing you should be aware of is if you are using two graphics cards in a mac the first card has to do all the rendering and then it copies the data to the second card for the other display.
this makes things very slow - so generally you get better results from using just one card and something like a matrox dualhead2go on each head.
We’re running a mac pro with:
2.66GHz Quad-Core Intel Xeon Nehalem processor
3 GB memory
640GB 7200-rpm Serial ATA 3G/s hard drive
(2) NVIDIA GeForce GT120 512mb video cards with DVI out
18x Super drive
I’ve read that about the apple graphics card thing. However, the difference between the performance of two apps with each on only one card vs. one app across all cards was pretty wild. something like 30-40fps in the former and <5fps in the latter. is that just a GLUT thing, or is there a different issue at root?
No I believe it is not a GLUT thing.
It is more of an issue of having one card sending two screens worth of rendering to the other card to display. Its the copy operation that slows thing down.
Basically as far as I know rendering one app across multiple graphics cards in OS X is going to be a problem.
i’ve had that same problem before and we couldn’t find a solution for it using multiple graphic cards. We ended up using matrox tripleheads and ran everything on a single graphics card.
for your installation i would suggest either 2 matrox dual heads or 1 triple head running one screen on one dvi and the triplehead connected to the other.
hope it helps
Hey all, thanks for the replies.
I’ve had a little bit of success today with this. I ended up using edvinbesic’s multiple cocoa window example (http://forum.openframeworks.cc/t/ofappcocoawindow—everything-but-fullscreen/2200/0) to render a top + bottom half of the app. It’s working with both windows in cocoa’s fullscreen mode right now, but I need to do some cocoa research to get the positioning right.
It’s a little bit hack-y, but what I ended up doing is adding a variable in the main testApp that decides whether it’s the top or bottom. If it’s the bottom, it translates itself up and draws. Then, in the CustomGLViewDelegate class (where the second cocoa window’s render functions are) I added this to “render”:
void CustomGLViewDelegate::render( int w, int h )
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// we need to call this so we can use normal of drawing routines
setupOpenGLForOF( w, h );
((testApp*)OFSAptr)->isTop = true;
((testApp*)OFSAptr)->isTop = false;
Not sure if this is a bad idea or not, but it works fairly well. Now my next step is to try to figure out how to compile ofxOsc with cocoa… it’s stuck on the line “extern NilType Nil;” in OscTypes.h
Hmm interesting solution.
So you have essentially two testApps running in the same main app with one for each window? Only downside to this is that you are performing the same calculations twice per frame. One way around this is to move all your testApp members to the top of the cpp file and then only let one of the testApp call the update() function.
For the OSC stuff looks like a type conflict between the Cocoa Nil type:
Usually in these situations there is not much you can do but change the type name in OSC and recompile it. If oscpack is C++ you might get away with adding a namespace.
I think that the update() is called only once, though I need to poke around with the code to confirm that. It looks like the CustomGLViewDelegate has its own update, render, etc functions, but shares texture data and such with the main testApp. But yeah, I’m still basically calling draw() twice every frame, though update() only runs once. It’s not ideal, but it’s giving me an acceptable framerate for sure.
I’m going to take a pass at the ofxOsc stuff, will post something if I figure it out!
just some ideas:
perhaps you can use OpenSceneGraph for rendering your opengl-content. It supports rendering on different graphic-cards / screens out of the box, but the learning curve is a bit steep.
Another idea: perhaps you can incorporate EqualizeGraphics into your Openframeworks-app and let equalizer render onto the four screens.
Did some poking around about the ofxOsc’s NilType getting in trouble with Cocoa’s nil type.
Not sure how safe this is, but it appears to work with this addition to OscTypes.h above struct NilType:
Thanks all for your suggestions. Right now going with two cocoa windows in fullscreen (one on each graphics card) and having a good deal of success for that. Would like to look into EqualizerGraphics in the future, though, as it looks like it’d be a better long term solution.