Package glitter :: Package textures :: Module texture
[hide private]
[frames] | no frames]

Source Code for Module glitter.textures.texture

  1  """Texture classes. 
  2   
  3  @todo: Check OpenGL memory layout; do shaders use the same coordinates as C{numpy} does? 
  4  @todo: Implement depth textures. 
  5  @todo: Implement C{__getitem__} and C{__setitem__} for subimages (C{glTexSubImage3D}, C{glGetTexImage} with C{format=GL_RED} etc.). 
  6  @todo: Implement image textures. 
  7   
  8  @author: Stephan Wenger 
  9  @date: 2012-02-29 
 10  """ 
 11   
 12  import numpy as _np 
 13   
 14  import glitter.raw as _gl 
 15  from glitter.utils import texture_compare_funcs, texture_compare_modes, texture_min_filters, texture_mag_filters, texture_swizzles, texture_wrapmodes, dtype_to_gl_iformat, dtype_to_gl_format, gl_iformat_to_dtype, gl_iformat_to_dtype, dtype_to_gl_format, gl_iformat_to_gl_type, Datatype, coerce_array, ManagedObject, BindReleaseObject, float32 
16 17 -class Texture(ManagedObject, BindReleaseObject):
18 _generate_id = _gl.glGenTextures 19 _delete_id = _gl.glDeleteTextures 20 _db = "textures" 21 22 _ndim = NotImplemented 23 _set = NotImplemented 24 25 compare_funcs = texture_compare_funcs 26 compare_modes = texture_compare_modes 27 min_filters = texture_min_filters 28 mag_filters = texture_mag_filters 29 swizzles = texture_swizzles 30 wrapmodes = texture_wrapmodes 31
32 - def bind(self):
33 return self._context.texture_units.bind(self)
34
35 - def release(self):
36 self._context.texture_units.release(self)
37
38 - def __init__(self, data=None, shape=None, dtype=None, mipmap=False, context=None):
39 if any(x is NotImplemented for x in (self._ndim, self._set)): 40 raise TypeError("%s is abstract" % self.__class__.__name__) 41 super(Texture, self).__init__(context=context) 42 self.set_data(data, shape, dtype, mipmap)
43
44 - def __getitem__(self, key):
45 """Return a tuple describing a texture layer. 46 47 This is mainly provided as a convenience notation for binding texture 48 layers to L{Framebuffer}s. 49 """ 50 51 return (self, key)
52
53 - def __len__(self):
54 return self.shape[0]
55
56 - def set_data(self, data=None, shape=None, dtype=None, level=0, mipmap=False):
57 if data is None: 58 if shape is None: 59 raise ValueError("must specify either data or shape") 60 if dtype is None: 61 dtype = float32 62 else: 63 data = coerce_array(data, dtype) 64 if shape is not None: 65 data = data.reshape(shape) 66 shape = data.shape 67 dtype = Datatype.from_numpy(data.dtype) 68 69 if len(shape) != self._ndim: 70 raise TypeError("shape must be %d-dimensional" % self._ndim) 71 72 _iformat = dtype_to_gl_iformat[dtype, shape[-1]] 73 _format = dtype_to_gl_format[dtype, shape[-1]] 74 _type = dtype._as_gl() 75 _data = data.ctypes if data is not None else _gl.POINTER(_gl.GLvoid)() 76 _gl.glPixelStorei(_gl.GL_UNPACK_ALIGNMENT, 1) 77 with self: 78 args = [self._target, level, _iformat] + list(reversed(shape[:-1])) + [0, _format, _type, _data] 79 self._set(*args) 80 if dtype.is_float(): 81 self.min_filter = self.min_filters.LINEAR_MIPMAP_LINEAR if mipmap else self.min_filters.LINEAR 82 self.mag_filter = self.mag_filters.LINEAR 83 else: 84 self.min_filter = self.min_filters.NEAREST 85 self.mag_filter = self.mag_filters.NEAREST 86 87 if mipmap: 88 self.generate_mipmap()
89
90 - def get_data(self, level=0):
91 _data = _np.empty(self.shape, dtype=self.dtype.as_numpy()) 92 _gl.glPixelStorei(_gl.GL_PACK_ALIGNMENT, 1) 93 with self: 94 _gl.glGetTexImage(self._target, level, self._format, self._type, _data.ctypes) 95 return _data
96
97 - def generate_mipmap(self):
98 with self: 99 _gl.glGenerateMipmap(self._target)
100 101 @property
102 - def data(self):
103 return self.get_data()
104 105 @data.setter
106 - def data(self, data):
107 self.set_data(data)
108 109 @property
110 - def shape(self):
111 with self: 112 colors = gl_iformat_to_dtype[self._iformat][1] 113 _width = _gl.GLint() 114 _gl.glGetTexLevelParameteriv(self._target, 0, _gl.GL_TEXTURE_WIDTH, _gl.pointer(_width)) 115 if self._ndim == 2: 116 return (_width.value, colors) 117 _height = _gl.GLint() 118 _gl.glGetTexLevelParameteriv(self._target, 0, _gl.GL_TEXTURE_HEIGHT, _gl.pointer(_height)) 119 if self._ndim == 3: 120 return (_height.value, _width.value, colors) 121 _depth = _gl.GLint() 122 _gl.glGetTexLevelParameteriv(self._target, 0, _gl.GL_TEXTURE_DEPTH, _gl.pointer(_depth)) 123 if self._ndim == 4: 124 return (_depth.value, _height.value, _width.value, colors)
125 126 @property
127 - def dtype(self):
128 return gl_iformat_to_dtype[self._iformat][0]
129 130 @property
131 - def _iformat(self):
132 _iformat = _gl.GLint() 133 with self: 134 _gl.glGetTexLevelParameteriv(self._target, 0, _gl.GL_TEXTURE_INTERNAL_FORMAT, _gl.pointer(_iformat)) 135 return _iformat.value
136 137 @property
138 - def _format(self):
139 return dtype_to_gl_format[self.dtype, self.shape[-1]]
140 141 @property
142 - def _type(self):
144 145 @property
146 - def base_level(self):
147 _base_level = _gl.GLint() 148 with self: 149 _gl.glGetTexParameterIiv(self._target, _gl.GL_TEXTURE_BASE_LEVEL, _gl.pointer(_base_level)) 150 return _base_level.value
151 152 @base_level.setter
153 - def base_level(self, base_level):
154 with self: 155 _gl.glTexParameterIiv(self._target, _gl.GL_TEXTURE_BASE_LEVEL, _gl.pointer(_gl.GLint(base_level)))
156 157 @property
158 - def border_color(self):
159 if self.dtype.is_float(): 160 _border_color = (_gl.GLfloat * 4)() 161 with self: 162 _gl.glGetTexParameterfv(self._target, _gl.GL_TEXTURE_BORDER_COLOR, _border_color) 163 elif self.dtype.is_signed(): 164 _border_color = (_gl.GLint * 4)() 165 with self: 166 _gl.glGetTexParameterIiv(self._target, _gl.GL_TEXTURE_BORDER_COLOR, _border_color) 167 else: 168 _border_color = (_gl.GLuint * 4)() 169 with self: 170 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_BORDER_COLOR, _border_color) 171 return [_border_color[i] for i in range(4)]
172 173 @border_color.setter
174 - def border_color(self, border_color):
175 if self.dtype.is_float(): 176 _border_color = (_gl.GLfloat * 4)() 177 for i, v in zip(range(4), border_color): 178 _border_color[i] = v 179 with self: 180 _gl.glTexParameterfv(self._target, _gl.GL_TEXTURE_BORDER_COLOR, _border_color) 181 elif self.dtype.is_signed(): 182 _border_color = (_gl.GLint * 4)() 183 for i, v in zip(range(4), border_color): 184 _border_color[i] = v 185 with self: 186 _gl.glTexParameterIiv(self._target, _gl.GL_TEXTURE_BORDER_COLOR, _border_color) 187 else: 188 _border_color = (_gl.GLuint * 4)() 189 for i, v in zip(range(4), border_color): 190 _border_color[i] = v 191 with self: 192 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_BORDER_COLOR, _border_color)
193 194 @property
195 - def compare_func(self):
196 _compare_func = _gl.GLenum() 197 with self: 198 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_COMPARE_FUNC, _gl.pointer(_compare_func)) 199 return self.compare_funcs[_compare_func.value]
200 201 @compare_func.setter
202 - def compare_func(self, compare_func):
203 _compare_func = _gl.GLenum(self.compare_funcs(compare_func)._value) 204 with self: 205 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_COMPARE_FUNC, _gl.pointer(_compare_func))
206 207 @property
208 - def compare_mode(self):
209 _compare_mode = _gl.GLenum() 210 with self: 211 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_COMPARE_MODE, _gl.pointer(_compare_mode)) 212 return self.compare_modes[_compare_mode.value]
213 214 @compare_mode.setter
215 - def compare_mode(self, compare_mode):
216 _compare_mode = _gl.GLenum(self.compare_modes(compare_mode)._value) 217 with self: 218 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_COMPARE_MODE, _gl.pointer(_compare_mode))
219 220 @property
221 - def immutable_format(self): # Textures become immutable if their storage is specified with glTexStorage1D, glTexStorage2D or glTexStorage3D
222 _immutable_format = _gl.GLenum() 223 with self: 224 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_COMPARE_MODE, _gl.pointer(_immutable_format)) 225 return bool(_immutable_format.value)
226 227 @property
228 - def lod_bias(self):
229 _lod_bias = _gl.GLfloat() 230 with self: 231 _gl.glGetTexParameterfv(self._target, _gl.GL_TEXTURE_LOD_BIAS, _gl.pointer(_lod_bias)) 232 return _lod_bias.value
233 234 @lod_bias.setter
235 - def lod_bias(self, lod_bias):
236 with self: 237 _gl.glTexParameterfv(self._target, _gl.GL_TEXTURE_LOD_BIAS, _gl.pointer(_gl.GLfloat(lod_bias)))
238 239 @property
240 - def min_filter(self):
241 _min_filter = _gl.GLenum() 242 with self: 243 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_MIN_FILTER, _gl.pointer(_min_filter)) 244 return self.min_filters[_min_filter.value]
245 246 @min_filter.setter
247 - def min_filter(self, min_filter):
248 _min_filter = _gl.GLenum(self.min_filters(min_filter)._value) 249 with self: 250 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_MIN_FILTER, _gl.pointer(_min_filter))
251 252 @property
253 - def mag_filter(self):
254 _mag_filter = _gl.GLenum() 255 with self: 256 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_MAG_FILTER, _gl.pointer(_mag_filter)) 257 return self.mag_filters[_mag_filter.value]
258 259 @mag_filter.setter
260 - def mag_filter(self, mag_filter):
261 _mag_filter = _gl.GLenum(self.mag_filters(mag_filter)._value) 262 with self: 263 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_MAG_FILTER, _gl.pointer(_mag_filter))
264 265 @property
266 - def min_lod(self):
267 _min_lod = _gl.GLint() 268 with self: 269 _gl.glGetTexParameterIiv(self._target, _gl.GL_TEXTURE_MIN_LOD, _gl.pointer(_min_lod)) 270 return _min_lod.value
271 272 @min_lod.setter
273 - def min_lod(self, min_lod):
274 with self: 275 _gl.glTexParameterIiv(self._target, _gl.GL_TEXTURE_MIN_LOD, _gl.pointer(_gl.GLint(min_lod)))
276 277 @property
278 - def max_lod(self):
279 _max_lod = _gl.GLint() 280 with self: 281 _gl.glGetTexParameterIiv(self._target, _gl.GL_TEXTURE_MAX_LOD, _gl.pointer(_max_lod)) 282 return _max_lod.value
283 284 @max_lod.setter
285 - def max_lod(self, max_lod):
286 with self: 287 _gl.glTexParameterIiv(self._target, _gl.GL_TEXTURE_MAX_LOD, _gl.pointer(_gl.GLint(max_lod)))
288 289 @property
290 - def max_level(self):
291 _max_level = _gl.GLint() 292 with self: 293 _gl.glGetTexParameterIiv(self._target, _gl.GL_TEXTURE_MAX_LEVEL, _gl.pointer(_max_level)) 294 return _max_level.value
295 296 @max_level.setter
297 - def max_level(self, max_level):
298 with self: 299 _gl.glTexParameterIiv(self._target, _gl.GL_TEXTURE_MAX_LEVEL, _gl.pointer(_gl.GLint(max_level)))
300 301 @property
302 - def swizzle_r(self):
303 _swizzle_r = _gl.GLenum() 304 with self: 305 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_SWIZZLE_R, _gl.pointer(_swizzle_r)) 306 return self.swizzles[_swizzle_r.value]
307 308 @swizzle_r.setter
309 - def swizzle_r(self, swizzle_r):
310 _swizzle_r = _gl.GLenum(self.swizzles(swizzle_r)._value) 311 with self: 312 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_SWIZZLE_R, _gl.pointer(_swizzle_r))
313 314 @property
315 - def swizzle_g(self):
316 _swizzle_g = _gl.GLenum() 317 with self: 318 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_SWIZZLE_G, _gl.pointer(_swizzle_g)) 319 return self.swizzles[_swizzle_g.value]
320 321 @swizzle_g.setter
322 - def swizzle_g(self, swizzle_g):
323 _swizzle_g = _gl.GLenum(self.swizzles(swizzle_g)._value) 324 with self: 325 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_SWIZZLE_G, _gl.pointer(_swizzle_g))
326 327 @property
328 - def swizzle_b(self):
329 _swizzle_b = _gl.GLenum() 330 with self: 331 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_SWIZZLE_B, _gl.pointer(_swizzle_b)) 332 return self.swizzles[_swizzle_b.value]
333 334 @swizzle_b.setter
335 - def swizzle_b(self, swizzle_b):
336 _swizzle_b = _gl.GLenum(self.swizzles(swizzle_b)._value) 337 with self: 338 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_SWIZZLE_B, _gl.pointer(_swizzle_b))
339 340 @property
341 - def swizzle_a(self):
342 _swizzle_a = _gl.GLenum() 343 with self: 344 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_SWIZZLE_A, _gl.pointer(_swizzle_a)) 345 return self.swizzles[_swizzle_a.value]
346 347 @swizzle_a.setter
348 - def swizzle_a(self, swizzle_a):
349 _swizzle_a = _gl.GLenum(self.swizzles(swizzle_a)._value) 350 with self: 351 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_SWIZZLE_A, _gl.pointer(_swizzle_a))
352 353 @property
354 - def swizzle_rgba(self):
355 _swizzle_rgba = (_gl.GLenum * 4)() 356 with self: 357 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_SWIZZLE_RGBA, _swizzle_rgba) 358 return [self.swizzles[_swizzle_rgba[i]] for i in range(4)]
359 360 @swizzle_rgba.setter
361 - def swizzle_rgba(self, swizzle_rgba):
362 _swizzle_rgba = (_gl.GLenum * 4)() 363 for i, v in zip(range(4), swizzle_rgba): 364 _swizzle_rgba[i] = self.swizzles(v)._value 365 with self: 366 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_SWIZZLE_RGBA, _swizzle_rgba)
367 368 @property
369 - def wrap_s(self):
370 _wrap_s = _gl.GLenum() 371 with self: 372 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_WRAP_S, _gl.pointer(_wrap_s)) 373 return self.wrapmodes[_wrap_s.value]
374 375 @wrap_s.setter
376 - def wrap_s(self, wrap_s):
377 _wrap_s = _gl.GLenum(self.wrapmodes(wrap_s)._value) 378 with self: 379 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_WRAP_S, _gl.pointer(_wrap_s))
380 381 @property
382 - def wrap_t(self):
383 _wrap_t = _gl.GLenum() 384 with self: 385 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_WRAP_T, _gl.pointer(_wrap_t)) 386 return self.wrapmodes[_wrap_t.value]
387 388 @wrap_t.setter
389 - def wrap_t(self, wrap_t):
390 _wrap_t = _gl.GLenum(self.wrapmodes(wrap_t)._value) 391 with self: 392 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_WRAP_T, _gl.pointer(_wrap_t))
393 394 @property
395 - def wrap_r(self):
396 _wrap_r = _gl.GLenum() 397 with self: 398 _gl.glGetTexParameterIuiv(self._target, _gl.GL_TEXTURE_WRAP_R, _gl.pointer(_wrap_r)) 399 return self.wrapmodes[_wrap_r.value]
400 401 @wrap_r.setter
402 - def wrap_r(self, wrap_r):
403 _wrap_r = _gl.GLenum(self.wrapmodes(wrap_r)._value) 404 with self: 405 _gl.glTexParameterIuiv(self._target, _gl.GL_TEXTURE_WRAP_R, _gl.pointer(_wrap_r))
406
407 -class Texture1D(Texture):
408 _target = _gl.GL_TEXTURE_1D 409 _binding = "texture_binding_1d" 410 _ndim = 2 411 _set = _gl.glTexImage1D
412
413 -class Texture2D(Texture):
414 _target = _gl.GL_TEXTURE_2D 415 _binding = "texture_binding_2d" 416 _ndim = 3 417 _set = _gl.glTexImage2D
418
419 -class TextureArray1D(Texture):
420 _target = _gl.GL_TEXTURE_1D_ARRAY 421 _binding = "texture_binding_1d_array" 422 _ndim = 3 423 _set = _gl.glTexImage2D
424
425 -class RectangleTexture(Texture):
426 _target = _gl.GL_TEXTURE_RECTANGLE 427 _binding = "texture_binding_rectangle" 428 _ndim = 3 429 _set = _gl.glTexImage2D
430
431 -class BufferTexture(Texture):
432 """Texture that stores its data in a buffer. 433 434 @todo: Override constructor, C{set_data} and C{get_data}; use C{glTexBuffer} 435 """ 436 437 _target = _gl.GL_TEXTURE_BUFFER 438 _binding = "texture_binding_buffer" 439 _ndim = 3 440 _set = _gl.glTexImage2D
441
442 -class CubeMapTexture(Texture):
443 _target = _gl.GL_TEXTURE_CUBE_MAP 444 _binding = "texture_binding_cube_map" 445 _ndim = 3 446 _set = _gl.glTexImage2D
447
448 -class MultisampleTexture2D(Texture):
449 _target = _gl.GL_TEXTURE_2D_MULTISAMPLE 450 _binding = "texture_binding_2d_multisample" 451 _ndim = 3 452 _set = _gl.glTexImage2D
453
454 -class Texture3D(Texture):
455 _target = _gl.GL_TEXTURE_3D 456 _binding = "texture_binding_3d" 457 _ndim = 4 458 _set = _gl.glTexImage3D
459
460 -class TextureArray2D(Texture):
461 _target = _gl.GL_TEXTURE_2D_ARRAY 462 _binding = "texture_binding_2d_array" 463 _ndim = 4 464 _set = _gl.glTexImage3D
465
466 -class MultisampleTextureArray2D(Texture):
467 _target = _gl.GL_TEXTURE_2D_MULTISAMPLE_ARRAY 468 _binding = "texture_binding_2d_multisample_array" 469 _ndim = 4 470 _set = _gl.glTexImage3D
471 472 __all__ = [ 473 "Texture", 474 "Texture1D", 475 "Texture2D", 476 "TextureArray1D", 477 "RectangleTexture", 478 "BufferTexture", 479 "CubeMapTexture", 480 "MultisampleTexture2D", 481 "Texture3D", 482 "TextureArray2D", 483 "MultisampleTextureArray2D", 484 ] 485