Multiple windows?

Hi all!

So, I’m pretty new at all this, I was wondering whether it is possible to make two windows run simultaneusly? This, for the purpose of running the two windows on separate screens and making objects transferrable between the two?

Firstly, if it is possible at all, since I cannot find any information regarding this.

Secondly, any pointers to get me started would be greatly appreciated!

Many thanks!

Hi Learning007,

Drawing between separate windows can be very difficult, you would have to do it within OpenGL I suspect and it can get very complicated. What might be best would be to declare a window that spans all the screens, and just animate within the window (effectively animating between screens).

Which platform are you developing on OSX? Windows? Mac OS X?

Cheers,

Joel

It’s actually pretty easy to get a multiple window happening in OF. OF is built on top of glut, which has multi-window functionality. The downside is that you can’t use the usual virtual function draw() to draw the second window, and you have to do a few low-level opengl-y things, like call glutSwapBuffers() at the end of your function.

If you add this code to your main() function, after the ofSetupOpenGL call

  
  
	win_h = glutGetWindow();   
	other_win_h = glutCreateWindow("Other window");  
	glutDisplayFunc(render_other_window);  
	glutSetWindow(win_h);  

and then create a render function for the second window:

  
void render_other_window()  
{  
    glutSetWindow(other_win_h);  // have to tell glut which window you are rendering  
   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // OF usually does this for you.  
   // render code....  
   glutSwapBuffers();  
   glutSetWindow(win_h);  
}  

You should be in business. Check out the glut docs for more info.

Kevin

P.S. with a bit of thought, it might be possible to derive a class from SimpleApp that supports multiple windows (as opposed to doing surgery on the OF code base)

I managed to have two windows but the display_func is only called when the window thinks it needs to refresh. I probably need to execute the glutPostRedisplay() for that window but I’m not sure where I should put this. I tried the draw and update function and it works till some extend but the framerate drops.

Has anyone some working openframeworks example code for this?

I found: http://users.encs.concordia.ca/~grogono-…-ee-win.cpp

But this is pure glut and not openFrameworks.

What I actually want is the the output of my openframeworks app on two windows. One half on one screen and one on the other. I tried FBO’s for this but this also slows down the program.

Rick

A while ago I tried to create multiple windows, but had no luck. I tried within OF and also
created a separate GLUT non-OF project just to test if it was some OF-thingy messing it up.
No luck, GLUT refuses to refresh both windows at the same time, and manually calling
the display functions reduced framerate so much I dropped it entirely.

I was only after one output and one control window though, and i’m not 100% sure of this
but I belive i’ve read that everything you create in OpenGL is context sensitive. So if you
create a texture/fbo within the context of one window, you cannot use it in the context of
another, so what you would be forced to do anyway would be to render the scene twice.
There is a way to share data between contexts but it seemed awfully tricky to get just right.
Please someone correct me on this one if i’m wrong.

Would it be more feasable to create regular OS-X windows, render offscreen to fbo, grab
the texture and pass it to the windows for display? This would probably be a bit on the slow-side
aswell since grabbing textures from the gfx card is bandwidth sensitive, but if your scenes
are complex enough and not bandwidth-bound you might get better performance then
rendering everything twice (and keeping duplicates of everyhing in memory if my statement
above is accurate).

If someone has an example of how to utilize a normal OS-X window with the regular GLUT
one in OF, please post it, i’m very interested in the results.

I’m at the same stage discribed by edvinbesic. I’ve used the example provided by kefex and placed a glutPostRedisplay in my update function. this is my code for drawing the texture stored in my FBO:

void renderOutputWindow()
{
GLuint texture_id;
//cout << “here” << endl;

texture_id= app->getBufferTextureID();

//cout << texture_id << endl;
/*
int width=640;
int height=480;
*/
glutSetWindow(other_win_h); // have to tell glut which window you are rendering
glDisable(GL_DEPTH_TEST);
glDisable(GL_COLOR_BUFFER_BIT);

int x1 = -1;
int x2 = 1;
int y1 = -1;
int y2 = 1;

glEnable (GL_TEXTURE_2D) ;

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, (GLuint) texture_id);

glBegin (GL_QUADS);
glTexCoord2f (0.0, 0.0);
glVertex2f (x1, y1);
glTexCoord2f (1.0, 0.0);
glVertex2f (x2, y1);
glTexCoord2f (1.0, 1.0);
glVertex2f (x2 , y2);
glTexCoord2f (0.0, 1.0);
glVertex2f (x1, y2);
glEnd ();

glutSwapBuffers();
glutSetWindow(win_h);

}

All I get is a white quad so I’m guessing I’m not accessing the texture, just like what edvinbesic said. Anyone has any ideas about this issue?

I had the same problem with multiple windows and sharing textures. Theoretically you could share the openGL context, on windows with wglShareLists(), on linx glXCreateContext and on mac with aglCreateContext(). But I didn’t manage the get them running…

So I used a very simple solution that probably is pretty slow but worked for me. You have to create two functions, one to change to the window and one to swap back.

  
void changeToOtherWindow(){  
	glutSetWindow(other_win_h);  // have to tell glut which window you are rendering  
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
}  
  
void returnFromOtherWindow(){  
	glutSwapBuffers();  
	glutSetWindow(win_h);  
}  

I defined them right in the beginning of main.cpp and “imported” them to testApp.h with

  
extern void changeToOtherWindow();  
extern void returnFromOtherWindow();  

then you can call this wherever you want to:

  
changeToOtherWindow();  
thumb.setFromPixels([some data], player.width, player.height, OF_IMAGE_COLOR);  
thumb.resize(200, thumb.height/(float)thumb.width*200);  
returnFromOtherWindow();  

lg.ph

As underdoeg says, you have to share the contexts. Every time you create a window, you need a different OpenGL context. If you try to use a texture created in one context in another, that other context won’t have access to the resource so you will get white.

The only way to share resources is by sharing contexts. You will run in to problems if the windows are being driven by different graphics cards, but otherwise it works beautifully.

The usual root to making this work is to create a base OpenGL context that each window shares so you could actually have as many windows sharing resources as you want. I’m not sure how to do this in GLUT, but there definitely sample code around for native approaches.

If you still need two windows, I put together an addon based on information of this thread called ofx Fenster. You can find it here: http://forum.openframeworks.cc/t/ofxfenster—addon-to-handle-a-second-window-[outdated]/3916/0

cheers
philip

[quote author=“underdoeg”]If you still need two windows, I put together an addon based on information of this thread called ofx Fenster. You can find it here: http://forum.openframeworks.cc/t/ofxfenster—addon-to-handle-a-second-window-[outdated]/3916/0

cheers
philip[/quote]

I get the following error when trying to use ofx Fenster: GCC 4.2 is not compatible with the Mac OS X 10.4 SDK (file main.cpp)

Any suggestions on how to fix this issue?

Thks.