def __init__( self, width=256, height=256, title=None, visible=True, aspect=None, decoration=True, fullscreen=False, config=None, context=None, color=(0,0,0,1), vsync=False): if len(__windows__) > 0: log.critical( """SDL backend cannot have more than one window.\n""" """Exiting...""") sys.exit(0) window.Window.__init__(self, width=width, height=height, title=title, visible=visible, aspect=aspect, decoration=decoration, fullscreen=fullscreen, config=config, context=context, color=color) if config is None: config = configuration.Configuration() set_configuration(config) pygame.display.gl_set_attribute( pygame.GL_SWAP_CONTROL, 1 if vsync else 0) flags = __flags__ if self._decoration == False: flags = __flags__ | pygame.NOFRAME pygame.display.set_mode((width, height), flags) pygame.display.set_caption(self._title) __windows__.append(self)
def load(filename, *args, **kwargs): """ Load data content from a filename """ extension = os.path.basename(filename).split('.')[-1] if extension == 'npy': return np.load(filename, *args, **kwargs) elif extension in ['ttf', 'otf']: if filename is not None: return filename if depth == 0: log.warning("Falling back to default font") return get("SourceSansPro-Regular.otf", 1) else: log.critical("Default font not available") raise RuntimeError elif extension == 'obj': return objload(filename, *args, **kwargs) elif extension in ['svg', 'json', 'csv', 'tsv']: return filename elif extension in ('png', 'jpg', 'jpeg', 'tif', 'tiff', 'tga'): if Image is not None: if filename is not None: return np.array(Image.open(filename)) log.warning("File not found") return checkerboard(16, 32) else: log.warning("PIL/Pillow not installed, cannot load image") return checkerboard(16, 32) log.warning("Data not found (%s)" % name) raise RuntimeError return None
def load(filename, *args, **kwargs): """ Load data content from a filename """ extension = os.path.basename(filename).split('.')[-1] if extension == 'npy': return np.load(filename, *args, **kwargs) elif extension in ['ttf', 'otf']: if filename is not None: return filename if depth == 0: log.warning("Falling back to default font") return get("SourceSansPro-Regular.otf", 1) else: log.critical("Default font not available") raise RuntimeError elif extension == 'obj': return objload(filename, *args, **kwargs) elif extension in ['svg', 'json', 'csv', 'tsv']: return filename elif extension in ('png', 'jpg', 'jpeg', 'tif', 'tiff', 'tga'): if Image is not None: if filename is not None: return np.array(Image.open(filename)) log.warning("File not found") return checkerboard(16,32) else: log.warning("PIL/Pillow not installed, cannot load image") return checkerboard(16,32) log.warning("Data not found (%s)" % name) raise RuntimeError return None
def __init__( self, width=256, height=256, title=None, visible=True, aspect=None, decoration=True, fullscreen=False, config=None, context=None, color=(0,0,0,1)): if len(__windows__) > 0: log.critical( """SDL backend cannot have more than one window.\n""" """Exiting...""") sys.exit(0) window.Window.__init__(self, width=width, height=height, title=title, visible=visible, aspect=aspect, decoration=decoration, fullscreen=fullscreen, config=config, context=context, color=color) if config is None: config = configuration.Configuration() set_configuration(config) flags = __flags__ if self._decoration == False: flags = __flags__ | pygame.NOFRAME pygame.display.set_mode((width, height), flags) pygame.display.set_caption(self._title) __windows__.append(self)
def __init__( self, width=256, height=256, title=None, visible=True, aspect=None, decoration=True, fullscreen=False, config=None, context=None, color=(0,0,0,1), vsync=False): if vsync: log.warn('vsync not implemented for osxglut backend') if len(__windows__) > 0: log.critical( """OSXGLUT backend is unstable with more than one window.\n""" """Exiting...""") sys.exit(0) window.Window.__init__(self, width=width, height=height, title=title, visible=visible, aspect=aspect, decoration=decoration, fullscreen=fullscreen, config=config, context=context, color=color) if config is None: config = configuration.Configuration() set_configuration(config) self._native_window = glut.glutCreateWindow( self._title ) if bool(glut.glutSetOption): glut.glutSetOption(glut.GLUT_ACTION_ON_WINDOW_CLOSE, glut.GLUT_ACTION_CONTINUE_EXECUTION) glut.glutSetOption(glut.GLUT_ACTION_GLUTMAINLOOP_RETURNS, glut.GLUT_ACTION_CONTINUE_EXECUTION) glut.glutWMCloseFunc( self._close ) glut.glutDisplayFunc( self._display ) glut.glutReshapeFunc( self._reshape ) glut.glutKeyboardFunc( self._keyboard ) glut.glutKeyboardUpFunc( self._keyboard_up ) glut.glutMouseFunc( self._mouse ) glut.glutMotionFunc( self._motion ) glut.glutPassiveMotionFunc( self._passive_motion ) glut.glutVisibilityFunc( self._visibility ) glut.glutEntryFunc( self._entry ) glut.glutSpecialFunc( self._special ) glut.glutSpecialUpFunc( self._special_up ) glut.glutReshapeWindow( self._width, self._height ) if visible: glut.glutShowWindow() else: glut.glutHideWindow() # This ensures glutCheckLoop never blocks def on_idle(): pass glut.glutIdleFunc(on_idle) __windows__.append(self)
def replace(match): filename = match.group("filename") if filename not in includes: includes.append(filename) path = library.find(filename) if not path: log.critical('"%s" not found' % filename) raise RuntimeError("File not found") text = '\n// --- start of "%s" ---\n' % filename text += remove_comments(open(path).read()) text += '// --- end of "%s" ---\n' % filename return text return ''
def get_file(name): """ Retrieve a shader full path from sub-directories """ path = os.path.dirname(__file__) or '.' filename = os.path.abspath(os.path.join(path,name)) if os.path.exists(filename): return filename for d in os.listdir(path): fullpath = os.path.abspath(os.path.join(path,d)) if os.path.isdir(fullpath): filename = os.path.abspath(os.path.join(fullpath,name)) if os.path.exists(filename): return filename log.critical("Shader '%s' not found" % name) raise RuntimeError("Shader file not found")
def __init__(self, width=256, height=256, title=None, visible=True, aspect=None, decoration=True, fullscreen=False, config=None, context=None, color=(0, 0, 0, 1), vsync=False): if vsync: log.warn('vsync not implemented for freeglut backend') if len(__windows__) > 0: log.critical( """OSXGLUT backend is unstable with more than one window.\n""" """Exiting...""") sys.exit(0) window.Window.__init__(self, width=width, height=height, title=title, visible=visible, aspect=aspect, decoration=decoration, fullscreen=fullscreen, config=config, context=context, color=color) if config is None: config = configuration.Configuration() set_configuration(config) self._native_window = glut.glutCreateWindow(self._title) if bool(glut.glutSetOption): glut.glutSetOption(glut.GLUT_ACTION_ON_WINDOW_CLOSE, glut.GLUT_ACTION_CONTINUE_EXECUTION) glut.glutSetOption(glut.GLUT_ACTION_GLUTMAINLOOP_RETURNS, glut.GLUT_ACTION_CONTINUE_EXECUTION) glut.glutWMCloseFunc(self._close) glut.glutDisplayFunc(self._display) glut.glutReshapeFunc(self._reshape) glut.glutKeyboardFunc(self._keyboard) glut.glutKeyboardUpFunc(self._keyboard_up) glut.glutMouseFunc(self._mouse) glut.glutMotionFunc(self._motion) glut.glutPassiveMotionFunc(self._passive_motion) glut.glutVisibilityFunc(self._visibility) glut.glutEntryFunc(self._entry) glut.glutSpecialFunc(self._special) glut.glutSpecialUpFunc(self._special_up) glut.glutReshapeWindow(self._width, self._height) if visible: glut.glutShowWindow() else: glut.glutHideWindow() # This ensures glutCheckLoop never blocks def on_idle(): pass glut.glutIdleFunc(on_idle) __windows__.append(self)
def __init__(self, width=512, height=512, title=None, visible=True, aspect=None, decoration=True, fullscreen=False, config=None, context=None, color=(0, 0, 0, 1), vsync=False): window.Window.__init__(self, width=width, height=height, title=title, visible=visible, aspect=aspect, decoration=decoration, fullscreen=fullscreen, config=config, context=context, color=color) # Whether hidpi is active self._hidpi = False def on_error(error, message): log.warning(message) glfw.glfwSetErrorCallback(on_error) glfw.glfwWindowHint(glfw.GLFW_RESIZABLE, True) glfw.glfwWindowHint(glfw.GLFW_DECORATED, True) glfw.glfwWindowHint(glfw.GLFW_VISIBLE, True) if not decoration: glfw.glfwWindowHint(glfw.GLFW_DECORATED, False) if not visible: glfw.glfwWindowHint(glfw.GLFW_VISIBLE, False) if config is None: config = configuration.Configuration() set_configuration(config) self._native_window = glfw.glfwCreateWindow(self._width, self._height, self._title, None, None) if not self._native_window: log.critical("Window creation failed") __exit__() sys.exit() glfw.glfwMakeContextCurrent(self._native_window) glfw.glfwSwapInterval(1 if vsync else 0) # OSX: check framebuffer size / window size. On retina display, they # can be different so we try to correct window size such as having # the framebuffer size of the right size w, h = glfw.glfwGetFramebufferSize(self._native_window) if w != width or h != height: width, height = width // 2, height // 2 glfw.glfwSetWindowSize(self._native_window, width, height) log.info("HiDPI detected, fixing window size") self._hidpi = True def on_framebuffer_resize(win, width, height): self._width, self._height = width, height self.dispatch_event('on_resize', width, height) glfw.glfwSetFramebufferSizeCallback(self._native_window, on_framebuffer_resize) # def on_resize(win, width, height): # self._width, self._height = width, height # self.dispatch_event('on_resize', width, height) # glfw.glfwSetWindowSizeCallback(self._native_window, on_resize) def on_cursor_enter(win, entered): if entered: self.dispatch_event('on_enter') else: self.dispatch_event('on_leave') glfw.glfwSetCursorEnterCallback(self._native_window, on_cursor_enter) def on_window_close(win): self.close() glfw.glfwSetWindowCloseCallback(self._native_window, on_window_close) def on_keyboard(win, key, scancode, action, mods): symbol = self._keyboard_translate(key) modifiers = self._modifiers_translate(mods) if action in [glfw.GLFW_PRESS, glfw.GLFW_REPEAT]: self.dispatch_event('on_key_press', symbol, modifiers) else: self.dispatch_event('on_key_release', symbol, modifiers) glfw.glfwSetKeyCallback(self._native_window, on_keyboard) def on_character(win, character): self.dispatch_event('on_character', u"%c" % character) glfw.glfwSetCharCallback(self._native_window, on_character) def on_mouse_button(win, button, action, mods): x, y = glfw.glfwGetCursorPos(win) if self._hidpi: x, y = 2 * x, 2 * y button = __mouse_map__.get(button, window.mouse.UNKNOWN) if action == glfw.GLFW_RELEASE: self._button = window.mouse.NONE self._mouse_x = x self._mouse_y = y self.dispatch_event('on_mouse_release', x, y, button) elif action == glfw.GLFW_PRESS: self._button = button self._mouse_x = x self._mouse_y = y self.dispatch_event('on_mouse_press', x, y, button) glfw.glfwSetMouseButtonCallback(self._native_window, on_mouse_button) def on_mouse_motion(win, x, y): if self._hidpi: x, y = 2 * x, 2 * y dx = x - self._mouse_x dy = y - self._mouse_y self._mouse_x = x self._mouse_y = y if self._button != window.mouse.NONE: self.dispatch_event('on_mouse_drag', x, y, dx, dy, self._button) else: self.dispatch_event('on_mouse_motion', x, y, dx, dy) glfw.glfwSetCursorPosCallback(self._native_window, on_mouse_motion) def on_scroll(win, xoffset, yoffset): x, y = glfw.glfwGetCursorPos(win) if self._hidpi: x, y = 2 * x, 2 * y self.dispatch_event('on_mouse_scroll', x, y, xoffset, yoffset) glfw.glfwSetScrollCallback(self._native_window, on_scroll) self._width, self._height = self.get_size() __windows__.append(self)
def use(backend, api=None, major=None, minor=None, profile=None): """ Select a specific backend Parameters ---------- backend : ['osxglut', 'freeglut', 'pyglet', 'glfw', 'sdl', 'sdl2', 'pyside'] Graphical toolkit to use api : ['GL'|'ES'] OpenGL API to use major : int OpenGL major version to use minor : int OpenGL minor version to use profile : ['compatibility'|'core'] OpenGL profile to use Note ---- A shortened version is available with the following syntax: use("backend (api major.minor profile)") For example, `use("glfw (GL 3.3 core)")` """ global __backend__ # Parse options (in backend name, see note above) exp = """(?P<backend>\w+)? (.*\( (.*(?P<api>GL|ES))? (.*(?P<major>[1234])\.(?P<minor>[012345]))? (.*(?P<profile>compatibility|core))?.*\))?""" r = re.search(exp, backend, re.IGNORECASE | re.VERBOSE) _backend = r.group('backend') or "glfw" _api = r.group('api') or "GL" _major = int(r.group('major') or "2") _minor = int(r.group('minor') or "1") _profile = r.group('profile') or "" # Arguments take precedence over shortened options backend = _backend api = api or _api major = major or _major minor = minor or _minor profile = profile or _profile config = configuration.get_default() config.api = api config.major_version = major config.minor_version = minor config.profile = profile if backend not in backends.__backends__: log.critical("Unknown backend (%s)" % backend) log.cirtical("Available backends are: %s", str(backends.__backends__)) sys.exit(0) # BUG: For some reason, the import module changes the working directory # We save it beforehand and restore it just after workdir = os.getcwd() name = "glumpy.app.window.backends.backend_" + backend importlib.import_module(name) backend = sys.modules[name] os.chdir(workdir) # Check availability if backend.available(): __backend__ = backend return backend else: log.warning("Backend (%s) not available" % backend) return None
def __new__(cls, *args, **kwargs): global __backend__ all = list(backends.__backends__) options = parser.get_options() # No backend was specified # Check for command line argument then pick a default one if possible if __backend__ is None: if options.backend != all[0]: all = [ options.backend, ] + all for name in all: backend = use(name) if backend and backend.available(): __backend__ = backend break # No backend available, there's nothing we can do if __backend__ is None: log.critical("No suitable backend found") raise NotImplementedError config = configuration.get_default() if "config" not in kwargs.keys(): kwargs['config'] = config # Get command line size # if options.size: # size = options.size.split(",") # kwargs['width'] = int(size[0]) # kwargs['height'] = int(size[1]) # else: # kwargs['width'] = kwargs.get('width', 512) # kwargs['height'] = kwargs.get('height', 512) # Get command line position # if options.position: # position = options.position.split(",") # #kwargs['x'] = kwargs.get('x', int(position[0])) # #kwargs['y'] = kwargs.get('y', int(position[1])) # else: # pass # #kwargs['x'] = kwargs.get('x', 0) # #kwargs['y'] = kwargs.get('y', 0) # Create the backend window window = __backend__.Window(*args, **kwargs) window._backend = __backend__ config = configuration.gl_get_configuration() window._config = config log.info("Using %s (%s %d.%d)" % (__backend__.name(), config.api, config.major_version, config.minor_version)) # Display fps options if options.display_fps: @window.timer(1.0) def timer(elapsed): print("Estimated FPS: %f" % fps()) return window
def __init__( self, width=512, height=512, title=None, visible=True, aspect=None, decoration=True, fullscreen=False, config=None, context=None, color=(0,0,0,1)): window.Window.__init__(self, width=width, height=height, title=title, visible=visible, aspect=aspect, decoration=decoration, fullscreen=fullscreen, config=config, context=context, color=color) # Whether hidpi is active self._hidpi = False def on_error(error, message): log.warning(message) glfw.glfwSetErrorCallback(on_error) glfw.glfwWindowHint(glfw.GLFW_RESIZABLE, True) glfw.glfwWindowHint(glfw.GLFW_DECORATED, True) glfw.glfwWindowHint(glfw.GLFW_VISIBLE, True) if not decoration: glfw.glfwWindowHint(glfw.GLFW_DECORATED, False) if not visible: glfw.glfwWindowHint(glfw.GLFW_VISIBLE, False) if config is None: config = configuration.Configuration() set_configuration(config) self._native_window = glfw.glfwCreateWindow( self._width, self._height, self._title, None, None) if not self._native_window: log.critical("Window creation failed") __exit__() sys.exit() glfw.glfwMakeContextCurrent(self._native_window) glfw.glfwSwapInterval(0) # OSX: check framebuffer size / window size. On retina display, they # can be different so we try to correct window size such as having # the framebuffer size of the right size w,h = glfw.glfwGetFramebufferSize(self._native_window) if w != width or h!= height: width, height = width//2, height//2 glfw.glfwSetWindowSize(self._native_window, width, height) log.info("HiDPI detected, fixing window size") self._hidpi = True def on_framebuffer_resize(win, width, height): self._width, self._height = width, height self.dispatch_event('on_resize', width, height) glfw.glfwSetFramebufferSizeCallback(self._native_window, on_framebuffer_resize) # def on_resize(win, width, height): # self._width, self._height = width, height # self.dispatch_event('on_resize', width, height) # glfw.glfwSetWindowSizeCallback(self._native_window, on_resize) def on_cursor_enter(win, entered): if entered: self.dispatch_event('on_enter') else: self.dispatch_event('on_leave') glfw.glfwSetCursorEnterCallback(self._native_window, on_cursor_enter) def on_window_close(win): self.close() glfw.glfwSetWindowCloseCallback(self._native_window, on_window_close) def on_keyboard(win, key, scancode, action, mods): symbol = self._keyboard_translate(key) modifiers = self._modifiers_translate(mods) if action in[glfw.GLFW_PRESS,glfw.GLFW_REPEAT]: self.dispatch_event('on_key_press', symbol, modifiers) else: self.dispatch_event('on_key_release', symbol, modifiers) glfw.glfwSetKeyCallback(self._native_window, on_keyboard) def on_character(win, character): self.dispatch_event('on_character', u"%c" % character) glfw.glfwSetCharCallback(self._native_window, on_character) def on_mouse_button(win, button, action, mods): x,y = glfw.glfwGetCursorPos(win) if self._hidpi: x, y = 2*x, 2*y button = __mouse_map__.get(button, window.mouse.UNKNOWN) if action == glfw.GLFW_RELEASE: self._button = window.mouse.NONE self._mouse_x = x self._mouse_y = y self.dispatch_event('on_mouse_release', x, y, button) elif action == glfw.GLFW_PRESS: self._button = button self._mouse_x = x self._mouse_y = y self.dispatch_event('on_mouse_press', x, y, button) glfw.glfwSetMouseButtonCallback(self._native_window, on_mouse_button) def on_mouse_motion(win, x, y): if self._hidpi: x, y = 2*x, 2*y dx = x - self._mouse_x dy = y - self._mouse_y self._mouse_x = x self._mouse_y = y if self._button != window.mouse.NONE: self.dispatch_event('on_mouse_drag', x, y, dx, dy, self._button) else: self.dispatch_event('on_mouse_motion', x, y, dx, dy) glfw.glfwSetCursorPosCallback(self._native_window, on_mouse_motion) def on_scroll(win, xoffset, yoffset): x,y = glfw.glfwGetCursorPos(win) if self._hidpi: x, y = 2*x, 2*y self.dispatch_event('on_mouse_scroll', x, y, xoffset, yoffset) glfw.glfwSetScrollCallback( self._native_window, on_scroll ) self._width, self._height = self.get_size() __windows__.append(self)
def use(backend, api=None, major=None, minor=None, profile=None): """ Select a specific backend Parameters ---------- backend : ['osxglut', 'freeglut', 'pyglet', 'glfw', 'sdl', 'sdl2', 'pyside'] Graphical toolkit to use api : ['GL'|'ES'] OpenGL API to use major : int OpenGL major version to use minor : int OpenGL minor version to use profile : ['compatibility'|'core'] OpenGL profile to use Note ---- A shortened version is available with the following syntax: use("backend (api major.minor profile)") For example, `use("glfw (GL 3.3 core)")` """ global __backend__ # Parse options (in backend name, see note above) exp = """(?P<backend>\w+)? (.*\( (.*(?P<api>GL|ES))? (.*(?P<major>[1234])\.(?P<minor>[012345]))? (.*(?P<profile>compatibility|core))?.*\))?""" r = re.search(exp, backend, re.IGNORECASE | re.VERBOSE) _backend = r.group('backend') or "glfw" _api = r.group('api') or "GL" _major = int(r.group('major') or "2") _minor = int(r.group('minor') or "1") _profile = r.group('profile') or "" # Arguments take precedence over shortened options backend = _backend api = api or _api major = major or _major minor = minor or _minor profile = profile or _profile config = configuration.get_default() config.api = api config.major_version = major config.minor_version = minor config.profile = profile if backend not in backends.__backends__: log.critical("Unknown backend (%s)" % backend) log.critical("Available backends are: %s", str(backends.__backends__)) sys.exit(0) # BUG: For some reason, the import module changes the working directory # We save it beforehand and restore it just after workdir = os.getcwd() name = "glumpy.app.window.backends.backend_" + backend importlib.import_module(name) backend = sys.modules[name] os.chdir(workdir) # Check availability if backend.available(): __backend__ = backend return backend else: log.warning("Backend (%s) not available" % backend) return None
def __new__(cls, *args, **kwargs): global __backend__ all = list(backends.__backends__) options = parser.get_options() # No backend was specified # Check for command line argument then pick a default one if possible if __backend__ is None: if options.backend != all[0]: all = [options.backend,] + all for name in all: backend = use(name) if backend and backend.available(): __backend__ = backend break # No backend available, there's nothing we can do if __backend__ is None: log.critical("No suitable backend found") raise NotImplementedError config = configuration.get_default() if "config" not in kwargs.keys(): kwargs['config'] = config # Get command line size # if options.size: # size = options.size.split(",") # kwargs['width'] = int(size[0]) # kwargs['height'] = int(size[1]) # else: # kwargs['width'] = kwargs.get('width', 512) # kwargs['height'] = kwargs.get('height', 512) # Get command line position # if options.position: # position = options.position.split(",") # #kwargs['x'] = kwargs.get('x', int(position[0])) # #kwargs['y'] = kwargs.get('y', int(position[1])) # else: # pass # #kwargs['x'] = kwargs.get('x', 0) # #kwargs['y'] = kwargs.get('y', 0) # Create the backend window window = __backend__.Window(*args, **kwargs) window._backend = __backend__ config = configuration.gl_get_configuration() window._config = config log.info("Using %s (%s %d.%d)" % (__backend__.name(), config.api, config.major_version, config.minor_version)) # Display fps options if options.display_fps: @window.timer(1.0) def timer(elapsed): print("Estimated FPS: %f"% fps()) return window