vispy 0.9.5__cp38-cp38-win_amd64.whl → 0.14.0__cp38-cp38-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of vispy might be problematic. Click here for more details.

Files changed (103) hide show
  1. vispy/app/backends/_glfw.py +2 -2
  2. vispy/app/backends/_pyglet.py +8 -2
  3. vispy/app/backends/_qt.py +88 -63
  4. vispy/app/backends/_wx.py +6 -1
  5. vispy/app/canvas.py +4 -2
  6. vispy/app/tests/test_canvas.py +52 -1
  7. vispy/app/tests/test_context.py +5 -3
  8. vispy/color/color_array.py +8 -1
  9. vispy/color/colormap.py +5 -25
  10. vispy/geometry/meshdata.py +76 -38
  11. vispy/geometry/rect.py +6 -0
  12. vispy/geometry/tests/test_meshdata.py +72 -0
  13. vispy/gloo/buffer.py +12 -0
  14. vispy/gloo/gl/_constants.py +9 -5
  15. vispy/gloo/gl/_es2.py +8 -4
  16. vispy/gloo/gl/_gl2.py +2 -3
  17. vispy/gloo/gl/_proxy.py +1 -1
  18. vispy/gloo/gl/_pyopengl2.py +12 -7
  19. vispy/gloo/gl/tests/test_names.py +3 -0
  20. vispy/gloo/glir.py +26 -13
  21. vispy/gloo/program.py +39 -22
  22. vispy/gloo/tests/test_program.py +9 -2
  23. vispy/gloo/tests/test_texture.py +19 -2
  24. vispy/gloo/texture.py +46 -16
  25. vispy/gloo/wrappers.py +4 -2
  26. vispy/glsl/build_spatial_filters.py +241 -293
  27. vispy/glsl/misc/spatial-filters.frag +1299 -254
  28. vispy/io/_data/spatial-filters.npy +0 -0
  29. vispy/io/datasets.py +2 -2
  30. vispy/io/image.py +1 -1
  31. vispy/io/stl.py +3 -3
  32. vispy/scene/cameras/base_camera.py +6 -2
  33. vispy/scene/cameras/panzoom.py +10 -14
  34. vispy/scene/cameras/perspective.py +6 -0
  35. vispy/scene/cameras/tests/test_cameras.py +27 -0
  36. vispy/scene/cameras/tests/test_perspective.py +37 -0
  37. vispy/scene/cameras/turntable.py +39 -23
  38. vispy/scene/canvas.py +9 -5
  39. vispy/scene/events.py +9 -0
  40. vispy/scene/node.py +19 -2
  41. vispy/scene/tests/test_canvas.py +30 -1
  42. vispy/scene/tests/test_visuals.py +113 -0
  43. vispy/scene/visuals.py +6 -1
  44. vispy/scene/widgets/viewbox.py +3 -2
  45. vispy/testing/_runners.py +6 -12
  46. vispy/testing/_testing.py +3 -4
  47. vispy/util/check_environment.py +4 -4
  48. vispy/util/gallery_scraper.py +50 -32
  49. vispy/util/tests/test_gallery_scraper.py +2 -0
  50. vispy/util/transforms.py +1 -1
  51. vispy/util/wrappers.py +1 -1
  52. vispy/version.py +2 -3
  53. vispy/visuals/__init__.py +2 -0
  54. vispy/visuals/_scalable_textures.py +20 -17
  55. vispy/visuals/collections/array_list.py +3 -3
  56. vispy/visuals/collections/base_collection.py +1 -1
  57. vispy/visuals/ellipse.py +1 -1
  58. vispy/visuals/filters/__init__.py +3 -2
  59. vispy/visuals/filters/base_filter.py +120 -0
  60. vispy/visuals/filters/clipping_planes.py +24 -12
  61. vispy/visuals/filters/markers.py +28 -0
  62. vispy/visuals/filters/mesh.py +61 -6
  63. vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
  64. vispy/visuals/graphs/graph.py +1 -1
  65. vispy/visuals/image.py +114 -26
  66. vispy/visuals/image_complex.py +130 -0
  67. vispy/visuals/instanced_mesh.py +152 -0
  68. vispy/visuals/isocurve.py +1 -1
  69. vispy/visuals/line/dash_atlas.py +46 -41
  70. vispy/visuals/line/line.py +2 -5
  71. vispy/visuals/markers.py +310 -384
  72. vispy/visuals/mesh.py +2 -2
  73. vispy/visuals/shaders/function.py +3 -0
  74. vispy/visuals/shaders/tests/test_function.py +6 -0
  75. vispy/visuals/tests/test_axis.py +2 -2
  76. vispy/visuals/tests/test_image.py +92 -2
  77. vispy/visuals/tests/test_image_complex.py +36 -0
  78. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  79. vispy/visuals/tests/test_markers.py +6 -0
  80. vispy/visuals/tests/test_mesh.py +17 -0
  81. vispy/visuals/tests/test_text.py +11 -0
  82. vispy/visuals/tests/test_volume.py +218 -12
  83. vispy/visuals/text/_sdf_cpu.cp38-win_amd64.pyd +0 -0
  84. vispy/visuals/text/_sdf_cpu.pyx +21 -23
  85. vispy/visuals/text/text.py +9 -3
  86. vispy/visuals/tube.py +2 -2
  87. vispy/visuals/visual.py +144 -3
  88. vispy/visuals/volume.py +300 -131
  89. {vispy-0.9.5.dist-info → vispy-0.14.0.dist-info}/LICENSE.txt +1 -1
  90. {vispy-0.9.5.dist-info → vispy-0.14.0.dist-info}/METADATA +218 -198
  91. {vispy-0.9.5.dist-info → vispy-0.14.0.dist-info}/RECORD +93 -96
  92. {vispy-0.9.5.dist-info → vispy-0.14.0.dist-info}/WHEEL +1 -1
  93. vispy/glsl/antialias/__init__.py +0 -0
  94. vispy/glsl/arrowheads/__init__.py +0 -0
  95. vispy/glsl/arrows/__init__.py +0 -0
  96. vispy/glsl/collections/__init__.py +0 -0
  97. vispy/glsl/colormaps/__init__.py +0 -0
  98. vispy/glsl/lines/__init__.py +0 -0
  99. vispy/glsl/markers/__init__.py +0 -0
  100. vispy/glsl/math/__init__.py +0 -0
  101. vispy/glsl/misc/__init__.py +0 -0
  102. vispy/glsl/transforms/__init__.py +0 -0
  103. {vispy-0.9.5.dist-info → vispy-0.14.0.dist-info}/top_level.txt +0 -0
