class GLUQuadric(_simple.GLUquadric): """Implementation class for GLUQuadric classes in PyOpenGL""" FUNCTION_TYPE = PLATFORM.functionTypeFor(PLATFORM.GLU) CALLBACK_TYPES = { # mapping from "which" GLU enumeration to a ctypes function type _simple.GLU_ERROR: FUNCTION_TYPE(None, _simple.GLenum) } def addCallback(self, which, function): """Register a callback for the quadric object At the moment only GLU_ERROR is supported by OpenGL, but we allow for the possibility of more callbacks in the future... """ callbackType = self.CALLBACK_TYPES.get(which) if not callbackType: raise ValueError( """Don"t have a registered callback type for %r""" % (which, )) if not isinstance(function, callbackType): cCallback = callbackType(function) else: cCallback = function PLATFORM.GLU.gluQuadricCallback(self, which, cCallback) # XXX catch errors! if getattr(self, "callbacks", None) is None: self.callbacks = {} self.callbacks[which] = cCallback return cCallback
def pullExtensions( self ): from OpenGL.platform import PLATFORM wglGetCurrentDC = PLATFORM.OpenGL.wglGetCurrentDC wglGetCurrentDC.restyle = HDC try: dc = wglGetCurrentDC() proc_address = PLATFORM.getExtensionProcedure( 'wglGetExtensionsStringARB' ) wglGetExtensionStringARB = PLATFORM.functionTypeFor( PLATFORM.WGL )( c_char_p, HDC, )( proc_address ) except TypeError as err: return None except AttributeError as err: return [] else: return wglGetExtensionStringARB(dc).split()
class GLUnurbs(glustruct.GLUStruct, simple.GLUnurbs): """GLU Nurbs structure with oor and callback storage support IMPORTANT NOTE: the texture coordinate callback receives a raw ctypes data-pointer, as without knowing what type of evaluation is being done (1D or 2D) we cannot safely determine the size of the array to convert it. This is a limitation of the C implementation. To convert to regular data-pointer, just call yourNurb.ptrAsArray( ptr, size, arrays.GLfloatArray ) with the size of data you expect. """ FUNCTION_TYPE = PLATFORM.functionTypeFor(PLATFORM.GLU) CALLBACK_FUNCTION_REGISTRARS = { # mapping from "which" to a function that should take 3 parameters, # the nurb, the which and the function pointer... } CALLBACK_TYPES = { # mapping from "which" GLU enumeration to a ctypes function type simple.GLU_NURBS_BEGIN: FUNCTION_TYPE(None, simple.GLenum), simple.GLU_NURBS_BEGIN_DATA: FUNCTION_TYPE(None, simple.GLenum, ctypes.POINTER(simple.GLvoid)), simple.GLU_NURBS_VERTEX: FUNCTION_TYPE(None, ctypes.POINTER(simple.GLfloat)), simple.GLU_NURBS_VERTEX_DATA: FUNCTION_TYPE(None, ctypes.POINTER(simple.GLfloat), ctypes.POINTER(simple.GLvoid)), simple.GLU_NURBS_NORMAL: FUNCTION_TYPE(None, ctypes.POINTER(simple.GLfloat)), simple.GLU_NURBS_NORMAL_DATA: FUNCTION_TYPE(None, ctypes.POINTER(simple.GLfloat), ctypes.POINTER(simple.GLvoid)), simple.GLU_NURBS_COLOR: FUNCTION_TYPE(None, ctypes.POINTER(simple.GLfloat)), simple.GLU_NURBS_COLOR_DATA: FUNCTION_TYPE(None, ctypes.POINTER(simple.GLfloat), ctypes.POINTER(simple.GLvoid)), simple.GLU_NURBS_TEXTURE_COORD: FUNCTION_TYPE(None, ctypes.POINTER(simple.GLfloat)), simple.GLU_NURBS_TEXTURE_COORD_DATA: FUNCTION_TYPE(None, ctypes.POINTER(simple.GLfloat), ctypes.POINTER(simple.GLvoid)), simple.GLU_NURBS_END: FUNCTION_TYPE(None), simple.GLU_NURBS_END_DATA: FUNCTION_TYPE(None, ctypes.POINTER(simple.GLvoid)), simple.GLU_NURBS_ERROR: FUNCTION_TYPE( None, simple.GLenum, ), } WRAPPER_METHODS = { simple.GLU_NURBS_BEGIN: None, simple.GLU_NURBS_BEGIN_DATA: '_justOOR', simple.GLU_NURBS_VERTEX: '_vec3', simple.GLU_NURBS_VERTEX_DATA: '_vec3', simple.GLU_NURBS_NORMAL: '_vec3', simple.GLU_NURBS_NORMAL_DATA: '_vec3', simple.GLU_NURBS_COLOR: '_vec4', simple.GLU_NURBS_COLOR_DATA: '_vec4', simple.GLU_NURBS_TEXTURE_COORD: '_tex', simple.GLU_NURBS_TEXTURE_COORD_DATA: '_tex', simple.GLU_NURBS_END: None, simple.GLU_NURBS_END_DATA: '_justOOR', simple.GLU_NURBS_ERROR: None, } def _justOOR(self, function): """Just do OOR on the last argument...""" def getOOR(*args): args = args[:-1] + (self.originalObject(args[-1]), ) return function(*args) return getOOR def _vec3(self, function, size=3): """Convert first arg to size-element array, do OOR on arg2 if present""" def vec(*args): vec = self.ptrAsArray(args[0], size, arrays.GLfloatArray) if len(args) > 1: oor = self.originalObject(args[1]) return function(vec, oor) else: return function(vec) return vec def _vec4(self, function): """Size-4 vector version...""" return self._vec3(function, 4) def _tex(self, function): """Texture coordinate callback NOTE: there is no way for *us* to tell what size the array is, you will get back a raw data-point, not an array, as you do for all other callback types!!! """ def oor(*args): if len(args) > 1: oor = self.originalObject(args[1]) return function(args[0], oor) else: return function(args[0]) return oor
('GLbyte', GL_BYTE), ('GLshort', GL_SHORT), ('GLint', GL_INT), ('GLubyte', GL_UNSIGNED_BYTE), ('GLushort', GL_UNSIGNED_SHORT), ('GLuint', GL_UNSIGNED_INT), ('GLenum', GL_UNSIGNED_INT), ] from OpenGL.platform import PLATFORM as _p GLDEBUGPROCARB = GLDEBUGPROCKHR = GLDEBUGPROC = _p.DEFAULT_FUNCTION_TYPE( void, GLenum, # source, GLenum, #type, GLuint, # id GLenum, # severity GLsizei, # length ctypes.c_char_p, # message GLvoidp, # userParam ) class _cl_context(ctypes.Structure): """Placeholder/empty structure for _cl_context""" class _cl_event(ctypes.Structure): """Placeholder/empty structure for _cl_event""" GLDEBUGPROCAMD = _p.DEFAULT_FUNCTION_TYPE(
class GLUtesselator(glustruct.GLUStruct, _simple.GLUtesselator): """Implementation class for GLUTessellator structures in OpenGL-ctypes""" FUNCTION_TYPE = PLATFORM.functionTypeFor(PLATFORM.GLU) CALLBACK_TYPES = { # mapping from "which" GLU enumeration to a ctypes function type _simple.GLU_TESS_BEGIN: FUNCTION_TYPE(None, _simple.GLenum), _simple.GLU_TESS_BEGIN_DATA: FUNCTION_TYPE(None, _simple.GLenum, ctypes.c_void_p), _simple.GLU_TESS_EDGE_FLAG: FUNCTION_TYPE(None, _simple.GLboolean), _simple.GLU_TESS_EDGE_FLAG_DATA: FUNCTION_TYPE(None, _simple.GLboolean, ctypes.c_void_p), _simple.GLU_TESS_VERTEX: FUNCTION_TYPE(None, ctypes.c_void_p), _simple.GLU_TESS_VERTEX_DATA: FUNCTION_TYPE(None, ctypes.c_void_p, ctypes.c_void_p), _simple.GLU_TESS_END: FUNCTION_TYPE(None), _simple.GLU_TESS_END_DATA: FUNCTION_TYPE(None, ctypes.c_void_p), _simple.GLU_TESS_COMBINE: FUNCTION_TYPE(None, ctypes.POINTER(_simple.GLdouble), ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(_simple.GLfloat), ctypes.POINTER(ctypes.c_void_p)), _simple.GLU_TESS_COMBINE_DATA: FUNCTION_TYPE( None, ctypes.POINTER(_simple.GLdouble), ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(_simple.GLfloat), ctypes.POINTER(ctypes.c_void_p), ctypes.c_void_p, ), _simple.GLU_TESS_ERROR: FUNCTION_TYPE(None, _simple.GLenum), _simple.GLU_TESS_ERROR_DATA: FUNCTION_TYPE(None, _simple.GLenum, ctypes.c_void_p), _simple.GLU_ERROR: FUNCTION_TYPE(None, _simple.GLenum) } WRAPPER_METHODS = { _simple.GLU_TESS_BEGIN_DATA: 'dataWrapper', _simple.GLU_TESS_EDGE_FLAG_DATA: 'dataWrapper', _simple.GLU_TESS_VERTEX: 'vertexWrapper', _simple.GLU_TESS_VERTEX_DATA: 'vertexWrapper', _simple.GLU_TESS_END_DATA: 'dataWrapper', _simple.GLU_TESS_COMBINE: 'combineWrapper', _simple.GLU_TESS_COMBINE_DATA: 'combineWrapper', _simple.GLU_TESS_ERROR_DATA: 'dataWrapper', } def gluTessVertex(self, location, data=None): """Add a vertex to this tessellator, storing data for later lookup""" vertexCache = getattr(self, 'vertexCache', None) if vertexCache is None: self.vertexCache = [] vertexCache = self.vertexCache location = arrays.GLdoubleArray.asArray(location, GL_1_1.GL_DOUBLE) if arrays.GLdoubleArray.arraySize(location) != 3: raise ValueError( """Require 3 doubles for array location, got: %s""" % (location, )) oorValue = self.noteObject(data) vp = ctypes.c_void_p(oorValue) self.vertexCache.append(location) return gluTessVertexBase(self, location, vp) def gluTessBeginPolygon(self, data): """Note the object pointer to return it as a Python object""" return _simple.gluTessBeginPolygon( self, ctypes.c_void_p(self.noteObject(data))) def combineWrapper(self, function): """Wrap a Python function with ctypes-compatible wrapper for combine callback For a Python combine callback, the signature looks like this: def combine( GLdouble coords[3], void *vertex_data[4], GLfloat weight[4] ): return data While the C signature looks like this: void combine( GLdouble coords[3], void *vertex_data[4], GLfloat weight[4], void **outData ) """ if (function is not None) and (not hasattr(function, '__call__')): raise TypeError("""Require a callable callback, got: %s""" % (function, )) def wrap(coords, vertex_data, weight, outData, *args): """The run-time wrapper around the function""" coords = self.ptrAsArray(coords, 3, arrays.GLdoubleArray) weight = self.ptrAsArray(weight, 4, arrays.GLfloatArray) # find the original python objects for vertex data vertex_data = [ self.originalObject(vertex_data[i]) for i in range(4) ] args = tuple([self.originalObject(x) for x in args]) try: result = function(coords, vertex_data, weight, *args) except Exception as err: raise err.__class__( """Failure during combine callback %r with args( %s,%s,%s,*%s):\n%s""" % ( function, coords, vertex_data, weight, args, str(err), )) outP = ctypes.c_void_p(self.noteObject(result)) if outData: outData[0] = outP else: raise RuntimeError("Null outData passed to callback") return None return wrap def dataWrapper(self, function): """Wrap a function which only has the one data-pointer as last arg""" if (function is not None) and (not hasattr(function, '__call__')): raise TypeError("""Require a callable callback, got: %s""" % (function, )) def wrap(*args): """Just return the original object for polygon_data""" args = args[:-1] + (self.originalObject(args[-1]), ) try: return function(*args) except Exception as err: err.args += (function, args) raise return wrap def dataWrapper2(self, function): """Wrap a function which has two data-pointers as last args""" if (function is not None) and (not hasattr(function, '__call__')): raise TypeError("""Require a callable callback, got: %s""" % (function, )) def wrap(*args): """Just return the original object for polygon_data""" args = args[:-2] + ( self.originalObject(args[-2]), self.originalObject(args[-1]), ) try: return function(*args) except Exception as err: err.args += (function, args) raise return wrap def vertexWrapper(self, function): """Converts a vertex-pointer into an OOR vertex for processing""" if (function is not None) and (not hasattr(function, '__call__')): raise TypeError("""Require a callable callback, got: %s""" % (function, )) def wrap(vertex, data=None): """Just return the original object for polygon_data""" vertex = self.originalObject(vertex) try: if data is not None: data = self.originalObject(data) return function(vertex, data) else: return function(vertex) except Exception as err: err.args += (function, (vertex, data)) raise return wrap
ARRAY_TYPE_TO_CONSTANT = [ ('GLclampd', GL_DOUBLE), ('GLclampf', GL_FLOAT), ('GLfloat', GL_FLOAT), ('GLdouble', GL_DOUBLE), ('GLbyte', GL_BYTE), ('GLshort', GL_SHORT), ('GLint', GL_INT), ('GLubyte', GL_UNSIGNED_BYTE), ('GLushort', GL_UNSIGNED_SHORT), ('GLuint', GL_UNSIGNED_INT), ('GLenum', GL_UNSIGNED_INT), ] from OpenGL.platform import PLATFORM as _p _FUNCTION_TYPE = _p.functionTypeFor(_p.GL) GLDEBUGPROCARB = GLDEBUGPROC = _FUNCTION_TYPE( void, GLenum, # source, GLenum, #type, GLuint, # id GLenum, # severity GLsizei, # length ctypes.c_char_p, # message GLvoidp, # userParam ) class _cl_context( ctypes.Structure ): """Placeholder/empty structure for _cl_context""" class _cl_event( ctypes.Structure ):
ARRAY_TYPE_TO_CONSTANT = [ ('GLclampd', GL_DOUBLE), ('GLclampf', GL_FLOAT), ('GLfloat', GL_FLOAT), ('GLdouble', GL_DOUBLE), ('GLbyte', GL_BYTE), ('GLshort', GL_SHORT), ('GLint', GL_INT), ('GLubyte', GL_UNSIGNED_BYTE), ('GLushort', GL_UNSIGNED_SHORT), ('GLuint', GL_UNSIGNED_INT), ('GLenum', GL_UNSIGNED_INT), ] from OpenGL.platform import PLATFORM _FUNCTION_TYPE = PLATFORM.functionTypeFor(PLATFORM.GL) GLDEBUGPROCARB = _FUNCTION_TYPE( void, GLenum, # source, GLenum, #type, GLuint, # id GLenum, # severity GLsizei, # length ctypes.c_char_p, # message GLvoidp, # userParam ) class _cl_context( ctypes.Structure ): """Placeholder/empty structure for _cl_context""" class _cl_event( ctypes.Structure ):
ARRAY_TYPE_TO_CONSTANT = [ ('GLclampd', GL_DOUBLE), ('GLclampf', GL_FLOAT), ('GLfloat', GL_FLOAT), ('GLdouble', GL_DOUBLE), ('GLbyte', GL_BYTE), ('GLshort', GL_SHORT), ('GLint', GL_INT), ('GLubyte', GL_UNSIGNED_BYTE), ('GLushort', GL_UNSIGNED_SHORT), ('GLuint', GL_UNSIGNED_INT), ('GLenum', GL_UNSIGNED_INT), ] from OpenGL.platform import PLATFORM as _p _FUNCTION_TYPE = _p.functionTypeFor(_p.GL) GLDEBUGPROCARB = GLDEBUGPROC = _FUNCTION_TYPE( void, GLenum, # source, GLenum, #type, GLuint, # id GLenum, # severity GLsizei, # length ctypes.c_char_p, # message GLvoidp, # userParam ) class _cl_context(ctypes.Structure): """Placeholder/empty structure for _cl_context"""