2010-11-30 9 views
9

Viele von Ihnen Qt (4.6 spezifisch) Benutzer werden mit dem Overpainting-Beispiel in den OpenGL-Tutorials vertraut sein. Ich versuche etwas sehr ähnliches zu tun, aber Shader für das reine OpenGL Daten anstelle der alten festen Funktionspipeline.QPainter über OpenGL in QGLWidget bei der Verwendung von Shadern

// Set background and state. 
makeCurrent(); 
qglClearColor(bgColour_); 

glEnable(GL_DEPTH_TEST); 
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 

if (smoothLines_) { 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glEnable(GL_LINE_SMOOTH); 
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 
} 

// Clear the buffers. 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glUseProgram(shader_); 

// Draw the grid. 
try { 
    glLineWidth(2.0f); 
    manager_->setColour(centreColour_); 
    grid_->draw(oE_GLGrid::Centre); 

    glLineWidth(1.5f); 
    manager_->setColour(majorColour_); 
    grid_->draw(oE_GLGrid::Major); 

    glLineWidth(1.0f); 
    manager_->setColour(minorColour_); 
    grid_->draw(oE_GLGrid::Minor); 
} catch(oE_GLException& e) { 
    cout << "OpenGL Error: " << e.what() << endl; 
    return; 
} 

// Reset OpenGL state for overlays. 
glDisable(GL_DEPTH_TEST); 
if (smoothLines_) { 
    glDisable(GL_BLEND); 
    glDisable(GL_LINE_SMOOTH); 
} 

// Draw the overlays. 
QPainter p(this); 
p.beginNativePainting(); 
p.fillRect(10, 10, 100, 100, 
     QColor(255, 0, 0)); 
p.endNativePainting(); 

Ich baue eine 3D-Asset-Anwendung daher die Grid-Zeug. Um es wirklich offensichtlich zu machen, wenn es funktioniert, sollte ein großes rotes Rechteck in der oberen linken Ecke des Widgets erscheinen - tut es aber nicht.

Die 3D funktioniert gut, aber QPainter bekommt nichts auf den Bildschirm. Der einzige wirkliche Unterschied, den ich zwischen meinen und den Dokumenten sehen kann, ist, dass alle Berechnungen der Projektions- und Transformationsmatrix in anderen Funktionen versteckt sind und dann über glUniform auf den Shader hochgeladen werden. Vermutlich, da QPainter die 2D-Assets in Dreiecke aufteilt, bedeutet dies, dass QPainters Shader keinen Zugriff auf meine Projektions-/Transformationsmatrizen haben, also wird mein rotes Dreieck gezeichnet - aber vielleicht irgendwo außerhalb des Bildschirms.

Antwort

10

Rufen Sie beginNativePainting() auf, bevor Sie OpenGL-Aufrufe vornehmen. Möglicherweise ist auch ein glPush/Pop des OpenGL-Status erforderlich. Probieren Sie etwas wie folgt aus:

QPainter p(this); 
p.beginNativePainting(); 

// Maybe necessary 
glPushAttrib(GL_ALL_ATTRIB_BITS); 
glMatrixMode(GL_PROJECTION); 
glPushMatrix(); 
glMatrixMode(GL_MODELVIEW); 
glPushMatrix(); 

// Put OpenGL code here 

// Necessary if used glPush-es above 
glMatrixMode(GL_PROJECTION); 
glPopMatrix(); 
glMatrixMode(GL_MODELVIEW); 
glPopMatrix(); 
glPopAttrib(); 

p.endNativePainting(); 

p.fillRect(10, 10, 100, 100, 
     QColor(255, 0, 0)); 
+0

noch kein Glück, ist die 3D-Daten nicht betroffen, aber die QPainter Daten nicht angezeigt. Ich frage mich, ob es schneller/einfacher ist, in einen Pixelpuffer zu rendern, diesen in einen QPainter als Hintergrundpixmap zu laden und dann über die Oberfläche zu "malen", bevor Sie auf den Bildschirm zeichnen. Oder ist das viel langsamer als es klingt? – cmannett85

+0

Werden die QPainter-Daten angezeigt, wenn Sie die 3D-Zeichnung nicht ausführen? – baysmith

+0

Ich habe die paintEvent() - Funktion nur mit den QPainter-Aufrufen gefüllt (wie im 2D-Beispiel in den Dokumenten) und nichts erscheint auf dem Bildschirm - außer das Widget ist schwarz gefüllt. – cmannett85

1

ich diese Antwort bin Entsendung zu stärken und zu klären, was ich als die wahre Lösung betrachten, fand durch cmannet85 (Kommentar von baysmith oben zu beantworten), das ist Bereinigen Sie die OpenGL-Vertex-Pufferbindungen, bevor Sie den QPainter-Code aufrufen.

Ich hatte ein fast identisches Problem, in dem ich zwischen QPainter-Funktionen und OpenGL-Funktionen wechseln musste. Wie cmannet85 herausfand, ist eine Ursache, dass, wenn OpenGL-Funktionen gebundene Vertexpuffer hinter sich lassen, sie QPainters Verwendung von OpenGL stören.

Ich war in der Lage, das Problem zu beheben, indem diese Aussage am Ende aller Teile meines OpenGL ES 2.0 Code hinzufügen, die glBindBuffer genannt:

glBindBuffer(GL_ARRAY_BUFFER,0); 

Ein zweiter Parameter von 0 entbindet den Puffer.

Es besteht keine Notwendigkeit für irgendwelche anderen Änderungen war wie das Hinzufügen Anrufe beginNativePainting ... endNativePainting usw.

Verwandte Themen