Confused with paint, update, refresh etc. Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
art-ganseforth
Earned some good credits
Earned some good credits
Posts: 116
Joined: Mon Sep 01, 2014 10:14 am

Confused with paint, update, refresh etc.

Post by art-ganseforth » Fri Oct 05, 2018 4:03 pm

Hi there,

i've two sifferent questions, so for the second one i open another thread. Here is the first: Im globally a bit confused concerning the process of updating and painting.

I work on an application using OpenGL to render on wxGLCanvas-controls. Also i use various other controls, like wxTextCtrl, wxStaticBitmap and wxFrame. The application is modular. So predefined groups of controls can be added and removed at runtime.
In order to have a interface that does not care about, which kind a control has, i use a container-control-class (clsControl) derived from wxPanel. So, each wxTextCtrl, wxStaticBitmap etc. is placed in an own clsControl::wxPanel. Like this, for most operations it's not needed, to know, what's inside the wxPanel.

In order to save CPU-time, for most controls i want to use m own paunt-calls - especially, because if the program is running, it renders frames @ 30 or 60Hz (or other framrates if it's configurated for). Therefore, various controls are painted by this. So extra-refreshes, by the system are not needed.

Unfortunately i've several problems in understanding how all the flags and fuctions concerning this, work together. Just for example:
  • wxWS_EX_PROCESS_UI_UPDATES
  • SetBackgroundStyle, and its flags
  • wxEVT_UPDATE_UI
  • wxUpdateUIEvent::SetUpdateInterval
  • etc.
Also i'm not sure, when to call event.Skip() in the paint-event-handler.

However, currenty i don't get my main-output to work.

I've two kinds of outputs, with each of them may be instanced several times. One is a preview (so a small wxGLCanvas in the main-window) the other type (the output) is placed in a wxFrame and should fill it completly. As explained, both are using clsControl::wxPanel as containers and differ only in the creation-process, which has the following code (the first one doen't work):

Code: Select all

    if (Type == "SCREEN") {     Type = "DISPLAY"; 
        SetName                 ("CONTROL:SCREEN");     
    
        CTRLframe   = new       clsFrame            (this,   -1, GetTitle(), wxDefaultPosition, wxSize(1024, 630), wxCAPTION | wxRESIZE_BORDER | wxSYSTEM_MENU | wxMINIMIZE_BOX | wxMAXIMIZE_BOX, "OUTPUT");

        CTRLcanvas  = new       wxGLCanvas          (CTRLframe,  Kontext, -1, wxPoint(0,0), wxSize(1024, 630), 0);
        CTRLframe   ->Parser    = Parser;           Parser  ->Frame     = CTRLframe;
        
        CTRLcanvas              ->Connect           (wxEVT_PAINT,         wxEventHandler(clsControl::OnPaint), NULL, this);
        CTRLcanvas              ->SetBackgroundStyle(wxBG_STYLE_PAINT    );
        CTRLframe               ->Show();
        CTRLcanvas->Show();
        this                    ->Hide();
    }   
    if (Type == "DISPLAY") {
        SetName                 ("CONTROL:DISPLAY");     

        CTRL            ->Hide();  
    
        CTRLcanvas  = new       wxGLCanvas          (this,  Kontext, -1, wxPoint(0,0), GetSize(), 0);
        
        CTRLcanvas              ->Connect           (wxEVT_LEFT_UP,  wxEventHandler(clsParser ::ParseOnEvent),  NULL, Parser);
        CTRLcanvas              ->Connect           (wxEVT_RIGHT_UP, wxEventHandler(clsParser ::ParseOnEvent),  NULL, Parser);

        CTRLcanvas              ->Connect           (wxEVT_PAINT,    wxEventHandler(clsControl::OnPaint),     NULL, this);
        CTRLcanvas              ->SetBackgroundStyle(wxBG_STYLE_PAINT    );
    }   
As you can see, in both cases, the paint-event-connect-call and SetBackgroundStyle are identical for the wxGLCanvas. The only difference, is that in the first case, the parent window is a frame. In both cases, the events are catched not from the wxGLCanvas, but from the containing clsControl::wxPanel.

The event-function is currently chaotic. But it's structure is this:

