def __init__(self): self.tcpPort = 31337 self.tcpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.tcpsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.tcpsocket.bind(("0.0.0.0", self.tcpPort)) self.tcpsocket.listen(10) self.discoverysocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.discoverysocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.discoverysocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) self.glfwWorkers = {} self.controllerConn = None self.controllerAddr = None self.outbuf = "" # IO buffer for controller self.inbuf = "" self.monitors = glfw.get_monitors() for monitor in glfw.get_monitors(): self.glfwWorkers[bytes.decode( glfw.get_monitor_name(monitor))] = glfwWorker(monitor)
def window_pos_clb(glfw_window, x_pos: int, y_pos: int): if len(glfw.get_monitors()) >= 1: for monitor_id, monitor in enumerate(glfw.get_monitors()): m_x, m_y, width, height = glfw.get_monitor_workarea( monitor) if m_x <= x_pos < m_x + width and m_y <= y_pos < m_y + height: self.config["monitor_id"] = monitor_id self.config["screen_x"] = x_pos self.config["screen_y"] = y_pos self.config.store()
def _select_monitor(self): self.monitor = None if SETTINGS.display in ["window", "windowed"]: return for monitor in glfw.get_monitors(): logger.info("* {} : {}".format(glfw.get_monitor_name(monitor), glfw.get_video_modes(monitor))) for monitor in glfw.get_monitors(): if glfw.get_monitor_name( monitor ) == SETTINGS.display or SETTINGS.display == "fullscreen": self.monitor = monitor break
def main(): if not glfw.init(): return monitors = glfw.get_monitors() print('Monitors') print(glfw.get_monitor_name(monitors[0])) print(glfw.get_monitor_name(monitors[1])) print(glfw.get_video_mode(monitors[0])) print(glfw.get_video_mode(monitors[1])) print(glfw.get_video_modes(monitors[0])) print(glfw.get_video_modes(monitors[1])) window = glfw.create_window(1024, 768, "Opengl GLFW Window", monitors[1], None) if not window: glfw.terminate() return glfw.make_context_current(window) while not glfw.window_should_close(window): glfw.poll_events() glfw.swap_buffers(window) glfw.terminate()
def __init__(self, server_instance): """Init """ self.DISPLAY = os.environ.get("DISPLAY") self.server = server_instance self.project_manager = self.server.project_manager self.pano_surfaces = None self.monitor = None self.output_window = None self.offscreen_window = None self.pano_renderer = None self.reset = False self.active = SETTINGS.display and SETTINGS.display != "none" and self.DISPLAY self.monitor_connected = False self.event_loop = Loop(0, glfw.wait_events, "X Event") self.event_loop.start(paused=True) if self.DISPLAY: glfw.init() self.monitor_connected = glfw.get_monitors() self.discovery_loop = Loop(2, self._discover_screen, "Screen discovery") self.discovery_loop.start()
def new_window_position( window, default_position: T.Tuple[int, int], previous_position: T.Optional[T.Tuple[int, int]], ) -> T.Tuple[int, int]: if previous_position is None: return default_position os_name = platform.system() if os_name == "Darwin": # The OS handle re-positioning windows with invalid positions return previous_position elif os_name == "Linux": # The OS handle re-positioning windows with invalid positions return previous_position elif os_name == "Windows": def validate_previous_position(monitor) -> bool: return _will_window_be_visible_in_monitor( window=window, monitor=monitor, window_position=previous_position, ) if any(validate_previous_position(m) for m in glfw.get_monitors()): return previous_position else: return default_position else: raise NotImplementedError(f"Unsupported system: {os_name}")
def main(self): if not glfw.init(): # failed to init so leave return # get a list of monitors as we want the second one monitors = glfw.get_monitors() # make a new window that fills the second screen window = glfw.create_window(self.width, self.height, "LabyrinthMaker_GLFW", monitors[1], None) if not window: # if it failed the leave glfw.terminate() return # set focus on the window glfw.make_context_current(window) # until we say exit keep runnning this while not glfw.window_should_close(window): # set cursor position because of remote login # as this runs all the time mouse is essentially dead # so youll have to 'killall python' to get out if self.mode != "DEBUG": glfw.set_cursor_pos(window, 2000, 0) # run the draw loop self.draw() # update gl things in the window glfw.swap_buffers(window) glfw.poll_events() # kill gl glfw.terminate()
def getmonitors( self ) -> Dict[str, ctypes.POINTER(ctypes.POINTER(glfw._GLFWmonitor))]: monitors = {} for monitor in glfw.get_monitors(): newmonitor = Monitor(monitor) monitors[newmonitor.name] = newmonitor return monitors
def center_pos(window, monitor_id, W, H): # W, H: window dimensions mon = glfw.get_monitors() xpos = glfw.get_monitor_pos(mon[monitor_id])[0] + \ glfw.get_video_mode(mon[monitor_id]).size[0]/2-W/2 ypos = glfw.get_monitor_pos(mon[monitor_id])[1] + \ glfw.get_video_mode(mon[monitor_id]).size[1]/2-H/2 glfw.set_window_pos(window, int(xpos), int(ypos))
def open_window(self): if not self._window: if self.fullscreen: try: monitor = glfw.get_monitors()[self.monitor_idx] except Exception: logger.warning( "Monitor at index %s no longer availalbe using default" % idx) self.monitor_idx = 0 monitor = glfw.get_monitors()[self.monitor_idx] mode = glfw.get_video_mode(monitor) height, width = mode.size.height, mode.size.width else: monitor = None height, width = 640, 480 self._window = glfw.create_window( height, width, "Calibration", monitor, glfw.get_current_context(), ) if not self.fullscreen: # move to y = 31 for windows os glfw.set_window_pos(self._window, 200, 31) # Register callbacks glfw.set_framebuffer_size_callback(self._window, on_resize) glfw.set_key_callback(self._window, self.on_window_key) glfw.set_window_close_callback(self._window, self.on_close) glfw.set_mouse_button_callback(self._window, self.on_window_mouse_button) on_resize(self._window, *glfw.get_framebuffer_size(self._window)) # gl_state settings active_window = glfw.get_current_context() glfw.make_context_current(self._window) basic_gl_setup() glfw.make_context_current(active_window) self.clicks_to_close = 5
def init_gl(self): # major, minor, rev = glfw.get_version() monitors = glfw.get_monitors() # print(major, minor, rev) # print(glfw.get_primary_monitor()) print(glfw.OPENGL_COMPAT_PROFILE) # print(glGetString(GL_VERSION)) # glfw.window_hint(GLFW_CONTEXT_VERSION_MAJOR, 3) print(glfw.get_version_string())
def move_window_to_monitor(window, monitor_name): monitors = glfw.get_monitors() monitor = None for m in monitors: if glfw.get_monitor_name(m) == monitor_name: monitor = m if monitor is not None: glfw.set_window_pos(window, *glfw.get_monitor_pos(monitor)) return True else: return False
def glfwMonitorCallback(self): # TODO: Test the F**K out of this! newMonitors = glfw.get_monitors() newMonitornames = [bytes.decode(glfw.get_monitor_name(monitor)) for monitor in newMonitors] for monitorName in self.glfwWorkers: if monitorName not in newMonitornames: print("Monitor " + monitorName + " doesn't exist anymore, worker is now doing whatever.") self.monitors = newMonitors self.monitornames = newMonitornames for monitor in self.monitors: self.monitorDict[bytes.decode(glfw.get_monitor_name(monitor))] = monitor
def activate(self): if self.config["monitor_id"] is not None and 0 <= self.config[ "monitor_id"] < len(glfw.get_monitors()): glfw.set_window_pos(self.window_handle, self.config["screen_x"], self.config["screen_y"]) elif self.config["monitor_id"] is not None: self.config["screen_x"] = 0 self.config["screen_y"] = 0 glfw.set_window_pos(self.window_handle, 0, 0) glfw.make_context_current(self.window_handle) glfw.set_input_mode(self.window_handle, glfw.CURSOR, glfw.CURSOR_NORMAL) glViewport(0, 0, self.config["width"], self.config["height"]) self.active = True
def sendMonitorsReply(self, msgid): self.monitors = glfw.get_monitors() msg = { "msgid": uuid.uuid4().int, "msgtype": "reply", "refid": msgid, "replydata": [ bytes.decode(glfw.get_monitor_name(monitor)) for monitor in self.monitors ] } self.sendMessage(msg)
def _discover_screen(self): if not glfw.get_monitors(): if os.environ.get("XDG_CURRENT_DESKTOP") != "GNOME": # If no monitors detected, updates list with xrandr cmd = "xrandr --query | grep ' connected'" result = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate() if result[0] != "": subprocess.call(["xrandr", "--auto"]) if not self.monitor_connected: # If we boot without a monitor connected, and then plug one, the first display switch fails for an unknown reason. # The current solution is to start with the pure cuda stitching loop, and then switch to opengl # Subsequent plug/unplug operation are fine, though self.monitor_connected = True async .defer(self.server.reset)
def __init__(self, win, *args, **kwargs): """Set up the backend window according the params of the PsychoPy win Before PsychoPy 1.90.0 this code was executed in Window._setupPygame() Parameters ---------- win : psychopy.visual.Window instance PsychoPy Window (usually not fully created yet). share : psychopy.visual.Window instance PsychoPy Window to share a context with bpc : array_like Bits per color (R, G, B). refreshHz : int Refresh rate in Hertz. depthBits : int, Framebuffer (back buffer) depth bits. swapInterval : int Swap interval for the current OpenGL context. stencilBits : int Framebuffer (back buffer) stencil bits. winTitle : str Optional window title string. *args Additional position arguments. **kwargs Additional keyword arguments. """ BaseBackend.__init__(self, win) # window to share a context with shareWin = kwargs.get('share', None) if shareWin is not None: if shareWin.winType == 'glfw': shareContext = shareWin.winHandle else: logging.warning( 'Cannot share a context with a non-GLFW window. Disabling.') shareContext = None else: shareContext = None if sys.platform=='darwin' and not win.useRetina and pyglet.version >= "1.3": raise ValueError("As of PsychoPy 1.85.3 OSX windows should all be " "set to useRetina=True (or remove the argument). " "Pyglet 1.3 appears to be forcing " "us to use retina on any retina-capable screen " "so setting to False has no effect.") # window framebuffer configuration win.bpc = kwargs.get('bpc', (8, 8, 8)) # nearly all displays use 8 bpc win.refreshHz = int(kwargs.get('refreshHz', 60)) win.depthBits = int(kwargs.get('depthBits', 8)) win.stencilBits = int(kwargs.get('stencilBits', 8)) # win.swapInterval = int(kwargs.get('swapInterval', 1)) # vsync ON if 1 # get monitors, with GLFW the primary display is ALWAYS at index 0 allScrs = glfw.get_monitors() if len(allScrs) < int(win.screen) + 1: logging.warn("Requested an unavailable screen number - " "using first available.") win.screen = 0 thisScreen = allScrs[win.screen] if win.autoLog: logging.info('configured GLFW screen %i' % win.screen) # find a matching video mode (can we even support this configuration?) isVidmodeSupported = False for vidmode in glfw.get_video_modes(thisScreen): size, bpc, hz = vidmode if win._isFullScr: # size and refresh rate are ignored if windowed hasSize = size == tuple(win.size) hasHz = hz == win.refreshHz else: hasSize = hasHz = True hasBpc = bpc == tuple(win.bpc) if hasSize and hasBpc and hasHz: isVidmodeSupported = True break nativeVidmode = glfw.get_video_mode(thisScreen) if not isVidmodeSupported: # the requested video mode is not supported, use current logging.warning( ("The specified video mode is not supported by this display, " "using native mode ...")) logging.warning( ("Overriding user video settings: size {} -> {}, bpc {} -> " "{}, refreshHz {} -> {}".format( tuple(win.size), nativeVidmode[0], tuple(win.bpc), nativeVidmode[1], win.refreshHz, nativeVidmode[2]))) # change the window settings win.size, win.bpc, win.refreshHz = nativeVidmode if win._isFullScr: useDisplay = thisScreen else: useDisplay = None # configure stereo useStereo = 0 if win.stereo: # provide warning if stereo buffers are requested but unavailable if not glfw.extension_supported('GL_STEREO'): logging.warning( 'A stereo window was requested but the graphics ' 'card does not appear to support GL_STEREO') win.stereo = False else: useStereo = 1 # setup multisampling # This enables multisampling on the window backbuffer, not on other # framebuffers. msaaSamples = 0 if win.multiSample: maxSamples = (GL.GLint)() GL.glGetIntegerv(GL.GL_MAX_SAMPLES, maxSamples) if (win.numSamples & (win.numSamples - 1)) != 0: # power of two? logging.warning( 'Invalid number of MSAA samples provided, must be ' 'power of two. Disabling.') elif 0 > win.numSamples > maxSamples.value: # check if within range logging.warning( 'Invalid number of MSAA samples provided, outside of valid ' 'range. Disabling.') else: msaaSamples = win.numSamples win.multiSample = msaaSamples > 0 # disable stencil buffer if not win.allowStencil: win.stencilBits = 0 # set buffer configuration hints glfw.window_hint(glfw.RED_BITS, win.bpc[0]) glfw.window_hint(glfw.GREEN_BITS, win.bpc[1]) glfw.window_hint(glfw.BLUE_BITS, win.bpc[2]) glfw.window_hint(glfw.REFRESH_RATE, win.refreshHz) glfw.window_hint(glfw.STEREO, useStereo) glfw.window_hint(glfw.SAMPLES, msaaSamples) glfw.window_hint(glfw.STENCIL_BITS, win.stencilBits) glfw.window_hint(glfw.DEPTH_BITS, win.depthBits) glfw.window_hint(glfw.AUTO_ICONIFY, 0) # window appearance and behaviour hints if not win.allowGUI: glfw.window_hint(glfw.DECORATED, 0) # create the window self.winHandle = glfw.create_window( width=win.size[0], height=win.size[1], title=str(kwargs.get('winTitle', "PsychoPy (GLFW)")), monitor=useDisplay, share=shareContext) # The window's user pointer maps the Python Window object to its GLFW # representation. glfw.set_window_user_pointer(self.winHandle, win) glfw.make_context_current(self.winHandle) # ready to use # set the position of the window if not fullscreen if not win._isFullScr: # if no window position is specified, centre it on-screen if win.pos is None: size, bpc, hz = nativeVidmode win.pos = [(size[0] - win.size[0]) / 2.0, (size[1] - win.size[1]) / 2.0] # get the virtual position of the monitor, apply offset to the # window position px, py = glfw.get_monitor_pos(thisScreen) glfw.set_window_pos(self.winHandle, int(win.pos[0] + px), int(win.pos[1] + py)) elif win._isFullScr and win.pos is not None: logging.warn("Ignoring window 'pos' in fullscreen mode.") # set the window icon glfw.set_window_icon(self.winHandle, 1, _WINDOW_ICON_) # set the window size to the framebuffer size win.size = np.array(glfw.get_framebuffer_size(self.winHandle)) if win.useFBO: # check for necessary extensions if not glfw.extension_supported('GL_EXT_framebuffer_object'): msg = ("Trying to use a framebuffer object but " "GL_EXT_framebuffer_object is not supported. Disabled") logging.warn(msg) win.useFBO = False if not glfw.extension_supported('GL_ARB_texture_float'): msg = ("Trying to use a framebuffer object but " "GL_ARB_texture_float is not supported. Disabling") logging.warn(msg) win.useFBO = False # Assign event callbacks, these are dispatched when 'poll_events' is # called. glfw.set_mouse_button_callback(self.winHandle, event._onGLFWMouseButton) glfw.set_scroll_callback(self.winHandle, event._onGLFWMouseScroll) glfw.set_key_callback(self.winHandle, event._onGLFWKey) glfw.set_char_mods_callback(self.winHandle, event._onGLFWText) # set swap interval to manual setting, independent of waitBlanking self.setSwapInterval(int(kwargs.get('swapInterval', 1))) # give the window class GLFW specific methods win.setMouseType = self.setMouseType if not win.allowGUI: self.setMouseVisibility(False)
def __init__(self, win, backendConf=None): """Set up the backend window according the params of the PsychoPy win Before PsychoPy 1.90.0 this code was executed in Window._setupPygame() Parameters ---------- win : `psychopy.visual.Window` instance PsychoPy Window (usually not fully created yet). backendConf : `dict` or `None` Backend configuration options. Options are specified as a dictionary where keys are option names and values are settings. For this backend the following options are available: * `share` (`psychopy.visual.Window instance`) PsychoPy Window to share a context with. * `refreshHz` (`int`) Refresh rate in Hertz. * `bpc` (`array_like`) Bits per color (R, G, B). * `swapInterval` (`int`) Swap interval for the current OpenGL context. * `depthBits` (`int`) Framebuffer (back buffer) depth bits. * `stencilBits` (`int`) Framebuffer (back buffer) stencil bits. * `winTitle` (`str`) Optional window title string. Examples -------- Create a window using the GLFW backend and specify custom options:: import psychopy.visual as visual options = {'bpc': (8, 8, 8), 'depthBits': 24, 'stencilBits': 8} win = visual.Window(winType='glfw', backendOptions=options) """ BaseBackend.__init__(self, win) # if `None`, change to `dict` to extract options backendConf = backendConf if backendConf is not None else {} if not isinstance(backendConf, dict): # type check on options raise TypeError( 'Object passed to `backendConf` must be type `dict`.') # window to share a context with shareWin = backendConf.get('share', None) if shareWin is not None: if shareWin.winType == 'glfw': shareContext = shareWin.winHandle else: logging.warning( 'Cannot share a context with a non-GLFW window. Disabling.') shareContext = None else: shareContext = None if sys.platform=='darwin' and not win.useRetina and pyglet.version >= "1.3": raise ValueError("As of PsychoPy 1.85.3 OSX windows should all be " "set to useRetina=True (or remove the argument). " "Pyglet 1.3 appears to be forcing " "us to use retina on any retina-capable screen " "so setting to False has no effect.") # window framebuffer configuration bpc = backendConf.get('bpc', (8, 8, 8)) if isinstance(bpc, int): win.bpc = (bpc, bpc, bpc) else: win.bpc = bpc win.refreshHz = int(backendConf.get('refreshHz', 60)) win.depthBits = int(backendConf.get('depthBits', 8)) win.stencilBits = int(backendConf.get('stencilBits', 8)) # win.swapInterval = int(backendConf.get('swapInterval', 1)) # vsync ON if 1 # get monitors, with GLFW the primary display is ALWAYS at index 0 allScrs = glfw.get_monitors() if len(allScrs) < int(win.screen) + 1: logging.warn("Requested an unavailable screen number - " "using first available.") win.screen = 0 thisScreen = allScrs[win.screen] if win.autoLog: logging.info('configured GLFW screen %i' % win.screen) # find a matching video mode (can we even support this configuration?) isVidmodeSupported = False for vidmode in glfw.get_video_modes(thisScreen): size, bpc, hz = vidmode if win._isFullScr: # size and refresh rate are ignored if windowed hasSize = size == tuple(win.size) hasHz = hz == win.refreshHz else: hasSize = hasHz = True hasBpc = bpc == tuple(win.bpc) if hasSize and hasBpc and hasHz: isVidmodeSupported = True break nativeVidmode = glfw.get_video_mode(thisScreen) if not isVidmodeSupported: # the requested video mode is not supported, use current logging.warning( ("The specified video mode is not supported by this display, " "using native mode ...")) actualWidth, actualHeight = nativeVidmode.size redBits, greenBits, blueBits = nativeVidmode.bits # change the window settings if win._isFullScr: logging.warning( ("Overriding user video settings: size {} -> {}, bpc {} -> " "{}, refreshHz {} -> {}".format( tuple(win.size), (actualWidth, actualHeight), tuple(win.bpc), (redBits, greenBits, blueBits), win.refreshHz, nativeVidmode.refresh_rate))) win.clientSize = np.array((actualWidth, actualHeight), int) else: logging.warning( ("Overriding user video settings: bpc {} -> " "{}, refreshHz {} -> {}".format( tuple(win.bpc), (redBits, greenBits, blueBits), win.refreshHz, nativeVidmode.refresh_rate))) win.bpc = (redBits, greenBits, blueBits) win.refreshHz = nativeVidmode.refresh_rate if win._isFullScr: useDisplay = thisScreen else: useDisplay = None # configure stereo useStereo = 0 if win.stereo: # provide warning if stereo buffers are requested but unavailable if not glfw.extension_supported('GL_STEREO'): logging.warning( 'A stereo window was requested but the graphics ' 'card does not appear to support GL_STEREO') win.stereo = False else: useStereo = 1 # setup multisampling # This enables multisampling on the window backbuffer, not on other # framebuffers. msaaSamples = 0 if win.multiSample: maxSamples = (GL.GLint)() GL.glGetIntegerv(GL.GL_MAX_SAMPLES, maxSamples) if (win.numSamples & (win.numSamples - 1)) != 0: # power of two? logging.warning( 'Invalid number of MSAA samples provided, must be ' 'power of two. Disabling.') elif 0 > win.numSamples > maxSamples.value: # check if within range logging.warning( 'Invalid number of MSAA samples provided, outside of valid ' 'range. Disabling.') else: msaaSamples = win.numSamples win.multiSample = msaaSamples > 0 # disable stencil buffer if not win.allowStencil: win.stencilBits = 0 # set buffer configuration hints glfw.window_hint(glfw.RED_BITS, win.bpc[0]) glfw.window_hint(glfw.GREEN_BITS, win.bpc[1]) glfw.window_hint(glfw.BLUE_BITS, win.bpc[2]) glfw.window_hint(glfw.REFRESH_RATE, win.refreshHz) glfw.window_hint(glfw.STEREO, useStereo) glfw.window_hint(glfw.SAMPLES, msaaSamples) glfw.window_hint(glfw.STENCIL_BITS, win.stencilBits) glfw.window_hint(glfw.DEPTH_BITS, win.depthBits) glfw.window_hint(glfw.AUTO_ICONIFY, 0) # window appearance and behaviour hints if not win.allowGUI: glfw.window_hint(glfw.DECORATED, 0) # create the window self.winHandle = glfw.create_window( width=win.clientSize[0], height=win.clientSize[1], title=str(backendConf.get('winTitle', "PsychoPy (GLFW)")), monitor=useDisplay, share=shareContext) # The window's user pointer maps the Python Window object to its GLFW # representation. glfw.set_window_user_pointer(self.winHandle, win) glfw.make_context_current(self.winHandle) # ready to use # set the position of the window if not fullscreen if not win._isFullScr: # if no window position is specified, centre it on-screen if win.pos is None: size, bpc, hz = nativeVidmode win.pos = [(size[0] - win.clientSize[0]) / 2.0, (size[1] - win.clientSize[1]) / 2.0] # get the virtual position of the monitor, apply offset to the # window position px, py = glfw.get_monitor_pos(thisScreen) glfw.set_window_pos(self.winHandle, int(win.pos[0] + px), int(win.pos[1] + py)) elif win._isFullScr and win.pos is not None: logging.warn("Ignoring window 'pos' in fullscreen mode.") # set the window icon if hasattr(glfw, 'set_window_icon'): glfw.set_window_icon(self.winHandle, 1, _WINDOW_ICON_) # set the window size to the framebuffer size self._frameBufferSize = np.array(glfw.get_framebuffer_size(self.winHandle)) if win.useFBO: # check for necessary extensions if not glfw.extension_supported('GL_EXT_framebuffer_object'): msg = ("Trying to use a framebuffer object but " "GL_EXT_framebuffer_object is not supported. Disabled") logging.warn(msg) win.useFBO = False if not glfw.extension_supported('GL_ARB_texture_float'): msg = ("Trying to use a framebuffer object but " "GL_ARB_texture_float is not supported. Disabling") logging.warn(msg) win.useFBO = False # Assign event callbacks, these are dispatched when 'poll_events' is # called. glfw.set_mouse_button_callback(self.winHandle, self.onMouseButton) glfw.set_cursor_pos_callback(self.winHandle, self.onMouseMove) glfw.set_cursor_enter_callback(self.winHandle, self.onMouseEnter) glfw.set_scroll_callback(self.winHandle, self.onMouseScroll) glfw.set_key_callback(self.winHandle, event._onGLFWKey) glfw.set_char_mods_callback(self.winHandle, event._onGLFWText) # set swap interval to manual setting, independent of waitBlanking self.setSwapInterval(int(backendConf.get('swapInterval', 1))) # give the window class GLFW specific methods win.setMouseType = self.setMouseType if not win.allowGUI: self.setMouseVisibility(False)
uniform float color; out vec4 oc; void main() { oc = vec4(color, color, color, 1.0); } ''' if __name__ == '__main__': if not glfw.init(): raise ValueError('GLFW init went wrong.') atexit.register(glfw.terminate) screen = 0 monitor = glfw.get_monitors()[screen] video_mode = glfw.get_video_mode(monitor) width, height = video_mode.size size = width, height # Configure the OpenGL context glfw.window_hint(glfw.CONTEXT_CREATION_API, glfw.NATIVE_CONTEXT_API) glfw.window_hint(glfw.CLIENT_API, glfw.OPENGL_API) glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, False) # turn on for mac compat glfw.window_hint(glfw.RESIZABLE, False) glfw.window_hint(glfw.DOUBLEBUFFER, True)
def main(): if not glfw.init(): raise RuntimeError('Failed to initialize GLFW') version = glfw.get_version_string().decode('ASCII') print('GLFW', version) monitors = glfw.get_monitors() for i, monitor in enumerate(monitors): name = glfw.get_monitor_name(monitor) primary = (glfw.get_monitor_pos(monitor) == glfw.get_monitor_pos(glfw.get_primary_monitor())) print('Monitor #{}: {}{}'.format(i, name.decode('utf8'), ' (primary)' if primary else '')) width_mm, height_mm = glfw.get_monitor_physical_size(monitor) diag_mm = math.sqrt(width_mm*width_mm + height_mm*height_mm) print('Diagonal: {:.1f}"'.format(diag_mm / 25.4)) mode = glfw.get_video_mode(monitor) print('Video mode: {}x{} {}Hz {}'.format(mode.size.width, mode.size.height, mode.refresh_rate, mode.bits)) xscale, yscale = glfw.get_monitor_content_scale(monitor) print('Scale: {}|{}'.format(xscale, yscale)) print('Virtual position:', glfw.get_monitor_pos(monitor)) print('Work ares:', glfw.get_monitor_workarea(monitor)) for mode in glfw.get_video_modes(monitor): print('Supported: {}x{} {}Hz {}'.format(mode.size.width, mode.size.height, mode.refresh_rate, mode.bits)) print(mode) print() glfw.window_hint(glfw.RESIZABLE, True) glfw.window_hint(glfw.STENCIL_BITS, 8) glfw.window_hint(glfw.CLIENT_API, glfw.OPENGL_API) glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 6) glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) monitor = glfw.get_primary_monitor() mode = glfw.get_video_mode(monitor) window = glfw.create_window(640, 480, 'Title', None, None) # window = glfw.create_window(mode.size.width, mode.size.height, 'Title', monitor, None) if window is None: glfw.terminate() raise RuntimeError('Failed to create a window') # glfw.set_window_monitor(window, monitor, 0, 0, mode.size.width, mode.size.height, mode.refresh_rate) width, height = glfw.get_window_size(window) print('Window size: {}x{}'.format(width, height)) print('Frame size:', glfw.get_window_frame_size(window)) width, height = glfw.get_framebuffer_size(window) print('Framebuffer size: {}x{}'.format(width, height)) print('Client API:', glfw.get_window_attrib(window, glfw.CLIENT_API)) version_major = glfw.get_window_attrib(window, glfw.CONTEXT_VERSION_MAJOR) version_minor = glfw.get_window_attrib(window, glfw.CONTEXT_VERSION_MINOR) revision = glfw.get_window_attrib(window, glfw.CONTEXT_REVISION) print('Version: {}.{} rev{}'.format(version_major, version_minor, revision)) glfw.make_context_current(window) renderer = Renderer(window) while not glfw.window_should_close(window): GL.glClear(GL.GL_COLOR_BUFFER_BIT) renderer.render() glfw.swap_buffers(window) glfw.poll_events() glfw.terminate()
def get_monitors_idx_list(): monitors = [glfw.get_monitor_name(m) for m in glfw.get_monitors()] return range(len(monitors)), monitors
def main(): glfw.init() glfw.window_hint(glfw.RESIZABLE, False) glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 6) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) w = glfw.create_window(800, 600, 'Window Title', None, None) glfw.make_context_current(w) ############### face = freetype.Face("/usr/share/fonts/TTF/IBMPlexSans-Regular.ttf") # Figure out DPI's of different monitors # Perhaps take these into account if you care, as well as window scale. # But what if your window is split across screens? for monitor in glfw.get_monitors(): name = glfw.get_monitor_name(monitor).decode('utf8') pw, ph = glfw.get_monitor_physical_size(monitor) videomode = glfw.get_video_mode(monitor) # in mm vw, vh = videomode.size.width, videomode.size.height # print(name, 25.4*vw/pw, 25.4*vh/ph) # convert to pixels per inch print(name, (1 / 72) * 25.4 * vw / pw, (1 / 72) * 25.4 * vh / ph) # pixels per point # Set char size via physical size calculation # width, height in 1/64 of points # A point is one 1/72 of an inch. My monitors have 1.35 to 1.84 pixels per point. # Device resolution in dots per inch. # pixel_size = point_size * resolution / 72 # face.set_char_size(width=16*64) #,height=0,hres=72,vres=72 # Set size of EM square via pixels directly face.set_pixel_sizes(20, 0) baseline_height = 20 * face.height / face.units_per_EM print(baseline_height) ############### # disable byte-alignment restriction # normally, textures need to occupy a multiple of 4 in memory # but glyphs are single-color so they don't satisfy this glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glyphs = {} for i in range(face.num_glyphs): face.load_glyph(i) #flags=FT_LOAD_RENDER - renders glyph after loading texture = glGenTextures(1) # all of these numbers are pixels*64 by default # so divide by 64 to make these just pixels glyphs[i] = { "texture": texture, "w": face.glyph.metrics.width / 64, "h": face.glyph.metrics.height / 64, "hori": { "advance": face.glyph.metrics.horiAdvance / 64, "bearingX": face.glyph.metrics.horiBearingX / 64, "bearingY": face.glyph.metrics.horiBearingY / 64, }, "vert": { "advance": face.glyph.metrics.vertAdvance / 64, "bearingX": face.glyph.metrics.vertBearingX / 64, "bearingY": face.glyph.metrics.vertBearingY / 64, } } bitmap = face.glyph.bitmap glBindTexture(GL_TEXTURE_2D, texture) glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, bitmap.width, bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, bitmap.buffer) # target, level, internalformat, width, height, border=0, format, type,data glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) # these two seem glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) # to be optional glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ################## shaderProgram = make_shader_program() glUseProgram(shaderProgram) posParamsUniform = glGetUniformLocation(shaderProgram, "posParams") def set_pos(x, y, dx, dy): s = 1 glUniform4f(posParamsUniform, s * x, s * y, s * dx, s * dy) # location, count, transpose, value vao = glGenVertexArrays(1) glBindVertexArray(vao) vbo = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, vbo) # two triangles to make a rectangle # coordinates are in screen space # to get texture coordinates to x->x and y->1-y vertices = [0.0, 1.0] + [0.0,0.0] + [1.0,0.0] +\ [0.0, 1.0] + [1.0,0.0] + [1.0,1.0] glBufferData(GL_ARRAY_BUFFER, len(vertices)*ctypes.sizeof(ctypes.c_float), \ (ctypes.c_float*len(vertices))(*vertices), GL_STATIC_DRAW) glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) glEnable(GL_BLEND) # need this because the shader uses alphas glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) fbsize = {} fbsize["w"], fbsize["h"] = glfw.get_framebuffer_size(w) while not glfw.window_should_close(w): glClearColor(0.0, 0.0, 0.0, 1.0) glClear(GL_COLOR_BUFFER_BIT) x, y = -1.0, 1.0 y -= baseline_height * 2 / fbsize["h"] for i in range(face.num_glyphs): bx = glyphs[i]["hori"]["bearingX"] * 2 / fbsize["w"] by = glyphs[i]["hori"]["bearingY"] * 2 / fbsize["h"] width = glyphs[i]["w"] * 2 / fbsize["w"] height = glyphs[i]["h"] * 2 / fbsize["h"] set_pos(x + bx, y + by - height, width, height) x += glyphs[i]["hori"]["advance"] * 2 / fbsize["w"] glBindTexture(GL_TEXTURE_2D, glyphs[i]["texture"]) glDrawArrays(GL_TRIANGLES, 0, 6) if i + 1 < face.num_glyphs: x += face.get_kerning(i, i + 1).x if x + glyphs[i + 1]["hori"]["advance"] * 2 / fbsize["w"] >= 1.0: x = -1.0 y -= baseline_height * 2 / fbsize["h"] if y <= -1.0: break glfw.swap_buffers(w) glfw.poll_events() glDeleteBuffers(1, vbo) glDeleteVertexArrays(1, vao) glDeleteProgram(shaderProgram) glfw.terminate()
def __init__(self, vispy_canvas, **kwargs): BaseCanvasBackend.__init__(self, vispy_canvas) p = self._process_backend_kwargs(kwargs) self._initialized = False # Deal with config _set_config(p.context.config) # Deal with context p.context.shared.add_ref('glfw', self) if p.context.shared.ref is self: share = None else: share = p.context.shared.ref._id glfw.window_hint(glfw.REFRESH_RATE, 0) # highest possible glfw.window_hint(glfw.RESIZABLE, int(p.resizable)) glfw.window_hint(glfw.DECORATED, int(p.decorate)) glfw.window_hint(glfw.VISIBLE, 0) # start out hidden glfw.window_hint(glfw.FLOATING, int(p.always_on_top)) if p.fullscreen is not False: self._fullscreen = True if p.fullscreen is True: monitor = glfw.get_primary_monitor() else: monitor = glfw.get_monitors() if p.fullscreen >= len(monitor): raise ValueError('fullscreen must be <= %s' % len(monitor)) monitor = monitor[p.fullscreen] use_size = glfw.get_video_mode(monitor)[:2] if use_size != tuple(p.size): logger.debug('Requested size %s, will be ignored to ' 'use fullscreen mode %s' % (p.size, use_size)) size = use_size else: self._fullscreen = False monitor = None size = p.size self._id = glfw.create_window(width=size[0], height=size[1], title=p.title, monitor=monitor, share=share) if not self._id: raise RuntimeError('Could not create window') glfw.make_context_current(self._id) glfw.swap_interval(1 if p.vsync else 0) # needs a valid context _VP_GLFW_ALL_WINDOWS.append(self) self._mod = list() # Register callbacks glfw.set_window_refresh_callback(self._id, self._on_draw) glfw.set_window_size_callback(self._id, self._on_resize) glfw.set_key_callback(self._id, self._on_key_press) glfw.set_char_callback(self._id, self._on_key_char) glfw.set_mouse_button_callback(self._id, self._on_mouse_button) glfw.set_scroll_callback(self._id, self._on_mouse_scroll) glfw.set_cursor_pos_callback(self._id, self._on_mouse_motion) glfw.set_window_close_callback(self._id, self._on_close) self._vispy_canvas_ = None self._needs_draw = False self._vispy_canvas.set_current() if p.position is not None: self._vispy_set_position(*p.position) if p.show: glfw.show_window(self._id) # Init self._initialized = True self._next_key_events = [] self._next_key_text = {} self._vispy_canvas.set_current() self._vispy_canvas.events.initialize() self._on_resize(self._id, size[0], size[1])
def currently_connected_monitors() -> T.List["GUIMonitor"]: return [GUIMonitor(i, h) for i, h in enumerate(glfw.get_monitors())]
C: "", D: "", delete: false } """ self.program.fragmentPathA = msg["A"] self.program.fragmentPathB = msg["B"] def handleTexture(self, msg): pass # TODO: implement lol if __name__ == "__main__": glfw.init() a = GlfwInstance(glfw.get_monitors()[0]) a.createWindow() b = Manager(a) gtime = glfw.get_time() while 1: # Limit framerate to 100 frames dt = glfw.get_time() - gtime b.loop() time.sleep(max(0.01 - dt, 0)) gtime = glfw.get_time() """ { type: "program", A: "", B: "",
def __init__(self, win, *args, **kwargs): """Set up the backend window according the params of the PsychoPy win Before PsychoPy 1.90.0 this code was executed in Window._setupPygame() :param win: a PsychoPy Window (usually not fully created yet) :param share: a PsychoPy Window to share a context with :param bpc: list-like, bits per color (R, G, B) :param refreshHz: int, refresh rate :param depthBits: int, framebuffer depth bits :param stencilBits: int, framebuffer stencil bits :param swapInterval: int, screen updates before swapping buffers :param winTitle: str, optional window title """ BaseBackend.__init__(self, win) # window to share a context with share_win = kwargs.get('share', None) if share_win is not None: if share_win.winType == 'glfw': share_context = share_win.winHandle else: logging.warning( 'Cannot share a context with a non-GLFW window. Disabling.' ) share_context = None else: share_context = None if sys.platform == 'darwin' and not win.useRetina and pyglet.version >= "1.3": raise ValueError("As of PsychoPy 1.85.3 OSX windows should all be " "set to useRetina=True (or remove the argument). " "Pyglet 1.3 appears to be forcing " "us to use retina on any retina-capable screen " "so setting to False has no effect.") # window framebuffer configuration win.bpc = kwargs.get('bpc', (8, 8, 8)) # nearly all displays use 8 bpc win.refreshHz = int(kwargs.get('refreshHz', 60)) win.depthBits = int(kwargs.get('depthBits', 8)) win.stencilBits = int(kwargs.get('stencilBits', 8)) # TODO - make waitBlanking set this too, independent right now win.swapInterval = int(kwargs.get('swapInterval', 1)) # vsync ON if 1 # get monitors, with GLFW the primary display is ALWAYS at index 0 allScrs = glfw.get_monitors() if len(allScrs) < int(win.screen) + 1: logging.warn("Requested an unavailable screen number - " "using first available.") win.screen = 0 this_screen = allScrs[win.screen] if win.autoLog: logging.info('configured GLFW screen %i' % win.screen) # find a matching video mode (can we even support this configuration?) vidmode_is_supported = False for vidmode in glfw.get_video_modes(this_screen): _size, _bpc, _hz = vidmode if win._isFullScr: # size and refresh rate are ignored if windowed has_size = _size == tuple(win.size) has_hz = _hz == win.refreshHz else: has_size = has_hz = True has_bpc = _bpc == tuple(win.bpc) if has_size and has_bpc and has_hz: vidmode_is_supported = True break _size, _bpc, _hz = glfw.get_video_mode(this_screen) if not vidmode_is_supported: # the requested video mode is not supported, use current logging.warning( ("The specified video mode is not supported by this display, " "using native mode ...")) logging.warning( ("Overriding user video settings: size {} -> {}, bpc {} -> " "{}, refreshHz {} -> {}".format(tuple(win.size), _size, tuple(win.bpc), _bpc, win.refreshHz, _hz))) # change the window settings win.bpc = _bpc win.refreshHz = _hz win.size = _size if win._isFullScr: use_display = this_screen else: use_display = None # configure stereo use_stereo = 0 if win.stereo: # provide warning if stereo buffers are requested but unavailable if not glfw.extension_supported('GL_STEREO'): logging.warning( 'A stereo window was requested but the graphics ' 'card does not appear to support GL_STEREO') win.stereo = False else: use_stereo = 1 # setup multisampling # This enables multisampling on the window backbuffer, not on other # framebuffers. msaa_samples = 0 if win.multiSample: max_samples = (GL.GLint)() GL.glGetIntegerv(GL.GL_MAX_SAMPLES, max_samples) if (win.numSamples & (win.numSamples - 1)) != 0: # power of two? logging.warning( 'Invalid number of MSAA samples provided, must be ' 'power of two. Disabling.') elif 0 > win.numSamples > max_samples.value: # check if within range logging.warning( 'Invalid number of MSAA samples provided, outside of valid ' 'range. Disabling.') else: msaa_samples = win.numSamples win.multiSample = msaa_samples > 0 # disable stencil buffer if win.allowStencil: win.stencilBits = 0 # set buffer configuration hints glfw.window_hint(glfw.RED_BITS, win.bpc[0]) glfw.window_hint(glfw.GREEN_BITS, win.bpc[1]) glfw.window_hint(glfw.BLUE_BITS, win.bpc[2]) glfw.window_hint(glfw.REFRESH_RATE, win.refreshHz) glfw.window_hint(glfw.STEREO, use_stereo) glfw.window_hint(glfw.SAMPLES, msaa_samples) glfw.window_hint(glfw.STENCIL_BITS, win.stencilBits) glfw.window_hint(glfw.DEPTH_BITS, win.depthBits) # window appearance and behaviour hints if not win.allowGUI: glfw.window_hint(glfw.DECORATED, 0) glfw.window_hint(glfw.AUTO_ICONIFY, 0) # window title title_text = str(kwargs.get('winTitle', "PsychoPy (GLFW)")) # create the window self.winHandle = glfw.create_window(width=win.size[0], height=win.size[1], title=title_text, monitor=use_display, share=share_context) # set the window icon glfw.set_window_icon(self.winHandle, 1, _WINDOW_ICON_) # The window's user pointer maps the Python Window object to its GLFW # representation. glfw.set_window_user_pointer(self.winHandle, win) glfw.make_context_current(self.winHandle) # ready to use # set the window size to the framebuffer size win.size = np.array(glfw.get_framebuffer_size(self.winHandle)) if win.useFBO: # check for necessary extensions if not glfw.extension_supported('GL_EXT_framebuffer_object'): msg = ("Trying to use a framebuffer object but " "GL_EXT_framebuffer_object is not supported. Disabled") logging.warn(msg) win.useFBO = False if not glfw.extension_supported('GL_ARB_texture_float'): msg = ("Trying to use a framebuffer object but " "GL_ARB_texture_float is not supported. Disabling") logging.warn(msg) win.useFBO = False # Assign event callbacks, these are dispatched when 'poll_events' is # called. glfw.set_mouse_button_callback(self.winHandle, event._onGLFWMouseButton) glfw.set_scroll_callback(self.winHandle, event._onGLFWMouseScroll) glfw.set_key_callback(self.winHandle, event._onGLFWKey) glfw.set_char_mods_callback(self.winHandle, event._onGLFWText) # enable vsync, GLFW has additional setting for this that might be # useful. glfw.swap_interval(win.swapInterval) # give the window class GLFW specific methods win.setMouseType = self.setMouseType if not win.allowGUI: self.setMouseVisibility(False) #glfw.set_window_size_callback(self.winHandle, _onResize) #self.winHandle.on_resize = _onResize # avoid circular reference # TODO - handle window resizing # Set the position of the window if not fullscreen. if not win.pos: # work out where the centre should be win.pos = [(_size[0] - win.size[0]) / 2.0, (_size[1] - win.size[1]) / 2.0] if not win._isFullScr: # get the virtual position of the monitor, apply offset to pos _px, _py = glfw.get_monitor_pos(this_screen) glfw.set_window_pos(self.winHandle, int(win.pos[0] + _px), int(win.pos[1] + _py))
def setFullScr(self, value): """Sets the window to/from full-screen mode. Parameters ---------- value : bool or int If `True`, resize the window to be fullscreen. """ # convert value to correct type value = bool(value) # get monitor handle for the window monitor = glfw.get_window_monitor(self.winHandle) # get the video mode for the monitor # get monitors, with GLFW the primary display is ALWAYS at index 0 allScrs = glfw.get_monitors() if len(allScrs) < int(self.win.screen) + 1: logging.warn("Requested an unavailable screen number - " "using first available.") self.win.screen = 0 thisScreen = allScrs[self.win.screen] if self.win.autoLog: logging.info('configured GLFW screen %i' % self.win.screen) # get monitor information nativeVidmode = glfw.get_video_mode(thisScreen) refreshRateHz = nativeVidmode.refresh_rate scrWidth, scrHeight = nativeVidmode.size winWidth, winHeight = nativeVidmode.size if value else self.win.windowedSize # set the monitor # glfw.window_hint(glfw.DECORATED, glfw.FALSE) glfw.set_window_monitor( self.winHandle, monitor if value else None, # if `None` windowed, else fullscreen 0, 0, # position keep zero and set later nativeVidmode.size[0] if value else self.win.windowedSize[0], nativeVidmode.size[1] if value else self.win.windowedSize[1], refreshRateHz) if not value: # extra stuff for non-fullscreen # if no window position is specified, centre it on-screen if self.win.pos is None: self.win.pos = [ (scrWidth - winWidth) / 2.0, (scrHeight - winHeight) / 2.0] # get the virtual position of the monitor, apply offset to the # window position px, py = glfw.get_monitor_pos(thisScreen) glfw.set_window_pos( self.winHandle, int(self.win.pos[0] + px), int(self.win.pos[1] + py)) # get the reported client size self.win.clientSize[:] = glfw.get_window_size(self.winHandle) self.frameBufferSize[:] = glfw.get_framebuffer_size(self.winHandle) self.win.viewport = ( 0, 0, self._frameBufferSize[0], self._frameBufferSize[1]) self.win.scissor = ( 0, 0, self._frameBufferSize[0], self._frameBufferSize[1]) self.win.resetEyeTransform()