@@ -19,6 +19,56 @@ def _fix_colors(colors):
19
19
  return colors
20
20
 
21
21
 
22
+ def _compute_face_normals(vertices):
23
+ if vertices.shape[1:] != (3, 3):
24
+ raise ValueError("Expected (N, 3, 3) array of vertices repeated on"
25
+ f" the triangle corners, got {vertices.shape}.")
26
+ edges1 = vertices[:, 1] - vertices[:, 0]
27
+ edges2 = vertices[:, 2] - vertices[:, 0]
28
+ return np.cross(edges1, edges2)
29
+
30
+
31
+ def _repeat_face_normals_on_corners(normals):
32
+ if normals.shape[1:] != (3,):
33
+ raise ValueError("Expected (F, 3) array of face normals, got"
34
+ f" {normals.shape}.")
35
+ n_corners_in_face = 3
36
+ new_shape = (normals.shape[0], n_corners_in_face, normals.shape[1])
37
+ return np.repeat(normals, n_corners_in_face, axis=0).reshape(new_shape)
38
+
39
+
40
+ def _compute_vertex_normals(face_normals, faces, vertices):
41
+ if face_normals.shape[1:] != (3,):
42
+ raise ValueError("Expected (F, 3) array of face normals, got"
43
+ f" {face_normals.shape}.")
44
+ if faces.shape[1:] != (3,):
45
+ raise ValueError("Expected (F, 3) array of face vertex indices, got"
46
+ f" {faces.shape}.")
47
+ if vertices.shape[1:] != (3,):
48
+ raise ValueError("Expected (N, 3) array of vertices, got"
49
+ f" {vertices.shape}.")
50
+
51
+ vertex_normals = np.zeros_like(vertices)
52
+ n_corners_in_triangle = 3
53
+ face_normals_repeated_on_corners = np.repeat(face_normals,
54
+ n_corners_in_triangle,
55
+ axis=0)
56
+ # NOTE: The next line is equivalent to
57
+ #
58
+ # vertex_normals[self._faces.ravel()] += face_normals_repeated_on_corners
59
+ #
60
+ # except that it accumulates the values from the right hand side at
61
+ # repeated indices on the left hand side, instead of overwritting them,
62
+ # like in the above.
63
+ np.add.at(vertex_normals, faces.ravel(), face_normals_repeated_on_corners)
64
+
65
+ norms = np.sqrt((vertex_normals**2).sum(axis=1))
66
+ nonzero_norms = norms > 0
67
+ vertex_normals[nonzero_norms] /= norms[nonzero_norms][:, None]
68
+
69
+ return vertex_normals
70
+
71
+
22
72
  class MeshData(object):
