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 / images.py < prev    next >
Encoding:
Python Source  |  2008-12-07  |  5.2 KB  |  140 lines

  1. """Image/texture implementation code
  2.  
  3. This module provides the Pan-OpenGL operations required to support OpenGL
  4. image handling.  Most of this code is simply boilerplate code that sets 
  5. OpenGL parameters such that normal Pythonic assumptions about data-ordering
  6. are met to allow easier interaction with other projects (such as PIL or 
  7. Numpy).
  8.  
  9. Generally speaking, there are 3 pieces of information which control how 
  10. an image is processed in the system:
  11.  
  12.     format -- this is the pixel format, such as GL_RGB/GL_RED/GL_ABGR_EXT
  13.     dims -- tuple of dimensions for the image, (width,height,depth) order 
  14.     type -- the storage data-type for the image, normally GL_UNSIGNED_BYTE 
  15.         when working in Python, but all of the standard OpenGL types for 
  16.         images can be used if you happen to have your data in some exotic
  17.         format.
  18.     
  19.     OpenGL.UNSIGNED_BYTE_IMAGES_AS_STRING -- if this global value is set,
  20.         then read of unsigned byte images using glReadPixels and 
  21.         glGetTexImage produces a string instead of the default array format.
  22.  
  23. Attributes of Note:
  24.  
  25.     COMPONENT_COUNTS -- used to lookup how many units of a 
  26.         given storage type are required to store a unit in a given format
  27.     
  28.     TYPE_TO_ARRAYTYPE -- maps Image storage types to their array data-type
  29.         constants, i.e. maps GL_UNSIGNED_SHORT_4_4_4_4 to GL_UNSIGNED_SHORT
  30.         so that we can use the standard array types for manipulating 
  31.         image arrays.
  32.     
  33.     RANK_PACKINGS -- commands required to set up default array-transfer 
  34.         operations for an array of the specified rank.
  35.  
  36. New image formats and types will need to be registered here to be supported,
  37. this means that extension modules which add image types/formats need to alter 
  38. the tables described above!
  39.  
  40.     XXX Should be an API to handle that instead of direct modification.
  41.  
  42. """
  43. from OpenGL.raw import GL as simple
  44. from OpenGL import arrays
  45. import OpenGL
  46. import ctypes
  47.  
  48. def SetupPixelRead( format, dims, type):
  49.     """Setup transfer mode for a read into a numpy array return the array
  50.     
  51.     Calls setupDefaultTransferMode, sets rankPacking and then 
  52.     returns a createTargetArray for the parameters.
  53.     """
  54.     setupDefaultTransferMode()
  55.     # XXX this is wrong? dims may grow or it may not, depends on whether
  56.     # the format can fit in the type or not, but rank is a property of the 
  57.     # image itself?  Don't know, should test.
  58.     rankPacking( len(dims)+1 )
  59.     return createTargetArray( format, dims, type )
  60.  
  61. def setupDefaultTransferMode( ):
  62.     """Set pixel transfer mode to assumed internal structure of arrays
  63.     
  64.     Basically OpenGL-ctypes (and PyOpenGL) assume that your image data is in 
  65.     non-byte-swapped order, with big-endian ordering of bytes (though that 
  66.     seldom matters in image data).  These assumptions are normally correct 
  67.     when dealing with Python libraries which expose byte-arrays.
  68.     """
  69.     simple.glPixelStorei(simple.GL_PACK_SWAP_BYTES, 0)
  70.     simple.glPixelStorei(simple.GL_PACK_LSB_FIRST, 0)
  71. def rankPacking( rank ):
  72.     """Set the pixel-transfer modes for a given image "rank" (# of dims)
  73.     
  74.     Uses RANK_PACKINGS table to issue calls to glPixelStorei
  75.     """
  76.     for func,which,arg in RANK_PACKINGS[rank]:
  77.         try:
  78.             func(which,arg)
  79.         except Exception, err:
  80.             # XXX should be logging a warning!
  81.             pass
  82.  
  83. def createTargetArray( format, dims, type ):
  84.     """Create storage array for given parameters
  85.     
  86.     If storage type requires > 1 unit per format pixel, then dims will be
  87.     extended by 1, so in the common case of RGB and GL_UNSIGNED_BYTE you 
  88.     will wind up with an array of dims + (3,) dimensions.  See COMPONENT_COUNTS
  89.     for table which controls which formats produce larger dimensions.
  90.     
  91.     Note that the base storage type must provide a zeros method.  The zeros
  92.     method relies on their being a registered default array-implementation for 
  93.     the storage type.  The default installation of OpenGL-ctypes will use 
  94.     Numpy arrays for returning the result.
  95.     """
  96.     # calculate the number of storage elements required to store 
  97.     # a single pixel of format, that's the dimension of the resulting array
  98.     componentCount = formatToComponentCount( format )
  99.     if componentCount > 1:
  100.         # requires multiple elements to store a single pixel (common)
  101.         # e.g. byte array (typeBits = 8) with RGB (24) or RGBA (32)
  102.         dims += (componentCount, )
  103.     arrayType = arrays.GL_CONSTANT_TO_ARRAY_TYPE[ TYPE_TO_ARRAYTYPE.get(type,type) ]
  104.     return arrayType.zeros( dims )
  105.  
  106. def formatToComponentCount( format ):
  107.     """Given an OpenGL image format specification, get components/pixel"""
  108.     size = COMPONENT_COUNTS.get( format )
  109.     if size is None:
  110.         raise ValueError( """Unrecognised image format: %r"""%(format,))
  111.     return size
  112.  
  113. def returnFormat( data, type ):
  114.     """Perform compatibility conversion for PyOpenGL 2.x image-as string results
  115.     
  116.     Uses OpenGL.UNSIGNED_BYTE_IMAGES_AS_STRING to control whether to perform the 
  117.     conversions.
  118.     """
  119.     if OpenGL.UNSIGNED_BYTE_IMAGES_AS_STRING:
  120.         if type == simple.GL_UNSIGNED_BYTE:
  121.             if hasattr( data, 'tostring' ):
  122.                 return data.tostring()
  123.             elif hasattr( data, 'raw' ):
  124.                 return data.raw 
  125.     return data
  126.  
  127.  
  128. COMPONENT_COUNTS = {
  129.     # Image-format-constant: number-of-components (integer)
  130. }
  131. TYPE_TO_BITS = { 
  132.     # GL-image-storage-type-constant: number-of-bits (integer)
  133. }
  134. TYPE_TO_ARRAYTYPE = { 
  135.     # GL-image-storage-type-constant: GL-datatype (constant)
  136. }
  137. RANK_PACKINGS = {
  138.     # rank (integer): list of (function,**arg) to setup for that rank
  139. }
  140.