Browse Source

GLRenderer: fix invalid enum error when using framebuffers

Kirill Vainer 10 years ago
parent
commit
78d2d6e944

+ 105 - 85
jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

@@ -1459,25 +1459,44 @@ public class GLRenderer implements Renderer {
                     rb.getId());
                     rb.getId());
         }
         }
     }
     }
+    
+    private void bindFrameBuffer(FrameBuffer fb) {
+        if (fb == null) {
+            if (context.boundFBO != 0) {
+                glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, 0);
+                statistics.onFrameBufferUse(null, true);
+                context.boundFBO = 0;
+                context.boundFB = null;
+            }
+        } else {
+            assert fb.getId() != -1 && fb.getId() != 0;
+            if (context.boundFBO != fb.getId()) {
+                glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, fb.getId());
+                context.boundFBO = fb.getId();
+                context.boundFB = fb;
+                statistics.onFrameBufferUse(fb, true);
+            } else {
+                statistics.onFrameBufferUse(fb, false);
+            }
+        }
+    }
 
 
     public void updateFrameBuffer(FrameBuffer fb) {
     public void updateFrameBuffer(FrameBuffer fb) {
+        if (fb.getNumColorBuffers() == 0 && fb.getDepthBuffer() == null) {
+            throw new IllegalArgumentException("The framebuffer: " + fb
+                    + "\nDoesn't have any color/depth buffers");
+        }
+
         int id = fb.getId();
         int id = fb.getId();
         if (id == -1) {
         if (id == -1) {
-            // create FBO
             glfbo.glGenFramebuffersEXT(intBuf1);
             glfbo.glGenFramebuffersEXT(intBuf1);
             id = intBuf1.get(0);
             id = intBuf1.get(0);
             fb.setId(id);
             fb.setId(id);
             objManager.registerObject(fb);
             objManager.registerObject(fb);
-
             statistics.onNewFrameBuffer();
             statistics.onNewFrameBuffer();
         }
         }
 
 
-        if (context.boundFBO != id) {
-            glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, id);
-            // binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0
-            context.boundDrawBuf = 0;
-            context.boundFBO = id;
-        }
+        bindFrameBuffer(fb);
 
 
         FrameBuffer.RenderBuffer depthBuf = fb.getDepthBuffer();
         FrameBuffer.RenderBuffer depthBuf = fb.getDepthBuffer();
         if (depthBuf != null) {
         if (depthBuf != null) {
@@ -1488,7 +1507,8 @@ public class GLRenderer implements Renderer {
             FrameBuffer.RenderBuffer colorBuf = fb.getColorBuffer(i);
             FrameBuffer.RenderBuffer colorBuf = fb.getColorBuffer(i);
             updateFrameBufferAttachment(fb, colorBuf);
             updateFrameBufferAttachment(fb, colorBuf);
         }
         }
-
+        
+        setReadDrawBuffers(fb);
         checkFrameBufferError();
         checkFrameBufferError();
 
 
         fb.clearUpdateNeeded();
         fb.clearUpdateNeeded();
@@ -1516,93 +1536,45 @@ public class GLRenderer implements Renderer {
     }
     }
 
 
     public void setMainFrameBufferOverride(FrameBuffer fb) {
     public void setMainFrameBufferOverride(FrameBuffer fb) {
+        mainFbOverride = null;
+        if (context.boundFBO == 0) {
+            // Main FB is now set to fb, make sure its bound
+            setFrameBuffer(fb);
+        }
         mainFbOverride = fb;
         mainFbOverride = fb;
     }
     }
 
 
-    public void setFrameBuffer(FrameBuffer fb) {
-        if (fb == null && mainFbOverride != null) {
-            fb = mainFbOverride;
-        }
-
-        if (context.boundFB == fb) {
-            if (fb == null || !fb.isUpdateNeeded()) {
-                return;
-            }
-        }
-
-        if (!caps.contains(Caps.FrameBuffer)) {
-            throw new RendererException("Framebuffer objects are not supported"
-                    + " by the video hardware");
-        }
-
-        // generate mipmaps for last FB if needed
-        if (context.boundFB != null) {
-            for (int i = 0; i < context.boundFB.getNumColorBuffers(); i++) {
-                RenderBuffer rb = context.boundFB.getColorBuffer(i);
-                Texture tex = rb.getTexture();
-                if (tex != null
-                        && tex.getMinFilter().usesMipMapLevels()) {
-                    setTexture(0, rb.getTexture());
-
-                    int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace());
-                    glfbo.glGenerateMipmapEXT(textureType);
-                }
-            }
+    public void setReadDrawBuffers(FrameBuffer fb) {
+        if (gl2 == null) {
+            return;
         }
         }
-
+        
+        final int NONE    = -2;
+        final int INITIAL = -1;
+        final int MRT_OFF = 100;
+        
         if (fb == null) {
         if (fb == null) {
-            // unbind any fbos
-            if (context.boundFBO != 0) {
-                glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, 0);
-                statistics.onFrameBufferUse(null, true);
-
-                context.boundFBO = 0;
+            // Set Read/Draw buffers to initial value.
+            if (context.boundDrawBuf != INITIAL) {
+                gl2.glDrawBuffer(context.initialDrawBuf);
+                context.boundDrawBuf = INITIAL;
             }
             }
-            // select back buffer
-            if (gl2 != null) {
-                if (context.boundDrawBuf != -1) {
-                    gl2.glDrawBuffer(context.initialDrawBuf);
-                    context.boundDrawBuf = -1;
-                }
-                if (context.boundReadBuf != -1) {
-                    gl2.glReadBuffer(context.initialReadBuf);
-                    context.boundReadBuf = -1;
-                }
+            if (context.boundReadBuf != INITIAL) {
+                gl2.glReadBuffer(context.initialReadBuf);
+                context.boundReadBuf = INITIAL;
             }
             }
-
-            context.boundFB = null;
         } else {
         } else {
-            if (fb.getNumColorBuffers() == 0 && fb.getDepthBuffer() == null) {
-                throw new IllegalArgumentException("The framebuffer: " + fb
-                        + "\nDoesn't have any color/depth buffers");
-            }
-
-            if (fb.isUpdateNeeded()) {
-                updateFrameBuffer(fb);
-            }
-
-            // update viewport to reflect framebuffer's resolution
-            setViewPort(0, 0, fb.getWidth(), fb.getHeight());
-
-            if (context.boundFBO != fb.getId()) {
-                glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, fb.getId());
-                statistics.onFrameBufferUse(fb, true);
-
-                context.boundFBO = fb.getId();
-            } else {
-                statistics.onFrameBufferUse(fb, false);
-            }
             if (fb.getNumColorBuffers() == 0) {
             if (fb.getNumColorBuffers() == 0) {
                 // make sure to select NONE as draw buf
                 // make sure to select NONE as draw buf
-                // no color buffer attached. select NONE
+                // no color buffer attached.
                 if (gl2 != null) {
                 if (gl2 != null) {
-                    if (context.boundDrawBuf != -2) {
+                    if (context.boundDrawBuf != NONE) {
                         gl2.glDrawBuffer(GL.GL_NONE);
                         gl2.glDrawBuffer(GL.GL_NONE);
-                        context.boundDrawBuf = -2;
+                        context.boundDrawBuf = NONE;
                     }
                     }
-                    if (context.boundReadBuf != -2) {
+                    if (context.boundReadBuf != NONE) {
                         gl2.glReadBuffer(GL.GL_NONE);
                         gl2.glReadBuffer(GL.GL_NONE);
-                        context.boundReadBuf = -2;
+                        context.boundReadBuf = NONE;
                     }
                     }
                 }
                 }
             } else {
             } else {
@@ -1622,7 +1594,7 @@ public class GLRenderer implements Renderer {
                                 + " by the video hardware!");
                                 + " by the video hardware!");
                     }
                     }
 
 
-                    if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()) {
+                    if (context.boundDrawBuf != MRT_OFF + fb.getNumColorBuffers()) {
                         intBuf16.clear();
                         intBuf16.clear();
                         for (int i = 0; i < fb.getNumColorBuffers(); i++) {
                         for (int i = 0; i < fb.getNumColorBuffers(); i++) {
                             intBuf16.put(GLFbo.GL_COLOR_ATTACHMENT0_EXT + i);
                             intBuf16.put(GLFbo.GL_COLOR_ATTACHMENT0_EXT + i);
@@ -1630,7 +1602,7 @@ public class GLRenderer implements Renderer {
 
 
                         intBuf16.flip();
                         intBuf16.flip();
                         glext.glDrawBuffers(intBuf16);
                         glext.glDrawBuffers(intBuf16);
-                        context.boundDrawBuf = 100 + fb.getNumColorBuffers();
+                        context.boundDrawBuf = MRT_OFF + fb.getNumColorBuffers();
                     }
                     }
                 } else {
                 } else {
                     RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex());
                     RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex());
@@ -1643,8 +1615,56 @@ public class GLRenderer implements Renderer {
                     }
                     }
                 }
                 }
             }
             }