23
73
  """
24
74
  Class for storing and operating on 3D mesh data.
@@ -141,7 +191,7 @@ class MeshData(object):
141
191
  self._compute_edges(indexed='faces')
142
192
  return self._edges_indexed_by_faces
143
193
  else:
144
- raise Exception("Invalid indexing mode. Accepts: None, 'faces'")
194
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
145
195
 
146
196
  def set_faces(self, faces):
147
197
  """Set the faces
@@ -191,7 +241,7 @@ class MeshData(object):
191
241
  self._vertices[self.get_faces()]
192
242
  return self._vertices_indexed_by_faces
193
243
  else:
194
- raise Exception("Invalid indexing mode. Accepts: None, 'faces'")
244
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
195
245
 
196
246
  def get_bounds(self):
197
247
  """Get the mesh bounds
@@ -234,7 +284,7 @@ class MeshData(object):
234
284
  if verts is not None:
235
285
  self._vertices_indexed_by_faces = verts
236
286
  else:
237
- raise Exception("Invalid indexing mode. Accepts: None, 'faces'")
287
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
238
288
 
239
289
  if reset_normals:
240
290
  self.reset_normals()
@@ -293,22 +343,19 @@ class MeshData(object):
293
343
  normals : ndarray
294
344
  The normals.
295
345
  """
346
+ if indexed not in (None, 'faces'):
347
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
348
+
296
349
  if self._face_normals is None:
297
- v = self.get_vertices(indexed='faces')
298
- self._face_normals = np.cross(v[:, 1] - v[:, 0],
299
- v[:, 2] - v[:, 0])
350
+ vertices = self.get_vertices(indexed='faces')
351
+ self._face_normals = _compute_face_normals(vertices)
300
352
 
301
- if indexed is None:
302
- return self._face_normals
303
- elif indexed == 'faces':
304
- if self._face_normals_indexed_by_faces is None:
305
- norms = np.empty((self._face_normals.shape[0], 3, 3),
306
- dtype=np.float32)
307
- norms[:] = self._face_normals[:, np.newaxis, :]
308
- self._face_normals_indexed_by_faces = norms
309
- return self._face_normals_indexed_by_faces
310
- else:
311
- raise Exception("Invalid indexing mode. Accepts: None, 'faces'")
353
+ if indexed == 'faces' and self._face_normals_indexed_by_faces is None:
354
+ self._face_normals_indexed_by_faces = \
355
+ _repeat_face_normals_on_corners(self._face_normals)
356
+
357
+ return (self._face_normals if indexed is None
358
+ else self._face_normals_indexed_by_faces)
312
359
 
313
360
  def get_vertex_normals(self, indexed=None):
314
361
  """Get vertex normals
@@ -326,29 +373,20 @@ class MeshData(object):
326
373
  normals : ndarray
327
374
  The normals.
328
375
  """
376
+ if indexed not in (None, 'faces'):
377
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
378
+
329
379
  if self._vertex_normals is None:
330
- faceNorms = self.get_face_normals()
331
- vertFaces = self.get_vertex_faces()
332
- self._vertex_normals = np.empty(self._vertices.shape,
333
- dtype=np.float32)
334
- for vindex in range(self._vertices.shape[0]):
335
- faces = vertFaces[vindex]
336
- if len(faces) == 0:
337
- self._vertex_normals[vindex] = (0, 0, 0)
338
- continue
339
- norms = faceNorms[faces] # get all face normals
340
- norm = norms.sum(axis=0) # sum normals
341
- renorm = (norm**2).sum()**0.5
342
- if renorm > 0:
343
- norm /= renorm
344
- self._vertex_normals[vindex] = norm
380
+ face_normals = self.get_face_normals()
381
+ faces = self.get_faces()
382
+ vertices = self.get_vertices()
383
+ self._vertex_normals = _compute_vertex_normals(face_normals, faces,
384
+ vertices)
345
385
 
