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.
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
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