gpt4 book ai didi

c++ - OpenGL 3.0 : Cannot use framebuffer object in shader (black)

转载 作者:太空宇宙 更新时间:2023-11-04 11:32:46 26 4
gpt4 key购买 nike

我想将场景绘制到帧缓冲区对象,然后在另一个着色器中使用它的纹理。出于测试目的,我只想实际输出帧缓冲区对象的纹理。然而,对应的部分(矩形)恰好是全黑的。所以我想知道是 fbo 的渲染不起作用还是无法访问它。

这里是重要的代码部分:

在渲染到 FBO 之前调用:

void TextureRenderer::bind() {
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);
// glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, mWidth, mHeight);
}

这是应该显示 FBO 的平面。第一个纹理“mTextureId”是我从 TGA 文件加载并显示的另一个纹理,效果很好。然而,第二个“mReflectionTextureId”是来自 VBO 的那个,这是我无法访问的那个(或者它真的是黑色的,因为之前有错误)。

void WaterPlane::render(const Transform& trans) {
mat4 projection = trans.projection;
mat4 view = trans.view;
mat4 model = mat4::identitiy();

glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);

mShader->bind();

// lets activate the textures now
glEnable(GL_TEXTURE_2D);

// bumpmap texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTextureId);
// set the texture
mShader->seti("waterBumpTextureSampler", 0);

// rendered reflection texture (has been rendered previously with the help of Framebuffer object for reflection)
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mReflectionTextureId);
// set reflection texture
mShader->seti("renderedReflection", 1);

mShader->setMatrix("matProjection", projection, GL_TRUE);
mShader->setMatrix("matView", view, GL_TRUE);
mShader->setMatrix("matModel", model, GL_TRUE);
mShader->setf("vecTextureShift", mTextureShift);

mVboWaterPlane->render();

mShader->release();

glDisable(GL_TEXTURE_2D);

glPopClientAttrib();
glPopAttrib();
}

最后,water.fs 着色器:

#version 130
in vec4 VertPosition;
in vec4 VertNormal;
in vec4 VertColor;
in vec4 VertTexture;

uniform vec3 lightPos;
uniform sampler2D waterBumpTextureSampler;
uniform sampler2D renderedReflection; // reflection on the water

void main()
{
// completely black
gl_FragColor = texture( renderedReflection, VertTexture.xz);

// if this is actually commented in the bumpmap texture will be shown nicely
// gl_FragColor = texture( waterBumpTextureSampler, VertTexture.xz);
}

所以一般来说,显示纹理是可行的,但是显示来自帧缓冲区对象的纹理却不行(或者之前对它的渲染不起作用)。

截图:

编辑:

FBO的初始化代码:

void TextureRenderer::init() {
glGenFramebuffers(1, &mFramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);

// The texture we're going to render to
glGenTextures(1, &mRenderedTextureId);

// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, mRenderedTextureId);

cout << "TextureRenderer: creating with id " << mFramebufferName << " and tex id " << mRenderedTextureId << endl;

// Give an empty image to OpenGL ( the last "0" )
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, mWidth, mHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

// Poor filtering. Needed !
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// The depth buffer
// TODO this is probably not needed?!?!?!
glGenRenderbuffers(1, &mDepthRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, mWidth, mHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderBuffer);

// Set "renderedTexture" as our colour attachement #0
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mRenderedTextureId, 0);

// Set the list of draw buffers.
GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers

// Always check that our framebuffer is ok
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
cout << "Problem during creation of TextureRenderer" << endl;
throw std::runtime_error("Something Bad happened here");
}

unbind();

cout << "TextureRenderer: creating with id " << mFramebufferName << "...done" << endl;
}

绑定(bind)代码(在渲染到 FBO 之前立即调用):

void TextureRenderer::bind() {
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);
// glPushAttrib(GL_VIEWPORT_BIT); // http://wiki.delphigl.com/index.php/Tutorial_Framebufferobject
glViewport(0, 0, mWidth, mHeight);
}

最佳答案

现在已经解决了。问题很简单,我在 water.fs(片段)着色器中使用了错误的纹理坐标。下面是 water.fs 的更正变体。请注意随后提供给 texture(...) 函数的坐标计算的差异。

in vec4 VertPosition; 
in vec4 VertNormal;
in vec4 VertColor;
in vec4 VertTexture;
in vec4 VertTexturePS;

uniform vec3 lightPos;
uniform sampler2D waterBumpTextureSampler;
uniform sampler2D texReflection; // reflection on the water

void main()
{
vec2 originalTexCoord = VertTexturePS.xy / VertTexturePS.w * 0.5 + vec2(0.5);
gl_FragColor = texture( texReflection, originalTexCoord.xy);
}

VertTexturePS 只是在 water.vs 中计算出来的:

VertTexturePS = matProjection * matView * matModel * vec4(Position.xyz, 1);

关于c++ - OpenGL 3.0 : Cannot use framebuffer object in shader (black),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24012931/

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