Прозрачный фон FrameBuffer в OpenGL

Я хочу использовать glClear и glClearColor для заполнения буфера кадра цветом, включая альфа-прозрачность. Однако кадровый буфер всегда отображается как непрозрачный, когда он привязан к текстуре, которая отображается на экране.

Я хочу, чтобы все, что отображается в буфере кадра, сохраняло прозрачность. Я просто хочу сменить фон.

См. Следующий код:

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 должна быть прозрачностью для фона фреймбуфера. Вот мой код инициализации:

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

Код немного запутан, потому что я внес много изменений, чтобы заставить все работать, и я не все как следует убрал.

Если кто-то может мне помочь, большое вам спасибо.


person Matthew Mitchell    schedule 21.01.2010    source источник


Ответы (3)


Я думаю, здесь есть основное неправильное понимание фреймбуфера. Фреймбуфер сам по себе не является буфером данных, он не хранит никаких данных. Вы прикрепляете к нему буферы (как текстуру), чтобы вы могли выполнять рендеринг в закадровые буферы так же, как вы рисуете на экране. Поэтому, когда вы говорите, что хотите «glClear и glClearColor заполнить буфер кадра цветом, включая альфа-прозрачность», это не совсем понятно, потому что сам кадровый буфер не содержит никаких данных о цвете.

Когда вы прикрепляете текстуру к фреймбуферу с помощью этого вызова:

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

Вы делаете "surface.texture" местом назначения рендеринга фреймбуфера. Другими словами, вы, по сути, говорите: «Когда я рисую в этот фреймбуфер, рисуйте в этой текстуре».

person manifest    schedule 23.02.2010
comment
Спасибо за ваш комментарий! Но вопрос в том, чтобы применить прозрачность к текстуре, примененной к фреймбуферу. Я столкнулся с той же трудностью. - person Danilo Assis Nobre dos Santos; 10.02.2021

Если вы пытаетесь сделать фреймбуфер прозрачным, чтобы можно было визуализировать объект поверх рабочего стола, вы должны знать, что это невозможно через Glut.

Такой эффект зависит от платформы, которую вы используете. Что это такое? Linux? Windows? Mac OS X? Вам придется запачкать руки (исключите Glut из уравнения) и немного больше узнать о строительстве окон.

Кстати, если ваша цель - Windows, вы должны проверить это:

(win32) Как сделать контекст рендеринга OpenGL с прозрачным фоном?

person karlphillip    schedule 08.02.2011

Чистый цвет альфа FBO должен быть равен 0:

glColorMask(TRUE, TRUE, TRUE, TRUE);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
person Xys    schedule 03.07.2020