How to close GLUT window without terminating of application? - c++

I've created an application with Qt Creator (OS Ubuntu 13.04). One function creates a window and draws a graphic using GLUT library, picture is right. But when I try to close window and continue working with my program, it terminates. How can I avoid this?
There is the code of my function:
void plot(int argc, char**argv,.../*other arguments*/)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_ALPHA);
glutCreateWindow("Green Window");
//some code
//...
glutDisplayFunc( draw );
glutMainLoop();
}
Application output prints "... exited with code 0"

If you read e.g. this reference of glutMainLoop you will see that glutMainLoop never returns. That means it will call exit directly instead of returning.
If you're using Qt, then it's able to open windows containing OpenGL contexts, windows compatible with the rest of Qt and which you can close at will.

You might want to switch to freeglut which has implemented the function glutLeaveMainLoop(). As the documentation says:
The glutLeaveMainLoop function causes freeglut to stop its event loop.
Usage
void glutLeaveMainLoop ( void );
Description
The glutLeaveMainLoop function causes freeglut to stop the event loop. If the GLUT_ACTION_ON_WINDOW_CLOSE option has been set to GLUT_ACTION_CONTINUE_EXECUTION, control will return to the function which called glutMainLoop; otherwise the application will exit.
If the application has two nested calls to glutMainLoop and calls glutLeaveMainLoop, the behaviour of freeglut is undefined. It may leave only the inner nested loop or it may leave both loops. If the reader has a strong preference for one behaviour over the other he should contact the freeglut Programming Consortium and ask for the code to be fixed.
Changes From GLUT
GLUT does not include this function.
Source:
http://freeglut.sourceforge.net/docs/api.php

For FreeGlut. If You want to close only window which has created with GLUT. Look:
int handle = glutCreateWindow("Red square example");
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
No thanks.

Related

Get Access violation reading location 0x000000b0 with glutMouseFunc

I'm using glutMouseFunc(mouseFunction); as a callback however I keep getting the Access violation reading location 0x000000b0 at this line glutMouseFunc(mouseFunction);
I'm not using any of the glutInit functions because they interfere with the program and they are not essential anyways.
Does anyone know why I'm getting this error when at this callback?
Here is my initialize function:
int Initialize()
{
/* Bunch of code here that is irrelevant to the problem.......*/
glutMouseFunc(mouseFunction); // Error occurs here.
}
And here is my mouseFunction:
void mouseFunction(int button, int state, int x, int y){
if(button==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN)
{
printf("Pressed middle mouse button!");
}
}
I've noticed one thing though, there error does not occur when I call the mouseFunction() as a normal function call in my Initialize method however once I try to use the mouseFunction with glutMouseFunc(mouseFunction), than the error happens so I believe this is more of an error with glutMouseFunc.
I'm not using any of the glutInit functions because they interfere with the program and they are not essential anyways.
This is your problem. If you're going to use GLUT, use it correctly.
The glutInit() function is essential - part of what it does is initializing internal state within GLUT. As you've discovered, with this state not properly initialized, other parts of GLUT (such as mouse event handling!) may not work properly.
Given your comments to the other questions your problem is simply, that you call glutMouseFunc without a GLUT window. Trying to register GLUT event callbacks without proper initialization or without a GLUT window created will crash your program.
You also say "GLUT interferes" with your actual window. So why would you try to register a GLUT callback at all if you don't have a window that could actually receive the events for GLUT to dispatch?
You should use the mouse event handling of the window you've already got. And what are you using GLUT for then anyway? The whole purpose of GLUT is to create a window for you and do event management. If you don't use GLUT for that, then don't use GLUT at all.
If it's for the teapot, well, you can have that without GLUT as well.

Multithreading opengl app in visual studio

I am implementing mutlithreading opengl application in visual studio.
Here is my code:
void temp(void *a)
{
/* create a window */
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutCreateWindow("Application");
glutDisplayFunc(display);
/* callback for mouse button changes */
glutMouseFunc(mousebutton);
/* callback for idle function */
glutIdleFunc(doIdle);
/* do initialization */
glutMainLoop();
}
int main (int argc, char ** argv)
{
glutInit(&argc,argv);
myinit();
_beginthread(temp, 0, (void*)0 );
Sleep( 100000000000000);
return 0;
}
If I create single thread with beginthread call, it works fine but if i call beginthread multiple times, it terminates immediately. I am not getting where i am going wrong.
Also, what is equivalent call of pthread_join in windows? how can i avoid that sleep in main ?
The problem with opengl is that is not thread safe, and it is highly recommended to do everything on the main thread. when you call _beginthread the second time, a second thread will start will override the display functions that were set by the first thread. GLUT was not design to be used in such and you app might terminate because of a failsafe system inside GLUT
If you want to have multiple windows the you need to use use other api to handle the second windows , but the opengl context is still the same. You ca try GLFW to achieve this , i know that has good support for multiple viewports.
Avoiding the sleep function in your case is very easy, you just call temp instead of _beginthread and that's it for the main function. Later on you can spawn more thread but you must stay away from opengl calls unless you are on the main thread.

