COLOR_ATTACHMENT's-フレームバッファオブジェクト内のカラーアタッチメントとして複数のテクスチャにレンダリングする方法は?

PinkTurtle

複数のテクスチャをCOLOR_ATTACHMENTsとしてレンダリングしようとしていますが成功しません。それらを表示することで得られるのは、テクスチャが読み取られているが「空」であることを意味する黒い画面(赤いクリアフィル付き)だけです。

私の擬似コードは次のとおりです。テクスチャインデックス1、2、3とカラーアタッチメント0、1、2をそれぞれ使用して3つのテクスチャをFBOにアタッチします。テストケースとして、シーンを3色の添付ファイルにレンダリングして、まったく同じデータを保持するようにしました。次に、シェーダーパス2(2Dサンプラーを使用)でこれらのテクスチャのいずれかを読み取り、クワッドに表示します。

これらの2つの追加のカラー添付ファイルの本来の目的は、GPUピンポン技術を使用してそれらをランダムデータバッファーとして使用することです。これまでのところ、テスト目的でテクスチャクローンとして使用しています。

GL_TEXTURE1COLOR_ATTACHMENT0から読み込もうとすると、問題はありませんが、他の2つ(黒い画面)からはうまくいきません。

コード :

// Texture indices - inside a 'myGlut' struct
GLenum skyboxTextureIndex = GL_TEXTURE0;
GLenum colorTextureIndex = GL_TEXTURE1;
unsigned int colorTextureIndexInt = 1;
GLenum depthTexture1Index = GL_TEXTURE2;
unsigned int depthTexture1IndexInt = 2;
GLenum depthTexture2Index = GL_TEXTURE3;
unsigned int depthTexture2IndexInt = 3;

//** Below is inside 'main()' **//

// Create frame buffer
myGlut.frameBuffer = glutils::createFrameBuffer();

// Create texture to hold color buffer
glActiveTexture(myGlut.colorTextureIndex);
glBindTexture(GL_TEXTURE_2D, myGlut.colorTexture);
myGlut.colorTexture = glutils::createTextureAttachment(myGlut.camera -> getRenderResizedWidthPx(), myGlut.camera -> getRenderResizedHeightPx());
glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT0, myGlut.colorTexture);

// Create 1st texture to hold depth buffer wannabe :>
glActiveTexture(myGlut.depthTexture1Index);
glBindTexture(GL_TEXTURE_2D, myGlut.depthTexture1);
myGlut.depthTexture1 = glutils::createTextureAttachment(myGlut.camera -> getRenderResizedWidthPx(), myGlut.camera -> getRenderResizedHeightPx());
glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT1, myGlut.depthTexture1);

// Create 2nd texture to hold depth buffer wannabe :>
glActiveTexture(myGlut.depthTexture2Index);
glBindTexture(GL_TEXTURE_2D, myGlut.depthTexture2);
myGlut.depthTexture2 = glutils::createTextureAttachment(myGlut.camera -> getRenderResizedWidthPx(), myGlut.camera -> getRenderResizedHeightPx());
glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT2, myGlut.depthTexture2);

// Check FBO
if (!glutils::checkFBOStatus()) return 0;

glutils::機能

// Clear screen
void glutils::clearScreen (float r, float g, float b, float a) {
    glClearColor(r, g, b, a);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

// Bind select framebuffer
void glutils::bindFrameBuffer(int frameBuffer, int width, int height) {
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    glViewport(0, 0, width, height);
}

// Create frame buffer
GLuint glutils::createFrameBuffer() {
    GLuint frameBuffer;
    glGenFramebuffers(1, &frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    return frameBuffer;
}

// Create a texture attachment
GLuint glutils::createTextureAttachment(int width, int height) {
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    return texture;
}

// Bind a texture attachment to select framebuffer
void glutils::bindTextureAttachment (GLenum colorAttachment, GLuint texture) {
    glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachment, GL_TEXTURE_2D, texture, 0);
}

// Check current frame buffer status
bool glutils::checkFBOStatus () {
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        std::cerr << "##### ERROR : Frambuffer not complete... #####" << std::endl;
        return false;
    }
    else return true;
}

次に、過剰表示機能:

// Clear screen
glutils::clearScreen(1.f, 0.f, 0.f, 1.f);

// Bind to custom framebuffer
glutils::bindFrameBuffer(myGlut.frameBuffer, myGlut.camera -> getScreenWidthPx(), myGlut.camera -> getScreenHeightPx());

// Set draw context
GLuint drawBuffers[2];
if (myGlut.depthTextureSwitch) {    drawBuffers[0] = GL_COLOR_ATTACHMENT0;
                                    drawBuffers[1] = GL_COLOR_ATTACHMENT2;
} else {                            drawBuffers[0] = GL_COLOR_ATTACHMENT0;
                                    drawBuffers[1] = GL_COLOR_ATTACHMENT1;
} glDrawBuffers(2, drawBuffers);

// Use main program and bind uniforms
glUseProgram(myGlut.theProgram);
myGlut.refreshUniformsPass_1();

// Draw quad to sample
glutils::drawQuad();

// Unbind custom framebuffer -> use default (screen)
glutils::unbindCurrentFrameBuffer(myGlut.camera -> getScreenWidthPx(), myGlut.camera -> getScreenHeightPx());

// Use secondary program and bind uniforms
glUseProgram(myGlut.theProgram2);
myGlut.refreshUniformsPass_2();

// Draw quad to apply texture to
glutils::drawQuad();

// Switch
myGlut.depthTextureSwitch = !myGlut.depthTextureSwitch;

// Display & loop
glutSwapBuffers();
glutPostRedisplay();

関連する均一なバインディング->パス1

glUniform1i(glGetUniformLocation(myGlut.theProgram, "depthTexture"), !myGlut.depthTextureSwitch ? myGlut.depthTexture2IndexInt : myGlut.depthTexture1IndexInt);

関連するシェーダーコード->パス1

layout (location = 0) out vec4 outputColor;
layout (location = 1) out vec4 outputDepth1;
layout (location = 2) out vec4 outputDepth2;
uniform sampler2D depthTexture;

void main() {
    // ...
    outputColor = someColor;
    outputDepth1 = someColor;
    outputDepth2 = someColor;
}

関連する均一なバインディング->パス2

glUniform1i(glGetUniformLocation(myGlut.theProgram2, "texFramebuffer"), myGlut.depthTextureSwitch ? myGlut.depthTexture1IndexInt : myGlut.depthTexture2IndexInt);

関連するシェーダーコードを使用->パス2

uniform sampler2D texFramebuffer;
out vec4 outputColor;
// ...
void main() {
    outputColor = texture(texFramebuffer, vec2(gl_FragCoord.x / screenWidthPx * resRatio, gl_FragCoord.y / screenHeightPx * resRatio));
}

一言で言えば:私は、GL_TEXTURE0ながらシーンを保持GL_TEXTURE1し、GL_TEXTURE2黒です。どうして ?

PinkTurtle

私はついに犯人を見つけました。ループdisplay()関数内でフレームバッファーをバインドしているため、FBOをバインドした後、テクスチャの添付ファイルもバインドする必要がありました。に変更

// Bind to custom framebuffer
glutils::bindFrameBuffer(myGlut.frameBuffer, myGlut.camera -> getScreenWidthPx(), myGlut.camera -> getScreenHeightPx());

// Bind to select attachments
glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT0, myGlut.colorTexture);
if (!myGlut.depthTextureSwitch) glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT1, myGlut.depthTexture1);
else glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT1, myGlut.depthTexture2);

必要なすべてのカラーアタッチメントにレンダリングすることができました。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