Seite 1 von 1

QGLWidget + QMessageBox = 2mal initGL()?

Verfasst: 1. Februar 2010 22:53
von EyesKiller
Hi Leute,
ich bin grad dabei die NeHe-Tut (Lesson22) durchzuarbeiten.

In Funktion initMultitexture() habe ich QMessageBox::information eingefügt. Kann mir jemand erklären, warum glInit() 2mal ausgeführt wird, wenn QMessageBox::information() in initMultitexture() ausgeführt wird? In initializeGL() wird der Funktion initMultitexture() aufgerufen. Wenn ich die QMessageBox::information() aus initMultitexture() auskommentiere wird glInit() korrekterweise nur einmal ausgeführt.

Warum?

So wie folgt sieht die Stack in Debugger aus. Die entsprechende Stelle habe ich fett markiert (daher mit Quote statt Code, kann man innerhalb von Code-Block nicht irgendwie markieren?). In Zeile 364 ist Haltepunkt, also kein Crash. ;)
0 GLBox::initMultitexture glbox.cpp 364
1 GLBox::initializeGL glbox.cpp 88
2 QGLWidget::glInit() /usr/lib/libQtOpenGL.so.4 0

3 QGLWidget::glDraw() /usr/lib/libQtOpenGL.so.4 0
4 QGLWidget::qt_metacall(QMetaObject::Call, int, void**) /usr/lib/libQtOpenGL.so.4 0
5 GLBox::qt_metacall moc_glbox.cpp 58
6 QMetaObject::activate(QObject*, int, int, void**) /usr/lib/libQtCore.so.4 0
7 QObject::event(QEvent*) /usr/lib/libQtCore.so.4 0
8 QApplicationPrivate::notify_helper(QObject*, QEvent*) /usr/lib/libQtGui.so.4 0
9 QApplication::notify(QObject*, QEvent*) /usr/lib/libQtGui.so.4 0
10 QCoreApplication::notifyInternal(QObject*, QEvent*) /usr/lib/libQtCore.so.4 0
11 ?? /usr/lib/libQtCore.so.4 0
12 ?? /usr/lib/libQtCore.so.4 0
13 g_main_context_dispatch /lib/libglib-2.0.so.0 0
14 ?? /lib/libglib-2.0.so.0 0
15 g_main_context_iteration /lib/libglib-2.0.so.0 0
16 QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) /usr/lib/libQtCore.so.4 0
17 ?? /usr/lib/libQtGui.so.4 0
18 QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) /usr/lib/libQtCore.so.4 0
19 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) /usr/lib/libQtCore.so.4 0
20 QDialog::exec() /usr/lib/libQtGui.so.4 0
21 ?? /usr/lib/libQtGui.so.4 0
22 QMessageBox::information(QWidget*, QString const&, QString const&, QFlags<QMessageBox::StandardButton>, QMessageBox::StandardButton) /usr/lib/libQtGui.so.4 0
23 QMessageBox::information qmessagebox.h 228
24 GLBox::initMultitexture glbox.cpp 373
25 GLBox::initializeGL glbox.cpp 88
26 QGLWidget::glInit() /usr/lib/libQtOpenGL.so.4 0

27 QGLWidget::resizeEvent(QResizeEvent*) /usr/lib/libQtOpenGL.so.4 0
28 QWidget::event(QEvent*) /usr/lib/libQtGui.so.4 0
29 QGLWidget::event(QEvent*) /usr/lib/libQtOpenGL.so.4 0
30 QApplicationPrivate::notify_helper(QObject*, QEvent*) /usr/lib/libQtGui.so.4 0
31 QApplication::notify(QObject*, QEvent*) /usr/lib/libQtGui.so.4 0
32 QCoreApplication::notifyInternal(QObject*, QEvent*) /usr/lib/libQtCore.so.4 0
33 QWidgetPrivate::sendPendingMoveAndResizeEvents(bool, bool) /usr/lib/libQtGui.so.4 0
34 QWidgetPrivate::show_helper() /usr/lib/libQtGui.so.4 0
35 QWidget::setVisible(bool) /usr/lib/libQtGui.so.4 0
36 QWidget::show qwidget.h 473
37 main main.cpp 18
Hier ist die Funktion initMultitexture():

Code: Alles auswählen

bool GLBox::initMultitexture()
{
    printf("\033[0;41m %s(%i): %s \033[0m\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
    char *extensions;   // fetch extension string
    extensions = strdup((char*) glGetString(GL_EXTENSIONS));    // fetch extension string
    int len = strlen(extensions);
    for(int i=0; i<len; ++i)    // separate it by newline instead of blank
        if(extensions[i]==' ')
            extensions[i] = '\n';   // replace ' ' by '\n'

#ifdef EXT_INFO
    QMessageBox::information(this, "supported GL extensions", extensions, QMessageBox::Ok);
#endif

    if(isInString(extensions, "GL_ARB_multitexture")            // is multitexturing supported?
        && __ARB_ENABLE                                         // override flag
        && isInString(extensions, "GL_EX_texture_env_combine")) // texture environment-combining supported?
    {
        glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTexelUnits_);
//        glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC) wglGetProcAddress("glMultiTexCoord1fARB");
//        glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");
//        glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC) wglGetProcAddress("glMultiTexCoord3fARB");
//        glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC) wglGetProcAddress("glMultiTexCoord4fARB");
//        glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
//        glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");

#ifdef EXT_INFO
        QMessageBox::information(this, "The GL_ARB_multitexture extension will be used.", "feature supported!", QMessageBox::Ok);
#endif
        return true;
    }

    useMultitexture_ = false;   // we can't use it if it isn't supported!
    return false;
}
GLBox ist eine Unterklasse von QGLWidget. Bevor jemand die Glaskugel holt, könnt ihr mir ruhig sagen wenn ich irgendwelche Infos vergessen habe.

cu Floh

Verfasst: 1. Februar 2010 23:11
von Christian81
QMessageBox ist modal und die Eventloop läuft weiter. Deshalb werden auch Events weiter abgearbeitet - wie z.B. ein repaint(). Ne MessageBox in einer zyklisch aufgerufenen Funktion ist demnach keine gute Idee.

Verfasst: 1. Februar 2010 23:38
von EyesKiller
Ich wüsste nicht daß initGL() zyklisch wäre. :? Ich habe diese Doc gelesen und erst so verstanden daß es nur einmal ausgeführt wird. Aber jetzt wo ich nochmal gelesen habe scheint es 2mal ausgeführt zu werden:
Einmal vor dem PaintGL() bzw. resizeGL() und dann nochmal wenn neue QGLContext zugeordnet wird. (die unterstrichene Part verstehe ich nicht so ganz, ich bin erst dabei OpenGL zu lernen)

cu Floh

Verfasst: 2. Februar 2010 09:12
von solarix
Das braucht doch nicht soooo viel Fantasie...stell dir doch einfach in den Methoden glDraw() (und allen weiteren die glInit() aufrufen) sowas vor:

Code: Alles auswählen

 if (!initialized)
    glInit();
Wenn du also (wie von Christian erklärt) mehrmals in den Eventloop kommst und mehrmals da durch kommst.. wird halt mehrmals glInit() aufgerufen.. oder?

Verfasst: 2. Februar 2010 16:15
von EyesKiller
@solaris:
Danke für die Hinweis (mit initialized), jetzt weiß ich wo mein Denkfehler war und verstehe warum initGL() mehrfach ausgeführt wird. :)
Aber gleich so genervt? :?

cu Floh