خلفية إطار شفافة في OpenGL
-
22-09-2019 - |
سؤال
أريد استخدام Glclear و GlclearColor لملء مخزن مؤقت للإطار بلون بما في ذلك شفافية ألفا. ومع ذلك ، فإن برنامج FrameBuffer يصنع دائمًا غير شفاف عندما يرتدي الملمس الذي يتم تقديمه على الشاشة.
أريد كل ما يتم تقديمه إلى FrameBuffer للحفاظ على شفافيةهم. أنا فقط أريد تغيير الخلفية.
انظر الرمز التالي:
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
الرمز فوضوي قليلاً لأنني قمت بالكثير من التعديلات للحصول على الأشياء للعمل ولم أترتب كل شيء بشكل صحيح.
إذا كان بإمكان أي شخص مساعدتي ، أشكرك كثيرًا.
المحلول
أعتقد أن هناك سوء فهم أساسي لـ FrameBuffer هنا. إن FrameBuffer ليس بالفعل عازلة للبيانات في حد ذاته ، فهو لا يحتفظ بأي بيانات. يمكنك إرفاق المخازن المؤقتة لها (مثل نسيج) بحيث يمكنك تقديم مخازن مؤقتة خارج الشاشة بنفس الطريقة التي ترسم بها على الشاشة. لذلك عندما تقول أنك تريد "glclear و glclearcolor لملء عازلة الإطار بلون بما في ذلك شفافية ألفا" ، فإنه لا معنى له لأن FrameBuffer لا يحمل أي بيانات ملونة نفسها.
عندما تقوم بتوصيل الملمس بـ FrameBuffer مع هذه المكالمة:
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, surface.texture, 0)
أنت تصنع "surface.texture" الوجهة التقديم لـ FrameBuffer. بمعنى آخر ، أنت تقول بشكل أساسي "عندما أرسم إلى هذا الإطار ، ارسم إلى هذا الملمس.".
نصائح أخرى
إذا كنت تحاول جعل برنامج FrameBuffer شفافًا حتى تتمكن من تقديم كائن فوق سطح المكتب ، فيجب أن تعرف ذلك هذا غير ممكن من خلال الوفرة.
هذا النوع من التأثير خاص بالمنصة التي تستخدمها. ما هذا؟ لينكس؟ شبابيك؟ Mac OS X؟ سيتعين عليك الحصول على يديك قذرة (إسقاط الوفرة من المعادلة) وفهم المزيد عن بناء النوافذ.
بالمناسبة ، إذا كان هدفك هو Windows ، فيجب عليك التحقق من ذلك: