OpenGL context overlaps


#1

Hi JUCE folks;

I am working on 3d application which utilizes OpenGLComponent, but having an artifact when working with multiple DoumentWindows when two separate ones overlap each other:

.

I have searched the form and found a topic for a similiar problem but could not find an answer:
http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=2504&highlight=opengl

Is there any workaround to solve this issue?

Thanks.


#2

If you’ve got a native OS window, there’s no way of drawing overlapping juce components on top of it. All toolkits have this issue when you start mixing lightweight and heavyweight windows. The only workaround would be to render the opengl off-screen, and render it as an image inside a lightweight component, (which would be much slower)


#3

I have changed the way my child dialogs created, as adding them to the desktop, but not the OpenGL content component, with “alwaysOnTop” setted true for all the child dialogs.

Although the overall result is not what it is intented, it seemed workaround for me, so i wanted to share it. Hope it is feasible.

[image]
http://www.solosoul.net/images/opengl-2.jpg
[/image]

Creating the dialogs:

	FSimBinDialog* fsimBinDlg = new FSimBinDialog(DialogIDs::DLG_BIN);

	addChildComponent(fsimBinDlg);
	fsimBinDlg->addToDesktop(fsimBinDlg->getDesktopWindowStyleFlags());

	FSimOpenGLDialog* fsimGLDlg = new FSimOpenGLDialog(DialogIDs::DLG_OPENGL);
	addChildComponent(fsimGLDlg);

And also now we have to take care for "minimise & restore"ing of the main window:

void FreightSimMainContent::minimiseDialogs()
{
	DIALOGS::iterator begin = m_Dialogs.begin(), end = m_Dialogs.end(), itor;

	for(itor=begin; itor != end; ++itor)
	{
		DocumentWindow* dialogPtr = itor->second;
		
		if (dialogPtr->isVisible())
			dialogPtr->setMinimised(true);
	}
}

#4

Hi! I found this solution too, but I have a problem with it, under VISTA. This is your screenshot, edited by me. If I switch back into the opengl window, only the left part of the component is refreshing. Have you any idea about it?


#5

Hello Everybody,

I’m new to Juce and I’m interested on this topic.

I’ve tried to reproduce what you are doing with the additional constraint that I want my overlaping window to be semi-transparent … My overlapping widget is a treecomponent. I would like to reproduce something like the CAD tree in CATIA:

It does note work and I don’t really understand why …

My application:

class JUCETestDemoApplication : public JUCEApplication
{
    /* Important! NEVER embed objects directly inside your JUCEApplication class! Use
       ONLY pointers to objects, which you should create during the initialise() method
       (NOT in the constructor!) and delete in the shutdown() method (NOT in the
       destructor!)

       This is because the application object gets created before Juce has been properly
       initialised, so any embedded objects would also get constructed too soon.
   */
    TestDemoWindow* theTestMainWindow;

public:
    //==============================================================================
    JUCETestDemoApplication()
        : theTestMainWindow (0)
    {
        // NEVER do anything in here that could involve any Juce function being called
        // - leave all your startup tasks until the initialise() method.
    }

    ~JUCETestDemoApplication()
    {
        // Your shutdown() method should already have done all the things necessary to
        // clean up this app object, so you should never need to put anything in
        // the destructor.

        // Making any Juce calls in here could be very dangerous...
    }

    //==============================================================================
    void initialise (const String& commandLine)
    {
        // just create the main window...
        theTestMainWindow = new TestDemoWindow();
        theTestMainWindow->centreWithSize (800, 600);
        theTestMainWindow->setVisible (true);

		theTestMainWindow->BuildContainer();
		theTestMainWindow->BuildTreeComponent();
		theTestMainWindow->BuildOpenGLWindow();

        /*  on return from this method, the app will go into its the main event
            dispatch loop, and this will run until something calls
            JUCEAppliction::quit().

            In this case, JUCEAppliction::quit() will be called by the
            demo window when the user clicks on its close button.
        */
    }

    void shutdown()
    {
        delete theTestMainWindow;
        theTestMainWindow = 0;
    }

    //==============================================================================
    const String getApplicationName()
    {
        return String("JUCE Test Demo");
    }