346
386
  if indexed is None:
347
387
  return self._vertex_normals
348
388
  elif indexed == 'faces':
349
389
  return self._vertex_normals[self.get_faces()]
350
- else:
351
- raise Exception("Invalid indexing mode. Accepts: None, 'faces'")
352
390
 
353
391
  def get_vertex_colors(self, indexed=None):
354
392
  """Get vertex colors
@@ -373,7 +411,7 @@ class MeshData(object):
373
411
  self._vertex_colors[self.get_faces()]
374
412
  return self._vertex_colors_indexed_by_faces
375
413
  else:
376
- raise Exception("Invalid indexing mode. Accepts: None, 'faces'")
414
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
377
415
 
378
416
  def get_vertex_values(self, indexed=None):
379
417
  """Get vertex colors
@@ -398,7 +436,7 @@ class MeshData(object):
398
436
  self._vertex_values[self.get_faces()]
399
437
  return self._vertex_values_indexed_by_faces
400
438
  else:
401
- raise Exception("Invalid indexing mode. Accepts: None, 'faces'")
439
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
402
440
 
403
441
  def set_vertex_colors(self, colors, indexed=None):
404
442
  """Set the vertex color array
@@ -488,7 +526,7 @@ class MeshData(object):
488
526
  self._face_colors.reshape(Nf, 1, 4)
489
527
  return self._face_colors_indexed_by_faces
490
528
  else:
491
- raise Exception("Invalid indexing mode. Accepts: None, 'faces'")
529
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
492
530
 
493
531
  def set_face_colors(self, colors, indexed=None):
494
532
  """Set the face color array
@@ -611,7 +649,7 @@ class MeshData(object):
611
649
  raise Exception("MeshData cannot generate edges--no faces in "
612
650
  "this data.")
613
651
  else:
614
- raise Exception("Invalid indexing mode. Accepts: None, 'faces'")
652
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
615
653
 
616
654
  def save(self):
617
655
  """Serialize this mesh to a string appropriate for disk storage
vispy/geometry/rect.py CHANGED
@@ -113,6 +113,12 @@ class Rect(object):
113
113
  return (self.pos[0] + self.size[0] * 0.5,
114
114
  self.pos[1] + self.size[1] * 0.5)
115
115
 
116
+ @center.setter
117
+ def center(self, value):
118
+ delta_x = value[0] - self.center[0]
119
+ delta_y = value[1] - self.center[1]
120
+ self.pos = (self.pos[0] + delta_x, self.pos[1] + delta_y)
121
+
116
122
  def padded(self, padding):
117
123
  """Return a new Rect padded (smaller) by padding on all sides
118
124
 
@@ -31,4 +31,76 @@ def test_meshdata():
31
31
  assert_array_equal(square_edges, mesh.get_edges())
32
32
 
33
33
 
