2010-01-21 14 views
4

Je souhaite utiliser glClear et glClearColor pour remplir une zone tampon avec une couleur incluant la transparence alpha. Cependant, le framebuffer devient toujours opaque lorsqu'il est lié à une texture qui est rendue à l'écran.Fond transparent FrameBuffer dans OpenGL

Je veux que tout ce qui est rendu au framebuffer conserve sa transparence. Je veux juste changer l'arrière-plan.

Voir le code suivant:

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 devrait être la transparence pour l'arrière-plan framebuffer. Voici mon code d'initialisation:

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:[email protected]") #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 

Le code est un peu en désordre parce que je l'ai fait beaucoup d'ajustements pour faire avancer les choses à travailler et je ne l'ai pas bien tout tondu.

Si quelqu'un peut m'aider, je vous remercie beaucoup.

Répondre

3

Je pense qu'il y a un malentendu fondamental du framebuffer ici. Le framebuffer n'est pas vraiment un tampon de données en soi, il ne contient aucune donnée. Vous y attachez des tampons (comme une texture) de sorte que vous pouvez rendre les tampons hors écran de la même manière que vous dessinez à l'écran. Donc, quand vous dites que vous voulez "glClear et glClearColor pour remplir un tampon de trame avec une couleur incluant la transparence alpha", cela n'a pas vraiment de sens car le framebuffer ne contient aucune donnée de couleur elle-même.

Lorsque vous associez la texture du framebuffer avec cet appel:

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

Vous faites le "surface.texture" la destination de rendu du framebuffer. En d'autres termes, vous dites essentiellement "Quand je dessine à ce framebuffer, dessinez dans cette texture.".

+2

A quel point appelle à glClear devrait fonctionner comme prévu. – Eric

2

Si vous essayez de rendre le framebuffer transparent afin que vous puissiez afficher un objet sur votre bureau, vous devez savoir que n'est pas possible via Glut.

Ce type d'effet est spécifique à la plate-forme que vous utilisez. Qu'est-ce que c'est? Linux? Les fenêtres? Mac OS X? Vous devrez vous salir les mains (laisser tomber Glut hors de l'équation) et comprendre un peu plus sur la construction de fenêtres.

Par ailleurs, si votre cible est Windows, vous devez vérifier:

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