| | |
| | """Test for a buffer-protocol-based access mechanism |
| | |
| | Will *only* work for Python 2.6+, and pretty much just works for strings |
| | under 2.6 (in terms of the common object types). |
| | """ |
| | import ctypes,sys,operator,logging,traceback |
| | from OpenGL.arrays import _buffers |
| | from OpenGL.raw.GL import _types |
| | from OpenGL.raw.GL.VERSION import GL_1_1 |
| | from OpenGL.arrays import formathandler |
| | from OpenGL import _configflags |
| | from OpenGL import acceleratesupport |
| | _log = logging.getLogger( __name__ ) |
| | try: |
| | reduce |
| | except NameError as err: |
| | from functools import reduce |
| |
|
| | MemoryviewHandler = BufferHandler = None |
| | if sys.version_info[:2] > (2,6): |
| | |
| | |
| | if acceleratesupport.ACCELERATE_AVAILABLE: |
| | try: |
| | from OpenGL_accelerate.buffers_formathandler import MemoryviewHandler |
| | except ImportError as err: |
| | traceback.print_exc() |
| | _log.warn( |
| | "Unable to load buffers_formathandler accelerator from OpenGL_accelerate" |
| | ) |
| | else: |
| | BufferHandler = MemoryviewHandler |
| | if not BufferHandler: |
| | class BufferHandler( formathandler.FormatHandler ): |
| | """Buffer-protocol data-type handler for OpenGL""" |
| | isOutput=False |
| | ERROR_ON_COPY = _configflags.ERROR_ON_COPY |
| | if sys.version_info[:2] >= (3,0): |
| | @classmethod |
| | def from_param( cls, value, typeCode=None ): |
| | if not isinstance( value, _buffers.Py_buffer ): |
| | value = cls.asArray( value ) |
| | |
| | return value |
| | else: |
| | |
| | |
| | @classmethod |
| | def from_param( cls, value, typeCode=None ): |
| | if not isinstance( value, _buffers.Py_buffer ): |
| | value = cls.asArray( value ) |
| | |
| | return value.buf |
| | def dataPointer( value ): |
| | if not isinstance( value, _buffers.Py_buffer ): |
| | value = _buffers.Py_buffer.from_object( value ) |
| | return value.buf |
| | dataPointer = staticmethod( dataPointer ) |
| | @classmethod |
| | def zeros( cls, dims, typeCode=None ): |
| | """Currently don't allow strings as output types!""" |
| | raise NotImplementedError( "Generic buffer type does not have output capability" ) |
| | return cls.asArray( bytearray( b'\000'*reduce(operator.mul,dims)*BYTE_SIZES[typeCode] ) ) |
| | @classmethod |
| | def ones( cls, dims, typeCode=None ): |
| | """Currently don't allow strings as output types!""" |
| | raise NotImplementedError( """Have not implemented ones for buffer type""" ) |
| | @classmethod |
| | def arrayToGLType( cls, value ): |
| | """Given a value, guess OpenGL type of the corresponding pointer""" |
| | format = value.format |
| | if format in ARRAY_TO_GL_TYPE_MAPPING: |
| | return ARRAY_TO_GL_TYPE_MAPPING[format] |
| | raise TypeError( 'Unknown format: %r'%(format,)) |
| | @classmethod |
| | def arraySize( cls, value, typeCode = None ): |
| | """Given a data-value, calculate ravelled size for the array""" |
| | return value.len // value.itemsize |
| | @classmethod |
| | def arrayByteCount( cls, value, typeCode = None ): |
| | """Given a data-value, calculate number of bytes required to represent""" |
| | return value.len |
| | @classmethod |
| | def unitSize( cls, value, default=None ): |
| | return value.dims[-1] |
| | @classmethod |
| | def asArray( cls, value, typeCode=None ): |
| | """Convert given value to an array value of given typeCode""" |
| | buf = _buffers.Py_buffer.from_object( value ) |
| | return buf |
| | @classmethod |
| | def dimensions( cls, value, typeCode=None ): |
| | """Determine dimensions of the passed array value (if possible)""" |
| | return value.dims |
| |
|
| | ARRAY_TO_GL_TYPE_MAPPING = _buffers.ARRAY_TO_GL_TYPE_MAPPING |
| | BYTE_SIZES = _buffers.BYTE_SIZES |
| |
|