7

マルチサンプリングされたシーンをテクスチャにレンダリングしようとしています。使用しているコードは次のとおりです。黒い画面が表示されます。init の最後に fbo の完全性をチェックすると、両方の fbo が完了していると報告されます。

void init_rendered_FBO() {
    glGenFramebuffers(1,&fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glGenTextures(1,&fbo_tex);
    glBindTexture(GL_TEXTURE_2D, fbo_tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width_screen, height_screen, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width_screen, height_screen);
    glBindTexture (GL_TEXTURE_2D, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex, 0);
    int objectType;
    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,&objectType);
    ASSERT(objectType == GL_TEXTURE);
    int objectName;
    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,&objectName);
    ASSERT(glIsTexture(objectName) == GL_TRUE);
    int wid, hei, fmt;
    glBindTexture(GL_TEXTURE_2D, objectName);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &wid);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &hei);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT,
            &fmt);
    glBindTexture(GL_TEXTURE_2D, 0);
    std::string format = convertInternalFormatToString(fmt);
    std::cout << "Color attachment 0: " << objectName << " " << wid << "x" << hei << ", " << format << std::endl;
    ASSERT(checkFramebufferStatus());
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

// this is the init function that gets called.
void init_rendered_multisample_FBO() {
    init_rendered_FBO();
    // now I'm going to set up the additional component necessary to perform multisampling which is a new fbo
    // that has a multisampled color buffer attached. I won't need a multisample depth buffer.
    glGenFramebuffers(1,&multi_fbo);
    glBindFramebuffer(GL_FRAMEBUFFER,multi_fbo);
    glGenRenderbuffers(1,&renderbuffer_multi);
    glBindRenderbuffer(GL_RENDERBUFFER,renderbuffer_multi);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA, width_screen,height_screen);
    glBindRenderbuffer(GL_RENDERBUFFER,0);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer_multi);
    int objectType;
    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,&objectType);
    ASSERT(objectType == GL_RENDERBUFFER);
    int objectName;
    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,&objectName);
    ASSERT(glIsRenderbuffer(objectName) == GL_TRUE);
    glBindRenderbuffer(GL_RENDERBUFFER,objectName);
    int wid,hei,fmt,sam;
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_WIDTH,&wid);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_HEIGHT,&hei);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_INTERNAL_FORMAT,&fmt);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_SAMPLES,&sam);
    glBindRenderbuffer(GL_RENDERBUFFER,0);
    printf("Renderbuffer: %dx%d, fmt=%d, samples=%d\n",wid,hei,fmt,sam);
    ASSERT(checkFramebufferStatus());
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
// this is called after rendering to multi_fbo
void resolve_multisample_FBO() {
    glBindFramebuffer(GL_READ_FRAMEBUFFER, multi_fbo);
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
    GLenum drawbuf = GL_COLOR_ATTACHMENT0;
    glDrawBuffers(1,&drawbuf);
    glBlitFramebuffer(0,0,width_screen,height_screen,0,0,width_screen,height_screen,GL_COLOR_BUFFER_BIT,GL_NEAREST);
}

私が忘れたものを見つけることができますか?glFramebufferRenderbuffer問題は通話にあると思います。最初の引数をに切り替えてみましたGL_READ_FRAMEBUFFERが、修正されませんでした。

確認glGetErrorしましたが、エラーはありません。INVALID_ENUM何か間違った設定をすると、必ず何かが失敗INVALID_OPERATIONし、問題を絞り込むのに役立ちます。

このコードを使用する方法は、マルチサンプリングを有効にするために変更する必要があるのは、描画時に multi_fbo をバインドし、バインドしてブリットする resolve 関数を呼び出すことだけです。その後、私の fbo テクスチャ (直接レンダリングすると正常に動作します) には、マルチサンプリングされたレンダリングが含まれているはずです。ただ、黒いだけです。glEnable(GL_MULTISAMPLE)また、初期化コードの別の部分も呼び出しました。

マルチサンプリングされていないテクスチャを別のテクスチャにブリットして、それが機能することを確認します。うまくいけば、それは私が失敗した場所を絞り込むのに役立ちます.

更新: したがって、通常の FBO を別の同一の FBO (どちらもカラー アタッチメント 0 にテクスチャがアタッチされています) にコピーすると、同じ黒い画面が生成されることがわかりました。ブリットは単に機能しません。

また奇妙なのは、ブリットしようとすると、SOURCE fbo のテクスチャを描画しても、まだすべて黒のままです。ブリットしようとすると、すべてが台無しになるようなものです。

FBOブリッティングコードを知っている、または持っている人はいますか? 見つけることはできませんが、マルチサンプリング FBO が機能している人がいることは知っています。

支援方法は次のとおりです。任意の時点で呼び出すコードがある場合はglBlitFramebuffer、その操作を設定するための他の呼び出しを確認したいと思います。起動すると、黒いバッファとテクスチャしか取得できないようです。

更新: バックバッファへのブリットは、マルチサンプリングでも機能します! もちろん、フレームバッファ 0 をバインドするだけなので、セットアップはまったく必要ありません。したがって、問題は、ブリットされるはずのテクスチャ アタッチメントを持つ FBO のセットアップにあるようです。

4

1 に答える 1

4

フレームバッファバインディングのリセットに失敗した以外は、何も悪いことをしていないことがわかりました。

最後に、void resolve_multisample_FBO()私は単に必要でしたglBindFramebuffer(GL_FRAMEBUFFER, 0);

3 時間を無駄にするひどい方法です。しかし、マルチサンプリングは見栄えがよく、それを補う以上のものです。

于 2012-02-12T13:15:32.927 に答える