Login  Register

Multisampled renderbuffer and dark edges

Posted by r.jaoui on Jun 27, 2021; 7:50am
URL: https://forum.jogamp.org/Multisampled-renderbuffer-and-dark-edges-tp4041171.html

Hello !

I'm not sure if this is caused by OpenGL or by JOGL, but when I render to a multisampled renderbuffer (or a multisampled texture), and then blit the result to another framebuffer with a texture attachement, and then render this texture, I seem to get darker edges than if I was to simply render the shape directly to the screen :

In this example, the red section with the star on the left is rendered to an FBO with multisampled color, stencil and depth renderbuffers, and then this FBO is blitted to another with a single texture attachement, which is finally used to render to the screen. on the right, the star is directly drawn to the screen afterwards.



This is a zoomed version of a previous test (note that I've also checked the actual pixel color values, that do differ) :



It seems like the border is significantly darker on the left, for a reason I don't understand.

Here are the important sections of code from my panel listener :

                @Override
                public void display(GLAutoDrawable displayable) {
                        gl = displayable.getGL().getGL2();
                       
                        gl.glClearColor(0f, 0f, 0f, 1f);
                        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT);
       
                        gl.glColor4f(0f, 0f, 0f, 1f);
                        gl.glRectd(-1f, 1f, 1f, getYScreen(310));
                        gl.glColor4f(0f, 0f, 1f, 1f);
                        gl.glRectd(-1f, getYScreen(310), 1f, getYScreen(340));
                        gl.glColor4f(0f, 1f, 0f, 1f);
                        gl.glRectd(-1f, getYScreen(340), 1f, getYScreen(370));
                        gl.glColor4f(0f, 1f, 1f, 1f);
                        gl.glRectd(-1f, getYScreen(370), 1f, getYScreen(400));
                        gl.glColor4f(1f, 0f, 0f, 1f);
                        gl.glRectd(-1f, getYScreen(400), 1f, getYScreen(430));
                        gl.glColor4f(1f, 0f, 1f, 1f);
                        gl.glRectd(-1f, getYScreen(430), 1f, getYScreen(460));
                        gl.glColor4f(1f, 1f, 0f, 1f);
                        gl.glRectd(-1f, getYScreen(460), 1f, getYScreen(490));
                        gl.glColor4f(1f, 1f, 1f, 1f);
                        gl.glRectd(-1f, getYScreen(490), 1f, -1f);
                       
                        gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, fboMSAA.get(0));
                        gl.glViewport(0, 0, 600, 300);

                gl.glBlendFuncSeparate(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA, GL2.GL_ONE, GL2.GL_ONE_MINUS_SRC_ALPHA);
                       
                        gl.glClearColor(1f, 0f, 0f, 1f);
                        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                       
                        float alpha = (float) frame.mouseX / (float) panel.getWidth();
                        if(alpha > 1f) alpha = 1f;
                        if(alpha < 0f) alpha = 0f;
                        alpha = 1f;
                       
                        gl.glColor4f(0f, 1f, 0f, alpha);
                        gl.glBegin(GL2.GL_TRIANGLE_FAN);
                        glVertex(150, 150, 600, 300);
                        for(int i = 0; i < 6; i++) {
                                float theta = (float) i * 3.1415926f * 4.0f / 5.0f;
                                glVertex(150 + 120.0 * Math.sin(theta), 150 - 120.0 * Math.cos(theta), 600, 300);
                        }
                        gl.glEnd();
                       
                        gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
                        gl.glBindFramebuffer(GL2.GL_READ_FRAMEBUFFER, fboMSAA.get(0));
                        gl.glBindFramebuffer(GL2.GL_DRAW_FRAMEBUFFER, fbo.get(0));
                        gl.glReadBuffer(GL2.GL_BACK);
                        gl.glBlitFramebuffer(0, 0, 600, 300, 0, 0, 600, 300, GL2.GL_COLOR_BUFFER_BIT, GL2.GL_NEAREST);
                       
                        gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
                        gl.glViewport(0, 0, panel.getWidth(), panel.getHeight());
       
                        gl.glColor4f(1f, 1f, 1f, 1f);
                        gl.glBindTexture(GL2.GL_TEXTURE_2D, texture.get(0));
                       
                        gl.glBegin(GL2.GL_QUADS);
                        gl.glTexCoord2f(0, 0);
                        glVertex(100.5, 250.5);
                        gl.glTexCoord2f(0, 1);
                        glVertex(100.5, 550.5);
                        gl.glTexCoord2f(1, 1);
                        glVertex(700.5, 550.5);
                        gl.glTexCoord2f(1, 0);
                        glVertex(700.5, 250.5);
                        gl.glEnd();
                       
                        gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);
                        gl.glBlendFuncSeparate(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA, GL2.GL_ONE, GL2.GL_ONE_MINUS_SRC_ALPHA);
       
                        gl.glColor4f(0f, 1f, 0f, alpha);
                        gl.glBegin(GL2.GL_TRIANGLE_FAN);
                        glVertex(550, 400);
                        for(int i = 0; i < 6; i++) {
                                float theta = (float) i * 3.1415926f * 4.0f / 5.0f;
                                glVertex(550 + 120.0 * Math.sin(theta), 400 + 120.0 * Math.cos(theta));
                        }
                        gl.glEnd();
                }


                @Override
                public void init(GLAutoDrawable displayable) {
                        gl = displayable.getGL().getGL2();
       
                gl.glEnable (GL2.GL_LINE_SMOOTH);
                gl.glEnable (GL2.GL_POINT_SMOOTH);
                gl.glEnable (GL2.GL_SMOOTH);
                gl.glEnable(GL2.GL_TEXTURE_2D);
               
                        gl.glDisable(GL.GL_CULL_FACE);
               
                gl.glDrawBuffer(GL.GL_FRONT_AND_BACK);
               
                        gl.glHint(GL2.GL_LINE_SMOOTH_HINT, GL2.GL_NICEST);
                        gl.glHint(GL2.GL_POINT_SMOOTH_HINT, GL2.GL_NICEST);
                        gl.glShadeModel(GL2.GL_SMOOTH);
       
                gl.glEnable(GL2.GL_BLEND);
                gl.glBlendFunc(GL2.GL_ONE, GL2.GL_ONE_MINUS_SRC_ALPHA);
               
                        gl.glClearColor(0f, 0f, 0f, 1f);
                        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT);
       
                gl.glEnable(GL.GL_MULTISAMPLE);
       
                        texture = IntBuffer.allocate(1);
                        fbo = IntBuffer.allocate(1);
                        textureMSAA = IntBuffer.allocate(1);
                        fboMSAA = IntBuffer.allocate(1);
                        colorMSAA = IntBuffer.allocate(1);
                        depthMSAA = IntBuffer.allocate(1);
                       
                        //CREATE THE MULTISAMPLED FBO
                        gl.glGenFramebuffers(1, fboMSAA);
                        gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, fboMSAA.get(0));
       
                        //CREATE THE MULTISAMPLED COLOR RENDERBUFFER
                        gl.glGenRenderbuffers(1, colorMSAA);
                        gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, colorMSAA.get(0));
                        gl.glRenderbufferStorageMultisample(GL2.GL_RENDERBUFFER, 8, GL2.GL_RGBA8, 600, 300);
       
                        //BIND THE MULTISAMPLED COLOR RENDERBUFFER TO THE FBO
                        gl.glFramebufferRenderbuffer(GL2.GL_FRAMEBUFFER, GL2.GL_COLOR_ATTACHMENT0, GL2.GL_RENDERBUFFER, colorMSAA.get(0));
       
                        //CREATE THE MULTISAMPLED STENCIL RENDERBUFFER
                        gl.glGenRenderbuffers(1, depthMSAA);
                        gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, depthMSAA.get(0));
                        gl.glRenderbufferStorageMultisample(GL2.GL_RENDERBUFFER, 8, GL2.GL_DEPTH24_STENCIL8, 600, 300);
       
                        //BIND THE MULTISAMPLED STENCIL RENDERBUFFER TO THE FBO
                        gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, fboMSAA.get(0));
                        gl.glFramebufferRenderbuffer(GL2.GL_FRAMEBUFFER, GL2.GL_DEPTH_ATTACHMENT, GL2.GL_RENDERBUFFER, depthMSAA.get(0));
                        gl.glFramebufferRenderbuffer(GL2.GL_FRAMEBUFFER, GL2.GL_STENCIL_ATTACHMENT, GL2.GL_RENDERBUFFER, depthMSAA.get(0));
       
                        //CREATE THE CLASSIC FBO
                        gl.glGenFramebuffers(1, fbo);
                        gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, fbo.get(0));
       
                        //CREATE THE CLASSIC TEXTURE
                        gl.glGenTextures(1, texture);
                        gl.glBindTexture(GL2.GL_TEXTURE_2D, texture.get(0));
       
                        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
                        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
                        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL2.GL_TEXTURE_BASE_LEVEL, 0);
                        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAX_LEVEL, 0);
                        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL2.GL_MIRRORED_REPEAT);
                        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL2.GL_MIRRORED_REPEAT);
                   
                        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL2.GL_RGBA8, 600, 300, 0, GL2.GL_BGRA, GL.GL_UNSIGNED_BYTE, null);
       
                        //BIND THE CLASSIC TEXTURE TO THE FBO
                        gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, GL2.GL_COLOR_ATTACHMENT0, GL2.GL_TEXTURE_2D, texture.get(0), 0);
                }


Thanks for your help !