gpt4 book ai didi

java - OpenGL - 为什么我的 fbo/纹理保持黑色?

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:01:29 31 4
gpt4 key购买 nike

*我一直在尽最大努力使用 OpenGL 的帧缓冲和 Java 的 LWJGL 库来实现可渲染纹理功能。然而,我总是得到的结果是 100% **黑色 ** 纹理。*

我只是想就问题所在寻求一些建议。我没有渲染任何特定的形状。我绑定(bind)生成的帧缓冲区并调用 glClearColor(1, 0, 0, 1);,然后调用 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);,然后取消绑定(bind)帧缓冲区。但是当我尝试渲染绑定(bind)到帧缓冲区的纹理时,纹理只显示黑色,而实际上它应该是红色的,对吧?

此外,glCheckFramebufferStatus() 返回 GL_FRAMEBUFFER_COMPLETE 因此我认为错误出在渲染部分,而不是初始化阶段。但无论如何我都会展示初始化代码。

初始化代码:

public RenderableTexture initialize(int width, int height, int internalFormat, int[] attachments, boolean useDepthBuffer) {
if(!GLContext.getCapabilities().GL_EXT_framebuffer_object) {
System.err.println("FrameBuffers not supported on your graphics card!");
}

this.width = width;
this.height = height;
hasDepthBuffer = useDepthBuffer;

fbo = glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

id = glGenTextures();
glBindTexture(GL_TEXTURE_2D, id);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer) null);


if(useDepthBuffer) {
rbo = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
}

glFramebufferTexture2D(GL_FRAMEBUFFER, attachments[0], GL_TEXTURE_2D, id, 0);

int[] drawBuffers = new int[attachments.length];

for(int i = 0; i < attachments.length; i++)
if(attachments[i] == GL_DEPTH_ATTACHMENT)
drawBuffers[i] = GL_NONE;
else
drawBuffers[i] = attachments[i];

glDrawBuffers(Util.toIntBuffer(drawBuffers));

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
System.err.println("Warning! Incomplete Framebuffer");
glBindFramebuffer(GL_FRAMEBUFFER, 0);

return this;
}

internalFormat 的值为 GL_RGBA8widthheight 的值为 512 和 512。 attachments[] 仅包含 1 个值,即 GL_COLOR_ATTACHMENT0useDepthBuffer 设置为 true

上面的代码只调用了一次。

这是渲染代码:

public RenderManager draw() {
glClearColor(bg.x, bg.y, bg.z, bg.w);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

texture.bindAsRenderTarget(true);
texture.releaseRenderTarget();
quad.draw();

return this;
}

我将清除颜色设置为黑色 (0, 0, 0, 1) 然后清除屏幕。然后调用 texture.bindAsRenderTarget(true);texture 对象是包含上面的 initialize 方法的对象,因此一些变量在该方法和 bindAsRenderTarget() 之间共享。

这个方法看起来像这样:

public RenderableTexture bindAsRenderTarget(boolean clear) {
glViewport(0, 0, width, height);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glClearColor(1, 0, 0, 1f);
if(clear)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
return this;
}

如您所见,我将视口(viewport)调整为纹理/帧缓冲区的大小。然后我绑定(bind)帧缓冲区并将清除颜色设置为红色。然后,由于我在渲染代码中传递了 true,它(我相信)将当前绑定(bind)的帧缓冲区清除为红色。

texture.releaseRenderTarget(); 调整视口(viewport)以适应显示,然后调用 glBindFramebuffer(GL_FRAMEBUFFER, 0);

代码的最后一行 quad.draw(); 简单地将绑定(bind)到帧缓冲区的纹理的 textureID 绑定(bind),然后用它绘制一个简单的四边形。

这就是全部内容。

我可以向您保证我正在正确地渲染四边形,因为我可以将从 PNG 文件加载的纹理绑定(bind)到它并且纹理已成功显示。

因此,为了清楚起见,主要问题几乎是:

到底为什么透明后纹理变黑了,它应该是红色的?我哪里做错了什么?

编辑:我觉得这可能与不同 gl 对象的边界有关。渲染缓冲区是否必须在渲染点绑定(bind)到它的帧缓冲区?不是吗?有关系吗?质地怎么样?他们应该在什么时候?

最佳答案

我做了一件非常愚蠢的事情。我在 (RenderableTextue.class) 中初始化 fbo 纹理的类是 Texture.class 的子类。包含 textureID 的绑定(bind)方法应该是从 Texture 类继承的,因为我已将 id 变量声明为 protected。但是,我不小心在子类中创建了一个本地 private 变量,因此,在生成纹理时,将 textureID 保存到本地 id 变量,并在绑定(bind)时使用父类(super class)中未初始化的 id。对于任何试图解决此问题但未能解决的人,我们深表歉意:s

关于java - OpenGL - 为什么我的 fbo/纹理保持黑色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28603532/

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