Пример #1
0
    def resize(self, x=0, y=0, w=0, h=0, layer=0):
        # Destroy current surface and native window
        if self.use_glx:
            glx.glXSwapBuffers(self.d, self.window)
        else:
            openegl.eglSwapBuffers(self.display, self.surface)
        if PLATFORM == PLATFORM_PI:
            openegl.eglDestroySurface(self.display, self.surface)

            self.dispman_update = bcm.vc_dispmanx_update_start(0)
            bcm.vc_dispmanx_element_remove(self.dispman_update,
                                           self.dispman_element)
            bcm.vc_dispmanx_update_submit_sync(self.dispman_update)
            bcm.vc_dispmanx_display_close(self.dispman_display)

            #Now recreate the native window and surface
            self.create_surface(x, y, w, h, layer)
        elif PLATFORM == PLATFORM_ANDROID:
            pass  #TODO something here
        elif X_WINDOW:
            xlib.XMoveResizeWindow(self.d, self.window, x, y, w, h)
Пример #2
0
    def destroy(self, display=None):
        if self.active:
            ###### brute force tidying experiment TODO find nicer way ########
            if display:

                func_list = [
                    [
                        opengles.glIsBuffer, opengles.glDeleteBuffers,
                        display.vbufs_dict.update(display.ebufs_dict)
                    ],  # merge two dictionaries with update()
                    [
                        opengles.glIsTexture, opengles.glDeleteTextures,
                        display.textures_dict
                    ],
                    [opengles.glIsProgram, opengles.glDeleteProgram, 0],
                    [opengles.glIsShader, opengles.glDeleteShader, 0]
                ]

                i_ct = (ctypes.c_int * 1)(0)  #convoluted 0
                for fi, func in enumerate(func_list):
                    streak_start = 0
                    if func[2]:  # list to work through
                        for i in func[2]:
                            if func[0](func[2][i]
                                       [0]) == 1:  #check if i exists as a name
                                try:
                                    func[1](1, byref(func[2][i][0]))
                                except:
                                    pass  # TODO find why this might fail (maybe race condition)
                    else:  # just do sequential numbers
                        for i in range(1, 10000):  # name 0 not to be deleted
                            if func[0](i) == 1:  #check if i exists as a name
                                if fi < 2:  # buffers or textures needs number to delete
                                    i_ct[
                                        0] = i  # pass as pointer to array of uint
                                    try:
                                        func[1](1, byref(i_ct))
                                    except:
                                        pass  # TODO not sure why this silently fails and prevents the rest of the tidy up
                                else:  # program and shader just one arg
                                    try:
                                        func[1](i)
                                    except:
                                        pass  # TODO see above
                                streak_start = i
                            elif i > (streak_start + 100):
                                break
            ##################################################################
            openegl.eglSwapBuffers(self.display, self.surface)
            openegl.eglMakeCurrent(self.display, EGL_NO_SURFACE,
                                   EGL_NO_SURFACE, EGL_NO_CONTEXT)
            openegl.eglDestroySurface(self.display, self.surface)
            openegl.eglDestroyContext(self.display, self.context)
            openegl.eglTerminate(self.display)
            if PLATFORM == PLATFORM_PI:
                self.dispman_update = bcm.vc_dispmanx_update_start(0)
                bcm.vc_dispmanx_element_remove(self.dispman_update,
                                               self.dispman_element)
                bcm.vc_dispmanx_update_submit_sync(self.dispman_update)
                bcm.vc_dispmanx_display_close(self.dispman_display)

            self.active = False
            if pi3d.USE_PYGAME:
                import pygame
                pygame.display.quit()
            elif PLATFORM != PLATFORM_PI and PLATFORM != PLATFORM_ANDROID:
                xlib.XCloseDisplay(self.d)
Пример #3
0
 def change_layer(self, layer=0):
     if PLATFORM == PLATFORM_PI:
         self.dispman_update = bcm.vc_dispmanx_update_start(0)
         bcm.vc_dispmanx_element_change_layer(self.dispman_update,
                                              self.dispman_element, layer)
         bcm.vc_dispmanx_update_submit_sync(self.dispman_update)
