def glVertexAttribPointerARB( baseOperation, index, size, type, normalized, stride, pointer, ): """Set an attribute pointer for a given shader (index) index -- the index of the generic vertex to bind, see glGetAttribLocation for retrieval of the value, note that index is a global variable, not per-shader size -- number of basic elements per record, 1,2,3, or 4 type -- enum constant for data-type normalized -- whether to perform int to float normalization on integer-type values stride -- stride in machine units (bytes) between consecutive records, normally used to create "interleaved" arrays pointer -- data-pointer which provides the data-values, normally a vertex-buffer-object or offset into the same. This implementation stores a copy of the data-pointer in the contextdata structure in order to prevent null- reference errors in the renderer. """ array = ArrayDatatype.asArray(pointer, type) key = ('vertex-attrib', index) contextdata.setValue(key, array) return baseOperation(index, size, type, normalized, stride, ArrayDatatype.voidDataPointer(array))
def copy_data( self ): """Copy our data into the buffer on the GL side (if required) Ensures that the GL's version of the data in the VBO matches our internal view of the data, either by copying the entire data-set over with glBufferData or by updating the already-transferred data with glBufferSubData. """ assert self.buffers, """Should do create_buffers before copy_data""" if self.copied: if self._copy_segments: while self._copy_segments: start,size,data = self._copy_segments.pop(0) dataptr = ArrayDatatype.voidDataPointer( data ) self.implementation.glBufferSubData(self.target, start, size, dataptr) else: if self.data is not None and self.size is None: self.size = ArrayDatatype.arrayByteCount( self.data ) self.implementation.glBufferData( self.target, self.size, self.data, self.usage, ) self.copied = True
def glVertexAttribPointer( baseOperation, index, size, type, normalized, stride, pointer, ): """Set an attribute pointer for a given shader (index) index -- the index of the generic vertex to bind, see glGetAttribLocation for retrieval of the value, note that index is a global variable, not per-shader size -- number of basic elements per record, 1,2,3, or 4 type -- enum constant for data-type normalized -- whether to perform int to float normalization on integer-type values stride -- stride in machine units (bytes) between consecutive records, normally used to create "interleaved" arrays pointer -- data-pointer which provides the data-values, normally a vertex-buffer-object or offset into the same. This implementation stores a copy of the data-pointer in the contextdata structure in order to prevent null- reference errors in the renderer. """ array = ArrayDatatype.asArray( pointer, type ) key = ('vertex-attrib',index) contextdata.setValue( key, array ) return baseOperation( index, size, type, normalized, stride, ArrayDatatype.voidDataPointer( array ) )
def __setitem__( self, slice, array): """Set slice of data on the array and vbo (if copied already) slice -- the Python slice object determining how the data should be copied into the vbo/array array -- something array-compatible that will be used as the source of the data, note that the data-format will have to be the same as the internal data-array to work properly, if not, the amount of data copied will be wrong. This is a reasonably complex operation, it has to have all sorts of state-aware changes to correctly map the source into the low-level OpenGL view of the buffer (which is just bytes as far as the GL is concerned). """ if slice.step and not slice.step == 1: raise NotImplemented( """Don't know how to map stepped arrays yet""" ) # TODO: handle e.g. mapping character data into an integer data-set data = ArrayDatatype.asArray( array ) start = (slice.start or 0) stop = (slice.stop or len(self.data)) if start < 0: start += len(self.data) start = max((start,0)) if stop < 0: stop += len(self.data) stop = max((stop,0)) self.data[ slice ] = data if self.copied and self.buffers: if start-stop != len(data): self.copied = False elif start-stop == len(self.data): # re-copy the whole data-set self.copied = False elif len(data): # now the fun part, we need to make the array match the # structure of the array we're going to copy into and make # the "size" parameter match the value we're going to copy in, # note that a 2D array (rather than a 1D array) may require # multiple mappings to copy into the memory area... # find the step size from the dimensions and base size... size = ArrayDatatype.arrayByteCount( data ) / len(array) #baseSize = ArrayDatatype.unitSize( data ) # now create the start and distance values... start *= size stop *= size # wait until the last moment (bind) to copy the data... self._copy_segments.append( (start,(stop-start), data) )
def init_gl(self, glcontext): assert not self.shader assert glcontext == self.glcontext frag_stage = GstGL.GLSLStage.new_default_fragment(self.glcontext) vert_stage = GstGL.GLSLStage.new_with_string( self.glcontext, GL_VERTEX_SHADER, GstGL.GLSLVersion.NONE, GstGL.GLSLProfile.COMPATIBILITY | GstGL.GLSLProfile.ES, VERTEX_SHADER_SRC) self.shader = GstGL.GLShader.new(self.glcontext) self.shader.compile_attach_stage(vert_stage) self.shader.compile_attach_stage(frag_stage) self.shader.link() self.u_transformation = glGetUniformLocation.wrappedOperation( self.shader.get_program_handle(), 'u_transformation') a_position = self.shader.get_attribute_location('a_position') a_texcoord = self.shader.get_attribute_location('a_texcoord') self.vao = glGenVertexArrays(1) glBindVertexArray(self.vao) self.positions_buffer = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.positions_buffer) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(POSITIONS), POSITIONS, GL_STATIC_DRAW) self.texcoords_buffer = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.texcoords_buffer) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(TEXCOORDS), TEXCOORDS, GL_STATIC_DRAW) self.vbo_indices = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.vbo_indices) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(INDICES), INDICES, GL_STATIC_DRAW) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.vbo_indices) glBindBuffer(GL_ARRAY_BUFFER, self.positions_buffer) glVertexAttribPointer.wrappedOperation(a_position, 2, GL_FLOAT, GL_FALSE, 0, None) glBindBuffer(GL_ARRAY_BUFFER, self.texcoords_buffer) glVertexAttribPointer.wrappedOperation(a_texcoord, 2, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(a_position) glEnableVertexAttribArray(a_texcoord) glBindVertexArray(0) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) glBindBuffer(GL_ARRAY_BUFFER, 0)
def set_array(self, data, size=None): """Update our entire array with new data""" self.data = data self.copied = False if size is not None: self.size = size elif self.data is not None: self.size = ArrayDatatype.arrayByteCount(self.data)
def set_array( self, data, size=None ): """Update our entire array with new data""" self.data = data self.copied = False if size is not None: self.size = size elif self.data is not None: self.size = ArrayDatatype.arrayByteCount( self.data )
def do_gl_start(self): frag_stage = GstGL.GLSLStage.new_default_fragment(self.context) vert_stage = GstGL.GLSLStage.new_with_string(self.context, GL_VERTEX_SHADER, GstGL.GLSLVersion.NONE, GstGL.GLSLProfile.COMPATIBILITY | GstGL.GLSLProfile.ES, VERTEX_SHADER) self.shader = GstGL.GLShader.new(self.context) self.shader.compile_attach_stage(vert_stage) self.shader.compile_attach_stage(frag_stage) self.shader.link() a_position = self.shader.get_attribute_location('a_position') a_texcoord = self.shader.get_attribute_location('a_texcoord') self.vao_id = glGenVertexArrays(1) glBindVertexArray(self.vao_id) self.positions_buffer = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.positions_buffer) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(POSITIONS), POSITIONS, GL_STATIC_DRAW) self.texcoords_buffer = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.texcoords_buffer) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(TEXCOORDS), TEXCOORDS, GL_STATIC_DRAW) self.vbo_indices_buffer = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.vbo_indices_buffer) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(INDICES), INDICES, GL_STATIC_DRAW) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.vbo_indices_buffer); glBindBuffer(GL_ARRAY_BUFFER, self.positions_buffer); glVertexAttribPointer.wrappedOperation(a_position, 2, GL_FLOAT, GL_FALSE, 0, None) glBindBuffer(GL_ARRAY_BUFFER, self.texcoords_buffer); glVertexAttribPointer.wrappedOperation(a_texcoord, 2, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(a_position) glEnableVertexAttribArray(a_texcoord) glBindVertexArray(0) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) glBindBuffer(GL_ARRAY_BUFFER, 0) return True
def copy_data( self ): """Copy our data into the buffer on the GL side""" assert self.buffers, """Should do create_buffers before copy_data""" if self.copied: if self._copy_segments: while self._copy_segments: start,size,data = self._copy_segments.pop(0) dataptr = ArrayDatatype.voidDataPointer( data ) self.implementation.glBufferSubData(self.target, start, size, dataptr) else: if self.data is not None and self.size is None: self.size = ArrayDatatype.arrayByteCount( self.data ) self.implementation.glBufferData( self.target, self.size, self.data, self.usage, ) self.copied = True
def copy_data(self): """Copy our data into the buffer on the GL side""" assert self.buffers, """Should do create_buffers before copy_data""" if self.copied: if self._copy_segments: while self._copy_segments: start, size, data = self._copy_segments.pop(0) dataptr = ArrayDatatype.voidDataPointer(data) self.implementation.glBufferSubData( self.target, start, size, dataptr) else: if self.data is not None and self.size is None: self.size = ArrayDatatype.arrayByteCount(self.data) self.implementation.glBufferData( self.target, self.size, self.data, self.usage, ) self.copied = True
def typeLookup( cls, type ): """Lookup handler by data-type""" registry = ArrayDatatype.getRegistry() try: return registry[ type ] except KeyError as err: key = '%s.%s'%(type.__module__,type.__name__) plugin = cls.LAZY_TYPE_REGISTRY.get( key ) if plugin: cls.loadPlugin( plugin ) return registry[ type ] raise KeyError( """Unable to find data-format handler for %s"""%( type,))
def set_array( self, data, size=None ): """Update our entire array with new data data -- PyOpenGL-compatible array-data structure, numpy arrays, ctypes arrays, etc. size -- if not provided, will use arrayByteCount to determine the size of the data-array, thus this value (number of bytes) is required when using opaque data-structures, (such as ctypes pointers) as the array data-source. """ self.data = data self.copied = False if size is not None: self.size = size elif self.data is not None: self.size = ArrayDatatype.arrayByteCount( self.data )
def loadPlugin(cls, entrypoint): """Load a single entry-point via plugins module""" if not entrypoint.loaded: from OpenGL.arrays.arraydatatype import ArrayDatatype try: plugin_class = entrypoint.load() except ImportError, err: from OpenGL import logs, WARN_ON_FORMAT_UNAVAILABLE log = logs.getLog('OpenGL.formathandler') if WARN_ON_FORMAT_UNAVAILABLE: logFunc = log.warn else: logFunc = log.info logFunc( 'Unable to load registered array format handler %s:\n%s', entrypoint.name, log.getException(err)) else: handler = plugin_class() handler.register(handler.HANDLED_TYPES) ArrayDatatype.getRegistry()[entrypoint.name] = handler entrypoint.loaded = True
def loadPlugin( cls, entrypoint ): """Load a single entry-point via plugins module""" if not entrypoint.loaded: from OpenGL.arrays.arraydatatype import ArrayDatatype try: plugin_class = entrypoint.load() except ImportError, err: from OpenGL import logs,WARN_ON_FORMAT_UNAVAILABLE log = logs.getLog( 'OpenGL.formathandler' ) if WARN_ON_FORMAT_UNAVAILABLE: logFunc = log.warn else: logFunc = log.info logFunc( 'Unable to load registered array format handler %s:\n%s', entrypoint.name, log.getException( err ) ) else: handler = plugin_class() handler.register( handler.HANDLED_TYPES ) ArrayDatatype.getRegistry()[ entrypoint.name ] = handler entrypoint.loaded = True
def check_GL_support(gldrawable, glcontext, min_texture_size=0, force_enable=False): if not gldrawable.gl_begin(glcontext): raise ImportError("gl_begin failed on %s" % gldrawable) props = {} try: if SILENCE_FORMAT_HANDLER_LOGGER: debug("silencing formathandler warnings") logging.getLogger('OpenGL.formathandler').setLevel(logging.WARN) import OpenGL props["pyopengl"] = OpenGL.__version__ from OpenGL.GL import GL_VERSION, GL_EXTENSIONS from OpenGL.GL import glGetString, glGetInteger gl_version_str = glGetString(GL_VERSION) if gl_version_str is None: gl_check_error("OpenGL version is missing - cannot continue") return {} gl_major = int(gl_version_str[0]) gl_minor = int(gl_version_str[2]) props["opengl"] = gl_major, gl_minor MIN_VERSION = (1,1) if (gl_major, gl_minor) < MIN_VERSION: gl_check_error("OpenGL output requires version %s or greater, not %s.%s" % (".".join([str(x) for x in MIN_VERSION]), gl_major, gl_minor)) else: debug("found valid OpenGL version: %s.%s", gl_major, gl_minor) try: extensions = glGetString(GL_EXTENSIONS).split(" ") except: gl_check_error("OpenGL could not find the list of GL extensions - does the graphics driver support OpenGL?") debug("OpenGL extensions found: %s", ", ".join(extensions)) props["extensions"] = extensions from OpenGL.arrays.arraydatatype import ArrayDatatype try: debug("found the following array handlers: %s", set(ArrayDatatype.getRegistry().values())) except: pass from OpenGL.GL import GL_RENDERER, GL_VENDOR, GL_SHADING_LANGUAGE_VERSION for d,s,fatal in (("vendor", GL_VENDOR, True), ("renderer", GL_RENDERER, True), ("shading language version", GL_SHADING_LANGUAGE_VERSION, False)): try: v = glGetString(s) debug("%s: %s", d, v) except: if fatal: gl_check_error("OpenGL property '%s' is missing" % d) else: log.warn("OpenGL property '%s' is missing" % d) v = "" props[d] = v from OpenGL.GLU import gluGetString, GLU_VERSION, GLU_EXTENSIONS for d,s in {"GLU version": GLU_VERSION, "GLU extensions":GLU_EXTENSIONS}.items(): v = gluGetString(s) debug("%s: %s", d, v) props[d] = v for k,vlist in BLACKLIST.items(): v = props.get(k) if v in vlist: if force_enable: log.warn("Warning: %s '%s' is blacklisted!", k, v) else: gl_check_error("%s '%s' is blacklisted!" % (k, v)) #check for specific functions we need: from OpenGL.GL import glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd check_functions(glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd) #check for framebuffer functions we need: from OpenGL.GL.ARB.framebuffer_object import GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D check_functions(GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D) for ext in required_extensions: if ext not in extensions: gl_check_error("OpenGL driver lacks support for extension: %s" % ext) else: debug("Extension %s is present", ext) #this allows us to do CSC via OpenGL: #see http://www.opengl.org/registry/specs/ARB/fragment_program.txt from OpenGL.GL.ARB.fragment_program import glInitFragmentProgramARB if not glInitFragmentProgramARB(): gl_check_error("OpenGL output requires glInitFragmentProgramARB") else: debug("glInitFragmentProgramARB works") from OpenGL.GL.ARB.texture_rectangle import glInitTextureRectangleARB if not glInitTextureRectangleARB(): gl_check_error("OpenGL output requires glInitTextureRectangleARB") else: debug("glInitTextureRectangleARB works") from OpenGL.GL.ARB.vertex_program import glGenProgramsARB, glDeleteProgramsARB, \ glBindProgramARB, glProgramStringARB check_functions(glGenProgramsARB, glDeleteProgramsARB, glBindProgramARB, glProgramStringARB) from OpenGL.GL import GL_MAX_RECTANGLE_TEXTURE_SIZE, GL_MAX_TEXTURE_SIZE texture_size = glGetInteger(GL_MAX_TEXTURE_SIZE) rect_texture_size = glGetInteger(GL_MAX_RECTANGLE_TEXTURE_SIZE) if min_texture_size>texture_size or min_texture_size>rect_texture_size: gl_check_error("The texture size is too small: %s" % texture_size) else: debug("Texture size GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB=%s, GL_MAX_TEXTURE_SIZE=%s", rect_texture_size, texture_size) return props finally: if SILENCE_FORMAT_HANDLER_LOGGER: try: logging.getLogger('OpenGL.formathandler').setLevel(logging.INFO) except: pass gldrawable.gl_end()
def check_GL_support(gldrawable, glcontext, min_texture_size=0, force_enable=False): if not gldrawable.gl_begin(glcontext): raise ImportError("gl_begin failed on %s" % gldrawable) props = {} try: #log redirection: def redirect_log(logger_name): logger = logging.getLogger(logger_name) assert logger is not None logger.saved_handlers = logger.handlers logger.saved_propagate = logger.propagate logger.handlers = [CaptureHandler()] logger.propagate = 0 return logger fhlogger = redirect_log('OpenGL.formathandler') elogger = redirect_log('OpenGL.extensions') alogger = redirect_log('OpenGL.acceleratesupport') arlogger = redirect_log('OpenGL.arrays') clogger = redirect_log('OpenGL.converters') import OpenGL props["pyopengl"] = OpenGL.__version__ from OpenGL.GL import GL_VERSION, GL_EXTENSIONS from OpenGL.GL import glGetString, glGetInteger gl_version_str = glGetString(GL_VERSION) if gl_version_str is None: gl_check_error("OpenGL version is missing - cannot continue") return {} gl_major = int(gl_version_str[0]) gl_minor = int(gl_version_str[2]) props["opengl"] = gl_major, gl_minor MIN_VERSION = (1, 1) if (gl_major, gl_minor) < MIN_VERSION: gl_check_error( "OpenGL output requires version %s or greater, not %s.%s" % (".".join([str(x) for x in MIN_VERSION]), gl_major, gl_minor)) else: log("found valid OpenGL version: %s.%s", gl_major, gl_minor) try: extensions = glGetString(GL_EXTENSIONS).split(" ") except: gl_check_error( "OpenGL could not find the list of GL extensions - does the graphics driver support OpenGL?" ) log("OpenGL extensions found: %s", ", ".join(extensions)) props["extensions"] = extensions from OpenGL.arrays.arraydatatype import ArrayDatatype try: log("found the following array handlers: %s", set(ArrayDatatype.getRegistry().values())) except: pass from OpenGL.GL import GL_RENDERER, GL_VENDOR, GL_SHADING_LANGUAGE_VERSION for d, s, fatal in (("vendor", GL_VENDOR, True), ("renderer", GL_RENDERER, True), ("shading language version", GL_SHADING_LANGUAGE_VERSION, False)): try: v = glGetString(s) log("%s: %s", d, v) except: if fatal: gl_check_error("OpenGL property '%s' is missing" % d) else: log.warn("OpenGL property '%s' is missing" % d) v = "" props[d] = v from OpenGL.GLU import gluGetString, GLU_VERSION, GLU_EXTENSIONS for d, s in { "GLU version": GLU_VERSION, "GLU extensions": GLU_EXTENSIONS }.items(): v = gluGetString(s) log("%s: %s", d, v) props[d] = v for k, vlist in BLACKLIST.items(): v = props.get(k) if v in vlist: if force_enable: log.warn("Warning: %s '%s' is blacklisted!", k, v) else: gl_check_error("%s '%s' is blacklisted!" % (k, v)) #check for specific functions we need: from OpenGL.GL import glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd check_functions(glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd) glEnablei = None try: from OpenGL.GL import glEnablei except: pass if not bool(glEnablei): log.warn( "OpenGL glEnablei is not available, disabling transparency") global GL_ALPHA_SUPPORTED GL_ALPHA_SUPPORTED = False #check for framebuffer functions we need: from OpenGL.GL.ARB.framebuffer_object import GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D check_functions(GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D) for ext in required_extensions: if ext not in extensions: gl_check_error( "OpenGL driver lacks support for extension: %s" % ext) else: log("Extension %s is present", ext) #this allows us to do CSC via OpenGL: #see http://www.opengl.org/registry/specs/ARB/fragment_program.txt from OpenGL.GL.ARB.fragment_program import glInitFragmentProgramARB if not glInitFragmentProgramARB(): gl_check_error("OpenGL output requires glInitFragmentProgramARB") else: log("glInitFragmentProgramARB works") from OpenGL.GL.ARB.texture_rectangle import glInitTextureRectangleARB if not glInitTextureRectangleARB(): gl_check_error("OpenGL output requires glInitTextureRectangleARB") else: log("glInitTextureRectangleARB works") from OpenGL.GL.ARB.vertex_program import glGenProgramsARB, glDeleteProgramsARB, \ glBindProgramARB, glProgramStringARB check_functions(glGenProgramsARB, glDeleteProgramsARB, glBindProgramARB, glProgramStringARB) try: from OpenGL.GL import GL_MAX_TEXTURE_SIZE texture_size = glGetInteger(GL_MAX_TEXTURE_SIZE) #this one may be missing? rect_texture_size = texture_size try: from OpenGL.GL import GL_MAX_RECTANGLE_TEXTURE_SIZE rect_texture_size = glGetInteger(GL_MAX_RECTANGLE_TEXTURE_SIZE) except ImportError, e: log("OpenGL: %s", e) log("using GL_MAX_TEXTURE_SIZE=%s as default", texture_size) except Exception, e: emsg = str(e) if hasattr(e, "description"): emsg = e.description gl_check_error("unable to query max texture size: %s" % emsg) return props if min_texture_size > texture_size or min_texture_size > rect_texture_size: gl_check_error("The texture size is too small: %s" % texture_size) else: log( "Texture size GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB=%s, GL_MAX_TEXTURE_SIZE=%s", rect_texture_size, texture_size) return props
def dimensions(self, value, typeCode=None): """Determine dimensions of the passed array value (if possible)""" return ArrayDatatype.dimensions(value.data)
def initializeGL(self): self.initGeometry() self.vertex_code = """ #version 120 //attribute vec4 color; attribute float x_position; attribute float y_position; //varying vec4 v_color; void main() { gl_Position = vec4(x_position, y_position, 0.0, 1.0); //v_color = color; } """ self.fragment_code = """ #version 120 //varying vec4 v_color; void main() { //gl_FragColor = v_color; gl_FragColor = vec4(1,1,1,1); } """ ## Build and activate program # Request program and shader slots from GPU self.program = GL.glCreateProgram() self.vertex = GL.glCreateShader(GL.GL_VERTEX_SHADER) self.fragment = GL.glCreateShader(GL.GL_FRAGMENT_SHADER) # Set shaders source GL.glShaderSource(self.vertex, self.vertex_code) GL.glShaderSource(self.fragment, self.fragment_code) # Compile shaders GL.glCompileShader(self.vertex) GL.glCompileShader(self.fragment) # Attach shader objects to the program GL.glAttachShader(self.program, self.vertex) GL.glAttachShader(self.program, self.fragment) #GL.glBindAttribLocation(self.program, 0, "x_position1".encode('utf-8')) #GL.glBindAttribLocation(self.program, 1, "y_position1".encode('utf-8')) # Build program GL.glLinkProgram(self.program) # Get rid of shaders (not needed anymore) GL.glDetachShader(self.program, self.vertex) GL.glDetachShader(self.program, self.fragment) # Make program the default program GL.glUseProgram(self.program) # Create array object self.vao = GL.glGenVertexArrays(1) GL.glBindVertexArray(self.vao) # Request buffer slot from GPU self.x_data_buffer = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.x_data_buffer) GL.glBufferData(GL.GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(self.x), self.x, GL.GL_DYNAMIC_DRAW) self.y_data_buffer = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.y_data_buffer) GL.glBufferData(GL.GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(self.y), self.y, GL.GL_DYNAMIC_DRAW) ## Bind attributes #self.stride = self.x.strides[0] #self.offset = ctypes.c_void_p(0) self.loc = GL.glGetAttribLocation(self.program, "x_position".encode('utf-8')) print(self.loc) GL.glEnableVertexAttribArray(self.loc) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.x_data_buffer) GL.glVertexAttribPointer(self.loc, 1, GL.GL_FLOAT, GL.GL_FALSE, 0, 0) #self.stride = self.y.strides[0] #self.offset = ctypes.c_void_p(0) self.loc = GL.glGetAttribLocation(self.program, "y_position".encode('utf-8')) print(self.loc) GL.glEnableVertexAttribArray(self.loc) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.y_data_buffer) GL.glVertexAttribPointer(self.loc, 1, GL.GL_FLOAT, GL.GL_FALSE, 0, 0)
def arrayToGLType(self, value): """Given a value, guess OpenGL type of the corresponding pointer""" return ArrayDatatype.arrayToGLType(value.data)
def arraySize(self, value, typeCode=None): """Given a data-value, calculate dimensions for the array""" return ArrayDatatype.arraySize(value.data)
def unitSize( self, value, typeCode=None ): """Determine unit size of an array (if possible)""" return ArrayDatatype.unitSize( value.data )
def arrayByteCount( self, value ): return ArrayDatatype.arrayByteCount( value.data )
def register(self, types=None): """Register this class as handler for given set of types""" from OpenGL.arrays.arraydatatype import ArrayDatatype ArrayDatatype.getRegistry().register(self, types)
def registerReturn(self): """Register this handler as the default return-type handler""" from OpenGL.arrays.arraydatatype import ArrayDatatype ArrayDatatype.getRegistry().registerReturn(self)
def check_PyOpenGL_support(force_enable): props = {} try: if CRASH: import ctypes ctypes.string_at(0) raise Exception("should have crashed!") elif TIMEOUT > 0: import time time.sleep(TIMEOUT) #log redirection: def redirect_log(logger_name): logger = logging.getLogger(logger_name) assert logger is not None logger.saved_handlers = logger.handlers logger.saved_propagate = logger.propagate logger.handlers = [CaptureHandler()] logger.propagate = 0 return logger fhlogger = redirect_log('OpenGL.formathandler') elogger = redirect_log('OpenGL.extensions') alogger = redirect_log('OpenGL.acceleratesupport') arlogger = redirect_log('OpenGL.arrays') clogger = redirect_log('OpenGL.converters') import OpenGL props["pyopengl"] = OpenGL.__version__ from OpenGL.GL import GL_VERSION, GL_EXTENSIONS from OpenGL.GL import glGetString, glGetInteger, glGetIntegerv gl_version_str = glGetString(GL_VERSION) if gl_version_str is None: raise_fatal_error("OpenGL version is missing - cannot continue") return {} gl_major = int(bytestostr(gl_version_str)[0]) gl_minor = int(bytestostr(gl_version_str)[2]) props["opengl"] = gl_major, gl_minor MIN_VERSION = (1, 1) if (gl_major, gl_minor) < MIN_VERSION: raise_fatal_error( "OpenGL output requires version %s or greater, not %s.%s" % (".".join([str(x) for x in MIN_VERSION]), gl_major, gl_minor)) else: log("found valid OpenGL version: %s.%s", gl_major, gl_minor) from OpenGL import version as OpenGL_version pyopengl_version = OpenGL_version.__version__ try: import OpenGL_accelerate #@UnresolvedImport accel_version = OpenGL_accelerate.__version__ props["accelerate"] = accel_version log("OpenGL_accelerate version %s", accel_version) except: log("OpenGL_accelerate not found") OpenGL_accelerate = None accel_version = None if accel_version is not None and pyopengl_version != accel_version: global _version_warning_shown if not _version_warning_shown: log.warn( "Warning: version mismatch between PyOpenGL and PyOpenGL-accelerate" ) log.warn(" %s vs %s", pyopengl_version, accel_version) log.warn(" this may cause crashes") _version_warning_shown = True gl_check_error( "PyOpenGL vs accelerate version mismatch: %s vs %s" % (pyopengl_version, accel_version)) vsplit = pyopengl_version.split('.') #we now require PyOpenGL 3.1 or later if vsplit[:3] < ['3', '1'] and not force_enable: raise_fatal_error("PyOpenGL version %s is too old and buggy" % pyopengl_version) return {} props["zerocopy"] = bool( OpenGL_accelerate) and is_pyopengl_memoryview_safe( pyopengl_version, accel_version) try: extensions = glGetString(GL_EXTENSIONS).decode().split(" ") except: log("error querying extensions", exc_info=True) extensions = [] raise_fatal_error( "OpenGL could not find the list of GL extensions - does the graphics driver support OpenGL?" ) log("OpenGL extensions found: %s", csv(extensions)) props["extensions"] = extensions from OpenGL.arrays.arraydatatype import ArrayDatatype try: log("found the following array handlers: %s", set(ArrayDatatype.getRegistry().values())) except: pass from OpenGL.GL import GL_RENDERER, GL_VENDOR, GL_SHADING_LANGUAGE_VERSION def fixstring(v): try: return str(v).strip() except: return str(v) for d, s, fatal in (("vendor", GL_VENDOR, True), ("renderer", GL_RENDERER, True), ("shading-language-version", GL_SHADING_LANGUAGE_VERSION, False)): try: v = glGetString(s) v = fixstring(v.decode()) log("%s: %s", d, v) except: if fatal: gl_check_error("OpenGL property '%s' is missing" % d) else: log("OpenGL property '%s' is missing", d) v = "" props[d] = v vendor = props["vendor"] version_req = VERSION_REQ.get(vendor) if version_req: req_maj, req_min = version_req if gl_major < req_maj or (gl_major == req_maj and gl_minor < req_min): if force_enable: log.warn( "Warning: '%s' OpenGL driver requires version %i.%i", vendor, req_maj, req_min) log.warn(" version %i.%i was found", gl_major, gl_minor) else: gl_check_error( "OpenGL version %i.%i is too old, %i.%i is required for %s" % (gl_major, gl_minor, req_maj, req_min, vendor)) from OpenGL.GLU import gluGetString, GLU_VERSION, GLU_EXTENSIONS for d, s in { "GLU.version": GLU_VERSION, "GLU.extensions": GLU_EXTENSIONS }.items(): v = gluGetString(s) v = v.decode() log("%s: %s", d, v) props[d] = v def match_list(thelist, listname): for k, vlist in thelist.items(): v = props.get(k) matches = [x for x in vlist if v.find(x) >= 0] if matches: log("%s '%s' found in %s: %s", k, v, listname, vlist) return (k, v) log("%s '%s' not found in %s: %s", k, v, listname, vlist) return None blacklisted = match_list(BLACKLIST, "blacklist") greylisted = match_list(GREYLIST, "greylist") whitelisted = match_list(WHITELIST, "whitelist") if blacklisted: if whitelisted: log.info( "%s '%s' enabled (found in both blacklist and whitelist)", *whitelisted) elif force_enable: log.warn("Warning: %s '%s' is blacklisted!", *blacklisted) log.warn(" force enabled by option") else: raise_fatal_error("%s '%s' is blacklisted!" % (blacklisted)) safe = bool(whitelisted) or not bool(blacklisted) if greylisted and not whitelisted: log.warn("Warning: %s '%s' is greylisted,", *greylisted) log.warn(" you may want to turn off OpenGL if you encounter bugs") props["safe"] = safe #check for specific functions we need: from OpenGL.GL import glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, glTexEnvi, glHint, glBlendFunc, glLineStipple, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd check_functions(glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, glTexEnvi, glHint, glBlendFunc, glLineStipple, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd) #check for framebuffer functions we need: from OpenGL.GL.ARB.framebuffer_object import GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D check_functions(GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D) glEnablei = None try: from OpenGL.GL import glEnablei except: pass if not bool(glEnablei): log.warn( "OpenGL glEnablei is not available, disabling transparency") global GL_ALPHA_SUPPORTED GL_ALPHA_SUPPORTED = False props["transparency"] = GL_ALPHA_SUPPORTED for ext in required_extensions: if ext not in extensions: raise_fatal_error( "OpenGL driver lacks support for extension: %s" % ext) else: log("Extension %s is present", ext) #this allows us to do CSC via OpenGL: #see http://www.opengl.org/registry/specs/ARB/fragment_program.txt from OpenGL.GL.ARB.fragment_program import glInitFragmentProgramARB if not glInitFragmentProgramARB(): raise_fatal_error( "OpenGL output requires glInitFragmentProgramARB") else: log("glInitFragmentProgramARB works") from OpenGL.GL.ARB.texture_rectangle import glInitTextureRectangleARB if not glInitTextureRectangleARB(): raise_fatal_error( "OpenGL output requires glInitTextureRectangleARB") else: log("glInitTextureRectangleARB works") from OpenGL.GL.ARB.vertex_program import glGenProgramsARB, glDeleteProgramsARB, \ glBindProgramARB, glProgramStringARB check_functions(glGenProgramsARB, glDeleteProgramsARB, glBindProgramARB, glProgramStringARB) try: from OpenGL.GL import GL_MAX_TEXTURE_SIZE texture_size = glGetInteger(GL_MAX_TEXTURE_SIZE) #this one may be missing? rect_texture_size = texture_size try: from OpenGL.GL import GL_MAX_RECTANGLE_TEXTURE_SIZE rect_texture_size = glGetInteger(GL_MAX_RECTANGLE_TEXTURE_SIZE) except ImportError as e: log("OpenGL: %s", e) log("using GL_MAX_TEXTURE_SIZE=%s as default", texture_size) except Exception as e: emsg = str(e) if hasattr(e, "description"): emsg = e.description gl_check_error("unable to query max texture size: %s" % emsg) return props log( "Texture size GL_MAX_RECTANGLE_TEXTURE_SIZE=%s, GL_MAX_TEXTURE_SIZE=%s", rect_texture_size, texture_size) texture_size_limit = min(rect_texture_size, texture_size) props["texture-size-limit"] = int(texture_size_limit) try: from OpenGL.GL import GL_MAX_VIEWPORT_DIMS v = glGetIntegerv(GL_MAX_VIEWPORT_DIMS) max_viewport_dims = int(v[0]), int(v[1]) assert max_viewport_dims[ 0] >= texture_size_limit and max_viewport_dims[ 1] >= texture_size_limit log("GL_MAX_VIEWPORT_DIMS=%s", max_viewport_dims) except ImportError as e: log.error("Error querying max viewport dims: %s", e) max_viewport_dims = texture_size_limit, texture_size_limit props["max-viewport-dims"] = max_viewport_dims return props finally: for x in alogger.handlers[0].records: #strip default message prefix: msg = x.getMessage().replace( "No OpenGL_accelerate module loaded: ", "") if msg == "No module named OpenGL_accelerate": msg = "missing accelerate module" if msg == "OpenGL_accelerate module loaded": log.info(msg) else: log.warn("PyOpenGL warning: %s", msg) #format handler messages: STRIP_LOG_MESSAGE = "Unable to load registered array format handler " missing_handlers = [] for x in fhlogger.handlers[0].records: msg = x.getMessage() p = msg.find(STRIP_LOG_MESSAGE) if p < 0: #unknown message, log it: log.info(msg) continue format_handler = msg[p + len(STRIP_LOG_MESSAGE):] p = format_handler.find(":") if p > 0: format_handler = format_handler[:p] missing_handlers.append(format_handler) if len(missing_handlers) > 0: log.warn("PyOpenGL warning: missing array format handlers: %s", csv(missing_handlers)) for x in elogger.handlers[0].records: msg = x.getMessage() #ignore extension messages: p = msg.startswith("GL Extension ") and msg.endswith("available") if not p: log.info(msg) missing_accelerators = [] STRIP_AR_HEAD = "Unable to load" STRIP_AR_TAIL = "from OpenGL_accelerate" for x in arlogger.handlers[0].records + clogger.handlers[0].records: msg = x.getMessage() if msg.startswith(STRIP_AR_HEAD) and msg.endswith(STRIP_AR_TAIL): m = msg[len(STRIP_AR_HEAD):-len(STRIP_AR_TAIL)].strip() m = m.replace("accelerators", "").replace("accelerator", "").strip() missing_accelerators.append(m) continue elif msg.startswith("Using accelerated"): log(msg) else: log.info(msg) if missing_accelerators: log.info("OpenGL accelerate missing: %s", csv(missing_accelerators)) def restore_logger(logger): logger.handlers = logger.saved_handlers logger.propagate = logger.saved_propagate restore_logger(fhlogger) restore_logger(elogger) restore_logger(alogger) restore_logger(arlogger) restore_logger(clogger)
def arrayToGLType( self, value ): """Given a value, guess OpenGL type of the corresponding pointer""" return ArrayDatatype.arrayToGLType( value.data )
def registerReturn( self ): """Register this handler as the default return-type handler""" from OpenGL.arrays.arraydatatype import ArrayDatatype ArrayDatatype.getRegistry().registerReturn( self )
def arraySize( self, value, typeCode = None ): """Given a data-value, calculate dimensions for the array""" return ArrayDatatype.arraySize( value.data )
def do_check_GL_support(force_enable): props = {} try: #log redirection: def redirect_log(logger_name): logger = logging.getLogger(logger_name) assert logger is not None logger.saved_handlers = logger.handlers logger.saved_propagate = logger.propagate logger.handlers = [CaptureHandler()] logger.propagate = 0 return logger fhlogger = redirect_log('OpenGL.formathandler') elogger = redirect_log('OpenGL.extensions') alogger = redirect_log('OpenGL.acceleratesupport') arlogger = redirect_log('OpenGL.arrays') clogger = redirect_log('OpenGL.converters') import OpenGL props["pyopengl"] = OpenGL.__version__ from OpenGL.GL import GL_VERSION, GL_EXTENSIONS from OpenGL.GL import glGetString, glGetInteger, glGetIntegerv gl_version_str = glGetString(GL_VERSION) if gl_version_str is None: gl_check_error("OpenGL version is missing - cannot continue") return {} gl_major = int(gl_version_str[0]) gl_minor = int(gl_version_str[2]) props["opengl"] = gl_major, gl_minor MIN_VERSION = (1,1) if (gl_major, gl_minor) < MIN_VERSION: gl_check_error("OpenGL output requires version %s or greater, not %s.%s" % (".".join([str(x) for x in MIN_VERSION]), gl_major, gl_minor)) else: log("found valid OpenGL version: %s.%s", gl_major, gl_minor) from OpenGL import version as OpenGL_version pyopengl_version = OpenGL_version.__version__ try: import OpenGL_accelerate accel_version = OpenGL_accelerate.__version__ props["accelerate"] = accel_version log("OpenGL_accelerate version %s", accel_version) except: log("OpenGL_accelerate not found") OpenGL_accelerate = None accel_version = None if accel_version is not None and pyopengl_version!=accel_version: global _version_warning_shown if not _version_warning_shown: log.warn("Warning: version mismatch between PyOpenGL and PyOpenGL-accelerate") log.warn(" this may cause crashes") _version_warning_shown = True vsplit = pyopengl_version.split('.') #we now require PyOpenGL 3.1 or later if vsplit[:2]<['3','1'] and not force_enable: gl_check_error("PyOpenGL version 3.1 or later is required (found version %s)" % pyopengl_version) return {} props["zerocopy"] = bool(OpenGL_accelerate) and is_pyopengl_memoryview_safe(pyopengl_version, accel_version) try: extensions = glGetString(GL_EXTENSIONS).decode().split(" ") except: log("error querying extensions", exc_info=True) extensions = [] gl_check_error("OpenGL could not find the list of GL extensions - does the graphics driver support OpenGL?") log("OpenGL extensions found: %s", ", ".join(extensions)) props["extensions"] = extensions from OpenGL.arrays.arraydatatype import ArrayDatatype try: log("found the following array handlers: %s", set(ArrayDatatype.getRegistry().values())) except: pass from OpenGL.GL import GL_RENDERER, GL_VENDOR, GL_SHADING_LANGUAGE_VERSION def fixstring(v): try: return str(v).strip() except: return str(v) for d,s,fatal in (("vendor", GL_VENDOR, True), ("renderer", GL_RENDERER, True), ("shading language version", GL_SHADING_LANGUAGE_VERSION, False)): try: v = glGetString(s) v = fixstring(v.decode()) log("%s: %s", d, v) except: if fatal: gl_check_error("OpenGL property '%s' is missing" % d) else: log("OpenGL property '%s' is missing", d) v = "" props[d] = v vendor = props["vendor"] version_req = VERSION_REQ.get(vendor) if version_req: req_maj, req_min = version_req if gl_major<req_maj or (gl_major==req_maj and gl_minor<req_min): if force_enable: log.warn("Warning: '%s' OpenGL driver requires version %i.%i", vendor, req_maj, req_min) log.warn(" version %i.%i was found", gl_major, gl_minor) else: gl_check_error("OpenGL version %i.%i is too old, %i.%i is required for %s" % (gl_major, gl_minor, req_maj, req_min, vendor)) from OpenGL.GLU import gluGetString, GLU_VERSION, GLU_EXTENSIONS for d,s in {"GLU version": GLU_VERSION, "GLU extensions":GLU_EXTENSIONS}.items(): v = gluGetString(s) v = v.decode() log("%s: %s", d, v) props[d] = v blacklisted = None whitelisted = None greylisted = None for k,vlist in BLACKLIST.items(): v = props.get(k) if v in vlist: log("%s '%s' found in blacklist: %s", k, v, vlist) blacklisted = k, v for k,vlist in GREYLIST.items(): v = props.get(k) if v in vlist: log("%s '%s' found in greylist: %s", k, v, vlist) greylisted = k, v for k,vlist in WHITELIST.items(): v = props.get(k) if v in vlist: log("%s '%s' found in whitelist: %s", k, v, vlist) whitelisted = k, v if blacklisted: if whitelisted: log.info("%s '%s' enabled (found in both blacklist and whitelist)", *whitelisted) elif force_enable: log.warn("Warning: %s '%s' is blacklisted!", *blacklisted) else: gl_check_error("%s '%s' is blacklisted!" % (blacklisted)) safe = bool(whitelisted) or not (bool(greylisted) or bool(blacklisted)) if safe and sys.version_info[0]>2: log.warn("Warning: OpenGL python3 support is not enabled by default") safe = False props["safe"] = safe #check for specific functions we need: from OpenGL.GL import glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, glTexEnvi, glHint, glBlendFunc, glLineStipple, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd check_functions(glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, glTexEnvi, glHint, glBlendFunc, glLineStipple, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd) glEnablei = None try: from OpenGL.GL import glEnablei except: pass if not bool(glEnablei): log.warn("OpenGL glEnablei is not available, disabling transparency") global GL_ALPHA_SUPPORTED GL_ALPHA_SUPPORTED = False props["transparency"] = GL_ALPHA_SUPPORTED #check for framebuffer functions we need: from OpenGL.GL.ARB.framebuffer_object import GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D check_functions(GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D) for ext in required_extensions: if ext not in extensions: gl_check_error("OpenGL driver lacks support for extension: %s" % ext) else: log("Extension %s is present", ext) #this allows us to do CSC via OpenGL: #see http://www.opengl.org/registry/specs/ARB/fragment_program.txt from OpenGL.GL.ARB.fragment_program import glInitFragmentProgramARB if not glInitFragmentProgramARB(): gl_check_error("OpenGL output requires glInitFragmentProgramARB") else: log("glInitFragmentProgramARB works") from OpenGL.GL.ARB.texture_rectangle import glInitTextureRectangleARB if not glInitTextureRectangleARB(): gl_check_error("OpenGL output requires glInitTextureRectangleARB") else: log("glInitTextureRectangleARB works") from OpenGL.GL.ARB.vertex_program import glGenProgramsARB, glDeleteProgramsARB, \ glBindProgramARB, glProgramStringARB check_functions(glGenProgramsARB, glDeleteProgramsARB, glBindProgramARB, glProgramStringARB) try: from OpenGL.GL import GL_MAX_TEXTURE_SIZE texture_size = glGetInteger(GL_MAX_TEXTURE_SIZE) #this one may be missing? rect_texture_size = texture_size try: from OpenGL.GL import GL_MAX_RECTANGLE_TEXTURE_SIZE rect_texture_size = glGetInteger(GL_MAX_RECTANGLE_TEXTURE_SIZE) except ImportError as e: log("OpenGL: %s", e) log("using GL_MAX_TEXTURE_SIZE=%s as default", texture_size) except Exception as e: emsg = str(e) if hasattr(e, "description"): emsg = e.description gl_check_error("unable to query max texture size: %s" % emsg) return props log("Texture size GL_MAX_RECTANGLE_TEXTURE_SIZE=%s, GL_MAX_TEXTURE_SIZE=%s", rect_texture_size, texture_size) texture_size_limit = min(rect_texture_size, texture_size) props["texture-size-limit"] = texture_size_limit try: from OpenGL.GL import GL_MAX_VIEWPORT_DIMS v = glGetIntegerv(GL_MAX_VIEWPORT_DIMS) max_viewport_dims = v[0], v[1] assert max_viewport_dims[0]>=texture_size_limit and max_viewport_dims[1]>=texture_size_limit log("GL_MAX_VIEWPORT_DIMS=%s", max_viewport_dims) except ImportError as e: log.error("Error querying max viewport dims: %s", e) max_viewport_dims = texture_size_limit, texture_size_limit props["max-viewport-dims"] = max_viewport_dims return props finally: for x in alogger.handlers[0].records: #strip default message prefix: msg = x.getMessage().replace("No OpenGL_accelerate module loaded: ", "") if msg=="No module named OpenGL_accelerate": msg = "missing accelerate module" if msg!="OpenGL_accelerate module loaded": msg = "PyOpenGL warning: %s" % msg log.info(msg) #format handler messages: STRIP_LOG_MESSAGE = "Unable to load registered array format handler " missing_handlers = [] for x in fhlogger.handlers[0].records: msg = x.getMessage() p = msg.find(STRIP_LOG_MESSAGE) if p<0: #unknown message, log it: log.info(msg) continue format_handler = msg[p+len(STRIP_LOG_MESSAGE):] p = format_handler.find(":") if p>0: format_handler = format_handler[:p] missing_handlers.append(format_handler) if len(missing_handlers)>0: log.warn("PyOpenGL warning: missing array format handlers: %s", ", ".join(missing_handlers)) for x in elogger.handlers[0].records: msg = x.getMessage() #ignore extension messages: p = msg.startswith("GL Extension ") and msg.endswith("available") if not p: log.info(msg) missing_accelerators = [] STRIP_AR_HEAD = "Unable to load" STRIP_AR_TAIL = "from OpenGL_accelerate" for x in arlogger.handlers[0].records+clogger.handlers[0].records: msg = x.getMessage() if msg.startswith(STRIP_AR_HEAD) and msg.endswith(STRIP_AR_TAIL): m = msg[len(STRIP_AR_HEAD):-len(STRIP_AR_TAIL)].strip() m = m.replace("accelerators", "").replace("accelerator", "").strip() missing_accelerators.append(m) continue elif msg.startswith("Using accelerated"): log(msg) else: log.info(msg) if missing_accelerators: log.info("OpenGL accelerate missing: %s", ", ".join(missing_accelerators)) def restore_logger(logger): logger.handlers = logger.saved_handlers logger.propagate = logger.saved_propagate restore_logger(fhlogger) restore_logger(elogger) restore_logger(alogger) restore_logger(arlogger) restore_logger(clogger)
def dimensions( self, value, typeCode=None ): """Determine dimensions of the passed array value (if possible)""" return ArrayDatatype.dimensions( value.data )
def do_check_GL_support(force_enable): props = {} try: #log redirection: def redirect_log(logger_name): logger = logging.getLogger(logger_name) assert logger is not None logger.saved_handlers = logger.handlers logger.saved_propagate = logger.propagate logger.handlers = [CaptureHandler()] logger.propagate = 0 return logger fhlogger = redirect_log('OpenGL.formathandler') elogger = redirect_log('OpenGL.extensions') alogger = redirect_log('OpenGL.acceleratesupport') arlogger = redirect_log('OpenGL.arrays') clogger = redirect_log('OpenGL.converters') import OpenGL props["pyopengl"] = OpenGL.__version__ from OpenGL.GL import GL_VERSION, GL_EXTENSIONS from OpenGL.GL import glGetString, glGetInteger gl_version_str = glGetString(GL_VERSION) if gl_version_str is None: gl_check_error("OpenGL version is missing - cannot continue") return {} gl_major = int(gl_version_str[0]) gl_minor = int(gl_version_str[2]) props["opengl"] = gl_major, gl_minor MIN_VERSION = (1, 1) if (gl_major, gl_minor) < MIN_VERSION: gl_check_error( "OpenGL output requires version %s or greater, not %s.%s" % (".".join([str(x) for x in MIN_VERSION]), gl_major, gl_minor)) else: log("found valid OpenGL version: %s.%s", gl_major, gl_minor) from OpenGL import version as OpenGL_version try: import OpenGL_accelerate except: OpenGL_accelerate = None props["zerocopy"] = is_pyopengl_memoryview_safe( OpenGL_version.__version__) and bool(OpenGL_accelerate) try: extensions = glGetString(GL_EXTENSIONS).decode().split(" ") except: log("error querying extensions", exc_info=True) extensions = [] gl_check_error( "OpenGL could not find the list of GL extensions - does the graphics driver support OpenGL?" ) log("OpenGL extensions found: %s", ", ".join(extensions)) props["extensions"] = extensions from OpenGL.arrays.arraydatatype import ArrayDatatype try: log("found the following array handlers: %s", set(ArrayDatatype.getRegistry().values())) except: pass from OpenGL.GL import GL_RENDERER, GL_VENDOR, GL_SHADING_LANGUAGE_VERSION for d, s, fatal in (("vendor", GL_VENDOR, True), ("renderer", GL_RENDERER, True), ("shading language version", GL_SHADING_LANGUAGE_VERSION, False)): try: v = glGetString(s) v = v.decode() log("%s: %s", d, v) except: if fatal: gl_check_error("OpenGL property '%s' is missing" % d) else: log("OpenGL property '%s' is missing", d) v = "" props[d] = v from OpenGL.GLU import gluGetString, GLU_VERSION, GLU_EXTENSIONS for d, s in { "GLU version": GLU_VERSION, "GLU extensions": GLU_EXTENSIONS }.items(): v = gluGetString(s) v = v.decode() log("%s: %s", d, v) props[d] = v blacklisted = None whitelisted = None greylisted = None for k, vlist in BLACKLIST.items(): v = props.get(k) if v in vlist: log("%s '%s' found in blacklist: %s", k, v, vlist) blacklisted = k, v for k, vlist in GREYLIST.items(): v = props.get(k) if v in vlist: log("%s '%s' found in greylist: %s", k, v, vlist) greylisted = k, v for k, vlist in WHITELIST.items(): v = props.get(k) if v in vlist: log("%s '%s' found in whitelist: %s", k, v, vlist) whitelisted = k, v if blacklisted: if whitelisted: log.info( "%s '%s' enabled (found in both blacklist and whitelist)", *whitelisted) elif force_enable: log.warn("Warning: %s '%s' is blacklisted!", *blacklisted) else: gl_check_error("%s '%s' is blacklisted!" % (blacklisted)) safe = bool(whitelisted) or not (bool(greylisted) or bool(blacklisted)) if safe and sys.version_info[0] > 2: log.warn( "Warning: OpenGL python3 support is not enabled by default") safe = False props["safe"] = safe #check for specific functions we need: from OpenGL.GL import glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, glTexEnvi, glHint, glBlendFunc, glLineStipple, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd check_functions(glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, glTexEnvi, glHint, glBlendFunc, glLineStipple, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd) glEnablei = None try: from OpenGL.GL import glEnablei except: pass if not bool(glEnablei): log.warn( "OpenGL glEnablei is not available, disabling transparency") global GL_ALPHA_SUPPORTED GL_ALPHA_SUPPORTED = False #check for framebuffer functions we need: from OpenGL.GL.ARB.framebuffer_object import GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D check_functions(GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D) for ext in required_extensions: if ext not in extensions: gl_check_error( "OpenGL driver lacks support for extension: %s" % ext) else: log("Extension %s is present", ext) #this allows us to do CSC via OpenGL: #see http://www.opengl.org/registry/specs/ARB/fragment_program.txt from OpenGL.GL.ARB.fragment_program import glInitFragmentProgramARB if not glInitFragmentProgramARB(): gl_check_error("OpenGL output requires glInitFragmentProgramARB") else: log("glInitFragmentProgramARB works") from OpenGL.GL.ARB.texture_rectangle import glInitTextureRectangleARB if not glInitTextureRectangleARB(): gl_check_error("OpenGL output requires glInitTextureRectangleARB") else: log("glInitTextureRectangleARB works") from OpenGL.GL.ARB.vertex_program import glGenProgramsARB, glDeleteProgramsARB, \ glBindProgramARB, glProgramStringARB check_functions(glGenProgramsARB, glDeleteProgramsARB, glBindProgramARB, glProgramStringARB) try: from OpenGL.GL import GL_MAX_TEXTURE_SIZE texture_size = glGetInteger(GL_MAX_TEXTURE_SIZE) #this one may be missing? rect_texture_size = texture_size try: from OpenGL.GL import GL_MAX_RECTANGLE_TEXTURE_SIZE rect_texture_size = glGetInteger(GL_MAX_RECTANGLE_TEXTURE_SIZE) except ImportError as e: log("OpenGL: %s", e) log("using GL_MAX_TEXTURE_SIZE=%s as default", texture_size) except Exception as e: emsg = str(e) if hasattr(e, "description"): emsg = e.description gl_check_error("unable to query max texture size: %s" % emsg) return props log( "Texture size GL_MAX_RECTANGLE_TEXTURE_SIZE=%s, GL_MAX_TEXTURE_SIZE=%s", rect_texture_size, texture_size) props["texture-size-limit"] = min(rect_texture_size, texture_size) return props finally: for x in alogger.handlers[0].records: #strip default message prefix: msg = x.getMessage().replace( "No OpenGL_accelerate module loaded: ", "") if msg == "No module named OpenGL_accelerate": msg = "missing accelerate module" if msg != "OpenGL_accelerate module loaded": msg = "PyOpenGL warning: %s" % msg log.info(msg) #format handler messages: STRIP_LOG_MESSAGE = "Unable to load registered array format handler " missing_handlers = [] for x in fhlogger.handlers[0].records: msg = x.getMessage() p = msg.find(STRIP_LOG_MESSAGE) if p < 0: #unknown message, log it: log.info(msg) continue format_handler = msg[p + len(STRIP_LOG_MESSAGE):] p = format_handler.find(":") if p > 0: format_handler = format_handler[:p] missing_handlers.append(format_handler) if len(missing_handlers) > 0: log.warn("PyOpenGL warning: missing array format handlers: %s", ", ".join(missing_handlers)) for x in elogger.handlers[0].records: msg = x.getMessage() #ignore extension messages: p = msg.startswith("GL Extension ") and msg.endswith("available") if not p: log.info(msg) missing_accelerators = [] STRIP_AR_HEAD = "Unable to load" STRIP_AR_TAIL = "from OpenGL_accelerate" for x in arlogger.handlers[0].records + clogger.handlers[0].records: msg = x.getMessage() if msg.startswith(STRIP_AR_HEAD) and msg.endswith(STRIP_AR_TAIL): m = msg[len(STRIP_AR_HEAD):-len(STRIP_AR_TAIL)].strip() m = m.replace("accelerators", "").replace("accelerator", "").strip() missing_accelerators.append(m) continue log.info(msg) if missing_accelerators: log.info("OpenGL accelerate missing: %s", ", ".join(missing_accelerators)) def restore_logger(logger): logger.handlers = logger.saved_handlers logger.propagate = logger.saved_propagate restore_logger(fhlogger) restore_logger(elogger) restore_logger(alogger) restore_logger(arlogger) restore_logger(clogger)
def arrayByteCount(self, value): return ArrayDatatype.arrayByteCount(value.data)
def check_GL_support(gldrawable, glcontext, min_texture_size=0, force_enable=False): if not gldrawable.gl_begin(glcontext): raise ImportError("gl_begin failed on %s" % gldrawable) props = {} try: #log redirection: def redirect_log(logger_name): logger = logging.getLogger(logger_name) assert logger is not None logger.saved_handlers = logger.handlers logger.saved_propagate = logger.propagate logger.handlers = [CaptureHandler()] logger.propagate = 0 return logger fhlogger = redirect_log('OpenGL.formathandler') elogger = redirect_log('OpenGL.extensions') alogger = redirect_log('OpenGL.acceleratesupport') arlogger = redirect_log('OpenGL.arrays') clogger = redirect_log('OpenGL.converters') import OpenGL props["pyopengl"] = OpenGL.__version__ from OpenGL.GL import GL_VERSION, GL_EXTENSIONS from OpenGL.GL import glGetString, glGetInteger gl_version_str = glGetString(GL_VERSION) if gl_version_str is None: gl_check_error("OpenGL version is missing - cannot continue") return {} gl_major = int(gl_version_str[0]) gl_minor = int(gl_version_str[2]) props["opengl"] = gl_major, gl_minor MIN_VERSION = (1,1) if (gl_major, gl_minor) < MIN_VERSION: gl_check_error("OpenGL output requires version %s or greater, not %s.%s" % (".".join([str(x) for x in MIN_VERSION]), gl_major, gl_minor)) else: log("found valid OpenGL version: %s.%s", gl_major, gl_minor) from OpenGL import version as OpenGL_version try: import OpenGL_accelerate except: OpenGL_accelerate = None props["zerocopy"] = is_pyopengl_memoryview_safe(OpenGL_version.__version__) and bool(OpenGL_accelerate) try: extensions = glGetString(GL_EXTENSIONS).split(" ") except: extensions = [] gl_check_error("OpenGL could not find the list of GL extensions - does the graphics driver support OpenGL?") log("OpenGL extensions found: %s", ", ".join(extensions)) props["extensions"] = extensions from OpenGL.arrays.arraydatatype import ArrayDatatype try: log("found the following array handlers: %s", set(ArrayDatatype.getRegistry().values())) except: pass from OpenGL.GL import GL_RENDERER, GL_VENDOR, GL_SHADING_LANGUAGE_VERSION for d,s,fatal in (("vendor", GL_VENDOR, True), ("renderer", GL_RENDERER, True), ("shading language version", GL_SHADING_LANGUAGE_VERSION, False)): try: v = glGetString(s) log("%s: %s", d, v) except: if fatal: gl_check_error("OpenGL property '%s' is missing" % d) else: log("OpenGL property '%s' is missing", d) v = "" props[d] = v from OpenGL.GLU import gluGetString, GLU_VERSION, GLU_EXTENSIONS for d,s in {"GLU version": GLU_VERSION, "GLU extensions":GLU_EXTENSIONS}.items(): v = gluGetString(s) log("%s: %s", d, v) props[d] = v blacklisted = None whitelisted = None for k,vlist in BLACKLIST.items(): v = props.get(k) if v in vlist: log("%s '%s' found in blacklist: %s", k, v, vlist) blacklisted = k, v for k,vlist in WHITELIST.items(): v = props.get(k) if v in vlist: log("%s '%s' found in whitelist: %s", k, v, vlist) whitelisted = k, v if blacklisted: if whitelisted: log.info("%s '%s' enabled (found in both blacklist and whitelist)", *whitelisted) elif force_enable: log.warn("Warning: %s '%s' is blacklisted!", *blacklisted) else: gl_check_error("%s '%s' is blacklisted!" % (blacklisted)) #check for specific functions we need: from OpenGL.GL import glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, glTexEnvi, glHint, glBlendFunc, glLineStipple, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd check_functions(glActiveTexture, glTexSubImage2D, glTexCoord2i, \ glViewport, glMatrixMode, glLoadIdentity, glOrtho, \ glEnableClientState, glGenTextures, glDisable, \ glBindTexture, glPixelStorei, glEnable, glBegin, glFlush, \ glTexParameteri, glTexEnvi, glHint, glBlendFunc, glLineStipple, \ glTexImage2D, \ glMultiTexCoord2i, \ glVertex2i, glEnd) glEnablei = None try: from OpenGL.GL import glEnablei except: pass if not bool(glEnablei): log.warn("OpenGL glEnablei is not available, disabling transparency") global GL_ALPHA_SUPPORTED GL_ALPHA_SUPPORTED = False #check for framebuffer functions we need: from OpenGL.GL.ARB.framebuffer_object import GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D check_functions(GL_FRAMEBUFFER, \ GL_COLOR_ATTACHMENT0, glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D) for ext in required_extensions: if ext not in extensions: gl_check_error("OpenGL driver lacks support for extension: %s" % ext) else: log("Extension %s is present", ext) #this allows us to do CSC via OpenGL: #see http://www.opengl.org/registry/specs/ARB/fragment_program.txt from OpenGL.GL.ARB.fragment_program import glInitFragmentProgramARB if not glInitFragmentProgramARB(): gl_check_error("OpenGL output requires glInitFragmentProgramARB") else: log("glInitFragmentProgramARB works") from OpenGL.GL.ARB.texture_rectangle import glInitTextureRectangleARB if not glInitTextureRectangleARB(): gl_check_error("OpenGL output requires glInitTextureRectangleARB") else: log("glInitTextureRectangleARB works") from OpenGL.GL.ARB.vertex_program import glGenProgramsARB, glDeleteProgramsARB, \ glBindProgramARB, glProgramStringARB check_functions(glGenProgramsARB, glDeleteProgramsARB, glBindProgramARB, glProgramStringARB) try: from OpenGL.GL import GL_MAX_TEXTURE_SIZE texture_size = glGetInteger(GL_MAX_TEXTURE_SIZE) #this one may be missing? rect_texture_size = texture_size try: from OpenGL.GL import GL_MAX_RECTANGLE_TEXTURE_SIZE rect_texture_size = glGetInteger(GL_MAX_RECTANGLE_TEXTURE_SIZE) except ImportError, e: log("OpenGL: %s", e) log("using GL_MAX_TEXTURE_SIZE=%s as default", texture_size) except Exception, e: emsg = str(e) if hasattr(e, "description"): emsg = e.description gl_check_error("unable to query max texture size: %s" % emsg) return props if min_texture_size>texture_size or min_texture_size>rect_texture_size: gl_check_error("The texture size is too small: %s" % texture_size) else: log("Texture size GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB=%s, GL_MAX_TEXTURE_SIZE=%s", rect_texture_size, texture_size) props["texture-size-limit"] = min(rect_texture_size, texture_size) return props
def unitSize(self, value, typeCode=None): """Determine unit size of an array (if possible)""" return ArrayDatatype.unitSize(value.data)
def setSlice(self, start, size, data): """ sets a slice of data. """ dataptr = ArrayDatatype.voidDataPointer( data ) gl.glBufferSubData( self.target, start, size, dataptr )
def register( self, types=None ): """Register this class as handler for given set of types""" from OpenGL.arrays.arraydatatype import ArrayDatatype ArrayDatatype.getRegistry().register( self, types )
def init_gl(self, glcontext): #TODO deinit at some point assert not self.glcontext vert_stage = GstGL.GLSLStage.new_default_vertex(glcontext) frag_stage = GstGL.GLSLStage.new_with_string( glcontext, GL_FRAGMENT_SHADER, GstGL.GLSLVersion.NONE, GstGL.GLSLProfile.COMPATIBILITY | GstGL.GLSLProfile.ES, FRAGMENT_SHADER_SRC) self.hm_shader = GstGL.GLShader.new(glcontext) self.hm_shader.compile_attach_stage(vert_stage) self.hm_shader.compile_attach_stage(frag_stage) self.hm_shader.link() self.default_shader = GstGL.GLShader.new_default(glcontext) a_position = self.default_shader.get_attribute_location('a_position') a_texcoord = self.default_shader.get_attribute_location('a_texcoord') self.vao_id = glGenVertexArrays(1) glBindVertexArray(self.vao_id) self.positions_buffer = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.positions_buffer) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(POSITIONS), POSITIONS, GL_STATIC_DRAW) self.texcoords_buffer = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.texcoords_buffer) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(TEXCOORDS), TEXCOORDS, GL_STATIC_DRAW) self.vbo_indices_buffer = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.vbo_indices_buffer) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(INDICES), INDICES, GL_STATIC_DRAW) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.vbo_indices_buffer) glBindBuffer(GL_ARRAY_BUFFER, self.positions_buffer) glVertexAttribPointer.baseFunction(a_position, 2, GL_FLOAT, GL_FALSE, 0, None) glBindBuffer(GL_ARRAY_BUFFER, self.texcoords_buffer) glVertexAttribPointer.baseFunction(a_texcoord, 2, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(a_position) glEnableVertexAttribArray(a_texcoord) glBindVertexArray(0) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) glBindBuffer(GL_ARRAY_BUFFER, 0) hm_w, hm_h = self.get_heatmap_texture_size() texture_ids = glGenTextures(1) self.hm_tex_id = texture_ids glActiveTexture(GL_TEXTURE0 + 1) glBindTexture(GL_TEXTURE_2D, self.hm_tex_id) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, hm_w, hm_h, 0, GL_RGBA, GL_FLOAT, None) self.glcontext = glcontext