| """Exceptional cases that need some extra wrapping""" |
| from OpenGL import arrays |
| from OpenGL.arrays.arraydatatype import GLfloatArray |
| from OpenGL.lazywrapper import lazy as _lazy |
| from OpenGL.GL.VERSION import GL_1_1 as full |
| from OpenGL.raw.GL import _errors |
| from OpenGL._bytes import bytes |
| from OpenGL import _configflags |
| from OpenGL._null import NULL as _NULL |
| import ctypes |
|
|
| __all__ = [ |
| 'glBegin', |
| 'glCallLists', |
| 'glColor', |
| 'glDeleteTextures', |
| 'glEnd', |
| 'glMap1d', |
| 'glMap1f', |
| 'glMap2d', |
| 'glMap2f', |
| 'glMaterial', |
| 'glRasterPos', |
| 'glTexParameter', |
| 'glVertex', |
| 'glAreTexturesResident', |
| ] |
|
|
| glRasterPosDispatch = { |
| 2: full.glRasterPos2d, |
| 3: full.glRasterPos3d, |
| 4: full.glRasterPos4d, |
| } |
|
|
| if _configflags.ERROR_CHECKING: |
| @_lazy( full.glBegin ) |
| def glBegin( baseFunction, mode ): |
| """Begin GL geometry-definition mode, disable automatic error checking""" |
| _errors._error_checker.onBegin( ) |
| return baseFunction( mode ) |
| @_lazy( full.glEnd ) |
| def glEnd( baseFunction ): |
| """Finish GL geometry-definition mode, re-enable automatic error checking""" |
| _errors._error_checker.onEnd( ) |
| return baseFunction( ) |
| else: |
| glBegin = full.glBegin |
| glEnd = full.glEnd |
|
|
| @_lazy( full.glDeleteTextures ) |
| def glDeleteTextures( baseFunction, size, array=_NULL ): |
| """Delete specified set of textures |
| |
| If array is *not* passed then `size` must be a `GLuintArray` |
| compatible object which can be sized using `arraySize`, the |
| result of which will be used as size. |
| """ |
| if array is _NULL: |
| ptr = arrays.GLuintArray.asArray( size ) |
| size = arrays.GLuintArray.arraySize( ptr ) |
| else: |
| ptr = array |
| return baseFunction( size, ptr ) |
|
|
|
|
| def glMap2( baseFunction, arrayType ): |
| def glMap2( target, u1, u2, v1, v2, points): |
| """glMap2(target, u1, u2, v1, v2, points[][][]) -> None |
| |
| This is a completely non-standard signature which doesn't allow for most |
| of the funky uses with strides and the like, but it has been like this for |
| a very long time... |
| """ |
| ptr = arrayType.asArray( points ) |
| uorder,vorder,vstride = arrayType.dimensions( ptr ) |
| ustride = vstride*vorder |
| return baseFunction( |
| target, |
| u1, u2, |
| ustride, uorder, |
| v1, v2, |
| vstride, vorder, |
| ptr |
| ) |
| glMap2.__name__ = baseFunction.__name__ |
| glMap2.baseFunction = baseFunction |
| return glMap2 |
| glMap2d = glMap2( full.glMap2d, arrays.GLdoubleArray ) |
| glMap2f = glMap2( full.glMap2f, arrays.GLfloatArray ) |
| try: |
| del glMap2 |
| except NameError as err: |
| pass |
|
|
| def glMap1( baseFunction, arrayType ): |
| def glMap1(target,u1,u2,points): |
| """glMap1(target, u1, u2, points[][][]) -> None |
| |
| This is a completely non-standard signature which doesn't allow for most |
| of the funky uses with strides and the like, but it has been like this for |
| a very long time... |
| """ |
| ptr = arrayType.asArray( points ) |
| dims = arrayType.dimensions( ptr ) |
| uorder = dims[0] |
| ustride = dims[1] |
| return baseFunction( target, u1,u2,ustride,uorder, ptr ) |
| glMap1.__name__ == baseFunction.__name__ |
| glMap1.baseFunction = baseFunction |
| return glMap1 |
| glMap1d = glMap1( full.glMap1d, arrays.GLdoubleArray ) |
| glMap1f = glMap1( full.glMap1f, arrays.GLfloatArray ) |
| try: |
| del glMap1 |
| except NameError as err: |
| pass |
|
|
| def glRasterPos( *args ): |
| """Choose glRasterPosX based on number of args""" |
| if len(args) == 1: |
| |
| args = args[0] |
| function = glRasterPosDispatch[ len(args) ] |
| return function( *args ) |
|
|
| glVertexDispatch = { |
| 2: full.glVertex2d, |
| 3: full.glVertex3d, |
| 4: full.glVertex4d, |
| } |
| def glVertex( *args ): |
| """Choose glVertexX based on number of args""" |
| if len(args) == 1: |
| |
| args = args[0] |
| return glVertexDispatch[ len(args) ]( *args ) |
|
|
| @_lazy( full.glCallLists ) |
| def glCallLists( baseFunction, lists, *args ): |
| """glCallLists( bytes( lists ) or lists[] ) -> None |
| |
| Restricted version of glCallLists, takes a string or a GLuint compatible |
| array data-type and passes into the base function. |
| """ |
| if not len(args): |
| if isinstance( lists, bytes ): |
| return baseFunction( |
| len(lists), |
| full.GL_UNSIGNED_BYTE, |
| ctypes.c_void_p(arrays.GLubyteArray.dataPointer( lists )), |
| ) |
| ptr = arrays.GLuintArray.asArray( lists ) |
| size = arrays.GLuintArray.arraySize( ptr ) |
| return baseFunction( |
| size, |
| full.GL_UNSIGNED_INT, |
| ctypes.c_void_p( arrays.GLuintArray.dataPointer(ptr)) |
| ) |
| return baseFunction( lists, *args ) |
|
|
| def glTexParameter( target, pname, parameter ): |
| """Set a texture parameter, choose underlying call based on pname and parameter""" |
| if isinstance( parameter, float ): |
| return full.glTexParameterf( target, pname, parameter ) |
| elif isinstance( parameter, int ): |
| return full.glTexParameteri( target, pname, parameter ) |
| else: |
| value = GLfloatArray.asArray( parameter, full.GL_FLOAT ) |
| return full.glTexParameterfv( target, pname, value ) |
|
|
| def glMaterial( faces, constant, *args ): |
| """glMaterial -- convenience function to dispatch on argument type |
| |
| If passed a single argument in args, calls: |
| glMaterialfv( faces, constant, args[0] ) |
| else calls: |
| glMaterialf( faces, constant, *args ) |
| """ |
| if len(args) == 1: |
| arg = GLfloatArray.asArray( args[0] ) |
| if arg is None: |
| raise ValueError( """Null value in glMaterial: %s"""%(args,) ) |
| return full.glMaterialfv( faces, constant, arg ) |
| else: |
| return full.glMaterialf( faces, constant, *args ) |
|
|
| glColorDispatch = { |
| 3: full.glColor3fv, |
| 4: full.glColor4fv, |
| } |
|
|
| def glColor( *args ): |
| """glColor*f* -- convenience function to dispatch on argument type |
| |
| dispatches to glColor3f, glColor2f, glColor4f, glColor3f, glColor2f, glColor4f |
| depending on the arguments passed... |
| """ |
| arglen = len(args) |
| if arglen == 1: |
| arg = arrays.GLfloatArray.asArray( args[0] ) |
| function = glColorDispatch[arrays.GLfloatArray.arraySize( arg )] |
| return function( arg ) |
| elif arglen == 2: |
| return full.glColor2d( *args ) |
| elif arglen == 3: |
| return full.glColor3d( *args ) |
| elif arglen == 4: |
| return full.glColor4d( *args ) |
| else: |
| raise ValueError( """Don't know how to handle arguments: %s"""%(args,)) |
|
|
|
|
| |
| @_lazy( full.glAreTexturesResident ) |
| def glAreTexturesResident( baseFunction, *args ): |
| """Allow both Pythonic and C-style calls to glAreTexturesResident |
| |
| glAreTexturesResident( arrays.GLuintArray( textures) ) |
| |
| or |
| |
| glAreTexturesResident( int(n), arrays.GLuintArray( textures), arrays.GLuboolean( output) ) |
| |
| or |
| |
| glAreTexturesResident( int(n), arrays.GLuintArray( textures) ) |
| |
| returns the output arrays.GLubooleanArray |
| """ |
| if len(args) == 1: |
| |
| textures = args[0] |
| textures = arrays.GLuintArray.asArray( textures ) |
| n = arrays.GLuintArray.arraySize(textures) |
| output = arrays.GLbooleanArray.zeros( (n,)) |
| elif len(args) == 2: |
| try: |
| n = int( args[0] ) |
| except TypeError: |
| textures = args[0] |
| textures = arrays.GLuintArray.asArray( textures ) |
|
|
| n = arrays.GLuintArray.arraySize(textures) |
| output = args[1] |
| output = arrays.GLbooleanArray.asArray( output ) |
| else: |
| textures = args[1] |
| textures = arrays.GLuintArray.asArray( textures ) |
|
|
| output = arrays.GLbooleanArray.zeros( (n,)) |
| elif len(args) == 3: |
| n,textures,output = args |
| textures = arrays.GLuintArray.asArray( textures ) |
| output = arrays.GLbooleanArray.asArray( output ) |
| else: |
| raise TypeError( """Expected 1 to 3 arguments to glAreTexturesResident""" ) |
| texturePtr = arrays.GLuintArray.typedPointer( textures ) |
| outputPtr = arrays.GLbooleanArray.typedPointer( output ) |
| result = baseFunction( n, texturePtr, outputPtr ) |
| if result: |
| |
| for i in range(len(output)): |
| output[i] = 1 |
| return output |
|
|