1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
"""Array data-type implementations (abstraction points for GL array types"""
import ctypes
import OpenGL
from OpenGL import constants, plugins
from OpenGL.arrays import formathandler
from OpenGL import logs
log = logs.getLog( 'OpenGL.arrays.arraydatatype' )
class ArrayDatatype( object ):
"""Mix-in for array datatype classes
The ArrayDatatype marker essentially is used to mark a particular argument
as having an "array" type, which means that it is eligible for handling
via the arrays sub-package and its registered handlers.
"""
typeConstant = None
def getHandler( cls, value ):
"""Retrieve a handler for the given value, raise error on lookup failure"""
typ = type( value )
try:
handler = cls.TYPE_REGISTRY.get( typ )
except AttributeError, err:
formathandler.FormatHandler.loadAll()
cls.TYPE_REGISTRY = formathandler.FormatHandler.TYPE_REGISTRY
handler = cls.TYPE_REGISTRY.get( typ )
if handler is None:
handler = plugins.FormatHandler.match( typ )
if handler is None:
if hasattr( typ, '__mro__' ):
for base in typ.__mro__:
handler = cls.TYPE_REGISTRY.get( base )
if handler is None:
handler = plugins.FormatHandler.match( base )
if handler:
handler = cls.TYPE_REGISTRY[ base ]
handler.registerEquivalent( typ, base )
cls.TYPE_REGISTRY[ typ ] = handler
return handler
raise TypeError(
"""No array-type handler for type %r (value: %s) registered"""%(
typ, repr(value)[:50]
)
)
return handler
getHandler = classmethod( getHandler )
def from_param( cls, value ):
"""Given a value in a known data-pointer type, convert to a ctypes pointer"""
return cls.getHandler(value).from_param( value )
from_param = classmethod( logs.logOnFail( from_param, log ) )
def dataPointer( cls, value ):
"""Given a value in a known data-pointer type, return long for pointer"""
try:
return cls.getHandler(value).dataPointer( value )
except Exception, err:
log.warn(
"""Failure in from_param for %s instance %s""", type(value), value,
)
raise
dataPointer = classmethod( logs.logOnFail( dataPointer, log ) )
def voidDataPointer( cls, value ):
"""Given value in a known data-pointer type, return void_p for pointer"""
return ctypes.c_void_p( cls.dataPointer( value ))
voidDataPointer = classmethod( logs.logOnFail( voidDataPointer, log ) )
def typedPointer( cls, value ):
"""Return a pointer-to-base-type pointer for given value"""
return ctypes.cast( cls.dataPointer(value), ctypes.POINTER( cls.baseType ))
typedPointer = classmethod( typedPointer )
def asArray( cls, value, typeCode=None ):
"""Given a value, convert to preferred array representation"""
return cls.getHandler(value).asArray( value, typeCode or cls.typeConstant )
asArray = classmethod( logs.logOnFail( asArray, log ) )
def arrayToGLType( cls, value ):
"""Given a data-value, guess the OpenGL type of the corresponding pointer"""
return cls.getHandler(value).arrayToGLType( value )
arrayToGLType = classmethod( logs.logOnFail( arrayToGLType, log ) )
def arraySize( cls, value, typeCode = None ):
"""Given a data-value, calculate dimensions for the array (number-of-units)"""
return cls.getHandler(value).arraySize( value, typeCode or cls.typeConstant )
arraySize = classmethod( logs.logOnFail( arraySize, log ) )
def unitSize( cls, value, typeCode=None ):
"""Determine unit size of an array (if possible)
Uses our local type if defined, otherwise asks the handler to guess...
"""
return cls.getHandler(value).unitSize( value, typeCode or cls.typeConstant )
unitSize = classmethod( logs.logOnFail( unitSize, log ) )
def returnHandler( cls ):
"""Get the default return-handler"""
try:
return formathandler.FormatHandler.RETURN_HANDLER
except AttributeError, err:
if not formathandler.FormatHandler.TYPE_REGISTRY:
formathandler.FormatHandler.loadAll()
return formathandler.FormatHandler.chooseOutput( )
returnHandler = classmethod( logs.logOnFail( returnHandler, log ) )
def zeros( cls, dims, typeCode=None ):
"""Allocate a return array of the given dimensions filled with zeros"""
return cls.returnHandler().zeros( dims, typeCode or cls.typeConstant )
zeros = classmethod( logs.logOnFail( zeros, log ) )
def dimensions( cls, value ):
"""Given a data-value, get the dimensions (assumes full structure info)"""
return cls.getHandler(value).dimensions( value )
dimensions = classmethod( logs.logOnFail( dimensions, log ) )
def arrayByteCount( cls, value ):
"""Given a data-value, try to determine number of bytes it's final form occupies
For most data-types this is arraySize() * atomic-unit-size
"""
return cls.getHandler(value).arrayByteCount( value )
arrayByteCount = classmethod( logs.logOnFail( arrayByteCount, log ) )
# the final array data-type classes...
class GLclampdArray( ArrayDatatype, ctypes.POINTER(constants.GLclampd )):
"""Array datatype for GLclampd types"""
baseType = constants.GLclampd
typeConstant = constants.GL_DOUBLE
class GLclampfArray( ArrayDatatype, ctypes.POINTER(constants.GLclampf )):
"""Array datatype for GLclampf types"""
baseType = constants.GLclampf
typeConstant = constants.GL_FLOAT
class GLfloatArray( ArrayDatatype, ctypes.POINTER(constants.GLfloat )):
"""Array datatype for GLfloat types"""
baseType = constants.GLfloat
typeConstant = constants.GL_FLOAT
class GLdoubleArray( ArrayDatatype, ctypes.POINTER(constants.GLdouble )):
"""Array datatype for GLdouble types"""
baseType = constants.GLdouble
typeConstant = constants.GL_DOUBLE
class GLbyteArray( ArrayDatatype, ctypes.POINTER(constants.GLbyte )):
"""Array datatype for GLbyte types"""
baseType = constants.GLbyte
typeConstant = constants.GL_BYTE
class GLcharArray( ArrayDatatype, ctypes.c_char_p):
"""Array datatype for ARB extension pointers-to-arrays"""
baseType = constants.GLchar
typeConstant = constants.GL_BYTE
GLcharARBArray = GLcharArray
class GLshortArray( ArrayDatatype, ctypes.POINTER(constants.GLshort )):
"""Array datatype for GLshort types"""
baseType = constants.GLshort
typeConstant = constants.GL_SHORT
class GLintArray( ArrayDatatype, ctypes.POINTER(constants.GLint )):
"""Array datatype for GLint types"""
baseType = constants.GLint
typeConstant = constants.GL_INT
class GLubyteArray( ArrayDatatype, ctypes.POINTER(constants.GLubyte )):
"""Array datatype for GLubyte types"""
baseType = constants.GLubyte
typeConstant = constants.GL_UNSIGNED_BYTE
GLbooleanArray = GLubyteArray
class GLushortArray( ArrayDatatype, ctypes.POINTER(constants.GLushort )):
"""Array datatype for GLushort types"""
baseType = constants.GLushort
typeConstant = constants.GL_UNSIGNED_SHORT
class GLuintArray( ArrayDatatype, ctypes.POINTER(constants.GLuint )):
"""Array datatype for GLuint types"""
baseType = constants.GLuint
typeConstant = constants.GL_UNSIGNED_INT
class GLenumArray( ArrayDatatype, ctypes.POINTER(constants.GLenum )):
"""Array datatype for GLenum types"""
baseType = constants.GLenum
typeConstant = constants.GL_UNSIGNED_INT
class GLsizeiArray( ArrayDatatype, ctypes.POINTER(constants.GLsizei )):
"""Array datatype for GLenum types"""
baseType = constants.GLsizei
typeConstant = constants.GL_INT
GL_CONSTANT_TO_ARRAY_TYPE = {
constants.GL_DOUBLE : GLclampdArray,
constants.GL_FLOAT : GLclampfArray,
constants.GL_FLOAT : GLfloatArray,
constants.GL_DOUBLE : GLdoubleArray,
constants.GL_BYTE : GLbyteArray,
constants.GL_SHORT : GLshortArray,
constants.GL_INT : GLintArray,
constants.GL_UNSIGNED_BYTE : GLubyteArray,
constants.GL_UNSIGNED_SHORT : GLushortArray,
constants.GL_UNSIGNED_INT : GLuintArray,
#constants.GL_UNSIGNED_INT : GLenumArray,
}
|