Transparent FrameBuffer background in OpenGL

I want to use glClear and glClearColor to fill a frame buffer with a colour including alpha transparency. However the framebuffer always renders as opaque when binded to a texture which is rendered to the screen.

I want everything which is rendered to the framebuffer to kept their transparency. I just want to change the background.

See the following code:

def create_texture(surface):
surface.texture = glGenTextures(1)
glLoadIdentity() #Loads model matrix
glBindTexture(GL_TEXTURE_2D, surface.texture) #Binds the current 2D texture to the texture to be drawn
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) #Required to be set for maping the pixel data
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) #Similar as above
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface.surface_size[0], surface.surface_size[1], 0, GL_RGBA,GL_UNSIGNED_BYTE, #Put surface pixel data into texture
if == None:
    c = [float(sc)/255.0 for sc in surface.colour] #Divide colours by 255 because OpenGL uses 0-1
    if surface.background_alpha:
        c[3] = float(surface.background_alpha)/255.0
def setup_framebuffer(surface):
#Create texture if not done already
if surface.texture == None:
#Render child to parent
if surface.frame_buffer == None:
    surface.frame_buffer =  glGenFramebuffersEXT(1)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, surface.frame_buffer)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, surface.texture, 0)
glLoadIdentity() #Load the projection matrix
def end_framebuffer():
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)
    glLoadIdentity() #Load the projection matrix
    gluOrtho2D(0,1280,720,0) #Set an orthorgraphic view

surface.background_alpha should be the transparency for the framebuffer background. Here is my initialization code:

def __init__(self,title,game_size,on_exit = sys.exit):
        self.keys = [False] * 323 = []
        self.title = title
        self.game_size = game_size
        self.first_screen = (1280,720) #Take 120 pixels from the height because the menu bar, window bar and dock takes space
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA)
        glutGameModeString("1280x720:32@60") #720 HD
        self.game_gap = (0,0)
        self.on_exit = on_exit
        self.mod_key = 1024 if sys.platform == "darwin" else 64
        self.screen_change = True
        self.frames = [time.time()]
        self.fps = 60
        self.last_time = 0
        self.fade_surface = Surface([1280,720])
    def callbacks(self):
        glViewport(0,0,self.first_screen[0],self.first_screen[1]) #Creates the viewport which is mapped to the window
        glEnable(GL_BLEND) #Enable alpha blending
        glEnable(GL_TEXTURE_2D) #Enable 2D Textures
        glEnable(GL_POLYGON_SMOOTH) #Enable antialiased polygons
        glLoadIdentity() #Load the projection matrix
        gluOrtho2D(0,1280,720,0) #Set an orthorgraphic view

The code is a little messy because I have made lots of adjustments to get things to work and I haven't properly tidied everything up.

If anyone can help me, I thank you greatly.

Asked by: Max943 | Posted: 30-11-2021

Answer 1

I think there's a basic misunderstanding of the framebuffer here. The framebuffer is not really a buffer of data in itself, it does not hold any data. You attach buffers TO it (like a texture) so that you can render to offscreen buffers in the same manner you draw to the screen. So when you say you want to "glClear and glClearColor to fill a frame buffer with a colour including alpha transparency", it doesn't quite make sense because the framebuffer does not hold any color data itself.

When you attach the texture to the framebuffer with this call:

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, surface.texture, 0)

You're making the "surface.texture" the rendering destination of the framebuffer. In other words, you're essentially saying "When I draw to this framebuffer, draw into this texture.".

Answered by: Wilson208 | Posted: 01-01-2022

Answer 2

If you are trying to make the framebuffer transparent so you can render an object on top of your Desktop, you must know that that's not possible through Glut.

This kind of effect is specific to the platform you are using. What is it? Linux? Windows? Mac OS X? You'll have to get your hands dirty (drop Glut out of the equation) and understand a little more about building windows.

