1"""Exceptional cases that need some extra wrapping""" 2from OpenGL import arrays 3from OpenGL.arrays.arraydatatype import GLfloatArray 4from OpenGL.lazywrapper import lazy as _lazy 5from OpenGL.GL.VERSION import GL_1_1 as full 6from OpenGL.raw.GL import _errors 7from OpenGL._bytes import bytes 8from OpenGL import _configflags 9from OpenGL._null import NULL as _NULL 10import ctypes 11 12__all__ = [ 13 'glBegin', 14 'glCallLists', 15 'glColor', 16 'glDeleteTextures', 17 'glEnd', 18 'glMap1d', 19 'glMap1f', 20 'glMap2d', 21 'glMap2f', 22 'glMaterial', 23 'glRasterPos', 24 'glTexParameter', 25 'glVertex', 26 'glAreTexturesResident', 27] 28 29glRasterPosDispatch = { 30 2: full.glRasterPos2d, 31 3: full.glRasterPos3d, 32 4: full.glRasterPos4d, 33} 34 35if _configflags.ERROR_CHECKING: 36 @_lazy( full.glBegin ) 37 def glBegin( baseFunction, mode ): 38 """Begin GL geometry-definition mode, disable automatic error checking""" 39 _errors._error_checker.onBegin( ) 40 return baseFunction( mode ) 41 @_lazy( full.glEnd ) 42 def glEnd( baseFunction ): 43 """Finish GL geometry-definition mode, re-enable automatic error checking""" 44 _errors._error_checker.onEnd( ) 45 return baseFunction( ) 46else: 47 glBegin = full.glBegin 48 glEnd = full.glEnd 49 50@_lazy( full.glDeleteTextures ) 51def glDeleteTextures( baseFunction, size, array=_NULL ): 52 """Delete specified set of textures 53 54 If array is *not* passed then `size` must be a `GLuintArray` 55 compatible object which can be sized using `arraySize`, the 56 result of which will be used as size. 57 """ 58 if array is _NULL: 59 ptr = arrays.GLuintArray.asArray( size ) 60 size = arrays.GLuintArray.arraySize( ptr ) 61 else: 62 ptr = array 63 return baseFunction( size, ptr ) 64 65 66def glMap2( baseFunction, arrayType ): 67 def glMap2( target, u1, u2, v1, v2, points): 68 """glMap2(target, u1, u2, v1, v2, points[][][]) -> None 69 70 This is a completely non-standard signature which doesn't allow for most 71 of the funky uses with strides and the like, but it has been like this for 72 a very long time... 73 """ 74 ptr = arrayType.asArray( points ) 75 uorder,vorder,vstride = arrayType.dimensions( ptr ) 76 ustride = vstride*vorder 77 return baseFunction( 78 target, 79 u1, u2, 80 ustride, uorder, 81 v1, v2, 82 vstride, vorder, 83 ptr 84 ) 85 glMap2.__name__ = baseFunction.__name__ 86 glMap2.baseFunction = baseFunction 87 return glMap2 88glMap2d = glMap2( full.glMap2d, arrays.GLdoubleArray ) 89glMap2f = glMap2( full.glMap2f, arrays.GLfloatArray ) 90try: 91 del glMap2 92except NameError as err: 93 pass 94 95def glMap1( baseFunction, arrayType ): 96 def glMap1(target,u1,u2,points): 97 """glMap1(target, u1, u2, points[][][]) -> None 98 99 This is a completely non-standard signature which doesn't allow for most 100 of the funky uses with strides and the like, but it has been like this for 101 a very long time... 102 """ 103 ptr = arrayType.asArray( points ) 104 dims = arrayType.dimensions( ptr ) 105 uorder = dims[0] 106 ustride = dims[1] 107 return baseFunction( target, u1,u2,ustride,uorder, ptr ) 108 glMap1.__name__ == baseFunction.__name__ 109 glMap1.baseFunction = baseFunction 110 return glMap1 111glMap1d = glMap1( full.glMap1d, arrays.GLdoubleArray ) 112glMap1f = glMap1( full.glMap1f, arrays.GLfloatArray ) 113try: 114 del glMap1 115except NameError as err: 116 pass 117 118def glRasterPos( *args ): 119 """Choose glRasterPosX based on number of args""" 120 if len(args) == 1: 121 # v form... 122 args = args[0] 123 function = glRasterPosDispatch[ len(args) ] 124 return function( *args ) 125 126glVertexDispatch = { 127 2: full.glVertex2d, 128 3: full.glVertex3d, 129 4: full.glVertex4d, 130} 131def glVertex( *args ): 132 """Choose glVertexX based on number of args""" 133 if len(args) == 1: 134 # v form... 135 args = args[0] 136 return glVertexDispatch[ len(args) ]( *args ) 137 138@_lazy( full.glCallLists ) 139def glCallLists( baseFunction, lists, *args ): 140 """glCallLists( bytes( lists ) or lists[] ) -> None 141 142 Restricted version of glCallLists, takes a string or a GLuint compatible 143 array data-type and passes into the base function. 144 """ 145 if not len(args): 146 if isinstance( lists, bytes ): 147 return baseFunction( 148 len(lists), 149 full.GL_UNSIGNED_BYTE, 150 ctypes.c_void_p(arrays.GLubyteArray.dataPointer( lists )), 151 ) 152 ptr = arrays.GLuintArray.asArray( lists ) 153 size = arrays.GLuintArray.arraySize( ptr ) 154 return baseFunction( 155 size, 156 full.GL_UNSIGNED_INT, 157 ctypes.c_void_p( arrays.GLuintArray.dataPointer(ptr)) 158 ) 159 return baseFunction( lists, *args ) 160 161def glTexParameter( target, pname, parameter ): 162 """Set a texture parameter, choose underlying call based on pname and parameter""" 163 if isinstance( parameter, float ): 164 return full.glTexParameterf( target, pname, parameter ) 165 elif isinstance( parameter, int ): 166 return full.glTexParameteri( target, pname, parameter ) 167 else: 168 value = GLfloatArray.asArray( parameter, full.GL_FLOAT ) 169 return full.glTexParameterfv( target, pname, value ) 170 171def glMaterial( faces, constant, *args ): 172 """glMaterial -- convenience function to dispatch on argument type 173 174 If passed a single argument in args, calls: 175 glMaterialfv( faces, constant, args[0] ) 176 else calls: 177 glMaterialf( faces, constant, *args ) 178 """ 179 if len(args) == 1: 180 arg = GLfloatArray.asArray( args[0] ) 181 if arg is None: 182 raise ValueError( """Null value in glMaterial: %s"""%(args,) ) 183 return full.glMaterialfv( faces, constant, arg ) 184 else: 185 return full.glMaterialf( faces, constant, *args ) 186 187glColorDispatch = { 188 3: full.glColor3fv, 189 4: full.glColor4fv, 190} 191 192def glColor( *args ): 193 """glColor*f* -- convenience function to dispatch on argument type 194 195 dispatches to glColor3f, glColor2f, glColor4f, glColor3f, glColor2f, glColor4f 196 depending on the arguments passed... 197 """ 198 arglen = len(args) 199 if arglen == 1: 200 arg = arrays.GLfloatArray.asArray( args[0] ) 201 function = glColorDispatch[arrays.GLfloatArray.arraySize( arg )] 202 return function( arg ) 203 elif arglen == 2: 204 return full.glColor2d( *args ) 205 elif arglen == 3: 206 return full.glColor3d( *args ) 207 elif arglen == 4: 208 return full.glColor4d( *args ) 209 else: 210 raise ValueError( """Don't know how to handle arguments: %s"""%(args,)) 211 212 213# Rectagle coordinates, 214@_lazy( full.glAreTexturesResident ) 215def glAreTexturesResident( baseFunction, *args ): 216 """Allow both Pythonic and C-style calls to glAreTexturesResident 217 218 glAreTexturesResident( arrays.GLuintArray( textures) ) 219 220 or 221 222 glAreTexturesResident( int(n), arrays.GLuintArray( textures), arrays.GLuboolean( output) ) 223 224 or 225 226 glAreTexturesResident( int(n), arrays.GLuintArray( textures) ) 227 228 returns the output arrays.GLubooleanArray 229 """ 230 if len(args) == 1: 231 # Pythonic form... 232 textures = args[0] 233 textures = arrays.GLuintArray.asArray( textures ) 234 n = arrays.GLuintArray.arraySize(textures) 235 output = arrays.GLbooleanArray.zeros( (n,)) 236 elif len(args) == 2: 237 try: 238 n = int( args[0] ) 239 except TypeError: 240 textures = args[0] 241 textures = arrays.GLuintArray.asArray( textures ) 242 243 n = arrays.GLuintArray.arraySize(textures) 244 output = args[1] 245 output = arrays.GLbooleanArray.asArray( output ) 246 else: 247 textures = args[1] 248 textures = arrays.GLuintArray.asArray( textures ) 249 250 output = arrays.GLbooleanArray.zeros( (n,)) 251 elif len(args) == 3: 252 n,textures,output = args 253 textures = arrays.GLuintArray.asArray( textures ) 254 output = arrays.GLbooleanArray.asArray( output ) 255 else: 256 raise TypeError( """Expected 1 to 3 arguments to glAreTexturesResident""" ) 257 texturePtr = arrays.GLuintArray.typedPointer( textures ) 258 outputPtr = arrays.GLbooleanArray.typedPointer( output ) 259 result = baseFunction( n, texturePtr, outputPtr ) 260 if result: 261 # weirdness of the C api, doesn't produce values if all are true 262 for i in range(len(output)): 263 output[i] = 1 264 return output 265