glut_support.py
124 lines
| 4.4 KiB
| text/x-python
|
PythonLexer
Nicolas Rougier
|
r4819 | # coding: utf-8 | ||
""" | ||||
GLUT Inputhook support functions | ||||
""" | ||||
#----------------------------------------------------------------------------- | ||||
# Copyright (C) 2008-2009 The IPython Development Team | ||||
# | ||||
# Distributed under the terms of the BSD License. The full license is in | ||||
# the file COPYING, distributed as part of this software. | ||||
#----------------------------------------------------------------------------- | ||||
# GLUT is quite an old library and it is difficult to ensure proper | ||||
# integration within IPython since original GLUT does not allow to handle | ||||
# events one by one. Instead, it requires for the mainloop to be entered | ||||
# and never returned (there is not even a function to exit he | ||||
# mainloop). Fortunately, there are alternatives such as freeglut | ||||
# (available for linux and windows) and the OSX implementation gives | ||||
# access to a glutCheckLoop() function that blocks itself until a new | ||||
# event is received. This means we have to setup a default timer to | ||||
# ensure we got at least one event that will unblock the function. We set | ||||
# a default timer of 60fps. | ||||
# | ||||
# Furthermore, it is not possible to install these handlers without a | ||||
# window being first created. We choose to make this window invisible and | ||||
# the user is supposed to make it visible when needed (see gui-glut.py in | ||||
# the docs/examples/lib directory). This means that display mode options | ||||
# are set at this level and user won't be able to change them later | ||||
# without modifying the code. This should probably be made available via | ||||
# IPython options system. | ||||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
import sys | ||||
import time | ||||
import signal | ||||
import OpenGL | ||||
OpenGL.ERROR_CHECKING = False | ||||
import OpenGL.GLUT as glut | ||||
import OpenGL.platform as platform | ||||
#----------------------------------------------------------------------------- | ||||
# Constants | ||||
#----------------------------------------------------------------------------- | ||||
# Frame per second : 60 | ||||
# Should probably be an IPython option | ||||
glut_fps = 60 | ||||
# Display mode : double buffeed + rgba + depth | ||||
# Should probably be an IPython option | ||||
glut_display_mode = (glut.GLUT_DOUBLE | | ||||
glut.GLUT_RGBA | | ||||
glut.GLUT_DEPTH) | ||||
glutMainLoopEvent = None | ||||
if sys.platform == 'darwin': | ||||
try: | ||||
glutCheckLoop = platform.createBaseFunction( | ||||
'glutCheckLoop', dll=platform.GLUT, resultType=None, | ||||
argTypes=[], | ||||
doc='glutCheckLoop( ) -> None', | ||||
argNames=(), | ||||
) | ||||
except AttributeError: | ||||
raise RuntimeError( | ||||
'''Your glut implementation does not allow interactive sessions''' | ||||
'''Consider installing freeglut.''') | ||||
glutMainLoopEvent = glutCheckLoop | ||||
elif glut.HAVE_FREEGLUT: | ||||
glutMainLoopEvent = glut.glutMainLoopEvent | ||||
else: | ||||
raise RuntimeError( | ||||
'''Your glut implementation does not allow interactive sessions. ''' | ||||
'''Consider installing freeglut.''') | ||||
#----------------------------------------------------------------------------- | ||||
# Callback functions | ||||
#----------------------------------------------------------------------------- | ||||
def glut_display(): | ||||
# Dummy display function | ||||
pass | ||||
def glut_timer(fps): | ||||
# We should normally set the active window to 1 and post a | ||||
# redisplay for each window. The problem is that we do not know | ||||
# how much active windows we have and there is no function in glut | ||||
# to get that number. | ||||
# glut.glutSetWindow(1) | ||||
glut.glutTimerFunc( int(1000.0/fps), glut_timer, fps) | ||||
glut.glutPostRedisplay() | ||||
def glut_close(): | ||||
glut.glutHideWindow() | ||||
def glut_int_handler(signum, frame): | ||||
signal.signal(signal.SIGINT, signal.default_int_handler) | ||||
print '\nKeyboardInterrupt' | ||||
# Need to reprint the prompt at this stage | ||||
def inputhook_glut(): | ||||
""" Process pending GLUT events only. """ | ||||
# We need to protect against a user pressing Control-C when IPython | ||||
# is idle and this is running. We should trap KeyboardInterrupt and | ||||
# pass but it does not seem to work with glutMainLoopEvent. | ||||
# Instead, we setup a signal handler on SIGINT and returns after | ||||
# having restored the default python SIGINT handler. | ||||
signal.signal(signal.SIGINT, glut_int_handler) | ||||
try: | ||||
glutMainLoopEvent() | ||||
except KeyboardInterrupt: # this catch doesn't work for some reasons... | ||||
pass | ||||
return 0 | ||||