So, I'm creating a game where I have two different windows which have different display functions. What I'm wondering is if it's possible to update two windows simultaneously. Let's say for one window, I implicitly call glutPostRedisplay() to force an update. This will only cause an update on the current window. Yet, I wanted to update both of them.
Is this even possible? I've been searching for quite a long time and didn't seem to some to a definitive answer.
Thanks.
4.5 glutPostRedisplay
glutPostRedisplay marks the current window as needing to be redisplayed.
"Current window" eh? I wonder if...
4.3 glutSetWindow, glutGetWindow
glutSetWindow sets the current window; glutGetWindow returns the identifier of the current window.
foreach( int window : windows )
{
glutSetWindow( window );
glutPostRedisplay();
}
Related
I'm working on a project that requires me to switch between two windows, one using OpenCV and one using OpenGL, both fullscreen.
A GLFW key event opens the OpenCV window fine, but closing the OpenCV window, and attempting to return focus to the OpenGL window results in the window flickering and repeatedly attempting to give focus. This is my code to return focus to the OpenGL window, inside a while loop.
Edit: Ive found out that it only happens when the OpenGL window is fullscreen, which is a requirement of this program. Writing to console shows that the code is being called multiple times
if(!glfwGetWindowAttrib(window, GLFW_FOCUSED))
{
glfwFocusWindow(window);
while(!glfwGetWindowAttrib(window, GLFW_FOCUSED))
{
}
}
I managed to fix my problem by setting the GLFW flag GLFW_AUTO_ICONIFY to false on my openGL window.
The way you posted is not the proper way to set focus.
Use glfwSetWindowCloseCallback to set a close callback.
In that callback is where you set focus to another window.
Currently developing an APP using C++.
I am displaying multiple sub-windows in a single main window.
When one of the subwindows is put in Full Screen Mode , does the rendering of the other windows stop?
does the rendering of the other windows stop?
That depends on the implementation. If the program is implemented correctly, then the rendering should stop only if the window is fully covered.
Some people like to update the window in a timer callback (which is a bad practice), and then it would continue to render even when covered.
glutDisplayFunc is called only when there is a need to refresh the window.
I have a main window which has both a glut UI in the top 10% of the screen, and the openGL world in the bottom 90% of the screen. Every time my cursor starts hovering over the GLUT portion, openGL rendering will freeze. It resumes only when the cursor exits the GLUT area.
This is because as long as the cursor is hovering over the GLUT area, presumably glutIdleFunc is never called because glut is not "idle", so openGL stuff is not rendered.
I already tried making a new unrelated thread that just calls the display code and/or glutPostRedisplay but I got a framerate of whopping 20 fps as opposed to the 100+ fps the normal way. I don't know exactly why. (In this test I also disabled glutIdleFunc so there is no idle func, just the separate thread calling the display)
Ways to get around this (other than "stop using glut" which I might do in the future but for now I would like a temporary solution)?
I know this is an old question, but I was having a similar issue and wanted to share how I solved it.
Basically, in your idle function, you should manually set the window to your normal window ID. Thanks to Joel Davis' HexPlanet code ( https://github.com/joeld42/hexplanet/ ) for demonstrating this:
void glut_Idle( void )
{
// According to the GLUT specification, the current window is
// undefined during an idle callback. So we need to explicitly change
// it if necessary
if ( glutGetWindow() != g_glutMainWin )
{
glutSetWindow(g_glutMainWin);
}
...
}
Create a callback for passive motion func:
void passiveMouseFunc(int,int){
glutPostRedisplay();
}
And register it using:
glutPassiveMotionFunc(passiveMouseFunc);
I want to be able to render to an X Window given just its id.
In this case I have a window created in python by gtk.
I can get the window ID of a gtk.Drawable and pass it into my C python module, but can I then make OpenGL calls render to it?
I am aware of gtkglext, but would rather not use it if possible.
Update 1:
Ok, so (rather obviously now that I see it) You just do an XCreateWindow with a parent of the Window id that you get from gtk.window.xid, using the correct flags for an opengl window, and hey presto.
The only problem is I can't get it to work if there are not multiple widgets in the window, otherwise it seems that the xid represents a window that covers the entire toplevel window. Not sure how to rectify this.
Update 2:
It turns out that if you have a gl window that is the same size as the toplevel then the toplevel window will not get expose events until the gl window has its buffers swapped. You just have to keep swapping the buffers and things wil be fine.
Update 3:
To answer #babele's comment:
This page in the python gtk docs say how to make a gtk window from an existing xid. After that you just have to remeber to keep calling glXSwapBuffers for that window (if it is an opengl buffered window, otherwise it should just work when you use window_foreign_new).
So the process goes:
Create a gtk widget that will contain your OpenGL window (a DrawingArea is a good choice - you can't use eg a label as it won't have its own xid)
Get the widget's gtk.gdk.Window (docs)
Get the xid from the gtk.gdk.Window (call this window W1)
Pass it to your C/C++ code
Create the opengl capable window (W2) as a child of W1
Pass the xid of W2 back to python
Use window_foreign_new with W2's xid to create the new gtk.gdk.window object
Each time you call glXSwapBuffers on W2 gtk should then be able to react to expose events.
One bit that really threw me is that if W2 covers the whole of W1 then W1 won't receive events until W2's buffers get swapped. This is particularly confusing if W1 is a top-level window as it can be that nothing appears on your screen at all (the window is there but it looks like whatever is behind it until it gets painted to, which won't happen until it gets an expose event).
Also note that you'll have to manually manage the resizing of W2 by connecting to the gtk resize events. You can do this by connecting to this signal, then calling this function in the handler and passing the results to your c/c++ module where you can resize W2 appropriately. Its a good idea to request a minimum size.
You don't need to create a new window, you pass an existing window to glXMakeCurrent().
In your current setup you'd need to:
XGetWindowAttributes() to retrieve the visual the window was created with
glXCreateContext() using this visual
glXMakeCurrent() using this context and the window id
However, this is doing it backwards, forcing OpenGL to use the visual used for CreateWindow. This often works because the default visual has sane GLX properties, but a correct application will glXChooseVisual with desired GLX properties, then use that visual to create the window.
I have an application with an OpenGL window as a child window of the main window.
When I display a dialog box above the OpenGL window, it doesn't get drawn. It's like it's not getting WM_PAINT messages. If I can guess the title bar position of the dialog box, I can drag it and it's still responsive.
I realise this might be a vague question, but I was wondering if anyone else has seen this sort of behaviour before and knew of a solution?
I wondered if the Pixel Format Descriptor would make a difference - I had PFD_DRAW_TO_WINDOW, but changing to PDF_DRAW_TO_BITMAP didn't make any difference. I'm not sure what else I should be looking at?
Bugger. Should have given all the details. I was running Windows in a virtual machine on Mac OS X using Parallels. I upgrade from Parallels 3 to 4 and now everything is working fine. I suspect a Parallels video driver issue.
Thanks to all those who answered with suggestions.
Is your opengl window constantly rendering. It is possible that the 3D hardware is simply rendering into an overlay that is overdrawing your dialog box. If you position the dialog box so it overlaps your main window, can you see some of it?
Try to pause rendering into the main display to see if it effects the results.
You will also need to make sure that your window style ensures the results are clipped...
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
You should check though all the items mentioned in this MSDN article, as it covers a lot of the basics for getting opengl rendering in a window correctly.
http://msdn.microsoft.com/en-us/library/ms970745.aspx
You may need to switch overlay off. It can be done via forcing back buffer presenting method to copy instead of swap.
Use wglChoosePixelFormatARB and one of parameters should be
WGL_SWAP_METHOD_ARB with value WGL_SWAP_COPY_ARB
This may seems stupid but are you sure your OpenGL window is not flagged "topmost" ?
Does the dialog box disappear also behind borders of your window or just behind the OpenGL rendering rectangle ?