我想在我的QT应用程序中使用glReadPixels和GL_DEPTH_COMPONENT,以确保用户只能用鼠标选择可见顶点。当我尝试这样做时,我的应用程序崩溃并出现以下错误:
0x00007FFF94E60823(ig75icd64.dll)中的未处理异常 qtopenglsphere.exe:0xC0000005:访问冲突读取位置 0x00000000000000A8。
几点说明:
使用带有GL_RED的glreadpixels会返回正确的结果
我的集成GPU是Intel HD 4600.上面的错误中的ig75icd64.dll似乎是它的OpenGL驱动程序。 “OpenGL扩展查看器”报告此GPU与OpenGL 4.3及更早版本100%兼容。
目前程序正在透视图中绘制3D立方体,并启用深度测试并且立方体看起来很好。
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)
void GLWidget::findSelectedVertex(QPoint clickpoint)
{
float mousex = clickpoint.x();
float mousey = clickpoint.y();
float renderedPixelDepth;
glReadPixels(mousex,height()-mousey,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&renderedPixelDepth);// EXCEPTION THROWN HERE
QTextStream(stdout) << "Clicked point value = " << renderedPixelDepth << endl;
}
我觉得奇怪的是我可以将glReadPixels与GL_RED一起使用但不能与GL_DEPTH_COMPONENT一起使用。我试图确保我使用OpenGL4.0而不是OpenGL ES 2.0(没有GL_DEPTH_COMPONENT),但也许我错过了一些东西。
答案 0 :(得分:0)
由于为GL_DEPTH_COMPONENT
到glReadPixels
等驱动程序不支持的操作提供了限制或值,因此不允许兼容的OpenGL实现抛出异常。如果不支持,操作将记录glGetError
可检索的错误,并继续执行,就像从未调用过操作一样。
您不清楚哪条线路崩溃了。我的猜测是glReadPixels
操作失败,因为GL_DEPTH_COMPONENT
+ GL_FLOAT
不受支持,现在未初始化的浮动导致打印操作出现问题。如果那是从那里抛出异常的地方。