Qt+OpenGL - DoubleBuffering - Swap zuspät/zufrüh? Qt-4.5.1
Verfasst: 7. Dezember 2010 10:15
Hallo zusammen,
ich bin gerade dabei ein Live-AnzeigeTool für eine Kamera zu schreiben. Die Darstellung der Videobilder soll mit OpenGL auf einem QGLWidget geschehen.
Der Weg der Bilder auf den Bildschirm klappt auch wunderbar nur habe ich ein großes Problem:
Bei bewegten Bildern, zerreißt sich das Bild an immer derselben Stelle.
Ich habe mittlerweile eine ganze Menge ausprobiert:
Wenn ich das DoubleBuffering ausschalte, habe ich mehrere "Bruchstücke" im Bild (wie zu erwarten war).
Durch verlagern des Zeichnens von paintEventGL() in paintEvent() ändert sich auch nichts.
Ich habe es mit AutoSwap und ohne (mit manuellem Swap) probiert, aber die Kante bleibt immer an der einen Stelle.
Dann habe ich die Bildschirmfarbtiefe von 32 Bit auf 16 Bit reduziert und siehe da, die Bruchstelle ist ein wenig nach oben gewandert, bleibt aber immer an dieser neuen Stelle.
Ich arbeite derzeit mit 8 Bit RGB Bildern,
muss ich Qt die Bildschirmfarbtiefe mitteilen bzw. muss ich diese manuel abfragen und meine Bilder in diese Farbtiefe konvertieren? Sollte soetwas nicht der Treiber machen?
Hier noch meine Initialisierung des QGlFormats:
und meine Zeichenmethode
Hat jemand schonmal etwas ähnliches erlebt oder kann mir jemand sagen, was ich falsch mache?
edit:
Oh Mist, glaub ich bin ins falsche Unterforum gerutscht. Bitte verschieben.. Danke
Schöne Grüße
ich bin gerade dabei ein Live-AnzeigeTool für eine Kamera zu schreiben. Die Darstellung der Videobilder soll mit OpenGL auf einem QGLWidget geschehen.
Der Weg der Bilder auf den Bildschirm klappt auch wunderbar nur habe ich ein großes Problem:
Bei bewegten Bildern, zerreißt sich das Bild an immer derselben Stelle.
Ich habe mittlerweile eine ganze Menge ausprobiert:
Wenn ich das DoubleBuffering ausschalte, habe ich mehrere "Bruchstücke" im Bild (wie zu erwarten war).
Durch verlagern des Zeichnens von paintEventGL() in paintEvent() ändert sich auch nichts.
Ich habe es mit AutoSwap und ohne (mit manuellem Swap) probiert, aber die Kante bleibt immer an der einen Stelle.
Dann habe ich die Bildschirmfarbtiefe von 32 Bit auf 16 Bit reduziert und siehe da, die Bruchstelle ist ein wenig nach oben gewandert, bleibt aber immer an dieser neuen Stelle.
Ich arbeite derzeit mit 8 Bit RGB Bildern,
muss ich Qt die Bildschirmfarbtiefe mitteilen bzw. muss ich diese manuel abfragen und meine Bilder in diese Farbtiefe konvertieren? Sollte soetwas nicht der Treiber machen?
Hier noch meine Initialisierung des QGlFormats:
Code: Alles auswählen
Format.setDoubleBuffer ( true );
Format.setDirectRendering ( true );
Format.setSwapInterval ( 1 );
Format.setSampleBuffers ( true );
Format.setOverlay ( true );
Format.setStereo ( false );
setFormat(Format);
setAutoBufferSwap ( true );
Code: Alles auswählen
// OpenGL-Matrizen sichern und zurücksetzen:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glColor3f(1.0f,1.0f,1.0f);
glPushAttrib(GL_ALL_ATTRIB_BITS);
pBuffer = m_pImageBuffer;
// *** Zweidimensionales Subimage erzeugen ***
// Zweidimensionale Texturierung freigeben
glEnable(GL_TEXTURE_2D);
// Zweidimensionales Subimage (Das Videobild mit 1000 x 714 Pixeln)
// in die Original-Textur (1024 x 1024) mittig einbetten
glTexSubImage2D(
GL_TEXTURE_2D, // Zieltextur, muss GL_TEXTURE_2D sein
0, // LOD-Nummer, Level 0 ist die Standardtextur
12, // Offset-Wert innerhalb des Texturarrays in x-Richtung: (1024-1000)/2
155, // Offset-Wert innerhalb des Texturarrays in y-Richtung: (1024-714)/2
IMAGE_WIDTH, // Breite des Subimages
IMAGE_HEIGHT, // Höhe des Subimages
GL_BGR_EXT, // Format der Pixeldaten
GL_UNSIGNED_BYTE, // Datentyp der Pixeldaten
pBuffer); // Pointer zu den Bilddaten im Speicher
// *** Bild ausrichten ***
// Ersetzt die aktuelle Matrix (GL_PROJECTION, oben gesetzt) durch die Identitätsmatrix
glLoadIdentity();
// Bild ist in Original-Textur eingebettet:
// Original-Textur hat 1024 x 1024 Pixel
// Sub-Textur hat 1000 x 714 Pixel (100%) -> X-Achse auf 102,3% strecken
// Y-Achse auf 144,0% strecken
// Bild steht auf dem Kopf -> Vertikal (Y-Achse) drehen -> Parameter Y = negativ
glScalef(1.024f, -1.43f, 1.0f);
//glScalef(1.024f, -1.4341736694677871148459383753501f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
glEnd();
//*** Alles zurücksetzen fürs Zeichnen mit dem Painter ***
glPopAttrib();
// alte OpenGL-Matrizen laden
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
edit:
Oh Mist, glaub ich bin ins falsche Unterforum gerutscht. Bitte verschieben.. Danke
Schöne Grüße