Code: Select all

void clsControl:: OnPaint    (wxEvent& event) {                 Print(Mode);  // for debugging  
      
    if      (CTRLcanvas && CTRLcanvas->IsShownOnScreen()) {         event.Skip();     
[...]
    }
    else if (CTRLcanvas )    Print(Mode+" - (offscreen)"); // for debugging
    
    else if (CTRLbitmap && CTRLbitmap->IsShownOnScreen()) {              
[...]
For both cases, the event is triggered by this line, somewhere else in the program:

Code: Select all

if  (Control->CTRLcanvas) {             Control->CTRLcanvas->Refresh(); Control->CTRLcanvas->Update();  }
What i'm wondering about, is the following: The last line is (i tested this) executed for both types, but the clsControl:: OnPaint -function is not entered, for the clsControl containing the output-canvas. Only, for the previews it is executed.

By the way: It's the onl paint-function i have. So there is nothing else catching paint-events. So missing Skip() is not he problem.

Would be nice if someone had an idea, what the problem migt be...


Best,
Frank

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3263
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Confused with paint, update, refresh etc.

Post by ONEEYEMAN » Fri Oct 05, 2018 4:30 pm

Hi,
First and foremost - you should call event.Skip() in the paint event handler. If you are notg doing this it means that the system does not handle the event - only you are. This is to clarify it - if the event is not wxCommandEvent you absolutely have to call event.Skip() unless you know what you are doing. Of course there are exceptions, but they are very rare.

Now, in terms of your design - I hope that your OpenGL control is also in its own panel because it uses different painting mechanism than all other native controls.
I've two kinds of outputs, with each of them may be instanced several times. One is a preview (so a small wxGLCanvas in the main-window) the other type (the output) is placed in a wxFrame and should fill it completly. As explained, both are using clsControl::wxPanel as containers and differ only in the creation-process, which has the following code (the first one doen't work):
1. What exactly doesn't work?
2. How it doesn't work?
3. Where it doesn't work?


Also, you need to understand that OpenGL has its own painting mechanism which is different from the actual painting oif the graphics or controls.

Having said all that, I'd like to ask more question, which are the very basic for all questions/posts on wx-forum/wx-ML:

1. OS you use for testing?
2. wx version you are using?
3. toolkit you compiled your program against?
4. Compiler and compiler version you are using to build the code?
5. Any non-default parameters you are using to build the library?
6. Is there a mix between wx build options and build opetions of your software?

Thank you.

art-ganseforth
Earned some good credits
Earned some good credits
Posts: 116
Joined: Mon Sep 01, 2014 10:14 am

Re: Confused with paint, update, refresh etc.

Post by art-ganseforth » Fri Oct 05, 2018 5:21 pm

1. What exactly doesn't work?
If i call refresh (3rd posted code-fragment), the paint-event-function is "triggered" only for the previews, not for the output. I've a log-file, where i can precisely see, what is called.
2. How it doesn't work?
I'm not sure. It has to do with that the in code-fragment 1 connected event-function is not called for the canvas in the frame. As far as i understand this, the 3rd code-fragment should trigger this function in all cases. So - im my eyes, there is something blocking it, that i don't have in mind.
3. Where it doesn't work?
I think this should be clear now.
Also, you need to understand that OpenGL has its own painting mechanism which is different from the actual painting oif the graphics or controls.
I'm absolute no newbie and my application is a complex thing where i work on for some years now. In fact, what i do is normally done b a team. Small example?

Code: Select all

    var Sin          = 'IntCT = 0 + v1.Get() * bCT;
           R1.Set01(        (sin01(v2.Get()   + IntCT) * v3.Get()));
';
    var CubicM       = 'IntCT = 0 + v1.Get() * bCT;
           R1.Set01( scale01(pow01(mirror01(2 * IntCT),  v2.Get()*v2.Get()*v2.Get()*8),  v3.Get()));
';
    var Cubic        = 'IntCT = 0 + v1.Get() * bCT;
           R1.Set01(        (pow01(mirror01(2 * IntCT),  v2.Get()*v2.Get()*v2.Get()*8) * v3.Get()));
';

//    var SModulate    = 'R1.Set01( pow(v1.Get() * v2.Get(), 0.5));';
    var SSinM        = 'R1.Set01( v3.Get() - scale01(cos01(v2.Get()   + v1.Get()),  v3.Get()));';
    var SSin         = ' R1.Set01( v3.Get() -        (cos01(v2.Get()   + v1.Get()) * v3.Get()));';
    var SCubicM      = 'R1.Set01( v3.Get() - scale01(pow01(v1.Get(), v2.Get()*v2.Get()*v2.Get()*8),  v3.Get()));';
    var SCubic       = ' R1.Set01( v3.Get() -        (pow01(v1.Get(), v2.Get()*v2.Get()*v2.Get()*8) * v3.Get()));';

    var ActiveFunction = 'R1.Set01(0);';

    var SetFunction  = '        fnc = selFnc.GetInt(); 
        if      (fnc ==  0) { var ActiveFunction = "R1.Set01(0);";        }

        else if (fnc ==  2) { var ActiveFunction = ITrigger;  }
        else if (fnc ==  3) { var ActiveFunction = Intern;    }
        else if (fnc ==  4) { var ActiveFunction = ISinM;     }
As you see this fragment is no c-code. It's executed by my own interpreter. But i'm autodidact and not native english speaking. So sometimes it is not easy for me, to understand the references - esepecially if they use advanced terminology.
Having said all that, I'd like to ask more question, which are the very basic for all questions/posts on wx-forum/wx-ML:

...
wx2.9.3 (i think) [update: 2.9.7], win 10, MinGW. No advanced settings, no other libraries then std-things, wxWidgets, and glut. I'm lucky that everything works as it is.


Best,
Frank

Manolo
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 686
Joined: Mon Apr 30, 2012 11:07 pm

Re: Confused with paint, update, refresh etc.

Post by Manolo » Fri Oct 05, 2018 7:03 pm

Some thoughts about your code.

1) Don't use fixed sizes for the controls. If your app is executed with another window resolution all sizes (including text size) will be weird sizes. If the user is allowed to change the size of some window then all related windows should change their size accordingly. Use wxSizers.

