Hello, I'm building a tree/plant generator based on wxWidgets. The main frame has a left panel with all the controls, and a right one with the wxGLCanvas widget.
Here below you can see what it looks like right now:
The application works well, branch/leaves generation is multithreaded and stable. The issue I have is using controls and updating the wxGLCanvas.
Basically all the wxSlider, wxButton controls do not update the wxGLCanvas framebuffer unless I move the mouse a tiny bit after they have run their code. So for example, I use the slider to increase the height, and once the statusbar shows that the routine has finished, I move the mouse and voilà, the framebuffer is updated and the new tree shape modification shows up.
I obviously use wxGLCanvas::Update to perform the opengl update, I also tried to call the opengl Display loop manually without success.
But... and this is the odd part, if I use one of the wxToolbar buttons (those green ones you can see in the interface), they work flawlessly: they run the routine and update the wxGLCanvas correctly.
So I really don't know what the issue could be and a possible solution to it. Any suggestion is greatly appreciated.
One thing I noticed, when using wxSlider for example, is that once I release the handle it looks like it's still selected and sometimes part of the control disappears (see the following image, notice how the slider bar is missing):
wxGLCanvas: weird update issue
- papillon68
- Earned some good credits
- Posts: 118
- Joined: Tue Nov 06, 2007 11:19 pm
wxGLCanvas: weird update issue
Windows 10, MS VC++ 2019 (vc142), WxWidgets 3.14
Designed with WxWidgets: https://www.facebook.com/clorofillaApp
Designed with WxWidgets: https://www.facebook.com/clorofillaApp
Re: wxGLCanvas: weird update issue
Do you create a wxPaintDC in your paint event handler(s)? (You have to, even if you don't use it).
What's the CPU load?
What's the CPU load?
Use the source, Luke!
- papillon68
- Earned some good credits
- Posts: 118
- Joined: Tue Nov 06, 2007 11:19 pm
Re: wxGLCanvas: weird update issue
Hi, yes I do create the wxPaintDC for all the custom controls, like the slider for example.
I made a short Youtube movie that shows how the behavior is: see how after the slider is released, the canvas isn't updated until I move the mouse away. Note also how the slider handle seems to be like clicked or something.
Overlapped the CPU usage monitor and some captions. Cheers.
https://www.youtube.com/embed/-N0UbXWFuvE
Code: Select all
void ClorofillaSlider::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(this);
}
Overlapped the CPU usage monitor and some captions. Cheers.
https://www.youtube.com/embed/-N0UbXWFuvE
Windows 10, MS VC++ 2019 (vc142), WxWidgets 3.14
Designed with WxWidgets: https://www.facebook.com/clorofillaApp
Designed with WxWidgets: https://www.facebook.com/clorofillaApp
Re: wxGLCanvas: weird update issue
For the wxGLCanvas, too?I do create the wxPaintDC for all the custom controls, like the slider for example.
Just for a test, could you replace one custom slider with a standard one?
How do you do the rendering loop? Timer, Idle event, anything else?
The combined CPU load is not so informative. I wanted to see if maybe the main event loop is saturated with events.Overlapped the CPU usage monitor and some captions.
In general, this will be hard to debug from afar. I can only throw out some ideas.
Use the source, Luke!
- papillon68
- Earned some good credits
- Posts: 118
- Joined: Tue Nov 06, 2007 11:19 pm
Re: wxGLCanvas: weird update issue
Thanks, I really appreciate the help and hints. I think I found and solved the issue. The rendering loop is not continuous, i.e. it's updated manually.
It seems that once the multithreading code has run, even calling Refresh(0) or Update() won't actually have any effect on wxGLCanvas.
So my solution (maybe more a hack) was to enable continuous rendering as soon as the multithreading code runs, and disabling it afterwards.
This way, the canvas gets updated properly but I'm studying more this thing, I suppose there is a better way to fix it.
In any case, since you asked, also wxGLCanvas has a wxPaintDC call, and even using base widgets (so not subclassed) would show the issue.
At the end it appears to be a conflict between multithreading and opengl calls.
It seems that once the multithreading code has run, even calling Refresh(0) or Update() won't actually have any effect on wxGLCanvas.
So my solution (maybe more a hack) was to enable continuous rendering as soon as the multithreading code runs, and disabling it afterwards.
This way, the canvas gets updated properly but I'm studying more this thing, I suppose there is a better way to fix it.
In any case, since you asked, also wxGLCanvas has a wxPaintDC call, and even using base widgets (so not subclassed) would show the issue.
At the end it appears to be a conflict between multithreading and opengl calls.
Windows 10, MS VC++ 2019 (vc142), WxWidgets 3.14
Designed with WxWidgets: https://www.facebook.com/clorofillaApp
Designed with WxWidgets: https://www.facebook.com/clorofillaApp
Re: wxGLCanvas: weird update issue
Some comments, just to set it clear.
The best way to do wxGLCanvas update is to have a wxPaintEvent handler (i.e. void OnPaint(wxPaintEvent& evt)) in your wxGLCanvas class. This is what @doublemax is asking to be sure. This OnPaint() will be called automatically by the OS when it needs the window to get repainted.
And you can call this OnPaint handler also whenever you need it. After data is changed, or point of view changes or whatever. Be aware that it's much more better to call wxGLCanvas::Refresh() instead of wxGLCanvas::OnPaint.
You are using multithreading. Good. Remember to set as current the gl-context in the thread that uses gl-commands before they are used.
Finally, if your rendering is fast enough, then good to you. If not, measure where the flow struggles; perhaps the working thread, perhaps data transfer to GPU. If it's the thing that nothing can be accelerated, then you should render in chunks (and show them), so as the user see that the app is not stalled.
The best way to do wxGLCanvas update is to have a wxPaintEvent handler (i.e. void OnPaint(wxPaintEvent& evt)) in your wxGLCanvas class. This is what @doublemax is asking to be sure. This OnPaint() will be called automatically by the OS when it needs the window to get repainted.
And you can call this OnPaint handler also whenever you need it. After data is changed, or point of view changes or whatever. Be aware that it's much more better to call wxGLCanvas::Refresh() instead of wxGLCanvas::OnPaint.
You are using multithreading. Good. Remember to set as current the gl-context in the thread that uses gl-commands before they are used.
Finally, if your rendering is fast enough, then good to you. If not, measure where the flow struggles; perhaps the working thread, perhaps data transfer to GPU. If it's the thing that nothing can be accelerated, then you should render in chunks (and show them), so as the user see that the app is not stalled.
- papillon68
- Earned some good credits
- Posts: 118
- Joined: Tue Nov 06, 2007 11:19 pm
Re: wxGLCanvas: weird update issue
Thanks Manolo, you gave me too lot of good advises. Especially not to forget to set the opengl context as current in the main thread (which I missed). The application works pretty well so far and it's quite robust performance-wise, I really love the wx libraries.
Windows 10, MS VC++ 2019 (vc142), WxWidgets 3.14
Designed with WxWidgets: https://www.facebook.com/clorofillaApp
Designed with WxWidgets: https://www.facebook.com/clorofillaApp