2016-06-20 13 views
1

私はQOpenGLWidgetでQTを作成していますので、ユーザーがモデル内のノードをクリックできるようにする必要があります。選択を可視ノードだけに制限するために、選択アルゴリズムにglReadPixels(GL_DEPTH_COMPONENT)を含めるようにしました。QOpenGLWidgetとglReadPixelsとデプスバッファ

私の問題は、glReadPixels(depth)は常に0を返します。下のコードのすべてのエラー出力も0を返します。 glReadPixels(赤)が正しい値を返します。

GLenum err = GL_NO_ERROR; 
    QTextStream(stdout) << "error before reading gl_red = " << err << endl; 
    GLfloat winX, winY, myred, mydepth; 
    winX = mousex; 
    winY = this->height() - mousey; 
    glReadPixels(winX,winY,1,1,GL_RED,GL_FLOAT, &myred); 
    QTextStream(stdout) << "GL RED = " << myred << endl; 
    err = glGetError(); 
    QTextStream(stdout) << "error after reading gl_red = " << err << endl; 
    glReadPixels(winX,winY,1,1,GL_DEPTH_COMPONENT,GL_FLOAT, &mydepth); 
    QTextStream(stdout) << "GL_DEPTH_COMPONENT = " << mydepth << endl; 
    err = glGetError(); 
    QTextStream(stdout) << "error after reading gl_depth = " << err << endl; 

私の通常の3Dレンダリングが正常に動作している、私は私のinitializeGL()機能でglEnable(GL_DEPTH_TEST)を持っています。現時点では、派手なVBOやVAOは使用していません。 FaceMeshQualityColorおよびtriVerticesは両方ともデータ型QVector<QVector3D>です。 (のOpenGL ES 2.0とは反対に)私は明示的にglReadPixels(GL_DEPTH_COMPONENT)機能を備えたものに私のOpenGLのバージョンを設定し、私のメインのファイルで

shader = shaderVaryingColor; 
shader->bind(); 
shader->setAttributeArray("color", FaceMeshQualityColor.constData()); 
shader->enableAttributeArray("color"); 
shader->setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix); 
shader->setAttributeArray("vertex", triVertices.constData()); 
shader->enableAttributeArray("vertex"); 
glEnable(GL_POLYGON_OFFSET_FILL); 
glPolygonOffset(1,1); 
glDrawArrays(GL_TRIANGLES, 0, triVertices.size()); 
glDisable(GL_POLYGON_OFFSET_FILL); 
shader->disableAttributeArray("vertex"); 
shader->disableAttributeArray("color"); 
shader->release(); 

:私の現在の顔のレンダリングには、次の進行を次の

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    QSurfaceFormat format; 
    format.setVersion(2, 1); 
    format.setProfile(QSurfaceFormat::CoreProfile); 
    format.setDepthBufferSize(32); 
    QSurfaceFormat::setDefaultFormat(format); 
    MainWindow w; 
    w.showMaximized(); 
    return a.exec(); 
} 

glReadPixels(深さ)の私の問題は、何とか私の深度バッファの扱いに関係していませんか?

glReadPixelsを呼び出す前に、デプスバッファを読み込み可能にするには、そのバッファをアクティブにする必要がありますか?あるいは、私の頂点シェーダに別のオブジェクトに深度の位置を明示的に書き込ませる必要がありますか?

答えて

1

QOpenGLWidgetは、基礎となるFBOに作用します。マルチサンプリングが有効な場合、そのFBOから深度コンポーネントを読み込むことはできません。最も簡単な解決策は、あなたのコードは次のようになりますので、ゼロにサンプルを設定することです:

QSurfaceFormat format; 
format.setVersion(2, 1); 
format.setProfile(QSurfaceFormat::CoreProfile); 
format.setDepthBufferSize(32); 

format.setSamples(0); 

QSurfaceFormat::setDefaultFormat(format); 

それとも、マルチサンプリングを使用することができますが、追加のFBOは、デプスバッファをコピーすることができる場所マルチサンプリングせずに必要になります。

class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions 
{ 
// 
// OTHER WIDGET RELATED STUFF 
// 
QOpenGLFrameBufferObject *mFBO=0; 

MyGLWidget::paintGL() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // 
    // DRAW YOUR SCENE HERE! 
    // 

    QOpenGLContext *ctx = QOpenGLContext::currentContext(); 

    // FBO must be re-created! is there a way to reset it? 
    if(mFBO) delete mFBO; 

    QOpenGLFramebufferObjectFormat format; 
    format.setSamples(0); 
    format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); 
    mFBO = new QOpenGLFramebufferObject(size(), format); 

    glBindFramebuffer(GL_READ_FRAMEBUFFER, defaultFramebufferObject()); 
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO->handle()); 
    ctx->extraFunctions()->glBlitFramebuffer(0, 0, width(), height(), 0, 0, mFBO->width(), mFBO->height(), GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, GL_NEAREST); 

    mFBO->bind(); // must rebind, otherwise it won't work! 

    float mouseDepth = 1.f; 
    glReadPixels(mouseX, mouseY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &mouseDepth); 

    mFBO->release(); 
} 
}; 
関連する問題