GLUT window turns black "(not responding)" when CPU is busy - glut

I'm programming a raytracer and use GLUT to display the result. I render the the image in subblocks and after rendering each subblock i update the view.
What happens is that i see the render progress, but after some seconds, the render window turns black and the window caption reads "(not responding)". the renderprocess however continues to run (at 100% cpu usage) and outputs progressinfo on the console output. once the rendering is finished, the GLUT window turns back to normal and displays the image.
What can I do in order to keep the window responding during the rendering process so that it doesn't turn black?
Thanks!
//edit: I aparently block my mainthread while waiting for the render threads:
while(true){
if(m_activeRenderThreads==0)
break;
::WaitForSingleObject(updateEvent->m_hObject, 200);
notifyObservers(); //inherited from IFunctionObservable
}
notifyObservers() calls:
update(){
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0,0,resX,resY);
glRasterPos2i(-1,-1);
glDrawPixels(resX, resY, GL_RGB, GL_FLOAT, renderBuffer);
glutSwapBuffers();
}
this last function works only if I call it from the mainthread. calling it through the renderthreads doesn't update my window

What you need to do is put all your processing in a separate thread; the main GUI thread should only be used for responding to GUI events and painting the window, but should not do any intensive computations. So... in a separate thread, paint to a buffer, and then every so often you should schedule on the main GUI thread for this buffer to be copied into the UI.

Related

GLUT animation leads to 100% utilization of 1 core when the window is invisible

I developed a Python program that uses PyOpenGL and GLUT for window management to show an animation. In order to have the animation run at the fastest possible framerate, I set
glutIdleFunc(glutPostRedisplay)
as recommended e.g. here.
That works well, I get a steady 60 FPS with not a lot of CPU load.
However, as soon as the window is hidden by another window, one CPU core jumps to 100% utilization.
My suspicion is that while the window is visible, the rate at which the glutDisplayFunc is called is limited, because it contains a call glutSwapBuffers() which waits for vsync; and that this limitation fails when it is invisible.
I tried to solve the problem by keeping track of visibility (through a glutVisibilityFunc) and putting the following code at the beginning of my glutDisplayFunc:
if not visible:
time.sleep(0.1)
return
This does not however have the desired effect.
What's happening here, and how do I avoid it?
I found the solution here,
and it is obvious once you know it: Disable the glutPostRedisplay as glutIdleFunc when the window becomes invisible. Concretely, use a glutVisibilityFunc like this:
def visibility(state):
if state == GLUT_VISIBLE:
glutIdleFunc(glutPostRedisplay)
else:
glutIdleFunc(None)

Freezing OS X Screen in Cocoa

I have two methods that modify the display of the screen. Is there a way to freeze the screen until the second method is called?
// I want to freeze the screen here
updateDisplay1(); // Change in display doesn't take effect until screen is unfrozen
updateDisplay2();
// Unfreeze screen here
In Excel VBA this would be something like screenUpdating = FALSE. Is there a similar function in Cocoa?
One possible way is to take screenshot:
// Take screenshot of the screen
// Display the screenshot image in front of the screen
updateDisplay1(); // Change is not visible
updateDisplay2();
// Remove screenshot image
But I'm afraid this is slow and takes up a lot of memory. Is there a more efficient method?
What screen are you talking about?
Standard Cocoa behaviour is:
you update the properties of the various views you are interested in;
each of those will make a call to its own setNeedsDisplayInRect. As a result of those calls, a redraw will be scheduled on the run loop;
once you've finished doing all of your updates, the run loop will be able to move onto its next item;
eventually it'll reach the redraw it scheduled and will make appropriate drawRect calls to appropriate views.
So all view changes that you make in response to an action are automatically atomic. You have to go significantly out of your own way to create a partial update.
taking screenshots with CGWindowListCreateImage takes a few milliseconds and uses roughly any memory. it's usually done directly in the graphic card.
give it a try and measure before doing any performance assumptions:-)

wxPanel flickering/failure when window is inactive

