PDA

View Full Version : How to activate a GLUT window from a MFC window?



04-22-2002, 05:37 AM
Title speaks by itself

jimmi
04-22-2002, 06:01 AM
Do you mean how do I embed a GLUT program within an MFC app? I can see one problem here, GLUT relies on windows.h (ok - this is wrong see later ), and you shouldn't include windows.h and afxwin.h in the same program (or at least you have to include mfc first).
Why not just render to an MFC window?

jimmi


[This message has been edited by jimmi (edited 04-22-2002).]

Deiussum
04-22-2002, 07:33 AM
Originally posted by jimmi:
Do you mean how do I embed a GLUT program within an MFC app? I can see one problem here, GLUT relies on windows.h, and you can't include windows.h and afxwin.h in the same program (or at least you have to include mfc first).
Why not just render to an MFC window?

jimmi

That's wrong on 2 accounts.

1. Glut doesn't rely on windows.h. In fact it has stuff in there so that it can include gl.h and glu.h WITHOUT including windows.h. (i.e. it does it's own defines for stuff gl.h use that is normally defined in windows.h)

2. Where did you hear you can't include windows.h in an MFC app? There's nothing wrong with that, though it really would be redundant seeing as the includes that are usually added to an MFC app include windows.h already. (afxwin.h includes afx.h, which includes afxver_.h which includes afxv_w32.h, which includes windows.h) Ok... so there's an error condition at the top of afxv_w32.h that checks if windows.h has been included already, but that would only happen if you included windows.h before afxwin.h.

So far as the original poster goes... maybe you could explain a bit further what you want to do. It sounds like you have an MFC window and want to open a new window using glut on say a button click... If you want both windows to remain active, you're going to have to open the glut window in a separate thread. If you want the original window to be destroyed, and the glut window to be created, there are a few options. (One way would be to call your glutMainLoop after the window's been destroyed.) If you want the glut window to open similar to a modal dialog box where you can't use the original window for anything until the glut window closes, there would again be a few options. (One way might be to call your glutMainLoop in whatever event is supposed to launch the glut window.)

Edit:
I should have noted also that, unless you really have to, it probably wouldn't be the best mixing glut with an mfc app, even though it would be possible. If you're going to use a particular window creation method, why not stick with that method?

One more note: If you expect to be able to give glut pointers to class functions, you're going to have to make those class functions static.



[This message has been edited by Deiussum (edited 04-22-2002).]

jimmi
04-22-2002, 08:00 AM
Originally posted by Deiussum:
That's wrong on 2 accounts.

1. Glut doesn't rely on windows.h. In fact it has stuff in there so that it can include gl.h and glu.h WITHOUT including windows.h. (i.e. it does it's own defines for stuff gl.h use that is normally defined in windows.h)


OK conceeded.



2. Where did you hear you can't include windows.h in an MFC app? There's nothing wrong with that, though it really would be redundant seeing as the includes that are usually added to an MFC app include windows.h already. (afxwin.h includes afx.h, which includes afxver_.h which includes afxv_w32.h, which includes windows.h) Ok... so there's an error condition at the top of afxv_w32.h that checks if windows.h has been included already, but that would only happen if you included windows.h before afxwin.h.


This is almost exactly what I said. Ok, maybe the word 'shouldn't' ought to be substituted for the word 'can't'. But I do mention that you can do it if you include afxwin.h first.

Of course the important point is that the poster should probably be using MFC for all his windowing needs.

jimmi

04-22-2002, 10:49 PM
I have made an apply that is opening a GLUT window in order to display a vertex table with OpenGL. I have no clue about how to use MFC to display OpenGL, so I used GLUT. I have made buttons in which on click you change the z axis. But in order for the changes to be taken in account, you have to manually reactivate the glut window. I wish after the click to change the z axis the glut window was automatically activated so the changes can be taken in account.

Deiussum
04-23-2002, 04:24 AM
Ok, for what you want to do you'll need to setup your glut window in a separate thread. Look on MSDN for information on AfxBeginThread, or the Win32 function CreateThread. In that thread proc, you'll want to setup all your glut stuff, and call glutMainLoop. Create an idle loop for glut that calls glutPostRedisplay.

Now... to communicate between the MFC window and the glut window, there's a number of possibilities. The easiest way would be just to create a global variable for what you want to change... then you change that global with your MFC app, your glut window's display function uses that value for the rendering, and tada! You now have 2 windows made with different methods that are "communicating."

