2013-06-18 1 views
8

Ich frage mich, ob Aufruf von updateGL() in festen Timer-Intervallen den Renderprozess verlangsamen kann. Also, ich möchte versuchen, den Render in Echtzeit zu machen. Ich habe nicht die Funktion, es automatisch ausführen zu lassen. Wer weiß das?Wie make updateGL() in Echtzeit QT

zweitens habe ich updateGL() in meinem Programm kommentiert, CPU-Auslastung auf 1% und 0% reduziert. Jetzt, wenn ich auf das Display-Widget klicke, springt es auf 14%, warum? macht nicht die GPU den gesamten Rendering-Job? Wenn ja, warum springt die CPU auf 14? Wie kann ich das beheben?

+0

Für die CPU-Nutzung, nein, es ist nicht die GPU, die * all * den Job macht. Die CPU muss weiterhin die Befehle ausführen, die an die GPU übergeben werden, und manchmal auf die Synchronisation warten (und gegebenenfalls auch die Logik Ihrer Anwendung ausführen). Wenn deine Szene wirklich einfach ist, ist 14% definitiv nicht normal. Stellen Sie sicher, dass Sie nicht mehr als 60 fps zeichnen, was nicht sinnvoll ist. – Boris

Antwort

11

Ja, Sie können es in Echtzeit machen, ohne zu reißen (z. B. Neuzeichnen bei genau 60 fps, die Bildwiederholfrequenz Ihres Monitors).

Dazu müssen Sie V_SYNC ermöglichen, und ein QTimer timer; des Intervalls mit 0 Aktivieren V_SYNC die automatisch aufgerufen swapBuffers() Befehl an die CPU-warten, bis die vertikale Aktualisierungssignal von Ihrem Monitor machen. Dann wird der Timer tatsächlich mit der Aktualisierungsrate des Monitors synchronisiert. Eine ähnliche Information finden Sie hier: http://blog.qt.digia.com/blog/2010/12/02/velvet-and-the-qml-scene-graph/. Beachten Sie die QGLFormat::setSwapInterval(1) V_SYNC zu ermöglichen, wenn sie nicht automatisch von Ihrem Treibereinstellungen vorgenommen:

class MyGLWidget: public QGLWidget 
{ 
    // ... 
private: 
    QTimer timer; 
} 

QGLFormat desiredFormat() 
{ 
    QGLFormat fmt; 
    fmt.setSwapInterval(1); 
    return fmt; 
} 

MyGLWidget::MyGLWidget() : 
    QGLWidget(desiredFormat()) 
{ 
    // Configure the timer 
    connect(&timer, SIGNAL(timeout()), this, SLOT(updateGL())); 
    if(format().swapInterval() == -1) 
    { 
     // V_blank synchronization not available (tearing likely to happen) 
     qDebug("Swap Buffers at v_blank not available: refresh at approx 60fps."); 
     timer.setInterval(17); 
    } 
    else 
    { 
     // V_blank synchronization available 
     timer.setInterval(0); 
    } 
    timer.start(); 
} 

Parallel dazu können Sie eine QElapsedTimer messen laufen, wie viel Zeit zwischen zwei Zeichnung (normalerweise ca. 16.6ms) vergangen ist, und Verwendung Diese Informationen, zum Beispiel, um Ihre Szene zu aktualisieren.

+0

ich habe das hinzugefügt-> format(). SetSwapInterval (1); im Konstruktor und swapbuffers() am Ende der Funktion paintGL(). aber es hatte keine Wirkung. Wie macht man 60fps rendern? – Sam

+0

@ user1596226 Zwei Dinge: Sie sollten 'this-> format(). SetSwapInterval (1);' nicht aufrufen, sondern ein QGLFormat mit diesem Auslagerungsintervall erstellen und es an den Konstruktor Ihres 'QGLWidget' übergeben. Dann sollten Sie 'swapBuffers()' überhaupt nicht aufrufen: wie ich schon sagte, wird es automatisch nach Ihrer 'paintGL()' aufgerufen :) Sind Sie in der Lage, die Zeit zwischen jedem paintGL() mit einem 'zu messen und anzuzeigen QElapsedTimer'? Dies wird sehr hilfreich sein, um zu verstehen, was vor sich geht. – Boris

+0

Könntest du bitte für mich schreiben, ich weiß nicht genau, wie man dieses Flag zum Konstruktor hinzufügt. – Sam