2) wxControls redraw themselves when it's needed: size change, uncovered part, window move, user input, etc. The "paint" command is issued by the OS itself. Normally the OS waits to gather several paint-events (if they happen too quickly) and then draw the controls. "Too quickly" can be slow enough as to suffer flicklering. How "quickly" can be set by wxUpdateUIEvent::SetUpdateInterval.

You can ask the OS to do painting, by wxWindow::Refresh or wxWindow::Update. Then the bound function you have set (by "Connect" or "Bind" or an event-table) is called, typically "OnMyPaint(wxPaintEvent &event)". Inside this fucntion you absolutely must create a wxPaintDC or else you get an endless succession of paint messages.

Normally a evt-paint handler does not require the use of Skip. Skip(false) means "stop propagating the event to other handlers". For example the user types an unallowed character, you have a event-char handler, and prevent the OS to draw it on the control by this call.
If you have a "OnMyPaint" for each panel then be aware that the children of this panel will also be called for redraw. It's here where event.Skip() is needed to ensure the children are also redraw. For example, wxGLCanvas doesn't have children, but has its own OnPaint. To allow the parent to continue with the rest of children, use Skip in this OnPaint. Set it t "false/true" to see if the other children are drawn or not.

If you want to avoid repainting you can use wxWindow::Freeze or better wxWindowUpdateLocker. These functions have sense if you handle the evt-paint in the parent panel. If so, no evt.Skip is needed.
So you can have a list of what children should be repainted or not, and call wxWindowUpdateLocker for each not-repaint required.

3) As I told you in other question, before drawing into a wxGLCanvas set its context as current.

4) Don't set background style for a wxGLCanvas, nor clear its background (when using Refresh). They make no sense because you will use glClear before rendering, right?

5) If you use wxWidgets then glut is useless. All windows handling is done by wxWidgets. Don't confuse glut with glu. The latter is used in old OpenGL for some features, like gluLookAt, gluPerspective, etc. Also useless in new OpenGL.

art-ganseforth
Earned some good credits
Earned some good credits
Posts: 116
Joined: Mon Sep 01, 2014 10:14 am

