Viewing file: pointers.py (13.52 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
"""Implementations for "held-pointers" of various types
This argument type is special because it is stored, that is, it needs to be cached on our side so that the memory address does not go out-of-scope
storedPointers = {} def glVertexPointerd( array ): "Natural writing of glVertexPointerd using standard ctypes" arg2 = GL_DOUBLE arg3 = 0 # stride arg4 = arrays.asArray(array, GL_DOUBLE) arg1 = arrays.arraySize( arg4, 'd' ) platform.OpenGL.glVertexPointer( arg1, arg2, arg3, arrays.ArrayDatatype.dataPointer(arg4) ) glCheckError() # only store if we successfully set the value... storedPointers[ GL_VERTEX_ARRAY ] = arg4 return arg4 """ from OpenGL import platform, arrays, error, wrapper, contextdata, converters, constant, ERROR_ON_COPY from OpenGL.raw import GL as simple from OpenGL.raw.GL import annotations import ctypes import weakref
GLsizei = ctypes.c_int GLenum = ctypes.c_uint GLint = ctypes.c_int # OpenGL-ctypes variables that mimic OpenGL constant operation... GL_INTERLEAVED_ARRAY_POINTER = constant.Constant( 'GL_INTERLEAVED_ARRAY_POINTER', -32910 )
__all__ = ( 'glColorPointer', 'glColorPointerb','glColorPointerd','glColorPointerf','glColorPointeri', 'glColorPointers','glColorPointerub','glColorPointerui','glColorPointerus', 'glEdgeFlagPointer', 'glEdgeFlagPointerb', 'glIndexPointer', 'glIndexPointerb','glIndexPointerd','glIndexPointerf', 'glIndexPointeri','glIndexPointers','glIndexPointerub', 'glNormalPointer', 'glNormalPointerb', 'glNormalPointerd','glNormalPointerf','glNormalPointeri','glNormalPointers', 'glTexCoordPointer', 'glTexCoordPointerb','glTexCoordPointerd','glTexCoordPointerf', 'glTexCoordPointeri','glTexCoordPointers', 'glVertexPointer', 'glVertexPointerb','glVertexPointerd','glVertexPointerf','glVertexPointeri', 'glVertexPointers', 'glDrawElements','glDrawElementsui','glDrawElementsub','glDrawElementsus', 'glFeedbackBuffer', 'glSelectBuffer', 'glRenderMode', 'glGetPointerv', 'glInterleavedArrays', 'GL_INTERLEAVED_ARRAY_POINTER', )
# Have to create *new* ctypes wrappers for the platform object! # We can't just alter the default one since we have different ways of # calling it
POINTER_FUNCTION_DATA = [ ('glColorPointerd', simple.glColorPointer, simple.GL_DOUBLE, simple.GL_COLOR_ARRAY_POINTER, 0, 3), ('glColorPointerf', simple.glColorPointer, simple.GL_FLOAT, simple.GL_COLOR_ARRAY_POINTER, 0, 3), ('glColorPointeri', simple.glColorPointer, simple.GL_INT, simple.GL_COLOR_ARRAY_POINTER, 0, 3), ('glColorPointers', simple.glColorPointer, simple.GL_SHORT, simple.GL_COLOR_ARRAY_POINTER, 0, 3), ('glColorPointerub', simple.glColorPointer, simple.GL_UNSIGNED_BYTE, simple.GL_COLOR_ARRAY_POINTER, 0, 3), # these data-types are mapped from diff Numeric types ('glColorPointerb', simple.glColorPointer, simple.GL_BYTE, simple.GL_COLOR_ARRAY_POINTER, 0, 3), ('glColorPointerui', simple.glColorPointer, simple.GL_UNSIGNED_INT, simple.GL_COLOR_ARRAY_POINTER, 0, 3), ('glColorPointerus', simple.glColorPointer, simple.GL_UNSIGNED_SHORT, simple.GL_COLOR_ARRAY_POINTER, 0, 3), ('glEdgeFlagPointerb', simple.glEdgeFlagPointer, simple.GL_BYTE, simple.GL_EDGE_FLAG_ARRAY_POINTER, 2, None),
('glIndexPointerd', simple.glIndexPointer, simple.GL_DOUBLE, simple.GL_INDEX_ARRAY_POINTER, 1, None), ('glIndexPointerf', simple.glIndexPointer, simple.GL_FLOAT, simple.GL_INDEX_ARRAY_POINTER, 1, None), ('glIndexPointeri', simple.glIndexPointer, simple.GL_INT, simple.GL_INDEX_ARRAY_POINTER, 1, None), ('glIndexPointerub', simple.glIndexPointer, simple.GL_UNSIGNED_BYTE, simple.GL_INDEX_ARRAY_POINTER, 1, None), ('glIndexPointers', simple.glIndexPointer, simple.GL_SHORT, simple.GL_INDEX_ARRAY_POINTER, 1, None), # these data-types are mapped from diff Numeric types ('glIndexPointerb', simple.glIndexPointer, simple.GL_BYTE, simple.GL_INDEX_ARRAY_POINTER, 1, None),
('glNormalPointerd', simple.glNormalPointer, simple.GL_DOUBLE, simple.GL_NORMAL_ARRAY_POINTER, 1, None), ('glNormalPointerf', simple.glNormalPointer, simple.GL_FLOAT, simple.GL_NORMAL_ARRAY_POINTER, 1, None), ('glNormalPointeri', simple.glNormalPointer, simple.GL_INT, simple.GL_NORMAL_ARRAY_POINTER, 1, None), ('glNormalPointerb', simple.glNormalPointer, simple.GL_BYTE, simple.GL_NORMAL_ARRAY_POINTER, 1, None), ('glNormalPointers', simple.glNormalPointer, simple.GL_SHORT, simple.GL_NORMAL_ARRAY_POINTER, 1, None),
('glTexCoordPointerd', simple.glTexCoordPointer, simple.GL_DOUBLE, simple.GL_TEXTURE_COORD_ARRAY_POINTER, 0, 2), ('glTexCoordPointerf', simple.glTexCoordPointer, simple.GL_FLOAT, simple.GL_TEXTURE_COORD_ARRAY_POINTER, 0, 2), ('glTexCoordPointeri', simple.glTexCoordPointer, simple.GL_INT, simple.GL_TEXTURE_COORD_ARRAY_POINTER, 0, 2), ('glTexCoordPointerb', simple.glTexCoordPointer, simple.GL_BYTE, simple.GL_TEXTURE_COORD_ARRAY_POINTER, 0, 2), ('glTexCoordPointers', simple.glTexCoordPointer, simple.GL_SHORT, simple.GL_TEXTURE_COORD_ARRAY_POINTER, 0, 2),
('glVertexPointerd', simple.glVertexPointer, simple.GL_DOUBLE, simple.GL_VERTEX_ARRAY_POINTER, 0, 3), ('glVertexPointerf', simple.glVertexPointer, simple.GL_FLOAT, simple.GL_VERTEX_ARRAY_POINTER, 0, 3), ('glVertexPointeri', simple.glVertexPointer, simple.GL_INT, simple.GL_VERTEX_ARRAY_POINTER, 0, 3), ('glVertexPointerb', simple.glVertexPointer, simple.GL_INT, simple.GL_VERTEX_ARRAY_POINTER, 0, 3), ('glVertexPointers', simple.glVertexPointer, simple.GL_SHORT, simple.GL_VERTEX_ARRAY_POINTER, 0, 3), ] def wrapPointerFunction( name, baseFunction, glType, arrayType,startArgs, defaultSize ): """Wrap the given pointer-setting function""" function= wrapper.wrapper( baseFunction ) assert not getattr( function, 'pyConverters', None ), """Reusing wrappers?""" if arrayType: arrayModuleType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ glType ] function.setPyConverter( 'pointer', arrays.asArrayType(arrayModuleType) ) else: function.setPyConverter( 'pointer', arrays.AsArrayOfType('pointer','type') ) function.setCConverter( 'pointer', converters.getPyArgsName( 'pointer' ) ) if 'size' in function.argNames: function.setPyConverter( 'size' ) function.setCConverter( 'size', arrays.arraySizeOfFirstType(arrayModuleType,defaultSize) ) if 'type' in function.argNames: function.setPyConverter( 'type' ) function.setCConverter( 'type', glType ) if 'stride' in function.argNames: function.setPyConverter( 'stride' ) function.setCConverter( 'stride', 0 ) function.setStoreValues( arrays.storePointerType( 'pointer', arrayType ) ) function.setReturnValues( wrapper.returnPyArgument( 'pointer' ) ) return name,function
for name,function in [ wrapPointerFunction( *args ) for args in POINTER_FUNCTION_DATA ]: globals()[name] = function del name, function
glVertexPointer = wrapper.wrapper( simple.glVertexPointer ).setPyConverter( 'pointer', arrays.AsArrayOfType( 'pointer', 'type' ), ).setStoreValues( arrays.storePointerType( 'pointer', simple.GL_VERTEX_ARRAY_POINTER ) ).setReturnValues( wrapper.returnPyArgument( 'pointer' ) ) glTexCoordPointer = wrapper.wrapper( simple.glTexCoordPointer ).setPyConverter( 'pointer', arrays.AsArrayOfType( 'pointer', 'type' ), ).setStoreValues( arrays.storePointerType( 'pointer', simple.GL_TEXTURE_COORD_ARRAY_POINTER ) ).setReturnValues( wrapper.returnPyArgument( 'pointer' ) ) glNormalPointer = wrapper.wrapper( simple.glNormalPointer ).setPyConverter( 'pointer', arrays.AsArrayOfType( 'pointer', 'type' ), ).setStoreValues( arrays.storePointerType( 'pointer', simple.GL_NORMAL_ARRAY_POINTER ) ).setReturnValues( wrapper.returnPyArgument( 'pointer' ) ) glIndexPointer = wrapper.wrapper( simple.glIndexPointer ).setPyConverter( 'pointer', arrays.AsArrayOfType( 'pointer', 'type' ), ).setStoreValues( arrays.storePointerType( 'pointer', simple.GL_INDEX_ARRAY_POINTER ) ).setReturnValues( wrapper.returnPyArgument( 'pointer' ) ) glEdgeFlagPointer = wrapper.wrapper( simple.glEdgeFlagPointer ).setPyConverter( # XXX type is wrong! 'pointer', arrays.AsArrayTyped( 'pointer', arrays.GLushortArray ), ).setStoreValues( arrays.storePointerType( 'pointer', simple.GL_EDGE_FLAG_ARRAY_POINTER ) ).setReturnValues( wrapper.returnPyArgument( 'pointer' ) ) glColorPointer = wrapper.wrapper( simple.glColorPointer ).setPyConverter( 'pointer', arrays.AsArrayOfType( 'pointer', 'type' ), ).setStoreValues( arrays.storePointerType( 'pointer', simple.GL_COLOR_ARRAY_POINTER ) ).setReturnValues( wrapper.returnPyArgument( 'pointer' ) ) glInterleavedArrays = wrapper.wrapper( simple.glInterleavedArrays ).setStoreValues( arrays.storePointerType( 'pointer', GL_INTERLEAVED_ARRAY_POINTER ) ).setReturnValues( wrapper.returnPyArgument( 'pointer' ) )
glDrawElements = wrapper.wrapper( simple.glDrawElements ).setPyConverter( 'indices', arrays.AsArrayOfType( 'indices', 'type' ), ).setReturnValues( wrapper.returnPyArgument( 'indices' ) )
def glDrawElementsTyped( type, suffix ): arrayType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ type ] function = wrapper.wrapper( simple.glDrawElements ).setPyConverter('type').setCConverter( 'type', type ).setPyConverter('count').setCConverter( 'count', arrays.AsArrayTypedSize( 'indices', arrayType ), ).setPyConverter( 'indices', arrays.AsArrayTyped( 'indices', arrayType ), ).setReturnValues( wrapper.returnPyArgument( 'indices' ) ) return function for type,suffix in ((simple.GL_UNSIGNED_BYTE,'ub'),(simple.GL_UNSIGNED_INT,'ui'),(simple.GL_UNSIGNED_SHORT,'us')): globals()['glDrawElements%(suffix)s'%globals()] = glDrawElementsTyped( type,suffix ) del type,suffix,glDrawElementsTyped
# create buffer of given size and return it for future reference # keep a per-context weakref around to allow us to return the original # array we returned IFF the user has kept a reference as well... def glSelectBuffer( size, buffer = None ): """Create a selection buffer of the given size """ if buffer is None: buffer = arrays.GLuintArray.zeros( (size,) ) simple.glSelectBuffer( size, buffer ) contextdata.setValue( simple.GL_SELECTION_BUFFER_POINTER, buffer ) return buffer def glFeedbackBuffer( size, type, buffer = None ): """Create a selection buffer of the given size """ if buffer is None: buffer = arrays.GLfloatArray.zeros( (size,) ) simple.glFeedbackBuffer( size, type, buffer ) contextdata.setValue( simple.GL_FEEDBACK_BUFFER_POINTER, buffer ) contextdata.setValue( "GL_FEEDBACK_BUFFER_TYPE", type ) return buffer
def glRenderMode( newMode ): """Change to the given rendering mode If the current mode is GL_FEEDBACK or GL_SELECT, return the current buffer appropriate to the mode """ # must get the current mode to determine operation... from OpenGL.GL import glGetIntegerv from OpenGL.GL import selection, feedback currentMode = glGetIntegerv( simple.GL_RENDER_MODE ) try: currentMode = currentMode[0] except (TypeError,ValueError,IndexError), err: pass if currentMode in (simple.GL_RENDER,0): # no array needs to be returned... return simple.glRenderMode( newMode ) result = simple.glRenderMode( newMode ) # result is now an integer telling us how many elements were copied... if result < 0: if currentMode == simple.GL_SELECT: raise error.GLError( simple.GL_STACK_OVERFLOW, "glSelectBuffer too small to hold selection results", ) elif currentMode == simple.GL_FEEDBACK: raise error.GLError( simple.GL_STACK_OVERFLOW, "glFeedbackBuffer too small to hold selection results", ) else: raise error.GLError( simple.GL_STACK_OVERFLOW, "Unknown glRenderMode buffer (%s) too small to hold selection results"%( currentMode, ), ) # Okay, now that the easy cases are out of the way... # Do we have a pre-stored pointer about which the user already knows? context = platform.GetCurrentContext() if context == 0: raise error.Error( """Returning from glRenderMode without a valid context!""" ) arrayConstant, wrapperFunction = { simple.GL_FEEDBACK: (simple.GL_FEEDBACK_BUFFER_POINTER,feedback.parseFeedback), simple.GL_SELECT: (simple.GL_SELECTION_BUFFER_POINTER, selection.GLSelectRecord.fromArray), }[ currentMode ] current = contextdata.getValue( arrayConstant ) # XXX check to see if it's the *same* array we set currently! if current is None: current = glGetPointerv( arrayConstant ) # XXX now, can turn the array into the appropriate wrapper type... if wrapperFunction: current = wrapperFunction( current, result ) return current
# XXX this belongs in the GL module, not here! def glGetPointerv( constant ): """Retrieve a stored pointer constant""" # do we have a cached version of the pointer? # get the base pointer from the underlying operation vp = ctypes.voidp() simple.glGetPointerv( constant, ctypes.byref(vp) ) current = contextdata.getValue( constant ) if current is not None: if arrays.ArrayDatatype.dataPointer( current ) == vp.value: return current # XXX should be coercing to the proper type and converting to an array return vp
|