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.
Related
I am currently coding a program in C++/ Qt 5.9 to control a 3D Printer.
I have divided the project into several libraries :
The GUI Lib: The view
The Device Lib: Control each device (movement, printing tool, sensors)
The Controller Lib: Links the View with the Device lib
etc...
My problem is that I do not know how to initialize and terminate properly the execution of the program. More specifically, the Device library has a class named DeviceManager with two functions :
initialize() : which connect to each device and initialize them. This actions can take several seconds (10s for example)
finalize() : which closes all the connexions, can also take several seconds
What I would like to do is initialize the Device Lib in the right place without blocking the GUI and then finalize it in the right and not block the GUI
This is my main code :
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
My solution now is to call DeviceManager::initialize() in the MainWindow constructor and DeviceManager::finalize() in the MainWindow::closeEvent().
The problem: even if I use concurrency to initialize and finalize in a different thread, the application displays its window several seconds after it was launched and the display freezes when the application is closed because it has to wait for the finalize function to be done.
How should I properly handle this initialization and finalization problem, please ? Do I need to reimplement the QApplication class? Do I try and do it in the main? Do you know any great example of an open source application doing that kind of initialize and finalize work?
The problem: even if I use concurrency to initialize and finalize in a different thread, the application displays its window several seconds after it was launched and the display freezes when the application is closed because it has to wait for the finalize function to be done.
You could start the initialize() function as own detached thread before starting the MainWindow. This could cause problems if the initializing thread doesn't terminate before the first initialized "thing" is needed. Something like:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
std::thread{initialize}.detach();
MainWindow w;
w.show();
finialize();
return a.exec();
}
To prevent the problem, and maybe lock some function in the GUI, then you probably need to have a state variable that it sets under a mutex on its way out, and which you examine under a mutex to see if it has been set.
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.
Do I miss any Qt functionality if I substitute QApplication::exec() with standard Windows message loop implementation? This should clarify what I mean:
The ususal “Qt” way to run event processing:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window w;
w.show();
return a.exec();
}
“Windows” way to run event processing:
#include <Windows.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window w;
w.show();
MSG msg;
while(GetMessage(&msg, 0, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
The above demonstrates having external message loop with respect to QApplication instance, while QApplication instance itself doesn’t even have its own event loop at all.
In other words, if I have main.exe program (knowing nothing about Qt) with message loop and a .dll with Qt GUI and QApplication instance inside, will it be ok to let the external message loop from main.exe to handle events for Qt GUI?
Thanks in advance!
EDIT 1:
I’ll just answer myself in case it’s usefull for somebody:
We have a main .exe module written in C# under .NET that runs event loop processing, and we have a couple of .dlls written in Qt/C++ that have a GUI “inside” (and a QApplication instance that is shared). QApplication::exec() is never called but all the events are successfully dispatched by the main .exe (.NET) module’s event loop and all the Qt functionallity is present( signals/slots, threads, etc.)
EDIT 2:
That worked for Qt 4.8.2 but for Qt 5.1.0 things are a little bit different. Now you have to call QApplication::processEvents() once because it performs some initial initialization on its first call( installs WindowsHook on GetMessage or PeekMessage ). And after that whoever calls GetMessage in your application Qt events get processes and you are golden :)
The first thing which comes to my mind is that calling slots across threads won't work because the Qt event loop is executing those calls.
But the more important question is probably: Why do you want to do it like this especially since in qeventdispatcher_win.cpp is doing essentially the same thing?
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!
I've got some Asynchronous cleanup activity I need to do as my Qt application is shutting down.
My current approach is to trap the aboutToQuit signal. I launch my Asynchronous behavior, and then the application shuts down. Is there any way to block Qt from shutting down until my asynchronous behavior is complete?
This works on windows by trapping the main window's closeEvent and calling ignore() on the event. But on Mac, when a user quits, my ignore() isn't honored, and the Application shuts down before my asynchronous activity is complete.
Thanks.
Why do you launch your cleanup code asynchronously if you have to wait anyway until your code is done?
If you don't connect your slot as QueuedConnection to aboutToQuit it should block until your cleanup code is done.
But if you really want launch it asynchronously you have to synchronize it by hand:
QSemaphore wait4CleanupDone;
class MyQuitHandler { ... public slots: void handleQuit(); ... } myQuitHandler;
void MyQuitHandler::handleQuit() { ... ; wait4CleanupDone.release(); }
int main(int argc, char** argv) {
QApplication app(argc, argv);
QObject::connect(&app, SIGNAL(aboutToQuit()), &myQuitHandler, SLOT(handleQuit()));
...
int result = app.exec();
wait4CleanupDone.acquire();
return result;
}
But note, that your asynchronous code might be ignored in some cases anyway:
"We recommend that you connect clean-up code to the aboutToQuit() signal, instead of putting it in your application's main() function. This is because, on some platforms the QApplication::exec() call may not return. For example, on the Windows platform, when the user logs off, the system terminates the process after Qt closes all top-level windows. Hence, there is no guarantee that the application will have time to exit its event loop and execute code at the end of the main() function, after the QApplication::exec() call."
From: http://doc.trolltech.com/4.6/qapplication.html#exec
Crashes here regrettably when i try this.
problem is the connect call where it alraedy crashes line 3 of main.
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QObject::connect((QObject *)&app, SIGNAL(aboutToQuit()), (QObject *)&myQuitHandler,
SLOT(QuitApp()), Qt::QueuedConnection );
QGraphicsScene scene(QRectf(0, 0, 640, 480));
..
}
After i started using qgraphicsscene not a single signal works anymore as i get it not connected in a manner that any signal works.
So far could solve everything, how to solve this without 'connect' ?
Crash i get here is instant:
Invalid parameter passed to C runtime function.
exited with code -1073741819