Re: Confused with paint, update, refresh etc.

Post by art-ganseforth » Fri Oct 05, 2018 8:53 pm

At first: Thank you very much, for takin the time to read my posts ;)
Manolo wrote: 1) Don't use fixed sizes for the controls. If your app is executed with another window resolution all sizes (including text size) will be weird sizes. If the user is allowed to change the size of some window then all related windows should change their size accordingly. Use wxSizers.
With sizers i had various problems. Especially because i combine a lot of horizontal an vartically ordered controls and also because i'm for several reasons forced to use some controls with fixed positions (which doen't combine well). My positioning mostly works fine (except of one provisoric redundnt if-then-decision, which i know how to remove - with some work)
2) wxControls redraw themselves when it's needed: size change, uncovered part, window move, user input, etc. The "paint" command is issued by the OS itself. Normally the OS waits to gather several paint-events (if they happen too quickly) and then draw the controls. "Too quickly" can be slow enough as to suffer flicklering. How "quickly" can be set by wxUpdateUIEvent::SetUpdateInterval.
As far as i know from working with wxWidgets for several years now, this is right for simple things. Once i.e., i programmed a file-manager, using a wxGrid(?) or something like this (the abstract one, without internal data). Reading all the files (several thousands), for each entry in the grid (per file around twenty), an ui-update was proceeded. Calling the uptate manually after reading 10 or 20 files, speeded up that application 10x.

Also: In this case, i use around 20-30 small (size: 24x24 pixels or 8x8 pixels) wxStaticBitmap-controls i.e. as scope to display varying valuse or as color display. Since i update them manually with an interval around 100ms, my application needs ~10% less CPU.
[...] you absolutely must create a wxPaintDC or else you get an endless succession of paint messages.
Really? Thought, that i used the paint-event for the wxGLCanvas without wxPaintDC for a long time now. But anyway: Creating a wxPanitDC and then using OpenGL to render on the canvas seems to be redundant (after a short test, it seems to make no difference if i do or not). Also: as long as the paint-event-function is ignored, it doesn't matter if i create it, or not.
Normally a evt-paint handler [...]
This ansers some of my questions (i.e. if refresh causes children to be repainted). In my application, with some exceptions each specialized control (each one that does more then keeping other controls) is the only child of it's parent. I'm not sure how to explain this...
If you want to avoid repainting you can use wxWindow::Freeze or better wxWindowUpdateLocker. These functions have sense if you handle the evt-paint in the parent panel. If so, no evt.Skip is needed.
So you can have a list of what children should be repainted or not, and call wxWindowUpdateLocker for each not-repaint required.
A long tome ago, i did so. But it was not good. With wxGrid it was (as far as i remember) i.e. lik this, that after thawing, the complete grid was repainted cell by cell.
In this application i also tried it. Maybe i did somethin wrong, but the effect was that thaw caused a repaint of all my ~500 controls at once - while the main-output was freezed. Not nice if you do video-mapping. So continous updating of small elements is obviously better.
3) As I told you in other question, before drawing into a wxGLCanvas set its context as current.
Sorry, this i don't understand (or it is so obvious, that i don't see the point
4) Don't set background style for a wxGLCanvas, nor clear its background (when using Refresh). They make no sense because you will use glClear before rendering, right?
It's special thing of my program that glClear is not called in every case. But its like this: i render everythin internally using FBOs. The output (to previews or screens) is done in a second step, simply renering the complete internally generated image (texture) to the canvas at once. So concerning the outputs, everything is redrawn and clear is redundant - so far you're right.
I thought (after reading the documentation), setting the background-style to ..._PAINT, will prevent the system-repaints. But i can delete this line. Anyway, this is as far as i see noth the reason for the missing repaint of the output. Because for the other wxGLCanvas-controls i've also set the background-style.
5) If you use wxWidgets then glut is useless. All windows handling is done by wxWidgets. Don't confuse glut with glu. The latter is used in old OpenGL for some features, like gluLookAt, gluPerspective, etc. Also useless in new OpenGL.
[/quote]
I had a hard problem with crashes until i used some special glut-things. Maybe (i would guess this) that is implement glut, is the reason that wxWidgets 2.9.7 works with advanced OpenGL-things.


