PDA

View Full Version : GL Dialog Box (revisited)



jebus
06-19-2003, 03:41 AM
my goal is to make a Dialog based plugin (DLL) for Milkshape with a range of controls and an OpenGL rendering area on the box also. having searched these forums and google, i've found one mediocre tutorial and a few helpful hints. here's what i've extracted so far.

i have created the dialog box and my own custom class derived off of CDialog. i placed a picture box control on the dialog box and use GetDlgItem() and others to get the picture box's HWND (this is what i want to render to). i have the appropriate resize() function being called in OnSize(). i know to do the wglMakeCurrent() with the DC and RC when i want to use OpenGL's API and wglMakeCurrent(NULL, NULL) when I'm done.

now, i've only been able to get it to display the box as modal (w/no GL being drawn http://www.opengl.org/discussion_boards/ubb/frown.gif ). this is fine, but since i have no main loop, i can't render each frame. the tut i found has the render code in OnPaint and uses a timer. this doesn't seem like the best way to do it. has anyone ever done something like this?

jebus

knackered
06-19-2003, 03:53 AM
Use a thread.
This question is not really related to opengl - more of an mfc question, therefore it is being asked in the wrong place.

jebus
06-19-2003, 04:11 AM
sorry for the OT'ness but since my problem involves Milkshape, MFC, DLLs and OpenGL i chose this forum as i am most comfortable here. plus i seem to have the MFC nailed down.

jebus

V-man
06-19-2003, 04:12 AM
For a render loop :
Just make a function

void MYCLASS::RunForever()
{
while(untilexit)
{
RenderScene();
SwapBuffers();
ProcessKeyEvents();
ProcessMouseEvents();
}
}

So it's exactly like using a loop in WinMain.

I know this is off topic, but not many people use MFC in games and such so they think it's not possible.

knackered
06-19-2003, 06:14 AM
god it would be lovely to be able to do things like that - if only i didn't have to worry about multiple windows and viewports, asynchronous data loading, client/server protocols etc.
life would be so much simpler, but the programs wouldn't be as useful or flexible.

jebus
06-19-2003, 06:31 AM
V-man: yes that would be nice, however that would just bring my plugin to a screeching halt. windows is handling the run loop internally and my problem is that i can't get in there to put my render function :p

jebus

dorbie
06-19-2003, 06:39 AM
You should have an OnDraw callback, put your OpenGL rendering calls in there and you can trigger events for this based on an itimer, or dialog GUI inputs, whichever is more appropriate. The size callback should just reconfigure the viewport as usual. You really have to get into the business of issuing draw events from your dialog callbacks to refresh on user input or if you're animated go the itimer route.

This isn't my favourite way to render but if you aren't rolling your own event handling then you'll have to.

You really should go modeless, modal sucks and modeless is actually pretty easy.

I have some sample code for a modeless dialog and rendering in an OpenGL window (a picking tutorial I did years ago) but the redrawing is actually done in the main window, not the dialog, and I forget the details, I might have just implemented my own loop for the main window and handled events myself. The modeless communication is simply memory shared between threads.

[This message has been edited by dorbie (edited 06-19-2003).]

paulc
06-19-2003, 06:45 AM
I've done something very similar to this before. Unfortunately can't get at my code at the moment, but I think you should be able to process something like a WM_IDLE message (not sure exactly) in your dialog boxes message process function and whenever this message is received call InvalidateRect on the dialog box which will trigger a redraw. I will try and dig out the exact messages/functions if I get time later.

dorbie
06-19-2003, 06:49 AM
Hmm, invalidate rect is ringing a bell, it's been a while since I played with this stuff.

Korval
06-19-2003, 08:12 AM
First of all, why do you want this dialog to be modal? Is there any particular reason you want the rest of the application to hang while this dialog is up?

Secondly, on the assumption that this is the required behavior, all you need to do is this. Set up a window's timer. It doesn't have to be a high-precision one; just have it fire messages frequently. In that timer, invalidate the dialog's HWND. That will force OnPaint to be called.

jebus
06-19-2003, 09:26 AM
i doesn't have to be modal, but since it's a plugin for Milkshape, there's no way for my plugin to get changes in a model while the plugin is running. but, it could just as well be modeless. would i supply my own message proc if i made it modeless?

jebus

knackered
06-19-2003, 12:40 PM
Seeing as though the great "please let me be a moderator" dorbie has decided this particular thread is on-topic enough...
For you to have a modelss dialog in a plugin (read DLL) the Milkshape app would have to maintain a message pump, and call your plugin whenever windows messages are reached in the queue. It makes things a little bit trickier doesn't it?

paulc
06-19-2003, 02:30 PM
Well, one way to do it that eliminates the need for a timer is to use InvalidateRect every time WM_PAINT is issued. Whenever you've executed your draw code call InvalidateRect, with NULL for the rect parameter so it invalidates the entire area you're drawing to. Everytime you draw, it requests a subsequent re-draw.

V-man
06-19-2003, 06:18 PM
Originally posted by paulc:
Well, one way to do it that eliminates the need for a timer is to use InvalidateRect every time WM_PAINT is issued. Whenever you've executed your draw code call InvalidateRect, with NULL for the rect parameter so it invalidates the entire area you're drawing to. Everytime you draw, it requests a subsequent re-draw.

I'm not sure if this is a good idea under any platform.
For every invalidation, a WM_PAINT is generated. So if something else causes an invalidation (like a window covers your dialog temporarily), more invalidations will come until your message queue gets flauded to the point of overflow. Luckily, on Windows, painting is very low priority, but so is WM_TIMER.

Watch out!

JotDot
06-20-2003, 06:05 AM
Windows keeps an update region for the invalid portion of the window. Invalidating an area of the window does not force an immediate WM_PAINT. Rather, that area gets added to the update region. Only once there are no more messages in the application message queue does Windows send a WM_PAINT.

Thus there is no way that invalidating portions of the window would cause a flood of WM_PAINT messages. I have used this method on occasion (many years go) with success.

reference: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_4k6d.asp