QGLWidget + QMessageBox = 2mal initGL()?

Alles rund um die Programmierung mit Qt
Antworten
EyesKiller
Beiträge: 3
Registriert: 1. Februar 2010 00:25

QGLWidget + QMessageBox = 2mal initGL()?

Beitrag 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
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag 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.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
EyesKiller
Beiträge: 3
Registriert: 1. Februar 2010 00:25

Beitrag 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
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag 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?
EyesKiller
Beiträge: 3
Registriert: 1. Februar 2010 00:25

Beitrag 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
Antworten