gpt4 book ai didi

c++ - COLOR_ATTACHMENT's - 如何将多个纹理渲染为帧缓冲区对象内的颜色附件?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:47:42 26 4
gpt4 key购买 nike

我试图将多个纹理渲染为 COLOR_ATTACHMENT 但没有成功。我从显示它们得到的只是一个黑屏(带有红色透明填充),这意味着我的纹理已被读取但是是“空的”。

我的伪代码是:将 3 个纹理附加到 FBO,纹理索引分别为 1、2 和 3,颜色附件分别为 0、1 和 2。作为测试用例,我尝试将我的场景渲染为 3 种颜色的附件,因此它们应该保存相同的精确数据。然后在着色器 channel 2(使用 2D 采样器)读取这些纹理中的任何一个并将它们显示在四边形上。

我对这 2 个额外颜色附件的初衷是使用 GPU 乒乓技术将它们用作随机数据缓冲区。到目前为止,我只是将它们用作测试目的的纹理克隆。

当尝试从 GL_TEXTURE1 (COLOR_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();

相关统一绑定(bind) -> pass 1

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

相关着色器代码 -> Pass 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;
}

相关统一绑定(bind) -> pass 2

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

使用相关的着色器代码 -> pass 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_TEXTURE1GL_TEXTURE2 是黑色的。为什么?

最佳答案

我终于找到了罪魁祸首。因为我在循环的 display() 函数中绑定(bind)帧缓冲区,所以在绑定(bind) FBO 之后我还需要绑定(bind)纹理附件。更改为

// 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);

允许我渲染所有需要的颜色附件。

关于c++ - COLOR_ATTACHMENT's - 如何将多个纹理渲染为帧缓冲区对象内的颜色附件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30484629/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com