*我一直在尝试使用OpenGL的帧缓冲和Java中的LWJGL库来实现可渲染纹理功能。然而,我总是得到的结果是100%**黑色**纹理。*
我只是想问一下这个问题是什么。我没有呈现任何特定的形状。我绑定生成的帧缓冲区并调用glClearColor(1, 0, 0, 1);
然后调用glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
然后取消绑定帧缓冲区。但是当我尝试渲染绑定到帧缓冲区的纹理时,纹理只显示黑色,实际应该是红色,对吧?
此外,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_RGBA8
,width
和height
的值为512和512. attachments[]
只包含1个值,而且#39} ; s GL_COLOR_ATTACHMENT0
。 useDepthBuffer
设置为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;
}
如您所见,我将视口调整为纹理/帧缓冲区的大小。然后我绑定帧缓冲区并将清晰颜色设置为红色。然后,因为我在渲染代码中传递了true
,所以它(我相信)会将当前绑定的帧缓冲区清除为红色。
texture.releaseRenderTarget();
调整视口以适合显示,然后调用glBindFramebuffer(GL_FRAMEBUFFER, 0);
最后一行代码quad.draw();
只是绑定绑定到帧缓冲区的纹理的textureID,然后用它绘制一个简单的四边形。
那几乎就是全部。
我可以向您保证我正确渲染四边形,因为我可以将从PNG文件加载的纹理绑定到它,并且纹理成功显示。
所以为了弄清楚,主要的问题是:
为什么地球上的纹理是黑色的,因为它应该是红色的?在哪里以及我做错了什么?
编辑:我有一种感觉,它可能与某些关于不同gl ojects的边界有关。渲染缓冲区是否必须在渲染到它的帧缓冲区时被绑定?不是吗?有关系吗?纹理怎么样?他们应该在什么时候?
答案 0 :(得分:1)
我做了一些非常愚蠢的事。我在(RenderableTextue.class
)内初始化fbo纹理的类是Texture.class
的子类。包含textureID的绑定方法应该从Texture类继承,因为我已将id变量声明为protected
。但是,我偶然在子类中创建了一个本地private
变量,因此,在生成纹理时,将textureID保存到本地id变量,并在绑定时使用来自超类的未初始化的id。对于任何试图解决这个问题的人都很抱歉:s