34
+ def test_vertex_normals_indexed_none():
35
+ dtype_float = np.float32
36
+ dtype_int = np.int64
37
+ vertices = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]],
38
+ dtype=dtype_float)
39
+ faces = np.array([[0, 2, 1], [0, 3, 2], [0, 1, 3]], dtype=dtype_int)
40
+ mesh = MeshData(vertices=vertices, faces=faces)
41
+ vertex_normals_unnormalized = np.array(
42
+ [[-1, -1, -1], [0, -1, -1], [-1, 0, -1], [-1, -1, 0]],
43
+ dtype=dtype_float)
44
+ norms = np.sqrt((vertex_normals_unnormalized**2).sum(axis=1,
45
+ keepdims=True))
46
+ expected_vertex_normals = vertex_normals_unnormalized / norms
47
+
48
+ computed_vertex_normals = mesh.get_vertex_normals(indexed=None)
49
+
50
+ assert_array_equal(expected_vertex_normals, computed_vertex_normals)
51
+
52
+
53
+ def test_vertex_normals_indexed_faces():
54
+ dtype_float = np.float32
55
+ dtype_int = np.int64
56
+ vertices = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]],
57
+ dtype=dtype_float)
58
+ faces = np.array([[0, 2, 1], [0, 3, 2], [0, 1, 3]], dtype=dtype_int)
59
+ mesh = MeshData(vertices=vertices, faces=faces)
60
+ vertex_normals_unnormalized = np.array(
61
+ [[-1, -1, -1], [0, -1, -1], [-1, 0, -1], [-1, -1, 0]],
62
+ dtype=dtype_float)
63
+ norms = np.sqrt((vertex_normals_unnormalized**2).sum(axis=1,
64
+ keepdims=True))
65
+ vertex_normals = vertex_normals_unnormalized / norms
66
+ expected_vertex_normals = vertex_normals[faces]
67
+
68
+ computed_vertex_normals = mesh.get_vertex_normals(indexed="faces")
69
+
70
+ assert_array_equal(expected_vertex_normals, computed_vertex_normals)
71
+
72
+
73
+ def test_face_normals_indexed_none():
74
+ dtype_float = np.float32
75
+ dtype_int = np.int64
76
+ vertices = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]],
77
+ dtype=dtype_float)
78
+ faces = np.array([[0, 2, 1], [0, 3, 2], [0, 1, 3]], dtype=dtype_int)
79
+ mesh = MeshData(vertices=vertices, faces=faces)
80
+ expected_face_normals = np.array([[0, 0, -1], [-1, 0, 0], [0, -1, 0]],
81
+ dtype=dtype_float)
82
+
83
+ computed_face_normals = mesh.get_face_normals(indexed=None)
84
+
85
+ assert_array_equal(expected_face_normals, computed_face_normals)
86
+
87
+
88
+ def test_face_normals_indexed_faces():
89
+ dtype_float = np.float32
90
+ dtype_int = np.int64
91
+ vertices = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]],
92
+ dtype=dtype_float)
93
+ faces = np.array([[0, 2, 1], [0, 3, 2], [0, 1, 3]], dtype=dtype_int)
94
+ mesh = MeshData(vertices=vertices, faces=faces)
95
+ expected_face_normals = np.array([
96
+ [[0, 0, -1], [0, 0, -1], [0, 0, -1]],
97
+ [[-1, 0, 0], [-1, 0, 0], [-1, 0, 0]],
98
+ [[0, -1, 0], [0, -1, 0], [0, -1, 0]]],
99
+ dtype=dtype_float)
100
+
101
+ computed_face_normals = mesh.get_face_normals(indexed="faces")
102
+
103
+ assert_array_equal(expected_face_normals, computed_face_normals)
104
+
105
+
34
106
  run_tests_if_main()
vispy/gloo/buffer.py CHANGED
@@ -414,6 +414,10 @@ class VertexBuffer(DataBuffer):
414
414
  Buffer data (optional)
415
415
  """
416
416
 
417
+ def __init__(self, data=None, divisor=None):
418
+ super().__init__(data)
419
+ self.divisor = divisor
420
+
417
421
  _GLIR_TYPE = 'VertexBuffer'
418
422
 
419
423
  def _prepare_data(self, data, convert=False):
@@ -449,6 +453,14 @@ class VertexBuffer(DataBuffer):
449
453
  self._last_dim = c
450
454
  return data
451
455
 
456
+ @property
457
+ def divisor(self):
458
+ return self._divisor
459
+
460
+ @divisor.setter
461
+ def divisor(self, value):
462
+ self._divisor = max(1, int(value)) if value else None
463
+
452
464
 
453
465
  def _last_stack_str():
454
466
  """Print stack trace from call that didn't originate from here"""
@@ -1,4 +1,4 @@
1
- """
1
+ """GL definitions converted to Python by codegen/createglapi.py.
2
2
 
3
3
  THIS CODE IS AUTO-GENERATED. DO NOT EDIT.
4
4
 
@@ -8,11 +8,13 @@ Constants for OpenGL ES 2.0.
8
8
 
9
9
 
10
10
  class Enum(int):
11
- ''' Enum (integer) with a meaningfull repr. '''
11
+ """Enum (integer) with a meaningfull repr."""
12
+
12
13
  def __new__(cls, name, value):
13
14
  base = int.__new__(cls, value)
14
15
  base.name = name
15
16
  return base
17
+
16
18
  def __repr__(self):
17
19
  return self.name
18
20
 
@@ -149,6 +151,7 @@ GL_LOW_FLOAT = Enum('GL_LOW_FLOAT', 36336)
149
151
  GL_LOW_INT = Enum('GL_LOW_INT', 36339)
150
152
  GL_LUMINANCE = Enum('GL_LUMINANCE', 6409)
