OpenGL Component is not repainted


#1

Hello,

i am trying to get my OpenGL Component working. I instantiated my OpenGLCanvas from OpenGLComponent, implemented resized() and renderOpenGL() method. I do not update my window continuously, but only if something is changed, i.e. no timer-event is implemented. Normal window looks this way:

But when i open menu / hide window it gets not repainted:


i wonder, if i did something wrong or is it a feature?

Ruslan


#2

Hi

You have to implement the component’s paint() method, because when the OS needs to redraw a bit of the window for some reason, it’s the paint method that does that job.

It’s a very bad idea to do your drawing “when something has changed”, for many reasons. Instead, do all your drawing in the paint() method and just call repaint() when something changes.


#3

[quote=“jules”]Hi

You have to implement the component’s paint() method, because when the OS needs to redraw a bit of the window for some reason, it’s the paint method that does that job.

It’s a very bad idea to do your drawing “when something has changed”, for many reasons. Instead, do all your drawing in the paint() method and just call repaint() when something changes.[/quote]

no, by “when something changed” i mean that the whole window is not updated explicitly every x milliseconds. And, from the documentation of OpenGLComponent:

void OpenGLComponent::paint(Graphics & g)[virtual]
For internal use only.

what should i write there? The whole paint stuff sits in renderOpenGL() routine…

P.S. tried to write paint(Graphics& g) method, it is not called when the window gets invalidated


#4

(Sorry, I meant renderOpenGL() instead of paint(). Doh!)

Ok, sounds like you’re doing the right thing, there must be a buggette in the windowing code. I’ll investigate…


#5

[quote=“jules”](Sorry, I meant renderOpenGL() instead of paint(). Doh!)

Ok, sounds like you’re doing the right thing, there must be a buggette in the windowing code. I’ll investigate…[/quote]

i think, i found the cause of the problem. In juce_linux_Windowing.cpp the function

void juce_repaintOpenGLWindow (void* context)

is empty. I am searching now, what one can do, to ask the X-server to repaint the window…


#6

No, it’s not that. I’m looking into it at the moment, so will let you know…


#7

Ok, there’s a few tweaks required in juce_linux_Windowing.cpp…

[code] case Expose:
{
// Batch together all pending expose events
XExposeEvent* exposeEvent = (XExposeEvent*) &event->xexpose;
XEvent nextEvent;

            if (exposeEvent->window != windowH)
            {
                Window child;
                XTranslateCoordinates (display, exposeEvent->window, windowH, 
                                       exposeEvent->x, exposeEvent->y, &exposeEvent->x, &exposeEvent->y, 
                                       &child);
            }

            repaint (exposeEvent->x, exposeEvent->y,
                     exposeEvent->width, exposeEvent->height);

[/code]

[code] oc->embeddedWindow = XCreateWindow (display, windowH,
0, 0, 1, 1, 0,
bestVisual->depth,
InputOutput,
bestVisual->visual,
CWBorderPixel | CWColormap | CWEventMask,
&swa);

XSaveContext (display, (XID) oc->embeddedWindow, improbableNumber, (XPointer) peer);

XMapWindow (display, oc->embeddedWindow);
XFreeColormap (display, colourMap);

[/code]

I think that’s all I changed… It seems to work here, let me know how you get on.


#8

[quote=“jules”]Ok, there’s a few tweaks required in juce_linux_Windowing.cpp…

[code] case Expose:
{
// Batch together all pending expose events
XExposeEvent* exposeEvent = (XExposeEvent*) &event->xexpose;
XEvent nextEvent;

            if (exposeEvent->window != windowH)
            {
                Window child;
                XTranslateCoordinates (display, exposeEvent->window, windowH, 
                                       exposeEvent->x, exposeEvent->y, &exposeEvent->x, &exposeEvent->y, 
                                       &child);
            }

            repaint (exposeEvent->x, exposeEvent->y,
                     exposeEvent->width, exposeEvent->height);

[/code]

[code] oc->embeddedWindow = XCreateWindow (display, windowH,
0, 0, 1, 1, 0,
bestVisual->depth,
InputOutput,
bestVisual->visual,
CWBorderPixel | CWColormap | CWEventMask,
&swa);

XSaveContext (display, (XID) oc->embeddedWindow, improbableNumber, (XPointer) peer);

XMapWindow (display, oc->embeddedWindow);
XFreeColormap (display, colourMap);

[/code]

I think that’s all I changed… It seems to work here, let me know how you get on.[/quote]
nope, didnt help… To be sure, i commented out timer part of OpenGLDemo which comes with juce -> same result, window is not repainted.
I am going on vacation tomorrow, so in next 2 weeks i will not be able to test any code, sorry for that.


#9

Sorry, I missed a line out:

[code] Colormap colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone);
XSetWindowAttributes swa;
swa.colormap = colourMap;
swa.border_pixel = 0;
swa.event_mask = ExposureMask | StructureNotifyMask;

oc->embeddedWindow = XCreateWindow (display, windowH,
                                    0, 0, 1, 1, 0,
                                    bestVisual->depth,
                                    InputOutput,
                                    bestVisual->visual,
                                    CWBorderPixel | CWColormap | CWEventMask,
                                    &swa);

XSaveContext (display, (XID) oc->embeddedWindow, improbableNumber, (XPointer) peer);

XMapWindow (display, oc->embeddedWindow);
XFreeColormap (display, colourMap);

[/code]


#10

[quote=“jules”]Sorry, I missed a line out:
[/quote]
Yes, that was it! Thank you! :))


#11