FBO 纹理显示全黑
FBO texture is displaying completely black
我正在尝试关注 ThinMatrix's water tutorial。为此,我需要创建一个 FBO 并将其渲染为纹理。
但是如您所见,水完全是黑色的:
我直接使用教程中的 source code provided(从 link 复制)。
基本上,我创建了一个 FrameBuffer:
public FrameBufferObject() {//call when loading the game
initialiseReflectionFrameBuffer();
initialiseRefractionFrameBuffer(); //Let's ignore refraction for now, as I only use reflection at the moment.
}
private void initialiseReflectionFrameBuffer() {
reflectionFrameBuffer = createFrameBuffer();
reflectionTexture = createTextureAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
reflectionDepthBuffer = createDepthBufferAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
unbindCurrentFrameBuffer();
}
然后我创建一个纹理附件:
private int createTextureAttachment( int width, int height) {
int texture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height,
0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0,
texture, 0);
return texture;
}
我还创建了一个深度缓冲区附件:
private int createDepthBufferAttachment(int width, int height) {
int depthBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, width,
height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT,
GL30.GL_RENDERBUFFER, depthBuffer);
return depthBuffer;
}
然后,我将对象渲染到帧缓冲区对象:
Main.TerrainDemo.shader.start();
fbos.bindReflectionFrameBuffer();
for (Grass g : Main.TerrainDemo.toDraw){
g.render();
}
fbos.unbindCurrentFrameBuffer();
我这样绑定帧缓冲区:
private void bindFrameBuffer(int frameBuffer, int width, int height){
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
GL11.glViewport(0, 0, width, height);
System.out.println("Bound");
if(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) == GL30.GL_FRAMEBUFFER_COMPLETE) {
System.out.println("Frame buffer setup is complete: " + GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER));
}
System.out.println("Error: " + GL11.glGetError());
}
打印glGetError()时的"error"是正常的0
。 "frame buffer setup" 消息确实打印出来了。
之后,我预计调用 fbos.getReflectionTexture()
会 return 一个纹理 ID...确实如此!成功了returns texture ID 12。但是,我绑定它时的纹理是完全黑色的。
public int getReflectionTexture() {//get the resulting texture
return reflectionTexture; //Remember, this was our original texture attachment.
}
reflectionTexture = createTextureAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
我无法弄清楚哪里出了问题,以及为什么纹理没有显示任何渲染给它的东西。
我知道的事情没有错误:
我绝对正确地绘制了水本身并对其进行了纹理处理。我可以使用任何预加载的纹理和纹理水就好了:
此外,渲染到 FBO 的对象具有正确的平移、旋转等。如果我不绑定任何帧缓冲区,则在我的屏幕上正确绘制(和看到)用于 FBO 的植物。
所以我意识到这是一个非常古老的问题,可能没人再关心了,但我最近在完成相同的教程并遇到类似问题后发现自己在这里。
在练习了一些 google foo 之后,我意识到我在我的代码中犯了一个非常基本的错误,这可能是相同的解决方案。
我根本没有做;
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
这是正在使用的帧缓冲区对象,在再次填充之前:
我只是继续将它放在绑定帧缓冲区函数的末尾,我成功了!
private void bindFrameBuffer(int frameBuffer, int width, int height){
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
GL11.glViewport(0, 0, width, height);
System.out.println("Bound");
if(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) == GL30.GL_FRAMEBUFFER_COMPLETE) {
System.out.println("Frame buffer setup is complete: " + GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER));
}
System.out.println("Error: " + GL11.glGetError());
}
可能不是同一个问题,因为我的错误特别基本,但值得一试。
有谁知道这个解决方案是否正确,或者它是解决更大问题的创可贴?
我正在尝试关注 ThinMatrix's water tutorial。为此,我需要创建一个 FBO 并将其渲染为纹理。
但是如您所见,水完全是黑色的:
我直接使用教程中的 source code provided(从 link 复制)。
基本上,我创建了一个 FrameBuffer:
public FrameBufferObject() {//call when loading the game
initialiseReflectionFrameBuffer();
initialiseRefractionFrameBuffer(); //Let's ignore refraction for now, as I only use reflection at the moment.
}
private void initialiseReflectionFrameBuffer() {
reflectionFrameBuffer = createFrameBuffer();
reflectionTexture = createTextureAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
reflectionDepthBuffer = createDepthBufferAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
unbindCurrentFrameBuffer();
}
然后我创建一个纹理附件:
private int createTextureAttachment( int width, int height) {
int texture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height,
0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0,
texture, 0);
return texture;
}
我还创建了一个深度缓冲区附件:
private int createDepthBufferAttachment(int width, int height) {
int depthBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, width,
height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT,
GL30.GL_RENDERBUFFER, depthBuffer);
return depthBuffer;
}
然后,我将对象渲染到帧缓冲区对象:
Main.TerrainDemo.shader.start();
fbos.bindReflectionFrameBuffer();
for (Grass g : Main.TerrainDemo.toDraw){
g.render();
}
fbos.unbindCurrentFrameBuffer();
我这样绑定帧缓冲区:
private void bindFrameBuffer(int frameBuffer, int width, int height){
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
GL11.glViewport(0, 0, width, height);
System.out.println("Bound");
if(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) == GL30.GL_FRAMEBUFFER_COMPLETE) {
System.out.println("Frame buffer setup is complete: " + GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER));
}
System.out.println("Error: " + GL11.glGetError());
}
打印glGetError()时的"error"是正常的0
。 "frame buffer setup" 消息确实打印出来了。
之后,我预计调用 fbos.getReflectionTexture()
会 return 一个纹理 ID...确实如此!成功了returns texture ID 12。但是,我绑定它时的纹理是完全黑色的。
public int getReflectionTexture() {//get the resulting texture
return reflectionTexture; //Remember, this was our original texture attachment.
}
reflectionTexture = createTextureAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
我无法弄清楚哪里出了问题,以及为什么纹理没有显示任何渲染给它的东西。
我知道的事情没有错误:
我绝对正确地绘制了水本身并对其进行了纹理处理。我可以使用任何预加载的纹理和纹理水就好了:
此外,渲染到 FBO 的对象具有正确的平移、旋转等。如果我不绑定任何帧缓冲区,则在我的屏幕上正确绘制(和看到)用于 FBO 的植物。
所以我意识到这是一个非常古老的问题,可能没人再关心了,但我最近在完成相同的教程并遇到类似问题后发现自己在这里。
在练习了一些 google foo 之后,我意识到我在我的代码中犯了一个非常基本的错误,这可能是相同的解决方案。
我根本没有做;
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
这是正在使用的帧缓冲区对象,在再次填充之前:
我只是继续将它放在绑定帧缓冲区函数的末尾,我成功了!
private void bindFrameBuffer(int frameBuffer, int width, int height){
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
GL11.glViewport(0, 0, width, height);
System.out.println("Bound");
if(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) == GL30.GL_FRAMEBUFFER_COMPLETE) {
System.out.println("Frame buffer setup is complete: " + GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER));
}
System.out.println("Error: " + GL11.glGetError());
}
可能不是同一个问题,因为我的错误特别基本,但值得一试。
有谁知道这个解决方案是否正确,或者它是解决更大问题的创可贴?