Qt - How to detect closed window in custom event loop without using slots

I'm working on an OpenGL-based game using QGLWidget as a front-end. But due to all of the unnecessary overhead (plus having to distribute the heavy QT libraries!) I plan to migrate to GLUT, and am in the process of replacing 'Qt-stuff' with more standard alternatives before the big leap.
To replace the QTimers that control the framerate and fps timer, I'm trying to wedge those functions into a simple loop that replaces the app.exec() call, as follows:
//main.cpp
#include <QApplication>
#include <windows.h>
#include "mainwindow.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWindow mainWin;//only contains a glwidget
mainWin.show();
do {
app.processEvents();
//call draw functions/fps based on system tick count
//...
Sleep(10);
} while (!app.closingDown()); //<-- this doesn't terminate
return 0;
}
So far it works fine during runtime, however once you try to close the window (via the system 'X' button), the window goes away but the program hangs in the background. The problem is that I can't find a static flag or query function that indicates that exit() or close() has been called. bool closingDown() always seems to be false, and I've tried toggling a static flag in the ~MainWindow destructor and detecting that, but that doesn't work either since that isn't called until main ends. I know I could probably do it by tying into QApps' aboutToQuit() signal, or maybe making a derived class from Qapp, and intercepting it, but that kind of defeats the purpose of moving away from signals/slots. Is there a simple way to tell if a QApplication has been ordered to shut down, from outside of the class?
You can reimplement
void QWidget::closeEvent ( QCloseEvent * event )
method to set your static flag. That method invokes for close events from window.
I recommend adding app.sendPostedEvents(); before that QApplication::processEvents() call. It may actually fix your problem, but if not, you can at least use event handlers as mentioned by #dzhon.
Nitpick: Qt is generally not formatted in all-caps. Saying 'QT' makes it appear as if you are talking about QuickTime!

c++ gtk open multiple window

I'm still working on the example at this link: gtkmm statusicon quits after creation
I changed the function in this way to open the traybar different windows, but does not show anything.
void Tray::on_statusicon_popup(guint button, guint activate_time) {
printf("popup!\n");
Gtk::Window w;
w.show();
}
I tried to run every window with "Gtk::Main::run(w);" and it works, but I would like to not run a main loop for each window.
You're creating the window object on the stack, so it gets destroyed immediately after on_statusicon_popup() returns. If you want the window to outlast the function call, you'll need to create it on the heap and connect to its 'hide' signal (or similar) and delete the object from there.

changing GLUT calls to work with MFC/C++

I have a program that uses GLUT for its OpenGL rendering. Now I need it to be inside of a MFC project so that it can work with another program component.
I've followed this tutorial: http://www.codeguru.com/cpp/g-m/opengl/openfaq/article.php/c10975__1/Setting-Up-OpenGL-in-an-MFC-Control.htm
I am calling the function that was the GLUT display callback when the timer fires, but that's not working because the rendering depends on something that happens in the GLUT idle callback. I don't understand where I should call the GLUT idle callback in my MFC program. Is there a separate event handler I should make for it, and if so, which event? Or am I doing something else completely wrong? I'm fairly familiar with OpenGL but this is my first experience with MFC so I am probably erring on that side.
Thanks so much for your time; I really appreciate it!
I just browsed the tutorial you've linked to; on page two, something along the following lines can be found (I cleaned up the code a little bit):
void COpenGLControl::OnTimer(UINT nIDEvent)
{
if(nIDEvent==1)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
oglDrawScene();
// try to insert your idle function code here
SwapBuffers(hdc);
}
CWnd::OnTimer(nIDEvent);
}
So, basically this is the replacement for glutIdleFunc suggested by the tutorial. I'd simply try to insert the code called in your idle function before the call to SwapBuffers.
I hope that helps.