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 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 open_output_window(self): self._pause_event_loop() # Select monitor self._select_monitor() # Open window if self.monitor: # Fullscreen self._select_video_mode() x, y = glfw.get_monitor_pos(self.monitor) logger.info("Output selected : {} on {} at {},{}".format( str(self.video_mode), glfw.get_monitor_name(self.monitor), x, y)) w, h = self.video_mode[0] self.pano_renderer.setViewport(w, h) self.pano_renderer.setRefreshRate( self._convert_rate(30), self._convert_rate(self.video_mode[2])) if self.output_window: glfw.set_window_monitor(self.output_window, self.monitor, x, y, w, h, self.video_mode[2]) glfw.show_window(self.output_window) self.pano_renderer.enableOutput(True) else: self._open_output_window(w, h, self.monitor, self.video_mode) else: # No monitor available or windowed w = self.width / 4 h = self.height / 4 self.pano_renderer.setViewport(w, h) monitor = glfw.get_primary_monitor() if monitor: rate = glfw.get_video_mode(monitor)[2] self.pano_renderer.setRefreshRate(self._convert_rate(30), self._convert_rate(rate)) if self.output_window: self.pano_renderer.enableOutput(True) glfw.show_window(self.output_window) else: self._open_output_window(w, h) if not SETTINGS.display in ["window", "windowed"]: # No monitor available glfw.hide_window(self.output_window) self._unpause_event_loop()
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 __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)
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 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()