151
153
  GL_LUMINANCE_ALPHA = Enum('GL_LUMINANCE_ALPHA', 6410)
154
+ GL_MAX = Enum('GL_MAX', 32776)
152
155
  GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = Enum('GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS', 35661)
153
156
  GL_MAX_CUBE_MAP_TEXTURE_SIZE = Enum('GL_MAX_CUBE_MAP_TEXTURE_SIZE', 34076)
154
157
  GL_MAX_FRAGMENT_UNIFORM_VECTORS = Enum('GL_MAX_FRAGMENT_UNIFORM_VECTORS', 36349)
@@ -162,6 +165,7 @@ GL_MAX_VERTEX_UNIFORM_VECTORS = Enum('GL_MAX_VERTEX_UNIFORM_VECTORS', 36347)
162
165
  GL_MAX_VIEWPORT_DIMS = Enum('GL_MAX_VIEWPORT_DIMS', 3386)
163
166
  GL_MEDIUM_FLOAT = Enum('GL_MEDIUM_FLOAT', 36337)
164
167
  GL_MEDIUM_INT = Enum('GL_MEDIUM_INT', 36340)
168
+ GL_MIN = Enum('GL_MIN', 32775)
165
169
  GL_MIRRORED_REPEAT = Enum('GL_MIRRORED_REPEAT', 33648)
166
170
  GL_NEAREST = Enum('GL_NEAREST', 9728)
167
171
  GL_NEAREST_MIPMAP_LINEAR = Enum('GL_NEAREST_MIPMAP_LINEAR', 9986)
@@ -322,7 +326,7 @@ GL_ZERO = Enum('GL_ZERO', 0)
322
326
 
323
327
 
324
328
  ENUM_MAP = {}
325
- for ob in list(globals().values()):
326
- if repr(ob).startswith('GL_'):
329
+ for var_name, ob in list(globals().items()):
330
+ if var_name.startswith('GL_'):
327
331
  ENUM_MAP[int(ob)] = ob
328
- del ob
332
+ del ob, var_name
vispy/gloo/gl/_es2.py CHANGED
@@ -1,5 +1,10 @@
1
- """THIS CODE IS AUTO-GENERATED. DO NOT EDIT.
2
- GL ES 2.0 API (via Angle/DirectX on Windows)"""
1
+ """GL definitions converted to Python by codegen/createglapi.py.
2
+
3
+ THIS CODE IS AUTO-GENERATED. DO NOT EDIT.
4
+
5
+ GL ES 2.0 API (via Angle/DirectX on Windows)
6
+
7
+ """
3
8
 
4
9
  import ctypes
5
10
  from .es2 import _lib
@@ -81,8 +86,7 @@ def glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha):
81
86
  _lib.glBufferData.argtypes = ctypes.c_uint, ctypes.c_ssize_t, ctypes.c_void_p, ctypes.c_uint,
82
87
  # void = glBufferData(GLenum target, GLsizeiptr size, GLvoid* data, GLenum usage)
83
88
  def glBufferData(target, data, usage):
84
- """ Data can be numpy array or the size of data to allocate.
85
- """
89
+ """Data can be numpy array or the size of data to allocate."""
86
90
  if isinstance(data, int):
87
91
  size = data
88
92
  data = ctypes.c_voidp(0)
vispy/gloo/gl/_gl2.py CHANGED
@@ -1,4 +1,4 @@
1
- """
1
+ """GL definitions converted to Python by codegen/createglapi.py.
2
2
 
3
3
  THIS CODE IS AUTO-GENERATED. DO NOT EDIT.
4
4
 
@@ -121,8 +121,7 @@ def glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha):
121
121
 
122
122
  # void = glBufferData(GLenum target, GLsizeiptr size, GLvoid* data, GLenum usage)
123
123
  def glBufferData(target, data, usage):
124
- """ Data can be numpy array or the size of data to allocate.
125
- """
124
+ """Data can be numpy array or the size of data to allocate."""
126
125
  if isinstance(data, int):
127
126
  size = data
128
127
  data = ctypes.c_voidp(0)
vispy/gloo/gl/_proxy.py CHANGED
@@ -1,4 +1,4 @@
1
- """
1
+ """GL definitions converted to Python by codegen/createglapi.py.
2
2
 
3
3
  THIS CODE IS AUTO-GENERATED. DO NOT EDIT.
4
4
 