However: I learned some intresting details now, but the problem with the output still exists.

Best,
Frank

User avatar
doublemax
Moderator
Moderator
Posts: 13573
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Confused with paint, update, refresh etc.

Post by doublemax » Fri Oct 05, 2018 9:31 pm

But anyway: Creating a wxPanitDC and then using OpenGL to render on the canvas seems to be redundant (after a short test, it seems to make no difference if i do or not). Also: as long as the paint-event-function is ignored, it doesn't matter if i create it, or not.
Trust us: You must do it under Windows, otherwise the system will constantly create new paint events for that window.
If i call refresh (3rd posted code-fragment), the paint-event-function is "triggered" only for the previews, not for the output.
So you're saying it doesn't display at all? It shouldn't make any difference if you call Refresh() or if the system just ask the window to draw.

Code: Select all

CTRLcanvas  = new       wxGLCanvas          (this,  Kontext, -1, wxPoint(0,0), GetSize(), 0);
The GetSize() here is a little suspicious. Are you sure this returns a valid size when this line gets executed?
Also: In this case, i use around 20-30 small (size: 24x24 pixels or 8x8 pixels) wxStaticBitmap-controls i.e. as scope to display varying valuse or as color display. Since i update them manually with an interval around 100ms, my application needs ~10% less CPU.
This doesn't make any sense at all. This can only lead to more updates, never to less. If you really measure a performance difference (10% is not much and hard to reliably detect), there must be another reason for it.
Use the source, Luke!

art-ganseforth
Earned some good credits
Earned some good credits
Posts: 116
Joined: Mon Sep 01, 2014 10:14 am

Re: Confused with paint, update, refresh etc.

Post by art-ganseforth » Fri Oct 05, 2018 11:03 pm

I like you posts - quiet houmorous ;)
Surely i trust you.
I was just wodering because endless calls should crash the application, but m paint-function is not new. So, somewere all the paint-events must have been stuck all the time. Especially as i - for testing - run it often, befor i get to sleep, to see wif it's still working next morning. This means 30/60 paint-events per second...
So you're saying it doesn't display at all? It shouldn't make any difference if you call Refresh() or if the system just ask the window to draw.
I've wxGLCanvas in two - hmmm - arrangements. As only child of a wxFrame that i call "output" and as "preview", which is a small one in the main-window. The final configuration will be a control-window (wxFrame) on the main display (containing several "previews") and one ore more "outputs" on external devices.

In both cases there is a container-control added to a sub-window (wxPanel) of the main-window (wxFrame), but if it is a preview, the wxGLCanvas is a child of the wxPanel. If it is created as output, the container (wxPanel) is hidden. Instead, first a wxFram is created and the wxGLCanvas is placed in it. But functions of the (then hiden) container are called for several things. The container-class (if hidden or not) decides what to do then internally.
Note: The frame and the canvas are visible. The hidden contailer-control just process the events.
The GetSize() here is a little suspicious.
It's a function of the container-control. CTRLcanvas is it's child.
Here my english maybe reaches it's limits, but: If a control creates a child in its constuctor, for the size of the child, the term "this->GetSize()" or "this->GetClientSize()" is correct and, as far as i understand, this is not only correct for constructors, od am i wrong?.

The point is, (this is sometimes a bit confusing for me also), that there are always two controls created. I have no clsGLCanvas and no clsTextCtrl, derived from the wx-classes. I use the wx-classes pure. I've only the clsControl::wxPanel. In one case it has a wxGLCanvas inside, in the other a wxTextCtrl etc.
Therefore the GetSize, gets the size of the container to apply the same size to the wxGLCanvas that is created.
This doesn't make any sense at all. This can only lead to more updates, never to less. If you really measure a performance difference (10% is not much and hard to reliably detect), there must be another reason for it.
Hmmmm...
It' a while ago, but: yes.

Actually it's like this: I tested arund a lot, with the update-times of wxWidgets (and also with the performance of other wx-objects, like wxString).
I'm sure, that i did not understand the core of it yet - not at least because there are many parameters and possibilities (like catching ui-updeates with empty functions etc...), that it's not possible to test every combination sytematically.

