Adding OpenGL component to desktop on Mac


#1

Hi guys, I’m trying to add an OpenGL component to the desktop in OSX. Basically I’m using the code from the OpenGL demo in the demo project. I call component->addToDesktop(0), and the component appears and it seems to render correctly the first time, but after that it doesn’t update even though the Timer is being called. I’ve read through all the other posts and I’ve done everything I can: setOpaque(true), etc. Any ideas? I’m using v1.52 so maybe this is fixed in the repository head?
Thanks!


#2

Yes, definitely try the latest version before spending too much time debugging it.


#3

Ok, tried the latest version, but the same thing seems to happen.

I can debug into the repaint() call that’s triggered by the Timer callback, and it looks like it goes down into the WindowedGLContext::repaint() function, but it’s in Objective-C and I don’t really speak that language… though by the comments, it seems as though there are some hacks going on to force repainting to happen properly. Perhaps they’re not quite working as expected?

Thanks
MM


#4

If the demo renders correctly but your app doesn’t, my first suspicion would be that your app’s failing to do something, rather than assuming there’s a bug in the library.


#5

Sorry, I meant that the demo is indeed failing.


#6

AFAICT the demo definitely works in OSX…?!


#7

Huh. Does the component draw, ever? I’ve run into a few Macs where the OpenGL views in my app won’t run, and I’d presumed that it was due to my code. I guess I should run JuceDemo on them, and see if it’s systemic.

Bruce


#8

The bottom line is that I’m trying to have an OpenGL Component run full screen with nothing else visible - no window borders, no system menu bar, etc. I can’t seem to get this to work.

So for the purpose of explanation, if make a small (and unelegant) modification to the Juce Demo project such that the various demos are added directly to the desktop using addToDesktop(0) instead of being added to the main window as child components, they all still seem to work, except the OpenGL demo. It doesn’t render properly.

I really don’t think the issue is my code, since I’m only making one- or two-line edits to the Juce Demo.

If someone has successfully gotten an OpenGL component to work on OS X, running fullscreen with nothing else visible, I’d appreciate to know how you did it.

Thanks!


#9

I just tried adding contentComp->addToDesktop(0); into MainDemoWindow::MainDemoWindow right before setVisable(true) and the openGL demo seems to add to the desktop just fine (the main Juce window is still around allowing me to switch Demo’s, etc)… hmm


#10

Alright. I think I finally figured out what’s going on here. If the OpenGLComponent is the full area of its parent component, when its parent component is on the desktop, it doesn’t render properly. But if it’s 1 pixel smaller in any dimension, it does render.

So, for example, if my resized function is this:
void MyDesktopComponent::resized() {
myOpenGLComponent->setBounds(0, 0, getWidth(), getHeight()-1);
}
everything is fine.

But if it’s this:
myOpenGLComponent->setBounds(0, 0, getWidth(), getHeight());
it doesn’t render.

Diving down into the Juce code, it seems there are some comments in the WindowedGLContext::repaint function that might have something to do with this.

Anyone else come across this?


#11

Yep, that does seem to explain it. Can’t think of a good solution for it though…


#12

This topic isn’t dead for me, as I’m currently still trying to do a fullscreen OpenGL window. Just wanted to mention that I’ve found a workaround for now. Hopefully it will help those who are also trying to do fullscreen OpenGL on OS X.

The key is (as I think Jules has mentioned elsewhere) to have your OpenGLComponent inside another generic Component (which I’m calling “myDesktopComponent” below). And the trick to make it work (because otherwise it won’t, or maybe only the first time you use kiosk mode, but not if you exit kiosk mode and then return to it) is to resize your OpenGLComponent to be a bit smaller than its parent, and then back to the full size. Here is the general flow in terms of code:

myGLComponent = new MyGLComponent; // subclass of OpenGLComponent
myDesktopComponent = new Component;
myDesktopComponent->addAndMakeVisible(myGLComponent);
myDesktopComponent->addToDesktop(ComponentPeer::windowAppearsOnTaskbar);
// now this will set the size of myDesktopComponent to the full screen size (and hide the menubar/dock/etc.):
Desktop::getInstance().setKioskModeComponent(myDesktopComponent);
// now make the GL component a bit too small (notice the -1):
myGLComponent->setBounds(0, 0, myDesktopComponent->getWidth(), myDesktopComponent->getHeight()-1);
// now show the parent:
myDesktopComponent->setVisible(true);
myDesktopComponent->toFront(true);
// and size the GL component back to fill its parent
myGLComponent->setBounds(0, 0, myDesktopComponent->getWidth(), myDesktopComponent->getHeight());

By making the component a bit too small, and then making it normal again, you force a repaint, which fixes the issue.
Hope that helps someone.