2016-03-27 17 views
0

Ich möchte glReadPixels mit GL_DEPTH_COMPONENT in meiner QT-Anwendung verwenden, um sicherzustellen, dass Benutzer nur sichtbare Vertices mit ihrer Maus auswählen können. Als ich dies versuchen, stürzt meine Anwendung mit dem folgenden Fehler:glReadPixels GL_DEPTH_COMPONENT stürzt QT-Anwendung ab

Unhandled exception at 0x00007FFF94E60823 (ig75icd64.dll) in qtopenglsphere.exe: 0xC0000005: Access violation reading location 0x00000000000000A8.

Ein paar Anmerkungen:

  • mit glReadPixels mit GL_RED korrekte Ergebnisse liefert

  • meine integrierte GPU ist eine Intel HD 4600. ig75icd64.dll im Fehler oben scheint der OpenGL-Treiber dafür zu sein. "OpenGL extensions viewer" meldet, dass diese GPU zu 100% kompatibel mit OpenGL 4.3 und früher ist.

  • In dem Moment, in dem das Programm einen 3D-Würfel perspektivisch zeichnet, ist der Tiefen-Test aktiviert und der Würfel sieht gut aus.

Main.cpp

#include "mainwindow.h" 
#include <QApplication> 
#include <QOpenGLFunctions> 
#include <QTextStream> 

int main(int argc, char *argv[]) 
{ 
    QSurfaceFormat format; 
    format.setSamples(16); 
    format.setDepthBufferSize(24); 
    QSurfaceFormat::setDefaultFormat(format); 
    format.setRenderableType(QSurfaceFormat::OpenGL); 
    format.setVersion(4, 0); 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 
    return a.exec(); 
} 

glwidget.cpp - initialiseGL()

void GLWidget::initializeGL() 
{ 
    initializeOpenGLFunctions(); 
    glClearColor(0,0,0,1); 

    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_LIGHT0); 
    glEnable(GL_LIGHTING); 
    glEnable(GL_COLOR_MATERIAL); 

    shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, 
     "uniform mat4 mvpMatrix;\n" 
     "in vec4 vertex;\n" 
     "in vec4 color;\n" 
     "out vec4 varyingColor;\n" 
     "void main(void)\n" 
     "{\n" 
     "varyingColor = color;\n" 
     "gl_Position = mvpMatrix * vertex;\n" 
     "}"); 
    shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, 
     "in vec4 varyingColor;\n" 
     "out vec4 fragColor;\n" 
     "void main(void)\n" 
     "{\n" 
     " gl_FragColor = varyingColor;\n" 
     "}"); 
    shaderProgram.link(); 

<definition of cube vertices> 

} 

glwidget.cpp - paintGL()

void GLWidget::paintGL() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    mMatrix.setToIdentity(); 
    vMatrix.setToIdentity(); 

    QMatrix4x4 cameraTransformation; 
    cameraTransformation.rotate(alpha, 0, 1, 0); 
    cameraTransformation.rotate(beta, 1, 0, 0); 
    QVector3D cameraPosition = cameraTransformation* QVector3D(0, 0, distance); 
    QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0); 
    QVector3D cameratranslate(panx,pany,0); 
    cameratranslate = cameraTransformation*cameratranslate; 
    cameraPosition += cameratranslate; 
    vMatrix.lookAt(cameraPosition, cameratranslate, cameraUpDirection); 

    shaderProgram.bind(); 
    shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix); 
    shaderProgram.setAttributeArray("vertex", vertices.constData()); 
    shaderProgram.enableAttributeArray("vertex"); 
    shaderProgram.setAttributeArray("color", colors.constData()); 
    shaderProgram.enableAttributeArray("color"); 
    glDrawArrays(GL_TRIANGLES, 0, vertices.size()); 
    shaderProgram.disableAttributeArray("vertex"); 
    shaderProgram.disableAttributeArray("color"); 

    shaderProgram.release(); 
} 

glwidget.cpp - findSelectedVertex (QPoint)

Es scheint mir seltsam, dass ich glReadPixels mit GL_RED verwenden kann, aber nicht mit GL_DEPTH_COMPONENT. Ich habe versucht, sicherzustellen, dass ich OpenGL4.0 anstelle von OpenGL ES 2.0 verwende (das GL_DEPTH_COMPONENT nicht hat), aber vielleicht verpasse ich etwas.

Antwort

0

Eine kompatible OpenGL-Implementierung kann keine Ausnahme auslösen, da für Operationen, die nicht von einem Treiber unterstützt werden, z. B. GL_DEPTH_COMPONENT bis glReadPixels, eine Enumeration oder Werte bereitgestellt werden. Wenn die Operation nicht unterstützt wird, zeichnet sie einen Fehler auf, der durch glGetError abrufbar ist, und fährt fort, als ob die Operation nie aufgerufen würde.

Sie sind sich nicht sicher, welche Zeile abstürzt. Meine Schätzung ist, dass die glReadPixels Operation fehlschlägt, weil GL_DEPTH_COMPONENT + GL_FLOAT nicht unterstützt wird und der jetzt nicht initialisierte Float-Fehler im Druckvorgang verursacht. Wenn das ist von wo die Ausnahme überhaupt geworfen wird.

+0

Danke Andreas. Die Zeile glReadPixels ist das Problem und verursacht die Ausnahme. Ich erreiche nie die Linie, wo ich drucke. Die Verwendung von GL_RED und float gibt einen Wert von 0 bis 1 zurück, derselbe wie von GL_DEPTH_COMPONENT erwartet, daher sehe ich auch nicht, dass dies ein Problem sein könnte. – scatatat

+0

Ich hatte meinen fairen Anteil an unzuverlässigen Debuggern ... Gibt es irgendwelche Optimierungen, die den Debugger stören könnten? Haben Sie versucht, die Anwendung in einem Grafik-Debugger wie gDEBugger oder CodeXL auszuführen und bei einem Fehler zu brechen? Zur Lösung Ihres Problems bin ich am Verlust. Der Code sieht gut aus für mich. Ich war mit Plattformen, die einige der glReadPixels-Enumerationen (Mesa) nicht unterstützten, und das Ergebnis war ein OpenGL-Fehler und Daten, auf die nicht geschrieben wurde, genau wie vom Standard definiert. Dann wiederum, welche Teilmenge unterstützt wird, kann nicht von OpenGL abgefragt werden, da eine Teilmenge de facto nicht konform ist. – Andreas