Пример #4
0
    def create_surface(self, x=0, y=0, w=0, h=0, layer=0):
        #Set the viewport position and size
        dst_rect = c_ints((x, y, w, h))
        src_rect = c_ints((x, y, w << 16, h << 16))

        if PLATFORM == PLATFORM_ANDROID:
            self.surface = openegl.eglGetCurrentSurface(EGL_DRAW)
            # Get the width and height of the screen - TODO, this system returns 100x100
            time.sleep(0.2)  #give it a chance to find out the dimensions
            w = c_int()
            h = c_int()
            openegl.eglQuerySurface(self.display, self.surface, EGL_WIDTH,
                                    byref(w))
            openegl.eglQuerySurface(self.display, self.surface, EGL_HEIGHT,
                                    byref(h))
            self.width, self.height = w.value, h.value
        elif PLATFORM == PLATFORM_PI:
            self.dispman_display = bcm.vc_dispmanx_display_open(
                0)  #LCD setting
            self.dispman_update = bcm.vc_dispmanx_update_start(0)
            alpha = c_ints((DISPMANX_FLAGS_ALPHA_PREMULT, 0, 0))
            self.dispman_element = bcm.vc_dispmanx_element_add(
                self.dispman_update, self.dispman_display, layer, dst_rect, 0,
                src_rect, DISPMANX_PROTECTION_NONE, alpha, 0, 0)

            nativewindow = (GLint * 3)(self.dispman_element, w, h + 1)
            bcm.vc_dispmanx_update_submit_sync(self.dispman_update)

            self.nw_p = ctypes.pointer(nativewindow)
            ### NB changing the argtypes to allow passing of bcm native window is
            ### deeply unsatisfactory. But xlib defines Window as c_ulong and ctypes
            ### isn't happy about a pointer being cast to an int
            openegl.eglCreateWindowSurface.argtypes = [
                EGLDisplay, EGLConfig,
                POINTER((GLint * 3)), EGLint
            ]
            self.surface = openegl.eglCreateWindowSurface(
                self.display, self.config, self.nw_p, 0)

        elif pi3d.USE_PYGAME:
            import pygame
            flags = pygame.OPENGL
            wsize = (w, h)
            if w == self.width and h == self.height:  # i.e. full screen
                flags = pygame.FULLSCREEN | pygame.OPENGL
                wsize = (0, 0)
            if self.display_config & DISPLAY_CONFIG_NO_RESIZE:
                flags |= pygame.RESIZABLE
            if self.display_config & DISPLAY_CONFIG_NO_FRAME:
                flags |= pygame.NOFRAME
            if self.display_config & DISPLAY_CONFIG_FULLSCREEN:
                flags |= pygame.FULLSCREEN
            elif self.display_config & DISPLAY_CONFIG_MAXIMIZED:
                flags |= pygame.FULLSCREEN
                wsize = (0, 0)

            self.width, self.height = w, h
            self.d = pygame.display.set_mode(wsize, flags)
            self.window = pygame.display.get_wm_info()["window"]
            self.surface = openegl.eglCreateWindowSurface(
                self.display, self.config, self.window, 0)

        else:  # work on basis it's X11
            # Set some WM info
            self.root = xlib.XRootWindowOfScreen(self.screen)
            if self.use_glx:  # For drawing on X window with transparent background
                numfbconfigs = c_int()
                VisData = c_ints(
                    (glx.GLX_RENDER_TYPE, glx.GLX_RGBA_BIT,
                     glx.GLX_DRAWABLE_TYPE, glx.GLX_WINDOW_BIT,
                     glx.GLX_DOUBLEBUFFER, True, glx.GLX_RED_SIZE, 8,
                     glx.GLX_GREEN_SIZE, 8, glx.GLX_BLUE_SIZE, 8,
                     glx.GLX_ALPHA_SIZE, 8, glx.GLX_DEPTH_SIZE, 16, 0))
                glx_screen = xlib.XDefaultScreen(self.d)
                fbconfigs = glx.glXChooseFBConfig(self.d, glx_screen, VisData,
                                                  byref(numfbconfigs))
                fbconfig = 0
                for i in range(numfbconfigs.value):
                    visual = glx.glXGetVisualFromFBConfig(
                        self.d, fbconfigs[i]).contents
                    if not visual:
                        continue
                    pict_format = glx.XRenderFindVisualFormat(
                        self.d, visual.visual).contents
                    if not pict_format:
                        continue

                    fbconfig = fbconfigs[i]
                    if pict_format.direct.alphaMask > 0:
                        break

                if not fbconfig:
                    print("No matching FB config found")
                #/* Create a colormap - only needed on some X clients, eg. IRIX */
                cmap = xlib.XCreateColormap(self.d, self.root, visual.visual,
                                            AllocNone)
                attr = xlib.XSetWindowAttributes()
                attr.colormap = cmap
                attr.background_pixmap = 0
                attr.border_pixmap = 0
                attr.border_pixel = 0
                attr.event_mask = (StructureNotifyMask | EnterWindowMask
                                   | LeaveWindowMask | ExposureMask
                                   | ButtonPressMask | ButtonReleaseMask
                                   | OwnerGrabButtonMask | KeyPressMask
                                   | KeyReleaseMask)
                attr_mask = (  #  CWBackPixmap|
                    CWColormap | CWBorderPixel | CWEventMask)
                self.window = xlib.XCreateWindow(self.d, self.root, x, y, w, h,
                                                 0, visual.depth, 1,
                                                 visual.visual, attr_mask,
                                                 byref(attr))
            else:  # normal EGL created context
                self.window = xlib.XCreateSimpleWindow(self.d, self.root, x, y,
                                                       w, h, 1, 0, 0)

            s = ctypes.create_string_buffer(b'WM_DELETE_WINDOW')
            self.WM_DELETE_WINDOW = ctypes.c_ulong(
                xlib.XInternAtom(self.d, s, 0))

            # set window title
            title = ctypes.c_char_p(self.window_title)
            title_length = ctypes.c_int(len(self.window_title))
            wm_name_atom = ctypes.c_ulong(
                xlib.XInternAtom(self.d,
                                 ctypes.create_string_buffer(b'WM_NAME'), 0))
            string_atom = ctypes.c_ulong(
                xlib.XInternAtom(self.d,
                                 ctypes.create_string_buffer(b'STRING'), 0))
            xlib.XChangeProperty(self.d, self.window, wm_name_atom,
                                 string_atom, 8, xlib.PropModeReplace, title,
                                 title_length)

            if (w == self.width
                    and h == self.height) or (self.display_config
                                              & DISPLAY_CONFIG_FULLSCREEN):
                # set full-screen. Messy c function calls!
                wm_state = ctypes.c_ulong(
                    xlib.XInternAtom(self.d, b'_NET_WM_STATE', 0))
                fullscreen = ctypes.c_ulong(
                    xlib.XInternAtom(self.d, b'_NET_WM_STATE_FULLSCREEN', 0))
                fullscreen = ctypes.cast(ctypes.pointer(fullscreen),
                                         ctypes.c_char_p)
                XA_ATOM = 4
                xlib.XChangeProperty(self.d, self.window, wm_state, XA_ATOM,
                                     32, xlib.PropModeReplace, fullscreen, 1)

            self.width, self.height = w, h

            if self.display_config & DISPLAY_CONFIG_HIDE_CURSOR:
                black = xlib.XColor()
                black.red = 0
                black.green = 0
                black.blue = 0
                noData = ctypes.c_char_p(bytes([0, 0, 0, 0, 0, 0, 0, 0]))
                bitmapNoData = xlib.XCreateBitmapFromData(
                    self.d, self.window, noData, 8, 8)
                invisibleCursor = xlib.XCreatePixmapCursor(
                    self.d, bitmapNoData, bitmapNoData, black, black, 0, 0)
                xlib.XDefineCursor(self.d, self.window, invisibleCursor)

            #TODO add functions to xlib for these window manager libx11 functions
            #self.window.set_wm_name('pi3d xlib window')
            #self.window.set_wm_icon_name('pi3d')
            #self.window.set_wm_class('draw', 'XlibExample')

            xlib.XSetWMProtocols(self.d, self.window, self.WM_DELETE_WINDOW, 1)
            #self.window.set_wm_hints(flags = Xutil.StateHint,
            #                         initial_state = Xutil.NormalState)

            #self.window.set_wm_normal_hints(flags = (Xutil.PPosition | Xutil.PSize
            #                                         | Xutil.PMinSize),
            #                                min_width = 20,
            #                                min_height = 20)

            xlib.XSelectInput(
                self.d, self.window,
                KeyPressMask | KeyReleaseMask | ResizeRedirectMask)
            xlib.XMapWindow(self.d, self.window)
            #xlib.XMoveWindow(self.d, self.window, x, y) #TODO this has to happen later. Works after rendering first frame. Check when
            if self.use_glx:
                dummy = c_int()
                if not glx.glXQueryExtension(self.d, byref(dummy),
                                             byref(dummy)):
                    print("OpenGL not supported by X server\n")
                dummy_glx_context = ctypes.cast(0, glx.GLXContext)
                self.render_context = glx.glXCreateNewContext(
                    self.d, fbconfig, glx.GLX_RGBA_TYPE, dummy_glx_context,
                    True)
                if not self.render_context:
                    print("Failed to create a GL context\n")
                if not glx.glXMakeContextCurrent(
                        self.d, self.window, self.window, self.render_context):
                    print("glXMakeCurrent failed for window\n")
            else:
                self.surface = openegl.eglCreateWindowSurface(
                    self.display, self.config, self.window, 0)

        if not self.use_glx:
            assert self.surface != EGL_NO_SURFACE and self.surface is not None
            r = openegl.eglMakeCurrent(self.display, self.surface,
                                       self.surface, self.context)
            assert r

        #Create viewport
        opengles.glViewport(GLint(0), GLint(0), GLsizei(w), GLsizei(h))