    const String getApplicationVersion()
    {
        return String("1.0");
    }

    bool moreThanOneInstanceAllowed()
    {
        return false;
    }

    void anotherInstanceStarted (const String& commandLine)
    {
        // This will get called if the user launches another copy of the app, but
        // there's nothing that the demo app needs to do here.
    }

private:

};


//==============================================================================
/*
    This macro creates the application's main() function..
*/
START_JUCE_APPLICATION (JUCETestDemoApplication)

and the different components:

//==============================================================================
TestDemoWindow::TestDemoWindow()
    : ResizableWindow (	String("JUCE Test!"),  // TopLevelWindow
						Colour((uint8)0x00,(uint8)0x00,(uint8)0x00,(uint8)0xff), //Colours::floralwhite,
						true)
{
    commandManager = new ApplicationCommandManager();

    setResizable (false, false); // resizability is a property of ResizableWindow

    commandManager->registerAllCommandsForTarget (JUCEApplication::getInstance());

    // this lets the command manager use keypresses that arrive in our window to send
    // out commands
    addKeyListener (commandManager->getKeyMappings());

	m_pContainer = NULL;
	m_pTreeComponent = NULL;
	m_pOpenGLDemo = NULL;
}
//==============================================================================
TestDemoWindow::~TestDemoWindow()
{
    delete commandManager;
}
//==============================================================================
void TestDemoWindow::BuildOpenGLWindow()
{
	m_pOpenGLDemo = new OpenGLDemo();
	m_pOpenGLDemo->setBounds(0,0,getWidth(),getHeight());     //>setSize(getWidth(),getHeight());
	m_pContainer->addAndMakeVisible(m_pOpenGLDemo);
	m_pOpenGLDemo->toBack();
	//m_pOpenGLDemo->setAlwaysOnTop(true);
	//setContentComponent(	pOpenGLDemo,
	//						false,
	//						true );
	//addAndMakeVisible (new OpenGLDemo()); //createOpenGLDemo());
	resized();
}
//==============================================================================
void TestDemoWindow::BuildTreeComponent()
{
	m_pTreeComponent = new TreeTestComponent ();
	m_pContainer->addAndMakeVisible(m_pTreeComponent);
	m_pTreeComponent->addToDesktop(getDesktopWindowStyleFlags());
	m_pTreeComponent->toFront(true);   //setAlwaysOnTop(true);
	//setContentComponent(	TreeComponent,
	//						false,
	//						true );
	m_pTreeComponent->resized();
}
//==============================================================================
void TestDemoWindow::BuildContainer()
{
	m_pContainer = new Component();
	m_pContainer->setSize(800,600);
	//m_pContainer->setColour(TreeView::backgroundColourId, Colour(0xff000000));
	m_pContainer->setVisible(true);
	setContentComponent(	m_pContainer,
							false,
							true );
	resized();
}
//==============================================================================

Is it possible to have semi-transparent overlapping windows over OpenGL?
Did I make something wrong?

Thanks in advance for your help.

Glou


#6

says it all


#7

Hello,

Yes I saw this statement and I partially understand this *weight mixing problem, but DEVOXE snapshot show a juce component overlapping an OpenGL windows. So I wanted to have a better understanding of what he did …

Glou


#8

he have multiple windows added to the desktop not inside each child component. since OpenGL contexts are heavyweight, they are handled internally by the OS/video card so it is practically impossible to get them below another component unless they are different windows.


#9

The solution to your problem is something that has been discussed but no-one has been able to take on yet - make a Juce Component that has an OpenGL context as a ComponentPeer (as opposed to a native window).

There’s topics where Jules suggests the approach needed.

If you want to roll your own less flexible solution, you’d have to take snapshots of your component and pass them through as OpenGL textures and draw them in OpenGL. If they’re RGBA textures and you use the right blending mode, you have full control of transparency.

Bruce


#10

with latest versions of Qt is possible do things like this:

http://labs.trolltech.com/blogs/2008/06/27/accelerate-your-widgets-with-opengl/

and even this (much more impressive !):

http://labs.trolltech.com/blogs/2008/12/02/widgets-enter-the-third-dimension-wolfenqt/

when those kind of features will be implemented in juce ?
well, i probably will feature a white beard… !