04-23-2002, 05:31 AM
I do not think that you can have MFC in one thread and GLUT in another because the libraries they are using is not thread-safe. You have to create different processes.

It would work to have a idle function that calls glutPostRedisplay but it is better to do that only if the glut program got a message from the MFC program.
I guess you could call glutPushWindow to raise the glut window.

04-23-2002, 05:47 AM
Originally posted by Zico:
I guess you could call glutPushWindow to raise the glut window.

Which arguments shall I put into this function? I have no clue about how 'calling' my glut window from my mfc interface, even if with global variables I can interact between both (having manually to click on glut window so it redisplays)

04-23-2002, 06:28 AM
You should not call glut functions from the MFC program. Call glutPushWindow() from your idle function in the glut program. Just send a message from the MFC program to the glut program and let the glut program do all glut stuff.

Exactly how inter process communication is done depends on the OS. Under linux would you probably create a pipe.

I think that the best solution is to skip GLUT and just use MFC. They do the same thing and get in the way for each other. This would probably be easier since you do not have to create multiple processes. I think it also would be better since you could have the GUI and OpenGL stuff combined in one window.

Deiussum
04-23-2002, 11:24 AM
While I agree that using glut with MFC SHOULDN'T be done, saying that it CAN'T be done is totally false... To prove it to myself I wrote a quick little app that did just this.

There was one little anomaly where when the glut window was closed the whole app shut down. This could probably be handled by trapping for the WM_DESTROY event for the MFC dialog, and doing further testing.

It's ugly, but it works.

Here's the pertinent code...



float ang = 0.0;

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();
glRotatef(ang, 0.0, 1.0, 0.0);
glutSolidTeapot(1.0);
glPopMatrix();

glutSwapBuffers();
}

void reshape(int x, int y)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (float)x/(float)y, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}

void idle()
{
glutPostRedisplay();
}

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("test");

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutMainLoop();

return 0;
}

void CGLtestDlg::OnButton1()
{
DWORD dwTID;

::CreateThread(NULL, 0, ThreadProc, NULL, 0, &dwTID);

}

void CGLtestDlg::OnButton2()
{
// TODO: Add your control notification handler code here
ang += 5.0;
}

J P
04-23-2002, 01:06 PM
You can call any nonwindowing glut function in MFC but I wouldn't recommend calling a glut windowing function. MFC has its own way of managing windows.

I recommend that you either port the opengl to MFC or just leave it as a glut application.

If you need help in porting to MFC, see

http://pws.prserv.net/mfcogl/ it is a bit dated but the host of the newer site
http://www.mfcogl.com/

is having problems at the moment.

04-24-2002, 02:18 AM
I certainly belives that if you want to open a GLUT window from a MFC application is it best to create a new process. It is easy and it is safe. I checked GDI on msdn and it does not have so many restrictions for multiple threads as I assumed I do not know if the documentation is for all Window versions. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/prothred_4gab.asp

Even if the test program had worked without problems would that not proved anything. It could still be unsafe.

Calling nonwindowing glut functions in the MFC thread is not possible because the OpenGL context is not shared. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/ntopnglr_2u0k.asp

Deiussum
04-24-2002, 04:47 AM
Again, I totally agree that using an MFC window with a Glut window is ugly. They both use totally different paradigms. Using them together just doesn't feel right.

But!! What both MFC and Glut boil down to is just Win32 API calls. Yes, if you look deep enough there is a CreateWindow in the MFC code. And if you look in the Glut code for creating a window, you'll also see a CreateWindow call. Neither of these use some "magical" method of creating windows. MFC is more or less just a big complex class-based wrapper to the API. The windows version of Glut is basically just a procedural wrapper to the API.

Zico, Call it "unsafe" if it makes you feel better. But really, I don't see why it's any more "unsafe" than any other multi-threaded app using a free threading model. As long as you use the threads wisely, it would work. As far as using the non-windowing glut functions in the MFC thread not updating the scene in the glut thread, that's pretty much a given. And nowhere did I claim you could use glutSolidTeapot in the MFC thread and have it display in the glut thread. You would have to confine all the rendering for the glut window to the glut thread. That would all be part of using the threads wisely.

Personally I feel that for what the original poster wants two separate processes would be silly. One process just for pressing buttons to change the view of another process? Mememememememe (did I get enough me's) would be a lot better off learning the little extra that would be required to initialize OpenGL for MFC, or make the whole thing with Glut. If he wants to go the "ugly" route, though, it's his choice.