【问题标题】:Transparent FrameBuffer background in OpenGLOpenGL中的透明FrameBuffer背景
【发布时间】:2011-01-07 22:33:01
【问题描述】:

我想使用 glClear 和 glClearColor 用包括 alpha 透明度的颜色填充帧缓冲区。然而,当绑定到渲染到屏幕上的纹理时,帧缓冲区总是呈现为不透明的。

我希望渲染到帧缓冲区的所有内容都保持透明度。我只是想改变背景。

见以下代码:

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

代码有点乱,因为我做了很多调整才能让事情正常工作,但我没有正确整理所有内容。

如果有人可以帮助我,我非常感谢你。

【问题讨论】:

    标签: python opengl alphablending framebuffer pyopengl


    【解决方案1】:

    我认为这里对帧缓冲区存在基本误解。帧缓冲区本身并不是真正的数据缓冲区,它不保存任何数据。您将缓冲区附加到它(如纹理),以便您可以以与绘制到屏幕相同的方式渲染到屏幕外缓冲区。因此,当您说要“使用glClear 和glClearColor 来填充包含alpha 透明度的颜色的帧缓冲区”时,它并不完全有意义,因为帧缓冲区本身不保存任何颜色数据。

    当您使用此调用将纹理附加到帧缓冲区时:

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

    您正在使“surface.texture”成为帧缓冲区的渲染目的地。换句话说,您实质上是在说“当我绘制到这个帧缓冲区时,绘制到这个纹理中。”。

    【讨论】:

    • 感谢您的评论!但问题是将透明度应用于应用于帧缓冲区的纹理。我也面临同样的困难。
    【解决方案2】:

    如果您尝试使帧缓冲区透明以便可以在桌面上渲染对象,您必须知道这无法通过 Glut

    这种效果是特定于您使用的平台的。是什么? Linux?视窗? Mac OS X?您必须亲自动手(将 Glut 排除在等式之外)并了解更多关于构建窗户的知识。

    顺便说一句,如果你的目标是 Windows,你应该检查一下:

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

    【讨论】:

      【解决方案3】:

      FBO 的透明色 alpha 必须等于 0:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-03
        • 2012-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多