I’m working on a new version of a program I have been working for some time already (http://www.demopaja.org). As for the new version I have been searching and evaluating a cross platform GUI librarys. My main platform is Windows and I really would like to port the app to run on a Mac too.
My options at the moment are more or less JUCE or wxWidgets, I just dont like wxWidgets, and JUCE would allow me to create just the kind of UI I want. Still evaluating it, but it looks very promising and fits the way I like to work creating UI.
I have one major problem/concern regarding JUCE, though. My application is all about hardware accelerated 3D rendering, Direct3D or OpenGL (on Windows both, on Mac OGL). The JUCE architecture seemed to hide the underlying platform so well, that I’m not sure the amount of work that it requires to get that working.
All I need is to have one window where I can render my stuff (the new layout will be somewhat similar than the old one, see the link above). This window needs to have a native window handle as it is required by the rendering API setup.
To keep it short :)… my questions is, is it possible and how much effort it would require to have a OpenGL rendering window inside the main window? As that 3D rendering window will take most of the screen space I would also like not to render anything that lies under that 3D rendering window.
Someone else I know was thining of using it for openGL, though it’s not something I know much about. I wouldn’t have thought it’d be too hard to do though - you can easily get a window handle from a component to use directly, and I’ve done something similar with QuickTime. If you want to have a go, I’ll happily help you get it working.
It’ll probably involve a bit of messing about in the win32/mac native code to get the refresh working nicely. Why not post your code so we can have a look?
In my case one solution I have been thinking is to have four windows native. One at tbe bottom which acts like a container for the three latter ones, then one native window for the left pane and one for the bottom pane.
The container window would be dummy and it would not contain no drawing code at all, not even to clear the window. Also the opengl window should not be cleared or anything should not be drawn into that area.
That way the configuration would be similar is it would be in normal win32 app (maybe similar config would work in Mac too). I could use JUCE to the UI in the two smaller windows and still render nicely into the “main” window with OGL.
i created a small opengl juce test application…
next to the main juce window, a juce dialog with opengl support is created.
you will see a spinning cube, but it flickers a lot…
To get rid of the flickering you can add the following code at the top of the handlePaintMessage (juce_Win32_windowing.cpp).
// Just handle the wm paint, and return.
if( ownerWindow->getDoNotPaint() )
{
PAINTSTRUCT paintStruct;
HDC dc = BeginPaint (hW, &paintStruct); // Note this can immediately generate a WM_NCPAINT
Graphics imageGraphics (*paintingBuffer, 0, 0, 0, 0, 0, 0);
try
{
ownerWindow->handlePaint (imageGraphics);
}
catch (...)
{}
EndPaint (hW, &paintStruct);
return;
}
You of course need to add getDoNotPaint() and setDoNotPaint() to the native window class too. That was just quick hack to get it going. Other than that the JUCE window class (the win32 window class) seems to have most of the flags already which are used by any opengl app. I usually also add CS_HREDRAW | CS_VREDRAW flags to the class style. Those styles forces the whole window to redraw if the size changes. Not completely sure, but I think they caused some problem with overlapping windows (i.e. juce dialog under the opengl fialog).
Also in your example there you seemed to flip the buffer twice on paint(), and also the ValidateRect(hWnd,NULL); is not necessary, as the begin paint in above piece of code handles that. That free(glwindow) is really dangerous… create with ‘new’, free with ‘delete’… always
I tried to make a component but it seems that ogl does not co-exists very well with GDI. I event masked the update the same way as the quicktime component does, but did not help.
Once I have more time I will try following:
[list]- add a flag to the component class indicating masking ála the quicktime masking
allow a child component to have own native window (this will make a lot of things easier with opengl and d3d)[/list]
I have to still check out what opengl initialisation requires on Mac. I will post my findings here as I progress.
nice that you are having a look into this, an opengl dialog component would be a nice addition to your JUCE system.
You don’t need the glut.h…that was my fault, glut is the platform independant GUI framework of opengl. With glut it’s very easy to create opengl windows and have support for mouse, keys timers etc…
i will try out your modifications to the code…
i will to do this coming monday and i will try to send you the mac code as well…
yes i saw that i flipped the buffer twice, i corrected that allready…
i did not know that calling free was dangerous, in delphi it is the right and safest way to go.
ok guys, probably best not to spend too much of your time on this any more - I got a bit carried away here, and I’ve got a clean, working implementation almost ready.
It lets you create a GL component anywhere inside a normal component, and picks up mouse, keyboard, etc messages that go there too. Very nifty. Needed a few cunning tricks to get it to work, but it looks good!
Haven’t looked at mac support yet, but I’ll post this soon and let you have a go.
I ment that mixing and matching malloc/free (the C way) and new/delete (the C++ way) is dangerous. For VC++ it works with simple classes, since internally it uses malloc (or the windows api allocation function) anyway, but the destructor of the class is not called, and there may be some other interesting side effects too with virtual methods and such. For example on my computer your example was always crashing at exit.
Another thing is that if you allocate an array with new: char* test = new char[100], you have to use the array delete operator to delete it: delete [] test. Not very intuitive for someone just getting used to c++