+        }
+        
+    }
+    
+    public void setFrameBuffer(FrameBuffer fb) {
+        if (fb == null && mainFbOverride != null) {
+            fb = mainFbOverride;
+        }
+
+        if (context.boundFB == fb) {
+            if (fb == null || !fb.isUpdateNeeded()) {
+                return;
+            }
+        }
+
+        if (!caps.contains(Caps.FrameBuffer)) {
+            throw new RendererException("Framebuffer objects are not supported"
+                    + " by the video hardware");
+        }
+
+        // generate mipmaps for last FB if needed
+        if (context.boundFB != null) {
+            for (int i = 0; i < context.boundFB.getNumColorBuffers(); i++) {
+                RenderBuffer rb = context.boundFB.getColorBuffer(i);
+                Texture tex = rb.getTexture();
+                if (tex != null
+                        && tex.getMinFilter().usesMipMapLevels()) {
+                    setTexture(0, rb.getTexture());
+
+                    int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace());
+                    glfbo.glGenerateMipmapEXT(textureType);
+                }
+            }
+        }
+
+        if (fb == null) {
+            bindFrameBuffer(null);
+            setReadDrawBuffers(null);
+        } else {
+            if (fb.isUpdateNeeded()) {
+                updateFrameBuffer(fb);
+            } else {
+                bindFrameBuffer(fb);
+                setReadDrawBuffers(fb);
+            }
+
+            // update viewport to reflect framebuffer's resolution
+            setViewPort(0, 0, fb.getWidth(), fb.getHeight());
 
 
-            assert fb.getId() >= 0;
+            assert fb.getId() > 0;
             assert context.boundFBO == fb.getId();
             assert context.boundFBO == fb.getId();
 
 
             context.boundFB = fb;
             context.boundFB = fb;

+ 18 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GLTracer.java

@@ -336,6 +336,21 @@ public final class GLTracer implements InvocationHandler {
         print(")");
         print(")");
     }
     }
     
     
+    private void printArgsGetInteger(Object[] args) {
+        print("(");
+        int param = (Integer)args[0];
+        IntBuffer ib = (IntBuffer) args[1];
+        printEnum(param);
+        print(", ");
+        printOut();
+        if (param == GL2.GL_DRAW_BUFFER || param == GL2.GL_READ_BUFFER) {
+            printEnum(ib.get(0));
+        } else {
+            printInt(ib.get(0));
+        }
+        print(")");
+    }
+    
     private void printArgsTexParameter(Object[] args) {
     private void printArgsTexParameter(Object[] args) {
         print("(");
         print("(");
 
 
@@ -389,6 +404,9 @@ public final class GLTracer implements InvocationHandler {
         } else if (methodName.equals("glTexParameteri")) {
         } else if (methodName.equals("glTexParameteri")) {
             printArgsTexParameter(args);
             printArgsTexParameter(args);
             return;
             return;
+        } else if (methodName.equals("glGetInteger")) {
+            printArgsGetInteger(args);
+            return;
         }
         }
         
         
         if (args == null) {
         if (args == null) {