On the other hand: maybe were all the time the lost paint events, that made it slow. Is this possible?

User avatar
doublemax
Moderator
Moderator
Posts: 13573
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Confused with paint, update, refresh etc.

Post by doublemax » Sat Oct 06, 2018 12:43 am

Can you post a screenshot or is everything secret?

Honestly, i have no idea what your program is doing. You're doing so many things in "unique" ways that it's hard to tell if the problem is there or somewhere else.
I was just wodering because endless calls should crash the application
It's not a recursion. It's just that when the paint event handler is finished and you didn't create a wxPaintDC, Windows will "think" that the window has not been painted at all and will send another WM_PAINT message.


And although you wrote a lot of text, you didn't answer this question (at least not in a way i could understand):
So you're saying it doesn't display at all? It shouldn't make any difference if you call Refresh() or if the system just ask the window to draw.
What i wanted to know: Is the window initially (= program start) displayed correctly. Does it have the correct size and is just blank or black or is it not visible at all?

Regarding GetSize(). I was talking about the fact that GetSize() might not give the expected result during window creation and that you should just check its value. Maybe the window is not rendered because its size is (0,0).

Another reason why a paint event handler could not get called, is when the window is totally obstructed by another window.
Use the source, Luke!

art-ganseforth
Earned some good credits
Earned some good credits
Posts: 116
Joined: Mon Sep 01, 2014 10:14 am

Re: Confused with paint, update, refresh etc.

Post by art-ganseforth » Sat Oct 06, 2018 1:02 am

Can you post a screenshot or is everything secret?
How to? Just wanted to do this, so i made one, but i don't know to use the *bracket*img*bracket* tags.

I posted one here: https://www.opengl.org/discussion_board ... ost1292684 today.


Just a short answer. More follows...

art-ganseforth
Earned some good credits
Earned some good credits
Posts: 116
Joined: Mon Sep 01, 2014 10:14 am

Re: Confused with paint, update, refresh etc.

Post by art-ganseforth » Sat Oct 06, 2018 1:30 am

So you're saying it doesn't display at all? It shouldn't make any difference if you call Refresh() or if the system just ask the window to draw.
I' wondering also. The frame is not refreshed at all. Neither by the system nor by Refresh()-calls. For testing i did several things: I gave the frame another background-color then the wxGLCanvas. If i enlarge it now, the original size stays white. The new area is black (as the frame-background-color). But i don't catch size-events.
The second thing i did (after your post concerning paint events) is:
I commented out the ollowing two lines:

Code: Select all

        CTRLcanvas              ->Connect           (wxEVT_PAINT,    wxEventHandler(clsControl::OnPaint),     NULL, this);
        CTRLcanvas              ->SetBackgroundStyle(wxBG_STYLE_PAINT    );
So, there is no paint-event at all, connected to the canvas (system should do it now, as far as i undersand).
To realize this, i splitted the paint-event-function like this:

Code: Select all

