home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / lib / site-packages / OpenGL / GL / pointers.py < prev    next >
Encoding:
Python Source  |  2008-12-07  |  13.4 KB  |  321 lines

  1. """Implementations for "held-pointers" of various types
  2.  
  3. This argument type is special because it is stored, that is, it 
  4. needs to be cached on our side so that the memory address does not
  5. go out-of-scope
  6.  
  7. storedPointers = {}
  8. def glVertexPointerd( array ):
  9.     "Natural writing of glVertexPointerd using standard ctypes"
  10.     arg2 = GL_DOUBLE
  11.     arg3 = 0 # stride
  12.     arg4 = arrays.asArray(array, GL_DOUBLE)
  13.     arg1 = arrays.arraySize( arg4, 'd' )
  14.     platform.OpenGL.glVertexPointer( arg1, arg2, arg3, arrays.ArrayDatatype.dataPointer(arg4) )
  15.     glCheckError()
  16.     # only store if we successfully set the value...
  17.     storedPointers[ GL_VERTEX_ARRAY ] = arg4
  18.     return arg4
  19. """
  20. from OpenGL import platform, arrays, error, wrapper, contextdata, converters, constant
  21. from OpenGL.raw import GL as simple
  22. from OpenGL.raw.GL import annotations
  23. import ctypes
  24. import weakref
  25.  
  26. GLsizei = ctypes.c_int
  27. GLenum = ctypes.c_uint
  28. GLint = ctypes.c_int
  29. # OpenGL-ctypes variables that mimic OpenGL constant operation...
  30. GL_INTERLEAVED_ARRAY_POINTER = constant.Constant( 'GL_INTERLEAVED_ARRAY_POINTER', -32910 )
  31.  
  32. __all__ = (
  33.     'glColorPointer',
  34.     'glColorPointerb','glColorPointerd','glColorPointerf','glColorPointeri',
  35.     'glColorPointers','glColorPointerub','glColorPointerui','glColorPointerus',
  36.     'glEdgeFlagPointer',
  37.     'glEdgeFlagPointerb',
  38.     'glIndexPointer',
  39.     'glIndexPointerb','glIndexPointerd','glIndexPointerf',
  40.     'glIndexPointeri','glIndexPointers','glIndexPointerub',
  41.     'glNormalPointer',
  42.     'glNormalPointerb',
  43.     'glNormalPointerd','glNormalPointerf','glNormalPointeri','glNormalPointers',
  44.     'glTexCoordPointer',
  45.     'glTexCoordPointerb','glTexCoordPointerd','glTexCoordPointerf',
  46.     'glTexCoordPointeri','glTexCoordPointers',
  47.     'glVertexPointer',
  48.     'glVertexPointerb','glVertexPointerd','glVertexPointerf','glVertexPointeri',
  49.     'glVertexPointers',
  50.     'glDrawElements','glDrawElementsui','glDrawElementsub','glDrawElementsus',
  51.     'glFeedbackBuffer',
  52.     'glSelectBuffer',
  53.     'glRenderMode',
  54.     'glGetPointerv',
  55.     'glInterleavedArrays',
  56.     'GL_INTERLEAVED_ARRAY_POINTER',
  57. )
  58.  
  59.  
  60. # Have to create *new* ctypes wrappers for the platform object!
  61. # We can't just alter the default one since we have different ways of
  62. # calling it
  63.  
  64. POINTER_FUNCTION_DATA = [
  65.     ('glColorPointerd',  simple.glColorPointer, simple.GL_DOUBLE, simple.GL_COLOR_ARRAY_POINTER, 0, 3),
  66.     ('glColorPointerf',  simple.glColorPointer, simple.GL_FLOAT, simple.GL_COLOR_ARRAY_POINTER, 0, 3),
  67.     ('glColorPointeri',  simple.glColorPointer, simple.GL_INT, simple.GL_COLOR_ARRAY_POINTER, 0, 3),
  68.     ('glColorPointers',  simple.glColorPointer, simple.GL_SHORT, simple.GL_COLOR_ARRAY_POINTER, 0, 3),
  69.     ('glColorPointerub', simple.glColorPointer, simple.GL_UNSIGNED_BYTE, simple.GL_COLOR_ARRAY_POINTER, 0, 3),
  70.     # these data-types are mapped from diff Numeric types
  71.     ('glColorPointerb',  simple.glColorPointer, simple.GL_BYTE, simple.GL_COLOR_ARRAY_POINTER, 0, 3), 
  72.     ('glColorPointerui', simple.glColorPointer, simple.GL_UNSIGNED_INT, simple.GL_COLOR_ARRAY_POINTER, 0, 3),
  73.     ('glColorPointerus', simple.glColorPointer, simple.GL_UNSIGNED_SHORT, simple.GL_COLOR_ARRAY_POINTER, 0, 3),
  74.     
  75.     ('glEdgeFlagPointerb', simple.glEdgeFlagPointer, simple.GL_BYTE, simple.GL_EDGE_FLAG_ARRAY_POINTER, 2, None),
  76.  
  77.     ('glIndexPointerd',  simple.glIndexPointer, simple.GL_DOUBLE, simple.GL_INDEX_ARRAY_POINTER, 1, None),
  78.     ('glIndexPointerf',  simple.glIndexPointer, simple.GL_FLOAT, simple.GL_INDEX_ARRAY_POINTER, 1, None),
  79.     ('glIndexPointeri',  simple.glIndexPointer, simple.GL_INT, simple.GL_INDEX_ARRAY_POINTER, 1, None),
  80.     ('glIndexPointerub', simple.glIndexPointer, simple.GL_UNSIGNED_BYTE, simple.GL_INDEX_ARRAY_POINTER, 1, None),
  81.     ('glIndexPointers',  simple.glIndexPointer, simple.GL_SHORT, simple.GL_INDEX_ARRAY_POINTER, 1, None),
  82.     # these data-types are mapped from diff Numeric types
  83.     ('glIndexPointerb',  simple.glIndexPointer, simple.GL_BYTE, simple.GL_INDEX_ARRAY_POINTER, 1, None),
  84.  
  85.     ('glNormalPointerd',  simple.glNormalPointer, simple.GL_DOUBLE, simple.GL_NORMAL_ARRAY_POINTER, 1, None),
  86.     ('glNormalPointerf',  simple.glNormalPointer, simple.GL_FLOAT, simple.GL_NORMAL_ARRAY_POINTER, 1, None),
  87.     ('glNormalPointeri',  simple.glNormalPointer, simple.GL_INT, simple.GL_NORMAL_ARRAY_POINTER, 1, None),
  88.     ('glNormalPointerb',  simple.glNormalPointer, simple.GL_BYTE, simple.GL_NORMAL_ARRAY_POINTER, 1, None),
  89.     ('glNormalPointers',  simple.glNormalPointer, simple.GL_SHORT, simple.GL_NORMAL_ARRAY_POINTER, 1, None),
  90.  
  91.     ('glTexCoordPointerd',  simple.glTexCoordPointer, simple.GL_DOUBLE, simple.GL_TEXTURE_COORD_ARRAY_POINTER, 0, 2),
  92.     ('glTexCoordPointerf',  simple.glTexCoordPointer, simple.GL_FLOAT, simple.GL_TEXTURE_COORD_ARRAY_POINTER, 0, 2),
  93.     ('glTexCoordPointeri',  simple.glTexCoordPointer, simple.GL_INT, simple.GL_TEXTURE_COORD_ARRAY_POINTER, 0, 2),
  94.     ('glTexCoordPointerb',  simple.glTexCoordPointer, simple.GL_BYTE, simple.GL_TEXTURE_COORD_ARRAY_POINTER, 0, 2),
  95.     ('glTexCoordPointers',  simple.glTexCoordPointer, simple.GL_SHORT, simple.GL_TEXTURE_COORD_ARRAY_POINTER, 0, 2),
  96.  
  97.     ('glVertexPointerd', simple.glVertexPointer, simple.GL_DOUBLE, simple.GL_VERTEX_ARRAY_POINTER, 0, 3),
  98.     ('glVertexPointerf', simple.glVertexPointer, simple.GL_FLOAT, simple.GL_VERTEX_ARRAY_POINTER, 0, 3),
  99.     ('glVertexPointeri', simple.glVertexPointer, simple.GL_INT, simple.GL_VERTEX_ARRAY_POINTER, 0, 3),
  100.     ('glVertexPointerb', simple.glVertexPointer, simple.GL_INT, simple.GL_VERTEX_ARRAY_POINTER, 0, 3),
  101.     ('glVertexPointers', simple.glVertexPointer, simple.GL_SHORT, simple.GL_VERTEX_ARRAY_POINTER, 0, 3),
  102. ]
  103. def wrapPointerFunction( name, baseFunction, glType, arrayType,startArgs, defaultSize ):
  104.     """Wrap the given pointer-setting function"""
  105.     function= wrapper.wrapper( baseFunction )
  106.     assert not getattr( function, 'pyConverters', None ), """Reusing wrappers?"""
  107.     if arrayType:
  108.         arrayModuleType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ glType ]
  109.         function.setPyConverter( 'pointer', arrays.asArrayType(arrayModuleType) )
  110.         function.setCResolver( 'pointer', arrayModuleType.voidDataPointer )
  111.     else:
  112.         function.setPyConverter( 'pointer', arrays.AsArrayOfType('pointer','type') )
  113.         function.setCResolver( 'pointer', arrays.ArrayDatatype.voidDataPointer )
  114.     function.setCConverter( 'pointer', converters.getPyArgsName( 'pointer' ) )
  115.     if 'size' in function.argNames:
  116.         function.setPyConverter( 'size' )
  117.         function.setCConverter( 'size', arrays.arraySizeOfFirstType(arrayModuleType,defaultSize) )
  118.     if 'type' in function.argNames:
  119.         function.setPyConverter( 'type' )
  120.         function.setCConverter( 'type', glType )
  121.     if 'stride' in function.argNames:
  122.         function.setPyConverter( 'stride' )
  123.         function.setCConverter( 'stride', 0 )
  124.     function.setStoreValues( arrays.storePointerType( 'pointer', arrayType ) )
  125.     function.setReturnValues( wrapper.returnPyArgument( 'pointer' ) )
  126.     return name,function
  127.  
  128.  
  129.  
  130. for name,function in [
  131.     wrapPointerFunction( *args )
  132.     for args in POINTER_FUNCTION_DATA
  133. ]:
  134.     globals()[name] = function
  135. del name, function
  136.  
  137. glVertexPointer = wrapper.wrapper( simple.glVertexPointer ).setPyConverter(
  138.     'pointer', arrays.AsArrayOfType( 'pointer', 'type' ),
  139. ).setCResolver( 
  140.     'pointer', arrays.ArrayDatatype.voidDataPointer ,
  141. ).setStoreValues( 
  142.     arrays.storePointerType( 'pointer', simple.GL_VERTEX_ARRAY_POINTER ) 
  143. ).setReturnValues( 
  144.     wrapper.returnPyArgument( 'pointer' ) 
  145. )
  146. glTexCoordPointer = wrapper.wrapper( simple.glTexCoordPointer ).setPyConverter(
  147.     'pointer', arrays.AsArrayOfType( 'pointer', 'type' ),
  148. ).setCResolver( 
  149.     'pointer', arrays.ArrayDatatype.voidDataPointer ,
  150. ).setStoreValues( 
  151.     arrays.storePointerType( 'pointer', simple.GL_TEXTURE_COORD_ARRAY_POINTER ) 
  152. ).setReturnValues( 
  153.     wrapper.returnPyArgument( 'pointer' ) 
  154. )
  155. glNormalPointer = wrapper.wrapper( simple.glNormalPointer ).setPyConverter(
  156.     'pointer', arrays.AsArrayOfType( 'pointer', 'type' ),
  157. ).setCResolver( 
  158.     'pointer', arrays.ArrayDatatype.voidDataPointer ,
  159. ).setStoreValues( 
  160.     arrays.storePointerType( 'pointer', simple.GL_NORMAL_ARRAY_POINTER ) 
  161. ).setReturnValues( 
  162.     wrapper.returnPyArgument( 'pointer' ) 
  163. )
  164. glIndexPointer = wrapper.wrapper( simple.glIndexPointer ).setPyConverter(
  165.     'pointer', arrays.AsArrayOfType( 'pointer', 'type' ),
  166. ).setCResolver( 
  167.     'pointer', arrays.ArrayDatatype.voidDataPointer ,
  168. ).setStoreValues( 
  169.     arrays.storePointerType( 'pointer', simple.GL_INDEX_ARRAY_POINTER ) 
  170. ).setReturnValues( 
  171.     wrapper.returnPyArgument( 'pointer' ) 
  172. )
  173. glEdgeFlagPointer = wrapper.wrapper( simple.glEdgeFlagPointer ).setPyConverter(
  174.     # XXX type is wrong!
  175.     'pointer', arrays.AsArrayTyped( 'pointer', arrays.GLushortArray ),
  176. ).setCResolver( 
  177.     'pointer', arrays.ArrayDatatype.voidDataPointer ,
  178. ).setStoreValues( 
  179.     arrays.storePointerType( 'pointer', simple.GL_EDGE_FLAG_ARRAY_POINTER ) 
  180. ).setReturnValues( 
  181.     wrapper.returnPyArgument( 'pointer' ) 
  182. )
  183. glColorPointer = wrapper.wrapper( simple.glColorPointer ).setPyConverter(
  184.     'pointer', arrays.AsArrayOfType( 'pointer', 'type' ),
  185. ).setCResolver( 
  186.     'pointer', arrays.ArrayDatatype.voidDataPointer ,
  187. ).setStoreValues( 
  188.     arrays.storePointerType( 'pointer', simple.GL_COLOR_ARRAY_POINTER ) 
  189. ).setReturnValues( 
  190.     wrapper.returnPyArgument( 'pointer' ) 
  191. )
  192. glInterleavedArrays = wrapper.wrapper( simple.glInterleavedArrays ).setCResolver( 
  193.     'pointer', arrays.ArrayDatatype.voidDataPointer ,
  194. ).setStoreValues( 
  195.     arrays.storePointerType( 'pointer', GL_INTERLEAVED_ARRAY_POINTER ) 
  196. ).setReturnValues( 
  197.     wrapper.returnPyArgument( 'pointer' )
  198. )
  199.     
  200.  
  201. glDrawElements = wrapper.wrapper( simple.glDrawElements ).setPyConverter(
  202.     'indices', arrays.AsArrayOfType( 'indices', 'type' ),
  203. ).setCResolver( 
  204.     'indices', arrays.ArrayDatatype.voidDataPointer ,
  205. ).setReturnValues( 
  206.     wrapper.returnPyArgument( 'indices' ) 
  207. )
  208.  
  209. def glDrawElementsTyped( type, suffix ):
  210.     arrayType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ type ]
  211.     function = wrapper.wrapper( 
  212.         simple.glDrawElements 
  213.     ).setPyConverter('type').setCConverter(
  214.         'type', type
  215.     ).setPyConverter('count').setCConverter(
  216.         'count', arrays.AsArrayTypedSize( 'indices', arrayType ),
  217.     ).setPyConverter(
  218.         'indices', arrays.AsArrayTyped( 'indices', arrayType ),
  219.     ).setCResolver( 
  220.         'indices', arrayType.voidDataPointer ,
  221.     ).setReturnValues(
  222.         wrapper.returnPyArgument( 'indices' )
  223.     )
  224.     return function
  225. for type,suffix in ((simple.GL_UNSIGNED_BYTE,'ub'),(simple.GL_UNSIGNED_INT,'ui'),(simple.GL_UNSIGNED_SHORT,'us')):
  226.     globals()['glDrawElements%(suffix)s'%globals()] = glDrawElementsTyped( type,suffix )
  227. del type,suffix,glDrawElementsTyped
  228.  
  229. # create buffer of given size and return it for future reference
  230. # keep a per-context weakref around to allow us to return the original
  231. # array we returned IFF the user has kept a reference as well...
  232. def glSelectBuffer( size, buffer = None ):
  233.     """Create a selection buffer of the given size
  234.     """
  235.     if buffer is None:
  236.         buffer = arrays.GLintArray.zeros( (size,) )
  237.     simple.glSelectBuffer( size, buffer )
  238.     contextdata.setValue( simple.GL_SELECTION_BUFFER_POINTER, buffer )
  239.     return buffer
  240. def glFeedbackBuffer( size, type, buffer = None ):
  241.     """Create a selection buffer of the given size
  242.     """
  243.     if buffer is None:
  244.         buffer = arrays.GLfloatArray.zeros( (size,) )
  245.     simple.glFeedbackBuffer( size, type, buffer )
  246.     contextdata.setValue( simple.GL_FEEDBACK_BUFFER_POINTER, buffer )
  247.     contextdata.setValue( "GL_FEEDBACK_BUFFER_TYPE", type )
  248.     return buffer
  249.  
  250. def glRenderMode( newMode ):
  251.     """Change to the given rendering mode
  252.     
  253.     If the current mode is GL_FEEDBACK or GL_SELECT, return
  254.     the current buffer appropriate to the mode
  255.     """
  256.     # must get the current mode to determine operation...
  257.     from OpenGL.GL import glGetIntegerv
  258.     from OpenGL.GL import selection, feedback
  259.     currentMode = glGetIntegerv( simple.GL_RENDER_MODE )
  260.     try:
  261.         currentMode = currentMode[0]
  262.     except (TypeError,ValueError,IndexError), err:
  263.         pass
  264.     if currentMode in (simple.GL_RENDER,0):
  265.         # no array needs to be returned...
  266.         return simple.glRenderMode( newMode )
  267.     result = simple.glRenderMode( newMode )
  268.     # result is now an integer telling us how many elements were copied...
  269.     
  270.     if result < 0:
  271.         if currentMode == simple.GL_SELECT:
  272.             raise error.GLError(
  273.                 simple.GL_STACK_OVERFLOW,
  274.                 "glSelectBuffer too small to hold selection results",
  275.             )
  276.         elif currentMode == simple.GL_FEEDBACK:
  277.             raise error.GLError(
  278.                 simple.GL_STACK_OVERFLOW,
  279.                 "glFeedbackBuffer too small to hold selection results",
  280.             )
  281.         else:
  282.             raise error.GLError(
  283.                 simple.GL_STACK_OVERFLOW,
  284.                 "Unknown glRenderMode buffer (%s) too small to hold selection results"%(
  285.                     currentMode,
  286.                 ),
  287.             )
  288.     # Okay, now that the easy cases are out of the way...
  289.     #  Do we have a pre-stored pointer about which the user already knows?
  290.     context = platform.GetCurrentContext()
  291.     if context == 0:
  292.         raise error.Error(
  293.             """Returning from glRenderMode without a valid context!"""
  294.         )
  295.     arrayConstant, wrapperFunction = {
  296.         simple.GL_FEEDBACK: (simple.GL_FEEDBACK_BUFFER_POINTER,feedback.parseFeedback),
  297.         simple.GL_SELECT: (simple.GL_SELECTION_BUFFER_POINTER, selection.GLSelectRecord.fromArray),
  298.     }[ currentMode ]
  299.     current = contextdata.getValue( arrayConstant )
  300.     # XXX check to see if it's the *same* array we set currently!
  301.     if current is None:
  302.         current = glGetPointerv( arrayConstant )
  303.     # XXX now, can turn the array into the appropriate wrapper type...
  304.     if wrapperFunction:
  305.         current = wrapperFunction( current, result )
  306.     return current
  307.  
  308. # XXX this belongs in the GL module, not here!
  309. def glGetPointerv( constant ):
  310.     """Retrieve a stored pointer constant"""
  311.     # do we have a cached version of the pointer?
  312.     # get the base pointer from the underlying operation
  313.     vp = ctypes.voidp()
  314.     simple.glGetPointerv( constant, ctypes.byref(vp) )
  315.     current = contextdata.getValue( constant )
  316.     if current is not None:
  317.         if arrays.ArrayDatatype.dataPointer( current ) == vp.value:
  318.             return current
  319.     # XXX should be coercing to the proper type and converting to an array
  320.     return vp
  321.