Basically, I have a wxWidget application that implements OpenGL - the latter is displayed on a panel that can be updated through user input (clicking, dragging, etc), wxTimer, or events generated by external processes. The problem arises when focus is shifted to another window (whether an internal dialog box, or another application entirely) - the wxPanel ceases to update anywhere from immediately to after a few seconds, particularly if the other window is on top of it (sometimes, a small part of the panel that was obscured will still continue to update). Reactivating the application or resizing the window "unfreezes" the panel, and normal operation continues.
This is an issue I've always had in wxWidgets, be it with an OpenGL panel such as in this case, or otherwise. Generally, I've been able to get around it by making numerous SwapBuffer() calls in between a Freeze() and a Thaw() upon window refocusing, window resizing, or something similarly kludgy, but these all have the potential to produce flicker or other non-negligible visual artifacts, and additionally can affect performance if done every frame (such as when an animation needs to continue playing in an inactive window).
An indeterminate period of trial and error could probably produce something nice and kludgy for this also, but I'd really like to know, what is the "right" way to handle this problem? Many thanks in advance.
Here's a skeleton of the code for reference:
void MyGLCanvas::Draw(bool focus, int parentID) //This is what's called by the rest of the application
{
if (focus) { SetFocus(); }
SetCurrent();
wxClientDC dc(this);
Paint(dc);
}
void MyGLCanvas::Paint(wxDC &dc)
{
//All OpenGL drawing code here
glFlush();
SwapBuffers();
}
void MyGLCanvas::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(this);
Paint(dc);
event.Skip();
}
You're doing several strange or downright wrong things here:
Do not skip the event in your OnPaint(). This is a fatal error in wxWidgets 2.8 under Windows and even though we clean up after your code if it does this in 3.0, it's still a bad idea.
Don't use wxClientDC, just call Refresh() and let Windows repaint the window by invoking your existing OnPaint() handler.
Don't call SetFocus() from Draw(), this really shouldn't be necessary.
Do call SetCurrent() before drawing. Always, not just in Draw().
I don't know which of those results in the problems you're seeing but you really should change all of them. See samples\opengl\cube\cube.cpp for an example of how to do it correctly.

continuously update an NSImageView

I have an NSImageView that needs to redraw a constantly updating image.
I have a model object that creates the NSImage, and a controller that links this image to the NSImageView.
With multithreading, I can easily have the model object continuously update its output image in a background thread. But as UI interactions are supposed to be done on the main thread, I can't set the NSImageView's image on a background thread. If I update the NSImageView on the main thread, the program would become unresponsive
I hate to be contradictory but why do you think that updating the image on the main thread would make the program unresponsive?
If calculating the next NSImage is instantaneous then logically you should just calculate and display the last one since none of those in between will ever be perceived.
If calculating the next one costs some time then do the calculation off the main thread then push the image to the view on the main thread (eg, using performSelectorOnMainThread:...). The main thread won't become unresponsive because it has all that time while you're calculating the next image to deal with other events.
If updates are more frequent than the display's frame rate then you can probably go one better by setting yourself up with a CVDisplayLink and polling whatever is updating the image to get the latest one upon every tick of that.
Do not update NSimageView on background thread. it is not thread safe. you should use performSelectorOnMainThread:withObject:waitUntilDone:

In a double buffer opengl context, is it possible that front and back buffer be the same?

I have a situation in which I ask and get a double-buffering OpenGL context, but when I draw in it, both the front and back buffer are affected. The draw buffer is set to the back buffer (And only the back buffer). If I look in OpenGL Profiler, I do see all that: the value for GL_DRAW_BUFFER (GL_BACK) and the actual back and front buffer being drawn to.
Since I'm working with an NSWindow that has a backing store, We do not see any of this happening on the screen. The problem is that I'm getting screenshots of this window with CGWindowListCreateImage. This function seems to be fetching the image from the front buffer, and not from the screen buffer (Wherever that is...). So the image returned is incomplete: it only contains the elements that are drawn at the moment it is grabbed, even if no flush has been called.
There is a utility in the mac developer package called Pixie. It basically grab the screen at the mouse position, and display it zoomed in so you can analyze it. This program has the same behavior than calling CGWindowListCreateImage: you can see incomplete images. So I guess the problem is not with the way I use CGWindowListCreateImage, but rather with my window or my display...
Also, It does not seems to happen all the time. Not every windows show this behavior, and even for a given window, it seems to come and go, especially if I move the window to a different screen (In a dual display).
Anyone faced this before?