void clsControl:: OnPaint    (wxEvent& event) {           event.Skip(); 
    Paint    ();                
} 
void clsControl:: Paint    () {            //     Print(Mode);    
[...]
so, the second part can becalled direct instead of using the draw-event (which is not connected anymore).
The result is nothing. The frame stays white until i enlarge it (as said).

The third thing i did is, to log the size of the canvas in the moment of the output. Taking this for real, the canvas has 20x20 pixels, which is quiet strange. In between i repaced the "GetSize()" you talked about, agaist a fixed wxSize(1024,600), but still the reported size is 20x20px.

All in all this is quiet confusing for me.

art-ganseforth
Earned some good credits
Earned some good credits
Posts: 116
Joined: Mon Sep 01, 2014 10:14 am

Re: Confused with paint, update, refresh etc.

Post by art-ganseforth » Sat Oct 06, 2018 1:34 am

What i wanted to know: Is the window initially (= program start) displayed correctly. Does it have the correct size and is just blank or black or is it not visible at all?
There are two windows. The control (main) window, containing lots of controls, and the output (one or more), containing only one wxGLCanvas each. The last one stays white, everything else is updated correctly.

art-ganseforth
Earned some good credits
Earned some good credits
Posts: 116
Joined: Mon Sep 01, 2014 10:14 am

Re: Confused with paint, update, refresh etc.

Post by art-ganseforth » Sat Oct 06, 2018 1:37 am

Another reason why a paint event handler could not get called, is when the window is totally obstructed by another window
This was the first thing i tested. I work with two monitors.

art-ganseforth
Earned some good credits
Earned some good credits
Posts: 116
Joined: Mon Sep 01, 2014 10:14 am

Re: Confused with paint, update, refresh etc.

Post by art-ganseforth » Sat Oct 06, 2018 2:28 am

Concerning my program in general: I've spent a lot time in preparations (around 3 years), where i used it sometimes for some video-mapping, but all the time most was provisoric.

In between i've an interpreter, that can do most things i need. It controls the creation-of the UI (sizes, colors, control-types etc.) and it controls most of the OpenGL calls directly or by using small classes, that i progrmmed in c.

The complete program is modular. I can add modules and link them under each other, like i.e. there is the possibility to txture objects with fixed as also rendererd textures that are created by other modules. Also module-files can be modiied at runtime until up to comleatly create ne modules. This works mostly integrated with shaders. So the code interpretrd by my interpreter and OpenGL-Shaders are nearly integrated as if they are the same programming-laguage - not totally, but it ges better and better.

Just for exampe a module-definition as interpreted by my interpreter (one without shaders):

Code: Select all



    var Type         = "MACRO";
    var Title        = 'Object';

//    var Position     [x, y];
//    var Size         [1, 5];
    var Page         = _MD_PG_ACTIVE;

    InitControl      (Type, __File, 'Objects');

    SetPosition      (x,  y);
    SetSize          (1,  5);

    var TitleBar     = new titleBar('_MD_BUTTONS_ALL', '_MD_STORE_TEXTURE_MENU');
    
    var vcSync       = new valAny      ('1/96 Sync',    0,   0,  2,   0,  96,   1,     0);
    var selLevel     = new selList     ('Depth level',  2,   0,  7,   'Macro|Foreground|Background|Lanscape|Infinity', 'Foreground');
    var vcScale      = new valAny      ('Size',         9,   0,  3,   0,   4,   0.01,  1);
    var ccColor      = new colorAnyHSV ('Material',     0,   1,  6, 210,  64, 255);
    var vcLight      = new valAny      ('Light',        6,   1,  3,   0,   1,   0.05,  0.5);
    var vcEdge       = new valAny      ('Edge',         9,   1,  3,   0,   1,   0.05,  0.8);
//  var selUseDepth  = new selList     ('Depth-test',  12,   1,  2,   ' -| X', ' X');
    var selTexture   = new selModule   ('Texture',      0,   2, 16,   'Shader|Texture|Texture through|Renderer', 'StockImage');
    var selVBO       = new selModule   ('VBO',          0,   3, 16,   'VBO', 'VBO-Shader');
    var selPosition  = new selModule   ('Position',     0,   4, 16,   '3d through-pos', 'Position', 2);

    var Radius       = 1;
    var specColor    = 1;


    var OnPrepare    = 'selVBO.Prepare();';

    var OnApply      = '   
        ccColor         .UpdateRGB();

//        ResetGL_TexSettings();

//glColor4f       (1, 1, 1, 1);
//        glColor3fv      (ccColor.Color);
//        specColor       = vcLight.Get01();
        glMaterialf     (GL_FRONT_AND_BACK, GL_SHININESS, vcEdge.Get01());
        glMaterialfv    (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, ccColor.Color);
        glMaterialfv    (GL_FRONT_AND_BACK, GL_SPECULAR, [vcLight.Get01(),vcLight.Get01(),vcLight.Get01()]);

        glMatrixMode    (GL_TEXTURE);      glPushMatrix ();
        glMatrixMode    (GL_MODELVIEW);    glPushMatrix ();

        selTexture      .Apply();

        selPosition     .Apply();
        Radius          = vcScale.Get() * (0.1 * pow(4, selLevel.GetInt() + 1) + 1) * 0.25;
        glScalef        (Radius, Radius, Radius);

        selVBO          .Apply();

        glMatrixMode    (GL_TEXTURE);      glPopMatrix  ();
        glMatrixMode    (GL_MODELVIEW);    glPopMatrix  ();
';
As you see, there ate various gl... calls inside. Like this, i abstrahared most OpenGL-instructions, basic math, simple string manipulations (regex will follow) and various wxWidgets-things.

The Interpreter is (concerning math) quiet standard: A cascade of functions for each operator-prcedence-level (details on request, but i think you know what i mean). Variables and functions (mostly strings) are kept in maps that (to be faster) are presorted by the first letter. So there is a class containing ~40 maps - one for each possible first letter. These are something like nametabels.

A central point is, how integrated function are called. Here is an extract (also the irst letter...):

Code: Select all

    else if     (nam[0] == 'a') {
        if      (!strcmp (nam, "abs"))          (num1) = (fabs(list[0][0]));          
        else if (!strcmp (nam, "asin"))         (num1) = (asin(list[0][0]));
        else if (!strcmp (nam, "acos"))         (num1) = (acos(list[0][0]));
        else if (!strcmp (nam, "atan"))         (num1) = (atan(list[0][0])); 
    }
But i already have the concept for something thats nearer to a compiler.


Interpreters are cascaded in my program. Each clsControl::wxPanel-container has its own, but it can access all variables of it's parents, simelar to derived classes in C. So, every variable defined in the root-interpreter, are globally accessable but child-interpreters can "overload" them.



After some huge steps in the last weeks, i reached the state now, where it is - hmmm - at the edge of beeig professional, but i've to debug a bit (it's not stabel currently). This is why i ask so much currently. If this is done i'll give it everyone who is interested in.


