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 ! |
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. |
Free forum by Nabble | Edit this page |