By the way, if your target is Windows you should check this:

(win32) How to make an OpenGL rendering context with transparent background?

Answered by: Melissa289 | Posted: 01-01-2022

Answer 3

The clear color alpha of the FBO must be equal to 0 :

glColorMask(TRUE, TRUE, TRUE, TRUE);
glClearColor(0, 0, 0, 0);

Answered by: Walter154 | Posted: 01-01-2022

Similar questions

python - How to make a surface with a transparent background in pygame

Can someone give me some example code that creates a surface with a transparent background in pygame?

python - How to use PIL to make all white pixels transparent?

I'm trying to make all white pixels transparent using the Python Image Library. (I'm a C hacker trying to learn python so be gentle) I've got the conversion working (at least the pixel values look correct) but I can't figure out how to convert the list into a buffer to re-create the image. Here's the code img ='img.png') imga = img.convert("RGBA") datas = imga.getdata() newData = list() for i...

pygame - Updating part of a surface in python, or transparent surfaces

I have an application written in python that's basically an etch-a-sketch, you move pixels around with WASD and arrow keys and it leaves a trail. However, I want to add a counter for the amount of pixels on the screen. How do I have the counter update without updating the entire surface and pwning the pixel drawings? Alternatively, can I make a surface that's completely transparent except for the text so you can se...

django - python PIL - background displayed opaque instead of transparent

I want to generate 32x32 sized thumbnails from uploaded images (actually avatars). To prevent a thumbnail from being smaller than that size, I want to create a transparent 32x32 background and paste the thumbnail on it. The code below tries to do so. However, the avatar is displayed on a black and opaque background; I lose transparency information somewhere through the process. Where am I doing wrong?...

How do I create a Status Icon / System Tray Icon with custom text and transparent background using Python and GTK?

Here is the code that I have so far to define the icon: icon_bg = gtk.gdk.pixbuf_new_from_file('gmail.png') w, h = icon_bg.get_width(), icon_bg.get_height() cmap = gtk.gdk.Colormap(gtk.gdk.visual_get_system(), False) drawable = gtk.gdk.Pixmap(None, w, h, 24) drawable.set_colormap = cmap gc = drawable.new_gc() drawable.draw_pixbuf(gc, icon_bg, 0, 0, 0, 0, w, h) drawn_icon = gtk.gdk.Pixbuf(gtk.gdk.COLORSPAC...

python - How to make cStringIO transparent to another function that expects a real local file

I came up with the following problem: CODE A works right now.. I am saving a png file called chart.png locally, and then I am loading it into the proprietary function (which I do not have access). However, in CODE B, am trying to use cStringIO.StringIO() so that I do not have to write the file "chart.png" to the disk. But I cannot find a way to pass it to the pproprietaryfunction because it is expecting a real fil...

python - PIL: How to make area transparent in PNG?

I've been using PIL to crop Images, now I also want to make certain rectangular areas transparent, say from PIL import Image im ="sample.png") transparent_area = (50,80,100,200) ...

python - Matplotlib transparent line plots

I am plotting two similar trajectories in matplotlib and I'd like to plot each of the lines with partial transparency so that the red (plotted second) doesn't obscure the blue. EDIT: Here's the image with transparent lines.

python - Transparent 3D bar graphs

I would like to generate 3D bar graphs with transparent surfaces so that I can see what is going on behind tall bars. The mplot3d API docs say that keywords are allowed for the bar3d function. I pass all the required parameters but can only output graphs with solid surfaces.

python - Partially transparent scatter plot, but with a solid color bar

In Python, with Matplotlib, how to simply do a scatter plot with transparency (alpha < 1), but with a color bar that represents their color value, but has alpha = 1? Here is what one gets, with from pylab import *; scatter(range(10), arange(0, 100, 10), c=range(10), alpha=0.2); color_bar = colorbar(): How can the color ba...

Still can't find your answer? Check out these communities...

PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python