Incorrect alpha blending when rendering on a QGLFramebufferObject

I am writing an OpenGL-based vector graphics visualizer for my application. It should render the framebuffer object more directly to the screen. Since I am writing an application in Qt, I use the QGLFramebufferObject object, which is the wrapper class for the OpenGL framebuffer object.

I created a minimal example that shows the wrong result, which I also get when rendering more complex things (for example, using a flash shader that sets colors with a non-alpha value). I just draw a red circle and a translucent green on a black cleaned screen, and then the same on FBO:

void MainWidget::initializeGL() { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(0, 0, 0, 0); } void MainWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h); } void MainWidget::paintGL() { // DRAW ON THE SCREEN { glClear(GL_COLOR_BUFFER_BIT); glPointSize(100); glEnable(GL_POINT_SMOOTH); glBegin(GL_POINTS); glColor4f(1, 0, 0, 1); glVertex2f(-.2, 0); glColor4f(0, 1, 0, .5); glVertex2f( .2, 0); glEnd(); } QGLFramebufferObject fbo(width(), height()); fbo.bind(); // DRAW ON THE FBO USING THE SAME CODE AND THE SAME CONTEXT { glClear(GL_COLOR_BUFFER_BIT); glPointSize(100); glEnable(GL_POINT_SMOOTH); glBegin(GL_POINTS); glColor4f(1, 0, 0, 1); glVertex2f(-.2, 0); glColor4f(0, 1, 0, .5); glVertex2f( .2, 0); glEnd(); } fbo.release(); fbo.toImage().save("debug.png"); } 

The result looks like this on the screen (increased by 400%):

enter image description here

Rendering to a QGLFramebufferObject looks like this (also scales by 400%):

enter image description here

Please note that this image is not completely opaque, so here is this image with a closed chessboard:

enter image description here

Even the area in which two circles overlap is not completely opaque. And smoothing looks pretty ugly.

How does this happen? And how can I fix this?

I already tried:

  • Various mixing functions.
  • Explicitly disabling the depth buffer, stencil buffer, and fetch in the QGLFramebufferObject. I'm not sure if the default format of QGLFramebufferObject adds what I don't want.
+4
source share
1 answer

Try the following:

 QGLFramebufferObjectFormat fmt; fmt.setSamples(1); // or 4 or disable this line fmt.setInternalTextureFormat(GL_RGBA8); QGLFramebufferObject fbo(width(), height(), fmt); 

This creates a specific pixel format and also disables texture rendering using multisampling (otherwise QT always displays the texture). This can lead to different results. You can also experiment with the format.

Also, what is your equipment? My maximum point size is only 64 pixels (GTX 260), you are trying to display 100 points per pixel. This can be a problem. Are any OpenGL errors being generated? Does the same thing happen with small dots?

You can also try to hint (if possible in QT):

 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); 

But I would not expect this to change anything.

+1
source

Source: https://habr.com/ru/post/1432799/


All Articles