@@ -1,5 +1,10 @@
1
- """THIS CODE IS AUTO-GENERATED. DO NOT EDIT.
2
- Proxy API for GL ES 2.0 subset, via the PyOpenGL library."""
1
+ """GL definitions converted to Python by codegen/createglapi.py.
2
+
3
+ THIS CODE IS AUTO-GENERATED. DO NOT EDIT.
4
+
5
+ Proxy API for GL ES 2.0 subset, via the PyOpenGL library.
6
+
7
+ """
3
8
 
4
9
  import ctypes
5
10
  from OpenGL import GL
@@ -34,24 +39,24 @@ def glCompressedTexImage2D(target, level, internalformat, width, height, border,
34
39
  size = data.size
35
40
  GL.glCompressedTexImage2D(target, level, internalformat, width, height, border, size, data)
36
41
 
37
-
42
+
38
43
  def glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, data):
39
44
  size = data.size
40
45
  GL.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, size, data)
41
46
 
42
-
47
+
43
48
  def glDeleteBuffer(buffer):
44
49
  GL.glDeleteBuffers(1, [buffer])
45
50
 
46
-
51
+
47
52
  def glDeleteFramebuffer(framebuffer):
48
53
  FBO.glDeleteFramebuffers(1, [framebuffer])
49
54
 
50
-
55
+
51
56
  def glDeleteRenderbuffer(renderbuffer):
52
57
  FBO.glDeleteRenderbuffers(1, [renderbuffer])
53
58
 
54
-
59
+
55
60
  def glDeleteTexture(texture):
56
61
  GL.glDeleteTextures([texture])
57
62
 
@@ -234,6 +234,9 @@ GL_VERTEX_ATTRIB_ARRAY_SIZE GL_VERTEX_ATTRIB_ARRAY_STRIDE
234
234
  GL_VERTEX_ATTRIB_ARRAY_TYPE GL_VERTEX_SHADER GL_VIEWPORT GL_ZERO
