LWJGL copyFrameBuffer off-by-one error [patch]

When I use Renderer.copyFrameBuffer with LWJGL to copy between two identically sized FBOs, I end up with a single pixel of garbage along the top and right edges. LwjglRenderer.copyFrameBuffer doesn’t seem correct.



LWJGL doc says both src and dst rectangle bounds are inclusive:

http://lwjgl.org/javadoc/org/lwjgl/opengl/EXTFramebufferBlit.html

But the OpenGL spec says the lower bounds (X0,Y0) are inclusive while the upper bounds (X1,Y1) are exclusive:

http://www.opengl.org/sdk/docs/man3/xhtml/glBlitFramebuffer.xml

The OpenGL spec seems to be correct.



Also LwjglRenderer.copyFrameBuffer is in terms of width/height but glBlitFramebuffer is in terms of X,Y rectangle bounds (so need to add the lower bounds X,Y to width,height to get upper bounds X,Y).



This patch fixes all this and I no longer get the garbage (uncopied) pixels:



[patch]Index: src/lwjgl/com/jme3/renderer/lwjgl/LwjglRenderer.java

===================================================================

— src/lwjgl/com/jme3/renderer/lwjgl/LwjglRenderer.java (revision 9561)

+++ src/lwjgl/com/jme3/renderer/lwjgl/LwjglRenderer.java (working copy)

@@ -1144,15 +1144,15 @@



public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {

if (GLContext.getCapabilities().GL_EXT_framebuffer_blit) {

  •        int srcX = 0;<br />
    
  •        int srcY = 0;<br />
    
  •        int srcW = 0;<br />
    
  •        int srcH = 0;<br />
    
  •        int srcX0 = 0;<br />
    
  •        int srcY0 = 0;<br />
    
  •        int srcX1 = 0;<br />
    
  •        int srcY1 = 0;<br />
    

- int dstX = 0;
- int dstY = 0;
- int dstW = 0;
- int dstH = 0;
+ int dstX0 = 0;
+ int dstY0 = 0;
+ int dstX1 = 0;
+ int dstY1 = 0;

int prevFBO = context.boundFBO;

@@ -1175,32 +1175,32 @@

if (src == null) {
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
- srcX = vpX;
- srcY = vpY;
- srcW = vpW;
- srcH = vpH;
+ srcX0 = vpX;
+ srcY0 = vpY;
+ srcX1 = vpX + vpW;
+ srcY1 = vpY + vpH;
} else {
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src.getId());
- srcW = src.getWidth();
- srcH = src.getHeight();
+ srcX1 = src.getWidth();
+ srcY1 = src.getHeight();
}
if (dst == null) {
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
- dstX = vpX;
- dstY = vpY;
- dstW = vpW - 1;
- dstH = vpH - 1;
+ dstX0 = vpX;
+ dstY0 = vpY;
+ dstX1 = vpX + vpW;
+ dstY1 = vpY + vpH;
} else {
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dst.getId());
- dstW = dst.getWidth() - 1;
- dstH = dst.getHeight() - 1;
+ dstX1 = dst.getWidth();
+ dstY1 = dst.getHeight();
}
int mask = GL_COLOR_BUFFER_BIT;
if (copyDepth) {
mask |= GL_DEPTH_BUFFER_BIT;
}
- glBlitFramebufferEXT(0, 0, srcW, srcH,
- 0, 0, dstW, dstH, mask,
+ glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask,
GL_NEAREST);


[/patch]
4 Likes

Patch committed, It does fix the copy issue you raised in another thread indeed.

thanks a lot

great, thanks.