Best,
Frank

User avatar
doublemax
Moderator
Moderator
Posts: 13573
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Confused with paint, update, refresh etc.

Post by doublemax » Sat Oct 06, 2018 8:19 am

There are two windows. The control (main) window, containing lots of controls, and the output (one or more), containing only one wxGLCanvas each. The last one stays white, everything else is updated correctly.
Ok. The first thing to find out is where this white comes from, e.g. is it the background color of any window? As you already mentioned before, try setting distinctive background colors for the windows that are involved.

Also try replacing the "invisible" GLCanvas with a plain wxPanel and check if it shows up.

Code: Select all

CTRLcanvas  = new       wxGLCanvas          (this,  Kontext, -1, wxPoint(0,0), GetSize(), 0);
Have you tried replacing GetSize() with hardcoded values?

Code: Select all

void clsControl:: OnPaint    (wxEvent& event) {           event.Skip(); 
Is this real code? Why does it say wxEvent when it should be wxPaintEvent?
Use the source, Luke!

art-ganseforth
Earned some good credits
Earned some good credits
Posts: 116
Joined: Mon Sep 01, 2014 10:14 am

Re: Confused with paint, update, refresh etc.

Post by art-ganseforth » Sat Oct 06, 2018 11:14 am

Sometimes its good to sleep over....

After reading your post, i first used a text-ctrl to check if how other contrls in the frame would behave. Then i had the idea to give the canvas a tool-tip. So i could see, what is canvas, even if there is no refresh.
In both cases, the result was the expected (text-control / canvas cover frame-window). The more i wondered, that logging the tooltip in the paint-function results an empty string and size of the canvas still 20x20px...

So, i thought: it seems to be as if CTRLcanvas ist overwritten by another canvas (seemd redicolous, but afer all what i tested, i was really considering this). In fact i was right. It was one of this things that are as simple as unexpected. Therefore i searched a the wrong place.

It was a missing "else" in the creation-function (here correct, with "else"):

Code: Select all

    if (Type == "SCREEN") {     Type = "DISPLAY"; 
[...]
    }   
    else if (Type == "DISPLAY") {
[...]
    }   
Some weeks ago, the upper one was placed under the second one, but like this, there must be an else, otherwise both are executed. So in fact CTRLcanvas had bee overvritten by a second canvas placed somewhere in nirvana. So all the paint-calls used this one and not the one in the frame-window, do draw on.




However: This doen't change really much on the fact, that i'm stil cofuse about how all this updating-flags work together in detail..

Post Reply