1"""Image-handling routines 2 3### Unresolved: 4 5 Following methods are not yet resolved due to my not being sure how the 6 function should be wrapped: 7 8 glCompressedTexImage3D 9 glCompressedTexImage2D 10 glCompressedTexImage1D 11 glCompressedTexSubImage3D 12 glCompressedTexSubImage2D 13 glCompressedTexSubImage1D 14""" 15from OpenGL.raw.GL.VERSION import GL_1_1,GL_1_2, GL_3_0 16from OpenGL import images, arrays, wrapper 17from OpenGL._bytes import bytes,integer_types 18from OpenGL.raw.GL import _types 19import ctypes 20 21def asInt( value ): 22 if isinstance( value, float ): 23 return int(round(value,0)) 24 return value 25 26## update the image tables with standard image types... 27images.COMPONENT_COUNTS.update( { 28 GL_1_1.GL_BITMAP : 1, # must be GL_UNSIGNED_BYTE 29 30 GL_1_1.GL_RED : 1, 31 GL_1_1.GL_GREEN : 1, 32 GL_1_1.GL_BLUE : 1, 33 GL_1_1.GL_ALPHA : 1, 34 GL_3_0.GL_RED_INTEGER : 1, 35 GL_3_0.GL_GREEN_INTEGER : 1, 36 GL_3_0.GL_BLUE_INTEGER : 1, 37 GL_3_0.GL_ALPHA_INTEGER : 1, 38 GL_1_1.GL_LUMINANCE : 1, 39 GL_1_1.GL_LUMINANCE_ALPHA : 2, 40 GL_1_1.GL_COLOR_INDEX : 1, 41 GL_1_1.GL_STENCIL_INDEX : 1, 42 GL_1_1.GL_DEPTH_COMPONENT : 1, 43 44 GL_1_1.GL_RGB : 3, 45 GL_1_2.GL_BGR : 3, 46 GL_3_0.GL_RGB16F : 3, 47 GL_3_0.GL_RGB16I : 3, 48 GL_3_0.GL_RGB16UI : 3, 49 GL_3_0.GL_RGB32F : 3, 50 GL_3_0.GL_RGB32I : 3, 51 GL_3_0.GL_RGB32UI : 3, 52 GL_3_0.GL_RGB8I : 3, 53 GL_3_0.GL_RGB8UI : 3, 54 GL_3_0.GL_RGB9_E5 : 3, 55 GL_3_0.GL_RGB_INTEGER : 3, 56 57 GL_1_1.GL_RGBA : 4, 58 GL_1_2.GL_BGRA : 4, 59 GL_3_0.GL_RGBA16F : 4, 60 GL_3_0.GL_RGBA16I : 4, 61 GL_3_0.GL_RGBA16UI : 4, 62 GL_3_0.GL_RGBA32F : 4, 63 GL_3_0.GL_RGBA32I : 4, 64 GL_3_0.GL_RGBA32UI : 4, 65 GL_3_0.GL_RGBA8I : 4, 66 GL_3_0.GL_RGBA8UI : 4, 67 GL_3_0.GL_RGBA_INTEGER : 4, 68} ) 69 70images.TYPE_TO_ARRAYTYPE.update( { 71 GL_1_2.GL_UNSIGNED_BYTE_3_3_2 : GL_1_1.GL_UNSIGNED_BYTE, 72 GL_1_2.GL_UNSIGNED_BYTE_2_3_3_REV : GL_1_1.GL_UNSIGNED_BYTE, 73 GL_1_2.GL_UNSIGNED_SHORT_4_4_4_4 : GL_1_1.GL_UNSIGNED_SHORT, 74 GL_1_2.GL_UNSIGNED_SHORT_4_4_4_4_REV : GL_1_1.GL_UNSIGNED_SHORT, 75 GL_1_2.GL_UNSIGNED_SHORT_5_5_5_1 : GL_1_1.GL_UNSIGNED_SHORT, 76 GL_1_2.GL_UNSIGNED_SHORT_1_5_5_5_REV : GL_1_1.GL_UNSIGNED_SHORT, 77 GL_1_2.GL_UNSIGNED_SHORT_5_6_5 : GL_1_1.GL_UNSIGNED_SHORT, 78 GL_1_2.GL_UNSIGNED_SHORT_5_6_5_REV : GL_1_1.GL_UNSIGNED_SHORT, 79 GL_1_2.GL_UNSIGNED_INT_8_8_8_8 : GL_1_1.GL_UNSIGNED_INT, 80 GL_1_2.GL_UNSIGNED_INT_8_8_8_8_REV : GL_1_1.GL_UNSIGNED_INT, 81 GL_1_2.GL_UNSIGNED_INT_10_10_10_2 : GL_1_1.GL_UNSIGNED_INT, 82 GL_1_2.GL_UNSIGNED_INT_2_10_10_10_REV : GL_1_1.GL_UNSIGNED_INT, 83 GL_1_1.GL_UNSIGNED_BYTE : GL_1_1.GL_UNSIGNED_BYTE, 84 GL_1_1.GL_BYTE: GL_1_1.GL_BYTE, 85 GL_1_1.GL_UNSIGNED_SHORT : GL_1_1.GL_UNSIGNED_SHORT, 86 GL_1_1.GL_SHORT : GL_1_1.GL_SHORT, 87 GL_1_1.GL_UNSIGNED_INT : GL_1_1.GL_UNSIGNED_INT, 88 GL_1_1.GL_INT : GL_1_1.GL_INT, 89 GL_1_1.GL_FLOAT : GL_1_1.GL_FLOAT, 90 GL_1_1.GL_DOUBLE : GL_1_1.GL_DOUBLE, 91 GL_1_1.GL_BITMAP : GL_1_1.GL_UNSIGNED_BYTE, 92} ) 93images.TIGHT_PACK_FORMATS.update({ 94 GL_1_2.GL_UNSIGNED_BYTE_3_3_2 : 3, 95 GL_1_2.GL_UNSIGNED_BYTE_2_3_3_REV : 3, 96 GL_1_2.GL_UNSIGNED_SHORT_4_4_4_4 : 4, 97 GL_1_2.GL_UNSIGNED_SHORT_4_4_4_4_REV : 4, 98 GL_1_2.GL_UNSIGNED_SHORT_5_5_5_1 : 4, 99 GL_1_2.GL_UNSIGNED_SHORT_1_5_5_5_REV : 4, 100 GL_1_2.GL_UNSIGNED_SHORT_5_6_5 : 3, 101 GL_1_2.GL_UNSIGNED_SHORT_5_6_5_REV : 3, 102 GL_1_2.GL_UNSIGNED_INT_8_8_8_8 : 4, 103 GL_1_2.GL_UNSIGNED_INT_8_8_8_8_REV : 4, 104 GL_1_2.GL_UNSIGNED_INT_10_10_10_2 : 4, 105 GL_1_2.GL_UNSIGNED_INT_2_10_10_10_REV : 4, 106 GL_1_1.GL_BITMAP: 8, # single bits, 8 of them... 107}) 108 109images.RANK_PACKINGS.update( { 110 4: [ 111 # Note the sgis parameters are skipped here unless you import 112 # the sgis texture4D extension... 113 (GL_1_1.glPixelStorei,GL_1_1.GL_PACK_ALIGNMENT, 1), 114 ], 115 3: [ 116 (GL_1_1.glPixelStorei,GL_1_2.GL_PACK_SKIP_IMAGES, 0), 117 (GL_1_1.glPixelStorei,GL_1_2.GL_PACK_IMAGE_HEIGHT, 0), 118 (GL_1_1.glPixelStorei,GL_1_1.GL_PACK_ALIGNMENT, 1), 119 ], 120 2: [ 121 (GL_1_1.glPixelStorei,GL_1_1.GL_PACK_ROW_LENGTH, 0), 122 (GL_1_1.glPixelStorei,GL_1_1.GL_PACK_SKIP_ROWS, 0), 123 (GL_1_1.glPixelStorei,GL_1_1.GL_PACK_ALIGNMENT, 1), 124 ], 125 1: [ 126 (GL_1_1.glPixelStorei,GL_1_1.GL_PACK_SKIP_PIXELS, 0), 127 (GL_1_1.glPixelStorei,GL_1_1.GL_PACK_ALIGNMENT, 1), 128 ], 129} ) 130 131 132__all__ = ( 133 'glReadPixels', 134 'glReadPixelsb', 135 'glReadPixelsd', 136 'glReadPixelsf', 137 'glReadPixelsi', 138 'glReadPixelss', 139 'glReadPixelsub', 140 'glReadPixelsui', 141 'glReadPixelsus', 142 143 'glGetTexImage', 144 145 'glDrawPixels', 146 'glDrawPixelsb', 147 'glDrawPixelsf', 148 'glDrawPixelsi', 149 'glDrawPixelss', 150 'glDrawPixelsub', 151 'glDrawPixelsui', 152 'glDrawPixelsus', 153 154 155 'glTexSubImage2D', 156 'glTexSubImage1D', 157 #'glTexSubImage3D', 158 159 'glTexImage1D', 160 'glTexImage2D', 161 #'glTexImage3D', 162 163 'glGetTexImageb', 164 'glGetTexImaged', 165 'glGetTexImagef', 166 'glGetTexImagei', 167 'glGetTexImages', 168 'glGetTexImageub', 169 'glGetTexImageui', 170 'glGetTexImageus', 171 'glTexImage1Db', 172 'glTexImage2Db', 173 #'glTexImage3Db', 174 'glTexSubImage1Db', 175 'glTexSubImage2Db', 176 #'glTexSubImage3Db', 177 'glTexImage1Df', 178 'glTexImage2Df', 179 #'glTexImage3Df', 180 'glTexSubImage1Df', 181 'glTexSubImage2Df', 182 #'glTexSubImage3Df', 183 'glTexImage1Di', 184 'glTexImage2Di', 185 #'glTexImage3Di', 186 'glTexSubImage1Di', 187 'glTexSubImage2Di', 188 #'glTexSubImage3Di', 189 'glTexImage1Ds', 190 'glTexImage2Ds', 191 #'glTexImage3Ds', 192 'glTexSubImage1Ds', 193 'glTexSubImage2Ds', 194 #'glTexSubImage3Ds', 195 'glTexImage1Dub', 196 'glTexImage2Dub', 197 #'glTexImage3Dub', 198 'glTexSubImage1Dub', 199 'glTexSubImage2Dub', 200 #'glTexSubImage3Dub', 201 'glTexImage1Dui', 202 'glTexImage2Dui', 203 #'glTexImage3Dui', 204 'glTexSubImage1Dui', 205 'glTexSubImage2Dui', 206 #'glTexSubImage3Dui', 207 'glTexImage1Dus', 208 'glTexImage2Dus', 209 #'glTexImage3Dus', 210 'glTexSubImage1Dus', 211 'glTexSubImage2Dus', 212 #'glTexSubImage3Dus', 213 214 #'glColorTable', 215 #'glGetColorTable', 216 #'glColorSubTable', 217 218 #'glConvolutionFilter1D', 219 #'glConvolutionFilter2D', 220 #'glGetConvolutionFilter', 221 #'glSeparableFilter2D', 222 #'glGetSeparableFilter', 223 224 #'glGetMinmax', 225) 226 227def _get_texture_level_dims(target,level): 228 """Retrieve texture dims for given level and target""" 229 dims = [] 230 dim = _types.GLuint() 231 GL_1_1.glGetTexLevelParameteriv( target, level, GL_1_1.GL_TEXTURE_WIDTH, dim ) 232 dims = [dim.value] 233 if target != GL_1_1.GL_TEXTURE_1D: 234 GL_1_1.glGetTexLevelParameteriv( target, level, GL_1_1.GL_TEXTURE_HEIGHT, dim ) 235 dims.append( dim.value ) 236 if target != GL_1_1.GL_TEXTURE_2D: 237 GL_1_1.glGetTexLevelParameteriv( target, level, GL_1_1.GL_TEXTURE_DEPTH, dim ) 238 dims.append( dim.value ) 239 return dims 240 241for suffix,type in [ 242 ('b',GL_1_1.GL_BYTE), 243 ('d',GL_1_1.GL_DOUBLE), 244 ('f',GL_1_1.GL_FLOAT), 245 ('i',GL_1_1.GL_INT), 246 ('s',GL_1_1.GL_SHORT), 247 ('ub',GL_1_1.GL_UNSIGNED_BYTE), 248 ('ui',GL_1_1.GL_UNSIGNED_INT), 249 ('us',GL_1_1.GL_UNSIGNED_SHORT), 250]: 251 def glReadPixels( x,y,width,height,format,type=type, array=None, outputType=bytes ): 252 """Read specified pixels from the current display buffer 253 254 This typed version returns data in your specified default 255 array data-type format, or in the passed array, which will 256 be converted to the array-type required by the format. 257 """ 258 x,y,width,height = asInt(x),asInt(y),asInt(width),asInt(height) 259 arrayType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ images.TYPE_TO_ARRAYTYPE.get(type,type) ] 260 261 if array is None: 262 array = imageData = images.SetupPixelRead( format, (width,height), type ) 263 owned = True 264 else: 265 if isinstance( array, integer_types): 266 imageData = ctypes.c_void_p( array ) 267 else: 268 array = arrayType.asArray( array ) 269 imageData = arrayType.voidDataPointer( array ) 270 owned = False 271 GL_1_1.glReadPixels( 272 x,y, 273 width, height, 274 format,type, 275 imageData 276 ) 277 if owned and outputType is bytes: 278 return images.returnFormat( array, type ) 279 else: 280 return array 281 globals()["glReadPixels%s"%(suffix,)] = glReadPixels 282 def glGetTexImage( target, level,format,type=type, array=None, outputType=bytes ): 283 """Get a texture-level as an image 284 285 target -- enum constant for the texture engine to be read 286 level -- the mip-map level to read 287 format -- image format to read out the data 288 type -- data-type into which to read the data 289 array -- optional array/offset into which to store the value 290 291 outputType -- default (bytes) provides string output of the 292 results iff OpenGL.UNSIGNED_BYTE_IMAGES_AS_STRING is True 293 and type == GL_UNSIGNED_BYTE. Any other value will cause 294 output in the default array output format. 295 296 returns the pixel data array in the format defined by the 297 format, type and outputType 298 """ 299 arrayType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ images.TYPE_TO_ARRAYTYPE.get(type,type) ] 300 if array is None: 301 dims = _get_texture_level_dims(target,level) 302 array = imageData = images.SetupPixelRead( format, tuple(dims), type ) 303 owned = True 304 else: 305 if isinstance( array, integer_types): 306 imageData = ctypes.c_void_p( array ) 307 else: 308 array = arrayType.asArray( array ) 309 imageData = arrayType.voidDataPointer( array ) 310 owned = False 311 GL_1_1.glGetTexImage( 312 target, level, format, type, imageData 313 ) 314 if owned and outputType is bytes: 315 return images.returnFormat( array, type ) 316 else: 317 return array 318 globals()["glGetTexImage%s"%(suffix,)] = glGetTexImage 319## def glGetTexSubImage( target, level,format,type ): 320## """Get a texture-level as an image""" 321## dims = [GL_1_1.glGetTexLevelParameteriv( target, level, GL_1_1.GL_TEXTURE_WIDTH )] 322## if target != GL_1_1.GL_TEXTURE_1D: 323## dims.append( GL_1_1.glGetTexLevelParameteriv( target, level, GL_1_1.GL_TEXTURE_HEIGHT ) ) 324## if target != GL_1_1.GL_TEXTURE_2D: 325## dims.append( GL_1_1.glGetTexLevelParameteriv( target, level, GL_1_2.GL_TEXTURE_DEPTH ) ) 326## array = images.SetupPixelRead( format, tuple(dims), type ) 327## arrayType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ images.TYPE_TO_ARRAYTYPE.get(type,type) ] 328## GL_1_1.glGetTexImage( 329## target, level, format, type, ctypes.c_void_p( arrayType.dataPointer(array)) 330## ) 331## return array 332## "%s = glGetTexImage"%(suffix) 333 try: 334 del suffix,type 335 except NameError as err: 336 pass 337# Now the real glReadPixels... 338def glReadPixels( x,y,width,height,format,type, array=None, outputType=bytes ): 339 """Read specified pixels from the current display buffer 340 341 x,y,width,height -- location and dimensions of the image to read 342 from the buffer 343 format -- pixel format for the resulting data 344 type -- data-format for the resulting data 345 array -- optional array/offset into which to store the value 346 outputType -- default (bytes) provides string output of the 347 results iff OpenGL.UNSIGNED_BYTE_IMAGES_AS_STRING is True 348 and type == GL_UNSIGNED_BYTE. Any other value will cause 349 output in the default array output format. 350 351 returns the pixel data array in the format defined by the 352 format, type and outputType 353 """ 354 x,y,width,height = asInt(x),asInt(y),asInt(width),asInt(height) 355 356 arrayType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ images.TYPE_TO_ARRAYTYPE.get(type,type) ] 357 if array is None: 358 array = imageData = images.SetupPixelRead( format, (width,height), type ) 359 owned = True 360 else: 361 if isinstance( array, integer_types): 362 imageData = ctypes.c_void_p( array ) 363 else: 364 array = arrayType.asArray( array ) 365 imageData = arrayType.voidDataPointer( array ) 366 owned = False 367 368 GL_1_1.glReadPixels( 369 x,y,width,height, 370 format,type, 371 imageData 372 ) 373 if owned and outputType is bytes: 374 return images.returnFormat( array, type ) 375 else: 376 return array 377 378def glGetTexImage( target, level,format,type, array=None, outputType=bytes ): 379 """Get a texture-level as an image 380 381 target -- enum constant for the texture engine to be read 382 level -- the mip-map level to read 383 format -- image format to read out the data 384 type -- data-type into which to read the data 385 array -- optional array/offset into which to store the value 386 387 outputType -- default (bytes) provides string output of the 388 results iff OpenGL.UNSIGNED_BYTE_IMAGES_AS_STRING is True 389 and type == GL_UNSIGNED_BYTE. Any other value will cause 390 output in the default array output format. 391 392 returns the pixel data array in the format defined by the 393 format, type and outputType 394 """ 395 arrayType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ images.TYPE_TO_ARRAYTYPE.get(type,type) ] 396 if array is None: 397 dims = _get_texture_level_dims(target,level) 398 array = imageData = images.SetupPixelRead( format, tuple(dims), type ) 399 owned = True 400 else: 401 if isinstance( array, integer_types): 402 imageData = ctypes.c_void_p( array ) 403 else: 404 array = arrayType.asArray( array ) 405 imageData = arrayType.voidDataPointer( array ) 406 owned = False 407 GL_1_1.glGetTexImage( 408 target, level, format, type, imageData 409 ) 410 if outputType is bytes: 411 return images.returnFormat( array, type ) 412 else: 413 return array 414 415 416INT_DIMENSION_NAMES = [ 417 'width','height','depth','x','y','z', 418 'xoffset','yoffset','zoffset', 419 'start', 'count', 420] 421def asWrapper( value ): 422 if not isinstance( value, wrapper.Wrapper ): 423 return wrapper.wrapper( value ) 424 return value 425 426def asIntConverter( value, *args ): 427 if isinstance( value, float ): 428 return int(round(value,0)) 429 return value 430 431def setDimensionsAsInts( baseOperation ): 432 """Set arguments with names in INT_DIMENSION_NAMES to asInt processing""" 433 baseOperation = asWrapper( baseOperation ) 434 argNames = getattr( baseOperation, 'pyConverterNames', baseOperation.argNames ) 435 for i,argName in enumerate(argNames): 436 if argName in INT_DIMENSION_NAMES: 437 baseOperation.setPyConverter( argName, asIntConverter ) 438 return baseOperation 439 440 441 442class ImageInputConverter( object ): 443 def __init__( self, rank, pixelsName=None, typeName='type' ): 444 self.rank = rank 445 self.typeName = typeName 446 self.pixelsName = pixelsName 447 def finalise( self, wrapper ): 448 """Get our pixel index from the wrapper""" 449 self.typeIndex = wrapper.pyArgIndex( self.typeName ) 450 self.pixelsIndex = wrapper.pyArgIndex( self.pixelsName ) 451 def __call__( self, arg, baseOperation, pyArgs ): 452 """pyConverter for the pixels argument""" 453 images.setupDefaultTransferMode() 454 images.rankPacking( self.rank ) 455 type = pyArgs[ self.typeIndex ] 456 arrayType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ images.TYPE_TO_ARRAYTYPE[ type ] ] 457 return arrayType.asArray( arg ) 458# def cResolver( self, array ): 459# return array 460# return ctypes.c_void_p( arrays.ArrayDatatype.dataPointer( array ) ) 461 462class TypedImageInputConverter( ImageInputConverter ): 463 def __init__( self, rank, pixelsName, arrayType, typeName=None ): 464 self.rank = rank 465 self.arrayType = arrayType 466 self.pixelsName = pixelsName 467 self.typeName = typeName 468 def __call__( self, arg, baseOperation, pyArgs ): 469 """The pyConverter for the pixels""" 470 images.setupDefaultTransferMode() 471 images.rankPacking( self.rank ) 472 return self.arrayType.asArray( arg ) 473 def finalise( self, wrapper ): 474 """Get our pixel index from the wrapper""" 475 self.pixelsIndex = wrapper.pyArgIndex( self.pixelsName ) 476 def width( self, pyArgs, index, wrappedOperation ): 477 """Extract the width from the pixels argument""" 478 return self.arrayType.dimensions( pyArgs[self.pixelsIndex] )[0] 479 def height( self, pyArgs, index, wrappedOperation ): 480 """Extract the height from the pixels argument""" 481 return self.arrayType.dimensions( pyArgs[self.pixelsIndex] )[1] 482 def depth( self, pyArgs, index, wrappedOperation ): 483 """Extract the depth from the pixels argument""" 484 return self.arrayType.dimensions( pyArgs[self.pixelsIndex] )[2] 485 def type( self, pyArgs, index, wrappedOperation ): 486 """Provide the item-type argument from our stored value 487 488 This is used for pre-bound processing where we want to provide 489 the type by implication... 490 """ 491 return self.typeName 492 493class CompressedImageConverter( object ): 494 def finalise( self, wrapper ): 495 """Get our pixel index from the wrapper""" 496 self.dataIndex = wrapper.pyArgIndex( 'data' ) 497 def __call__( self, pyArgs, index, wrappedOperation ): 498 """Create a data-size measurement for our image""" 499 arg = pyArgs[ self.dataIndex ] 500 return arrays.ArrayType.arrayByteCount( arg ) 501 502 503 504DIMENSION_NAMES = ( 505 'width','height','depth' 506) 507PIXEL_NAMES = ( 508 'pixels', 'row', 'column', 509) 510DATA_SIZE_NAMES = ( 511 'imageSize', 512) 513 514def setImageInput( 515 baseOperation, arrayType=None, dimNames=DIMENSION_NAMES, 516 pixelName="pixels", typeName=None 517): 518 """Determine how to convert "pixels" into an image-compatible argument""" 519 baseOperation = asWrapper( baseOperation ) 520 # rank is the count of width,height,depth arguments... 521 rank = len([ 522 # rank is the number of dims we want, not the number we give... 523 argName for argName in baseOperation.argNames 524 if argName in dimNames 525 ]) + 1 526 if arrayType: 527 converter = TypedImageInputConverter( rank, pixelName, arrayType, typeName=typeName ) 528 for i,argName in enumerate(baseOperation.argNames): 529 if argName in dimNames: 530 baseOperation.setPyConverter( argName ) 531 baseOperation.setCConverter( argName, getattr(converter,argName) ) 532 elif argName == 'type' and typeName is not None: 533 baseOperation.setPyConverter( argName ) 534 baseOperation.setCConverter( argName, converter.type ) 535 else: 536 converter = ImageInputConverter( rank, pixelsName=pixelName, typeName=typeName or 'type' ) 537 for argName in baseOperation.argNames: 538 if argName in DATA_SIZE_NAMES: 539 baseOperation.setPyConverter( argName ) 540 baseOperation.setCConverter( argName, converter.imageDataSize ) 541 baseOperation.setPyConverter( 542 pixelName, converter, 543 ) 544# baseOperation.setCResolver( 545# pixelName, converter.cResolver 546# ) 547 return baseOperation 548 549glDrawPixels = setDimensionsAsInts( 550 setImageInput( 551 GL_1_1.glDrawPixels 552 ) 553) 554glTexSubImage2D = setDimensionsAsInts( 555 setImageInput( 556 GL_1_1.glTexSubImage2D 557 ) 558) 559glTexSubImage1D = setDimensionsAsInts( 560 setImageInput( 561 GL_1_1.glTexSubImage1D 562 ) 563) 564glTexImage2D = setDimensionsAsInts( 565 setImageInput( 566 GL_1_1.glTexImage2D 567 ) 568) 569glTexImage1D = setDimensionsAsInts( 570 setImageInput( 571 GL_1_1.glTexImage1D 572 ) 573) 574 575def typedImageFunction( suffix, arrayConstant, baseFunction ): 576 """Produce a typed version of the given image function""" 577 functionName = baseFunction.__name__ 578 functionName = '%(functionName)s%(suffix)s'%locals() 579 if baseFunction: 580 arrayType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ arrayConstant ] 581 function = setDimensionsAsInts( 582 setImageInput( 583 baseFunction, 584 arrayType, 585 typeName = arrayConstant, 586 ) 587 ) 588 return functionName, function 589 else: 590 return functionName, baseFunction 591 592def _setDataSize( baseFunction, argument='imageSize' ): 593 """Set the data-size value to come from the data field""" 594 if baseFunction: 595 converter = CompressedImageConverter() 596 return asWrapper( baseFunction ).setPyConverter( 597 argument 598 ).setCConverter( argument, converter ) 599 else: 600 return baseFunction 601 602def compressedImageFunction( baseFunction ): 603 """Set the imageSize and dimensions-as-ints converters for baseFunction""" 604 if baseFunction: 605 return setDimensionsAsInts( 606 _setDataSize( 607 baseFunction, argument='imageSize' 608 ) 609 ) 610 else: 611 return baseFunction 612 613for suffix,arrayConstant in [ 614 ('b', GL_1_1.GL_BYTE), 615 ('f', GL_1_1.GL_FLOAT), 616 ('i', GL_1_1.GL_INT), 617 ('s', GL_1_1.GL_SHORT), 618 ('ub', GL_1_1.GL_UNSIGNED_BYTE), 619 ('ui', GL_1_1.GL_UNSIGNED_INT), 620 ('us', GL_1_1.GL_UNSIGNED_SHORT), 621]: 622 for functionName in ( 623 'glTexImage1D','glTexImage2D', 624 'glTexSubImage1D','glTexSubImage2D', 625 'glDrawPixels', 626 #'glTexSubImage3D','glTexImage3D', # extension/1.2 standard 627 ): 628 functionName, function = typedImageFunction( 629 suffix, arrayConstant, getattr(GL_1_1,functionName), 630 ) 631 globals()[functionName] = function 632 try: 633 del function, functionName 634 except NameError as err: 635 pass 636 try: 637 del suffix,arrayConstant 638 except NameError as err: 639 pass 640