0

マルチサンプルアンチエイリアシングを使用して、描画したものをBMPに保存したいと思います。マルチサンプリングにはFBOを使用し、通常のFBOを使用します。この記事を参照しました:GL_framebuffer_multisample

しかし、glBlitFramebufferを使用してマルチサンプリング用のFBOから通常のFBOにデータをコピーすると、OpenGLエラーが発生します。ここでコードの一部をここに投稿します。

まず、2つのFBOを作成します。

glGenFramebuffers(1,&m_frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER,m_frameBuffer);

glGenRenderbuffers(1,&m_renderBufferColor);
glBindRenderbuffer(GL_RENDERBUFFER,m_renderBufferColor);
//在FBO里开启多重采样
glRenderbufferStorageMultisample(GL_RENDERBUFFER,4,
    GL_RGB,m_subImageWidth,m_subImageHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,
    GL_RENDERBUFFER,m_renderBufferColor);

glGenRenderbuffers(1,&m_renderBufferDepth);
glBindRenderbuffer(GL_RENDERBUFFER,m_renderBufferDepth);
glRenderbufferStorageMultisample(GL_RENDERBUFFER,4,
    GL_DEPTH_COMPONENT24,m_subImageWidth,m_subImageHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,
    GL_RENDERBUFFER,m_renderBufferDepth);

glBindFramebuffer(GL_FRAMEBUFFER,0);//解除绑定

//generate standard FBO for blitting
glGenFramebuffers(1,&m_frameBufferBlit);
glBindFramebuffer(GL_FRAMEBUFFER,m_frameBufferBlit);

glGenRenderbuffers(1,&m_renderBufferColorBlit);
glBindRenderbuffer(GL_RENDERBUFFER,m_renderBufferColorBlit);
glRenderbufferStorage(GL_RENDERBUFFER,GL_RGB,
    m_subImageWidth,m_subImageHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,
    GL_RENDERBUFFER,m_renderBufferColorBlit);

glGenRenderbuffers(1,&m_renderBufferDepthBlit);
glBindRenderbuffer(GL_RENDERBUFFER,m_renderBufferDepthBlit);
glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT24,
    m_subImageWidth,m_subImageHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,
    GL_RENDERBUFFER,m_renderBufferDepth);

glBindFramebuffer(GL_FRAMEBUFFER,0);//解除绑定

次に何かを描きます:

glBindFramebuffer(GL_FRAMEBUFFER,m_frameBuffer);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
    cout << "The frame buffer status is not complete!" << endl;
    return;
}

drawing();//draw something
glBindFramebuffer(GL_FRAMEBUFFER,0);

    int temp1 = GLUtils::checkForOpenGLError(__FILE__,__LINE__);
    //blitting
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER,m_frameBufferBlit);
    glBindFramebuffer(GL_READ_FRAMEBUFFER,m_frameBuffer);

    int temp2 = GLUtils::checkForOpenGLError(__FILE__,__LINE__);
    glBlitFramebuffer(0,0,m_subImageWidth,m_subImageHeight,
        0,0,m_subImageWidth,m_subImageHeight,
        GL_COLOR_BUFFER_BIT,GL_LINEAR);
    int temp3 = GLUtils::checkForOpenGLError(__FILE__,__LINE__);
    glBindFramebuffer(GL_READ_FRAMEBUFFER,0);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);

    //glBindFramebuffer(GL_FRAMEBUFFER,m_frameBuffer);
    glBindBuffer(GL_PIXEL_PACK_BUFFER,m_subImageBuffer[i]);
    glPixelStorei(GL_PACK_ALIGNMENT,1);

    glBindFramebuffer(GL_FRAMEBUFFER,m_frameBufferBlit);
    //注意:以BGR的顺序读取
    glReadPixels(0,0,m_subImageWidth,m_subImageHeight,
        GL_BGR,GL_UNSIGNED_BYTE,bufferOffset(0));
    int temp4 = GLUtils::checkForOpenGLError(__FILE__,__LINE__);
    m_subPixels[i] = static_cast<GLubyte*>(glMapBuffer(GL_PIXEL_PACK_BUFFER,GL_READ_ONLY));
    if (m_subPixels[i] == NULL)
    {
        cout << "NULL pointer" << endl;
    }
    gltGenBMP(subImageFile[i],GLT_BGR,m_subImageWidth,m_subImageHeight,m_subPixels[i]);
    glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
    glBindBuffer(GL_PIXEL_PACK_BUFFER,0);

    glBindFramebuffer(GL_FRAMEBUFFER,0);

関数GLUtils::checkForOpenGLErrorは、OpenGLエラーが発生したかどうかをチェックすることです(1を返すと、エラーが発生したことを意味します)。描画は何かをレンダリングすることであり、関数gltGenBMPはデータをBMPとして保存することです。これらはすべて正常に機能します。temp1とtemp2は0、temp3とtemp4は1であることがわかりました。結論として、何か問題があります。関数glBlitFramebufferを使用しますが、なぜですか?設定に問題がありますか?


更新: 通常のFBO m_frameBufferBlitを確認すると:

glBindFramebuffer(GL_DRAW_FRAMEBUFFER,m_frameBufferBlit);
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
    cout << "The frame buffer status is not complete!" << endl;
    return;
}

完全ではないので、FBOを正しく作成していませんか?

どうしたの?

4

1 に答える 1

1

フレームバッファの完全性の条件を思い出すと役立つ場合があります。

  • フレームバッファに少なくとも 1 つの画像が添付されている必要があります
  • すべての添付ファイルは添付ファイルである必要があります
  • すべてのアクティブな描画バッファには、関連付けられたイメージが必要です
  • 読み取りバッファがアクティブな場合、関連付けられたイメージが必要です
  • 添付されたすべての画像は、同じ数のサンプルを持つ必要があります

添付画像の完全性の条件:

  • 画像の幅と高さはゼロ以外でなければなりません
  • 画像の内部形式はアタッチメント ポイントと一致する必要があります (例: 深度画像は深度アタッチメントに接続する必要があります) 。

これらのルールは実際のルールを単純化したものであり、少し複雑であることに注意してください。

于 2012-07-18T17:40:04.763 に答える