Multisampled renderbuffer and dark edges

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Multisampled renderbuffer and dark edges

r.jaoui
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 !
Reply | Threaded
Open this post in threaded view
|

Re: Multisampled renderbuffer and dark edges

r.jaoui
Update : I found the solution, I needed to enable framebuffer sRGB mode by calling :

gl.glEnable(GL2.GL_FRAMEBUFFER_SRGB);

This way, no color mapping in the native linear color space is performed, and the multisampling resolve is performes with linear gamma operations.