Transparent FrameBuffer Background in OpenGL

I want to use glClear and glClearColor to fill the frame buffer with color, including alpha transparency. However, the framebuffer always appears as opaque when snapped to the texture that is displayed on the screen.

I want everything visualized in a framebuffer to keep them transparent. I just want to change the background.

See the following code:

def create_texture(surface): surface.texture = glGenTextures(1) glMatrixMode(GL_MODELVIEW) 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, surface.data) #Put surface pixel data into texture if surface.data == None: setup_framebuffer(surface) 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 glClearColor(*c) glClear(GL_COLOR_BUFFER_BIT) end_framebuffer() Surface.texture_ready.append(surface) def setup_framebuffer(surface): #Create texture if not done already if surface.texture == None: create_texture(surface) #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) glPushAttrib(GL_VIEWPORT_BIT) glViewport(0,0,surface._scale[0],surface._scale[1]) glMatrixMode(GL_PROJECTION) glLoadIdentity() #Load the projection matrix gluOrtho2D(0,surface._scale[0],0,surface._scale[1]) def end_framebuffer(): glPopAttrib() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) glMatrixMode(GL_PROJECTION) glLoadIdentity() #Load the projection matrix gluOrtho2D(0,1280,720,0) #Set an orthorgraphic view 

surface.background_alpha should be 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.events = [] pygame.font.init() pygame.mixer.init() 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 glutInit(sys.argv) glutInitWindowPosition(0,0) glutInitWindowSize(*game_size) glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA) glutGameModeString("1280x720: 32@60 ") #720 HD glutCreateWindow(title) glutSetIconTitle(title) self.callbacks() self.game_gap = (0,0) self.on_exit = on_exit self.mod_key = 1024 if sys.platform == "darwin" else 64 Surface.__init__(self,game_size) self.screen_change = True self.frames = [time.time()] self.fps = 60 self.last_time = 0 self.fade_surface = Surface([1280,720]) def callbacks(self): glutReshapeFunc(self.reshaped) glutKeyboardFunc(self.keydown) glutKeyboardUpFunc(self.keyup) glutSpecialFunc(self.specialdown) glutSpecialUpFunc(self.specialup) glutDisplayFunc(self.game_loop) glutIdleFunc(self.game_loop) glutMouseFunc(self.mouse_func) glutPassiveMotionFunc(self.mouse_move) 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 glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glMatrixMode(GL_PROJECTION) glLoadIdentity() #Load the projection matrix gluOrtho2D(0,1280,720,0) #Set an orthorgraphic view 

The code is a bit dirty because I made a lot of tweaks to make things work, and I didn't tidy everything up correctly.

If anyone can help me, I really thank you.

+4
source share
2 answers

I think that there is a basic misunderstanding of the framebuffer. The framebuffer is not really a data buffer in itself; it does not contain any data. You attach buffers to it (for example, a texture) so that you can render inactive buffers in the same way as on the screen. Therefore, when you say that you want โ€œglClear and glClearColor to fill the frame buffer with color, including alpha transparencyโ€, this is not entirely clear because the framebuffer does not contain any color data.

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

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

You make "surface.texture" the goal of rendering the framebuffer. In other words, you basically say: "When I draw this framebuffer, draw this texture."

+3
source

If you are trying to make the framebuffer transparent so that you can render the object on top of your desktop, you should know that which is not possible through Glut .

This effect depends on the platform you are using. What it is? Linux? Window? Mac OS X? You will need to get your hands dirty (discard the wilderness from the equation) and understand a little more about creating windows.

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

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

+2
source

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


All Articles