235
235
  """.replace('\n', ' ')
236
236
 
237
+ # vispy_ext.h
238
+ constant_names += "GL_MIN GL_MAX"
239
+
237
240
  function_names = [n.strip() for n in function_names.split(' ')]
238
241
  function_names = set([n for n in function_names if n])
239
242
  constant_names = [n.strip() for n in constant_names.split(' ')]
vispy/gloo/glir.py CHANGED
@@ -173,11 +173,13 @@ DRAW
173
173
 
174
174
  ::
175
175
 
176
- ('DRAW', <program_id>, <mode:str>, <selection:tuple>)
177
- # Example: Draw 100 lines
178
- ('DRAW', 4, 'lines', (0, 100))
176
+ ('DRAW', <program_id>, <mode:str>, <selection:tuple>, <instances:int>)
177
+ # Example: Draw 100 lines with non-instanced rendering
178
+ ('DRAW', 4, 'lines', (0, 100), 1)
179
179
  # Example: Draw 100 lines using index buffer with id 5
180
- ('DRAW', 4, 'points', (5, 'unsigned_int', 100))
180
+ ('DRAW', 4, 'points', (5, 'unsigned_int', 100), 1)
181
+ # Example: Draw a mesh with 10 vertices 20 times using instanced rendering
182
+ ('DRAW', 2, 'mesh', (0, 10), 20)
181
183
 
182
184
  Applies to: Program
183
185
 
@@ -362,7 +364,7 @@ import sys
362
364
  import re
363
365
  import json
364
366
  import weakref
365
- from distutils.version import LooseVersion
367
+ from packaging.version import Version
366
368
 
367
369
  import numpy as np
368
370
 
@@ -371,6 +373,9 @@ from ..util import logger
371
373
 
372
374
  # TODO: expose these via an extension space in .gl?
373
375
  _internalformats = [
376
+ gl.Enum('GL_DEPTH_COMPONENT', 6402),
377
+ gl.Enum('GL_DEPTH_COMPONENT16', 33189),
378
+ gl.Enum('GL_DEPTH_COMPONENT32_OES', 33191),
374
379
  gl.Enum('GL_RED', 6403),
375
380
  gl.Enum('GL_R', 8194),
376
381
  gl.Enum('GL_R8', 33321),
@@ -847,7 +852,7 @@ class GlirParser(BaseGlirParser):
847
852
  if not this_version:
848
853
  logger.warning("OpenGL version could not be determined, which "
849
854
  "might be a sign that OpenGL is not loaded correctly.")
850
- elif LooseVersion(this_version) < '2.1':
855
+ elif Version(this_version) < Version('2.1'):
851
856
  if os.getenv('VISPY_IGNORE_OLD_VERSION', '').lower() != 'true':
852
857
  logger.warning('OpenGL version 2.1 or higher recommended, '
853
858
  'got %s. Some functionality may fail.'
@@ -1220,7 +1225,7 @@ class GlirProgram(GlirObject):
1220
1225
  # Regular uniform
1221
1226
  func(handle, count, value)
1222
1227
 
1223
- def set_attribute(self, name, type_, value):
1228
+ def set_attribute(self, name, type_, value, divisor=None):
1224
1229
  """Set an attribute value. Value is assumed to have been checked."""
1225
1230
  if not self._linked:
1226
1231
  raise RuntimeError('Cannot set attribute when program has no code')
@@ -1247,7 +1252,7 @@ class GlirProgram(GlirObject):
1247
1252
  funcname = self.ATYPEMAP[type_]
1248
1253
  func = getattr(gl, funcname)
1249
1254
  # Set data
1250
- self._attributes[name] = 0, handle, func, value[1:]
1255
+ self._attributes[name] = 0, handle, func, value[1:], divisor
1251
1256
  else:
1252
1257
  # Get meta data
1253
1258
  vbo_id, stride, offset = value
@@ -1261,7 +1266,7 @@ class GlirProgram(GlirObject):
1261
1266
  # Set data
1262
1267
  func = gl.glVertexAttribPointer
1263
1268
  args = size, gtype, gl.GL_FALSE, stride, offset
1264
- self._attributes[name] = vbo.handle, handle, func, args
1269
+ self._attributes[name] = vbo.handle, handle, func, args, divisor
1265
1270
 
1266
1271
  def _pre_draw(self):
1267
1272
  self.activate()
@@ -1270,11 +1275,13 @@ class GlirProgram(GlirObject):
1270
1275
  gl.glActiveTexture(gl.GL_TEXTURE0 + unit)
1271
1276
  gl.glBindTexture(tex_target, tex_handle)
1272
1277
  # Activate attributes
1273
- for vbo_handle, attr_handle, func, args in self._attributes.values():
1278
+ for vbo_handle, attr_handle, func, args, divisor in self._attributes.values():
1274
1279
  if vbo_handle:
1275
1280
  gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_handle)
1276
1281
  gl.glEnableVertexAttribArray(attr_handle)
1277
1282
  func(attr_handle, *args)
1283
+ if divisor is not None:
1284
+ gl.glVertexAttribDivisor(attr_handle, divisor)
1278
1285
  else:
1279
1286
  gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
1280
1287
  gl.glDisableVertexAttribArray(attr_handle)
@@ -1308,7 +1315,7 @@ class GlirProgram(GlirObject):
1308
1315
  # apps it would not even make sense.
1309
1316
  # self.deactivate()
1310
1317
 
1311
- def draw(self, mode, selection):
1318
+ def draw(self, mode, selection, instances=1):
1312
1319
  """Draw program in given mode, with given selection (IndexBuffer or
1313
1320
  first, count).
1314
1321
  """
@@ -1334,14 +1341,20 @@ class GlirProgram(GlirObject):
1334
1341
  self._pre_draw()
1335
1342
  ibuf = self._parser.get_object(id_)
1336
1343
  ibuf.activate()
1337
- gl.glDrawElements(mode, count, as_enum(gtype), None)
1344
+ if instances > 1:
1345
+ gl.glDrawElementsInstanced(mode, count, as_enum(gtype), None, instances)
1346
+ else:
1347
+ gl.glDrawElements(mode, count, as_enum(gtype), None)
1338
1348
  ibuf.deactivate()
1339
1349
  else:
1340
1350
  # Selection based on start and count
1341
1351
  first, count = selection
1342
1352
  if count:
1343
1353
  self._pre_draw()
1344
- gl.glDrawArrays(mode, first, count)
1354
+ if instances > 1:
1355
+ gl.glDrawArraysInstanced(mode, first, count, instances)
1356
+ else:
1357
+ gl.glDrawArrays(mode, first, count)
1345
1358
  # Wrap up
1346
1359
  gl.check_error('Check after draw')
1347
1360
  self._post_draw()