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 !