vispy 0.15.0__cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.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.
- vispy/__init__.py +33 -0
- vispy/app/__init__.py +15 -0
- vispy/app/_default_app.py +76 -0
- vispy/app/_detect_eventloop.py +148 -0
- vispy/app/application.py +263 -0
- vispy/app/backends/__init__.py +52 -0
- vispy/app/backends/_egl.py +264 -0
- vispy/app/backends/_glfw.py +513 -0
- vispy/app/backends/_jupyter_rfb.py +278 -0
- vispy/app/backends/_offscreen_util.py +121 -0
- vispy/app/backends/_osmesa.py +235 -0
- vispy/app/backends/_pyglet.py +451 -0
- vispy/app/backends/_pyqt4.py +36 -0
- vispy/app/backends/_pyqt5.py +36 -0
- vispy/app/backends/_pyqt6.py +40 -0
- vispy/app/backends/_pyside.py +37 -0
- vispy/app/backends/_pyside2.py +52 -0
- vispy/app/backends/_pyside6.py +53 -0
- vispy/app/backends/_qt.py +1003 -0
- vispy/app/backends/_sdl2.py +444 -0
- vispy/app/backends/_template.py +244 -0
- vispy/app/backends/_test.py +8 -0
- vispy/app/backends/_tk.py +800 -0
- vispy/app/backends/_wx.py +476 -0
- vispy/app/backends/tests/__init__.py +0 -0
- vispy/app/backends/tests/test_offscreen_util.py +52 -0
- vispy/app/backends/tests/test_rfb.py +77 -0
- vispy/app/base.py +294 -0
- vispy/app/canvas.py +828 -0
- vispy/app/qt.py +92 -0
- vispy/app/tests/__init__.py +0 -0
- vispy/app/tests/qt-designer.ui +58 -0
- vispy/app/tests/test_app.py +442 -0
- vispy/app/tests/test_backends.py +164 -0
- vispy/app/tests/test_canvas.py +122 -0
- vispy/app/tests/test_context.py +92 -0
- vispy/app/tests/test_qt.py +47 -0
- vispy/app/tests/test_simultaneous.py +134 -0
- vispy/app/timer.py +174 -0
- vispy/color/__init__.py +17 -0
- vispy/color/_color_dict.py +193 -0
- vispy/color/color_array.py +447 -0
- vispy/color/color_space.py +181 -0
- vispy/color/colormap.py +1213 -0
- vispy/color/tests/__init__.py +0 -0
- vispy/color/tests/test_color.py +378 -0
- vispy/conftest.py +12 -0
- vispy/ext/__init__.py +0 -0
- vispy/ext/cocoapy.py +1522 -0
- vispy/ext/cubehelix.py +138 -0
- vispy/ext/egl.py +375 -0
- vispy/ext/fontconfig.py +118 -0
- vispy/ext/gdi32plus.py +206 -0
- vispy/ext/osmesa.py +105 -0
- vispy/geometry/__init__.py +23 -0
- vispy/geometry/_triangulation_debugger.py +171 -0
- vispy/geometry/calculations.py +162 -0
- vispy/geometry/curves.py +399 -0
- vispy/geometry/generation.py +643 -0
- vispy/geometry/isocurve.py +175 -0
- vispy/geometry/isosurface.py +465 -0
- vispy/geometry/meshdata.py +700 -0
- vispy/geometry/normals.py +78 -0
- vispy/geometry/parametric.py +56 -0
- vispy/geometry/polygon.py +137 -0
- vispy/geometry/rect.py +210 -0
- vispy/geometry/tests/__init__.py +0 -0
- vispy/geometry/tests/test_calculations.py +23 -0
- vispy/geometry/tests/test_generation.py +56 -0
- vispy/geometry/tests/test_meshdata.py +106 -0
- vispy/geometry/tests/test_triangulation.py +594 -0
- vispy/geometry/torusknot.py +142 -0
- vispy/geometry/triangulation.py +876 -0
- vispy/gloo/__init__.py +56 -0
- vispy/gloo/buffer.py +505 -0
- vispy/gloo/context.py +272 -0
- vispy/gloo/framebuffer.py +257 -0
- vispy/gloo/gl/__init__.py +234 -0
- vispy/gloo/gl/_constants.py +332 -0
- vispy/gloo/gl/_es2.py +986 -0
- vispy/gloo/gl/_gl2.py +1365 -0
- vispy/gloo/gl/_proxy.py +499 -0
- vispy/gloo/gl/_pyopengl2.py +362 -0
- vispy/gloo/gl/dummy.py +24 -0
- vispy/gloo/gl/es2.py +62 -0
- vispy/gloo/gl/gl2.py +98 -0
- vispy/gloo/gl/glplus.py +168 -0
- vispy/gloo/gl/pyopengl2.py +97 -0
- vispy/gloo/gl/tests/__init__.py +0 -0
- vispy/gloo/gl/tests/test_basics.py +282 -0
- vispy/gloo/gl/tests/test_functionality.py +568 -0
- vispy/gloo/gl/tests/test_names.py +246 -0
- vispy/gloo/gl/tests/test_use.py +71 -0
- vispy/gloo/glir.py +1824 -0
- vispy/gloo/globject.py +101 -0
- vispy/gloo/preprocessor.py +67 -0
- vispy/gloo/program.py +543 -0
- vispy/gloo/tests/__init__.py +0 -0
- vispy/gloo/tests/test_buffer.py +558 -0
- vispy/gloo/tests/test_context.py +119 -0
- vispy/gloo/tests/test_framebuffer.py +195 -0
- vispy/gloo/tests/test_glir.py +307 -0
- vispy/gloo/tests/test_globject.py +35 -0
- vispy/gloo/tests/test_program.py +302 -0
- vispy/gloo/tests/test_texture.py +732 -0
- vispy/gloo/tests/test_use_gloo.py +187 -0
- vispy/gloo/tests/test_util.py +60 -0
- vispy/gloo/tests/test_wrappers.py +261 -0
- vispy/gloo/texture.py +1046 -0
- vispy/gloo/util.py +129 -0
- vispy/gloo/wrappers.py +762 -0
- vispy/glsl/__init__.py +42 -0
- vispy/glsl/antialias/antialias.glsl +7 -0
- vispy/glsl/antialias/cap-butt.glsl +31 -0
- vispy/glsl/antialias/cap-round.glsl +29 -0
- vispy/glsl/antialias/cap-square.glsl +30 -0
- vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
- vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
- vispy/glsl/antialias/cap.glsl +67 -0
- vispy/glsl/antialias/caps.glsl +67 -0
- vispy/glsl/antialias/filled.glsl +50 -0
- vispy/glsl/antialias/outline.glsl +40 -0
- vispy/glsl/antialias/stroke.glsl +43 -0
- vispy/glsl/arrowheads/angle.glsl +99 -0
- vispy/glsl/arrowheads/arrowheads.frag +60 -0
- vispy/glsl/arrowheads/arrowheads.glsl +12 -0
- vispy/glsl/arrowheads/arrowheads.vert +83 -0
- vispy/glsl/arrowheads/curved.glsl +48 -0
- vispy/glsl/arrowheads/inhibitor.glsl +26 -0
- vispy/glsl/arrowheads/stealth.glsl +46 -0
- vispy/glsl/arrowheads/triangle.glsl +97 -0
- vispy/glsl/arrowheads/util.glsl +13 -0
- vispy/glsl/arrows/angle-30.glsl +12 -0
- vispy/glsl/arrows/angle-60.glsl +12 -0
- vispy/glsl/arrows/angle-90.glsl +12 -0
- vispy/glsl/arrows/arrow.frag +39 -0
- vispy/glsl/arrows/arrow.vert +49 -0
- vispy/glsl/arrows/arrows.glsl +17 -0
- vispy/glsl/arrows/common.glsl +187 -0
- vispy/glsl/arrows/curved.glsl +63 -0
- vispy/glsl/arrows/stealth.glsl +50 -0
- vispy/glsl/arrows/triangle-30.glsl +12 -0
- vispy/glsl/arrows/triangle-60.glsl +12 -0
- vispy/glsl/arrows/triangle-90.glsl +12 -0
- vispy/glsl/arrows/util.glsl +98 -0
- vispy/glsl/build_spatial_filters.py +660 -0
- vispy/glsl/collections/agg-fast-path.frag +20 -0
- vispy/glsl/collections/agg-fast-path.vert +78 -0
- vispy/glsl/collections/agg-glyph.frag +60 -0
- vispy/glsl/collections/agg-glyph.vert +33 -0
- vispy/glsl/collections/agg-marker.frag +35 -0
- vispy/glsl/collections/agg-marker.vert +48 -0
- vispy/glsl/collections/agg-path.frag +55 -0
- vispy/glsl/collections/agg-path.vert +166 -0
- vispy/glsl/collections/agg-point.frag +21 -0
- vispy/glsl/collections/agg-point.vert +35 -0
- vispy/glsl/collections/agg-segment.frag +32 -0
- vispy/glsl/collections/agg-segment.vert +75 -0
- vispy/glsl/collections/marker.frag +38 -0
- vispy/glsl/collections/marker.vert +48 -0
- vispy/glsl/collections/raw-path.frag +15 -0
- vispy/glsl/collections/raw-path.vert +24 -0
- vispy/glsl/collections/raw-point.frag +14 -0
- vispy/glsl/collections/raw-point.vert +31 -0
- vispy/glsl/collections/raw-segment.frag +18 -0
- vispy/glsl/collections/raw-segment.vert +26 -0
- vispy/glsl/collections/raw-triangle.frag +13 -0
- vispy/glsl/collections/raw-triangle.vert +26 -0
- vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
- vispy/glsl/collections/sdf-glyph.frag +80 -0
- vispy/glsl/collections/sdf-glyph.vert +59 -0
- vispy/glsl/collections/tick-labels.vert +71 -0
- vispy/glsl/colormaps/autumn.glsl +20 -0
- vispy/glsl/colormaps/blues.glsl +20 -0
- vispy/glsl/colormaps/color-space.glsl +17 -0
- vispy/glsl/colormaps/colormaps.glsl +24 -0
- vispy/glsl/colormaps/cool.glsl +20 -0
- vispy/glsl/colormaps/fire.glsl +21 -0
- vispy/glsl/colormaps/gray.glsl +20 -0
- vispy/glsl/colormaps/greens.glsl +20 -0
- vispy/glsl/colormaps/hot.glsl +22 -0
- vispy/glsl/colormaps/ice.glsl +20 -0
- vispy/glsl/colormaps/icefire.glsl +23 -0
- vispy/glsl/colormaps/parse.py +40 -0
- vispy/glsl/colormaps/reds.glsl +20 -0
- vispy/glsl/colormaps/spring.glsl +20 -0
- vispy/glsl/colormaps/summer.glsl +20 -0
- vispy/glsl/colormaps/user.glsl +22 -0
- vispy/glsl/colormaps/util.glsl +41 -0
- vispy/glsl/colormaps/wheel.glsl +21 -0
- vispy/glsl/colormaps/winter.glsl +20 -0
- vispy/glsl/lines/agg.frag +320 -0
- vispy/glsl/lines/agg.vert +241 -0
- vispy/glsl/markers/arrow.glsl +12 -0
- vispy/glsl/markers/asterisk.glsl +16 -0
- vispy/glsl/markers/chevron.glsl +14 -0
- vispy/glsl/markers/clover.glsl +20 -0
- vispy/glsl/markers/club.glsl +31 -0
- vispy/glsl/markers/cross.glsl +17 -0
- vispy/glsl/markers/diamond.glsl +12 -0
- vispy/glsl/markers/disc.glsl +9 -0
- vispy/glsl/markers/ellipse.glsl +67 -0
- vispy/glsl/markers/hbar.glsl +9 -0
- vispy/glsl/markers/heart.glsl +15 -0
- vispy/glsl/markers/infinity.glsl +15 -0
- vispy/glsl/markers/marker-sdf.frag +74 -0
- vispy/glsl/markers/marker-sdf.vert +41 -0
- vispy/glsl/markers/marker.frag +36 -0
- vispy/glsl/markers/marker.vert +46 -0
- vispy/glsl/markers/markers.glsl +24 -0
- vispy/glsl/markers/pin.glsl +18 -0
- vispy/glsl/markers/ring.glsl +11 -0
- vispy/glsl/markers/spade.glsl +28 -0
- vispy/glsl/markers/square.glsl +10 -0
- vispy/glsl/markers/tag.glsl +11 -0
- vispy/glsl/markers/triangle.glsl +14 -0
- vispy/glsl/markers/vbar.glsl +9 -0
- vispy/glsl/math/circle-through-2-points.glsl +30 -0
- vispy/glsl/math/constants.glsl +48 -0
- vispy/glsl/math/double.glsl +114 -0
- vispy/glsl/math/functions.glsl +20 -0
- vispy/glsl/math/point-to-line-distance.glsl +31 -0
- vispy/glsl/math/point-to-line-projection.glsl +29 -0
- vispy/glsl/math/signed-line-distance.glsl +27 -0
- vispy/glsl/math/signed-segment-distance.glsl +30 -0
- vispy/glsl/misc/regular-grid.frag +244 -0
- vispy/glsl/misc/spatial-filters.frag +1407 -0
- vispy/glsl/misc/viewport-NDC.glsl +20 -0
- vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
- vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
- vispy/glsl/transforms/hammer.glsl +44 -0
- vispy/glsl/transforms/identity.glsl +6 -0
- vispy/glsl/transforms/identity_forward.glsl +23 -0
- vispy/glsl/transforms/identity_inverse.glsl +23 -0
- vispy/glsl/transforms/linear-scale.glsl +127 -0
- vispy/glsl/transforms/log-scale.glsl +126 -0
- vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
- vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
- vispy/glsl/transforms/panzoom.glsl +10 -0
- vispy/glsl/transforms/polar.glsl +41 -0
- vispy/glsl/transforms/position.glsl +44 -0
- vispy/glsl/transforms/power-scale.glsl +139 -0
- vispy/glsl/transforms/projection.glsl +7 -0
- vispy/glsl/transforms/pvm.glsl +13 -0
- vispy/glsl/transforms/rotate.glsl +45 -0
- vispy/glsl/transforms/trackball.glsl +15 -0
- vispy/glsl/transforms/translate.glsl +35 -0
- vispy/glsl/transforms/transverse_mercator.glsl +38 -0
- vispy/glsl/transforms/viewport-clipping.glsl +14 -0
- vispy/glsl/transforms/viewport-transform.glsl +16 -0
- vispy/glsl/transforms/viewport.glsl +50 -0
- vispy/glsl/transforms/x.glsl +24 -0
- vispy/glsl/transforms/y.glsl +19 -0
- vispy/glsl/transforms/z.glsl +14 -0
- vispy/io/__init__.py +20 -0
- vispy/io/_data/spatial-filters.npy +0 -0
- vispy/io/datasets.py +94 -0
- vispy/io/image.py +231 -0
- vispy/io/mesh.py +122 -0
- vispy/io/stl.py +167 -0
- vispy/io/tests/__init__.py +0 -0
- vispy/io/tests/test_image.py +47 -0
- vispy/io/tests/test_io.py +121 -0
- vispy/io/wavefront.py +350 -0
- vispy/plot/__init__.py +36 -0
- vispy/plot/fig.py +58 -0
- vispy/plot/plotwidget.py +522 -0
- vispy/plot/tests/__init__.py +0 -0
- vispy/plot/tests/test_plot.py +46 -0
- vispy/scene/__init__.py +43 -0
- vispy/scene/cameras/__init__.py +27 -0
- vispy/scene/cameras/_base.py +38 -0
- vispy/scene/cameras/arcball.py +105 -0
- vispy/scene/cameras/base_camera.py +551 -0
- vispy/scene/cameras/fly.py +474 -0
- vispy/scene/cameras/magnify.py +163 -0
- vispy/scene/cameras/panzoom.py +311 -0
- vispy/scene/cameras/perspective.py +338 -0
- vispy/scene/cameras/tests/__init__.py +0 -0
- vispy/scene/cameras/tests/test_cameras.py +27 -0
- vispy/scene/cameras/tests/test_link.py +53 -0
- vispy/scene/cameras/tests/test_perspective.py +122 -0
- vispy/scene/cameras/turntable.py +183 -0
- vispy/scene/canvas.py +639 -0
- vispy/scene/events.py +85 -0
- vispy/scene/node.py +644 -0
- vispy/scene/subscene.py +20 -0
- vispy/scene/tests/__init__.py +0 -0
- vispy/scene/tests/test_canvas.py +119 -0
- vispy/scene/tests/test_node.py +142 -0
- vispy/scene/tests/test_visuals.py +141 -0
- vispy/scene/visuals.py +276 -0
- vispy/scene/widgets/__init__.py +18 -0
- vispy/scene/widgets/anchor.py +25 -0
- vispy/scene/widgets/axis.py +88 -0
- vispy/scene/widgets/colorbar.py +176 -0
- vispy/scene/widgets/console.py +351 -0
- vispy/scene/widgets/grid.py +509 -0
- vispy/scene/widgets/label.py +50 -0
- vispy/scene/widgets/tests/__init__.py +0 -0
- vispy/scene/widgets/tests/test_colorbar.py +47 -0
- vispy/scene/widgets/viewbox.py +199 -0
- vispy/scene/widgets/widget.py +478 -0
- vispy/testing/__init__.py +51 -0
- vispy/testing/_runners.py +448 -0
- vispy/testing/_testing.py +416 -0
- vispy/testing/image_tester.py +494 -0
- vispy/testing/rendered_array_tester.py +85 -0
- vispy/testing/tests/__init__.py +0 -0
- vispy/testing/tests/test_testing.py +20 -0
- vispy/util/__init__.py +32 -0
- vispy/util/bunch.py +15 -0
- vispy/util/check_environment.py +57 -0
- vispy/util/config.py +490 -0
- vispy/util/dpi/__init__.py +19 -0
- vispy/util/dpi/_linux.py +69 -0
- vispy/util/dpi/_quartz.py +26 -0
- vispy/util/dpi/_win32.py +34 -0
- vispy/util/dpi/tests/__init__.py +0 -0
- vispy/util/dpi/tests/test_dpi.py +16 -0
- vispy/util/eq.py +41 -0
- vispy/util/event.py +774 -0
- vispy/util/fetching.py +276 -0
- vispy/util/filter.py +44 -0
- vispy/util/fonts/__init__.py +14 -0
- vispy/util/fonts/_freetype.py +73 -0
- vispy/util/fonts/_quartz.py +192 -0
- vispy/util/fonts/_triage.py +36 -0
- vispy/util/fonts/_vispy_fonts.py +20 -0
- vispy/util/fonts/_win32.py +105 -0
- vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
- vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
- vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
- vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
- vispy/util/fonts/tests/__init__.py +0 -0
- vispy/util/fonts/tests/test_font.py +45 -0
- vispy/util/fourier.py +69 -0
- vispy/util/frozen.py +25 -0
- vispy/util/gallery_scraper.py +268 -0
- vispy/util/keys.py +91 -0
- vispy/util/logs.py +358 -0
- vispy/util/osmesa_gl.py +17 -0
- vispy/util/profiler.py +135 -0
- vispy/util/ptime.py +16 -0
- vispy/util/quaternion.py +229 -0
- vispy/util/svg/__init__.py +18 -0
- vispy/util/svg/base.py +20 -0
- vispy/util/svg/color.py +219 -0
- vispy/util/svg/element.py +51 -0
- vispy/util/svg/geometry.py +478 -0
- vispy/util/svg/group.py +66 -0
- vispy/util/svg/length.py +81 -0
- vispy/util/svg/number.py +25 -0
- vispy/util/svg/path.py +332 -0
- vispy/util/svg/shapes.py +57 -0
- vispy/util/svg/style.py +59 -0
- vispy/util/svg/svg.py +40 -0
- vispy/util/svg/transform.py +223 -0
- vispy/util/svg/transformable.py +28 -0
- vispy/util/svg/viewport.py +73 -0
- vispy/util/tests/__init__.py +0 -0
- vispy/util/tests/test_config.py +58 -0
- vispy/util/tests/test_docstring_parameters.py +123 -0
- vispy/util/tests/test_emitter_group.py +262 -0
- vispy/util/tests/test_event_emitter.py +743 -0
- vispy/util/tests/test_fourier.py +35 -0
- vispy/util/tests/test_gallery_scraper.py +112 -0
- vispy/util/tests/test_import.py +127 -0
- vispy/util/tests/test_key.py +22 -0
- vispy/util/tests/test_logging.py +45 -0
- vispy/util/tests/test_run.py +14 -0
- vispy/util/tests/test_transforms.py +42 -0
- vispy/util/tests/test_vispy.py +48 -0
- vispy/util/transforms.py +201 -0
- vispy/util/wrappers.py +155 -0
- vispy/version.py +21 -0
- vispy/visuals/__init__.py +50 -0
- vispy/visuals/_scalable_textures.py +487 -0
- vispy/visuals/axis.py +678 -0
- vispy/visuals/border.py +208 -0
- vispy/visuals/box.py +79 -0
- vispy/visuals/collections/__init__.py +30 -0
- vispy/visuals/collections/agg_fast_path_collection.py +219 -0
- vispy/visuals/collections/agg_path_collection.py +197 -0
- vispy/visuals/collections/agg_point_collection.py +52 -0
- vispy/visuals/collections/agg_segment_collection.py +142 -0
- vispy/visuals/collections/array_list.py +401 -0
- vispy/visuals/collections/base_collection.py +482 -0
- vispy/visuals/collections/collection.py +253 -0
- vispy/visuals/collections/path_collection.py +23 -0
- vispy/visuals/collections/point_collection.py +19 -0
- vispy/visuals/collections/polygon_collection.py +25 -0
- vispy/visuals/collections/raw_path_collection.py +119 -0
- vispy/visuals/collections/raw_point_collection.py +113 -0
- vispy/visuals/collections/raw_polygon_collection.py +77 -0
- vispy/visuals/collections/raw_segment_collection.py +112 -0
- vispy/visuals/collections/raw_triangle_collection.py +78 -0
- vispy/visuals/collections/segment_collection.py +19 -0
- vispy/visuals/collections/triangle_collection.py +16 -0
- vispy/visuals/collections/util.py +168 -0
- vispy/visuals/colorbar.py +699 -0
- vispy/visuals/cube.py +41 -0
- vispy/visuals/ellipse.py +162 -0
- vispy/visuals/filters/__init__.py +10 -0
- vispy/visuals/filters/base_filter.py +242 -0
- vispy/visuals/filters/clipper.py +60 -0
- vispy/visuals/filters/clipping_planes.py +122 -0
- vispy/visuals/filters/color.py +181 -0
- vispy/visuals/filters/markers.py +28 -0
- vispy/visuals/filters/mesh.py +801 -0
- vispy/visuals/filters/picking.py +60 -0
- vispy/visuals/filters/tests/__init__.py +3 -0
- vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
- vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
- vispy/visuals/glsl/__init__.py +1 -0
- vispy/visuals/glsl/antialiasing.py +133 -0
- vispy/visuals/glsl/color.py +63 -0
- vispy/visuals/graphs/__init__.py +1 -0
- vispy/visuals/graphs/graph.py +240 -0
- vispy/visuals/graphs/layouts/__init__.py +55 -0
- vispy/visuals/graphs/layouts/circular.py +49 -0
- vispy/visuals/graphs/layouts/force_directed.py +211 -0
- vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
- vispy/visuals/graphs/layouts/random.py +52 -0
- vispy/visuals/graphs/tests/__init__.py +1 -0
- vispy/visuals/graphs/tests/test_layouts.py +139 -0
- vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
- vispy/visuals/graphs/util.py +120 -0
- vispy/visuals/gridlines.py +161 -0
- vispy/visuals/gridmesh.py +98 -0
- vispy/visuals/histogram.py +58 -0
- vispy/visuals/image.py +701 -0
- vispy/visuals/image_complex.py +130 -0
- vispy/visuals/infinite_line.py +199 -0
- vispy/visuals/instanced_mesh.py +152 -0
- vispy/visuals/isocurve.py +213 -0
- vispy/visuals/isoline.py +241 -0
- vispy/visuals/isosurface.py +113 -0
- vispy/visuals/line/__init__.py +6 -0
- vispy/visuals/line/arrow.py +289 -0
- vispy/visuals/line/dash_atlas.py +90 -0
- vispy/visuals/line/line.py +545 -0
- vispy/visuals/line_plot.py +135 -0
- vispy/visuals/linear_region.py +199 -0
- vispy/visuals/markers.py +819 -0
- vispy/visuals/mesh.py +373 -0
- vispy/visuals/mesh_normals.py +159 -0
- vispy/visuals/plane.py +54 -0
- vispy/visuals/polygon.py +145 -0
- vispy/visuals/rectangle.py +196 -0
- vispy/visuals/regular_polygon.py +56 -0
- vispy/visuals/scrolling_lines.py +197 -0
- vispy/visuals/shaders/__init__.py +17 -0
- vispy/visuals/shaders/compiler.py +206 -0
- vispy/visuals/shaders/expression.py +99 -0
- vispy/visuals/shaders/function.py +788 -0
- vispy/visuals/shaders/multiprogram.py +145 -0
- vispy/visuals/shaders/parsing.py +140 -0
- vispy/visuals/shaders/program.py +161 -0
- vispy/visuals/shaders/shader_object.py +162 -0
- vispy/visuals/shaders/tests/__init__.py +0 -0
- vispy/visuals/shaders/tests/test_function.py +486 -0
- vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
- vispy/visuals/shaders/tests/test_parsing.py +57 -0
- vispy/visuals/shaders/variable.py +272 -0
- vispy/visuals/spectrogram.py +169 -0
- vispy/visuals/sphere.py +80 -0
- vispy/visuals/surface_plot.py +192 -0
- vispy/visuals/tests/__init__.py +0 -0
- vispy/visuals/tests/test_arrows.py +109 -0
- vispy/visuals/tests/test_axis.py +120 -0
- vispy/visuals/tests/test_collections.py +15 -0
- vispy/visuals/tests/test_colorbar.py +179 -0
- vispy/visuals/tests/test_colormap.py +97 -0
- vispy/visuals/tests/test_ellipse.py +122 -0
- vispy/visuals/tests/test_gridlines.py +30 -0
- vispy/visuals/tests/test_histogram.py +24 -0
- vispy/visuals/tests/test_image.py +392 -0
- vispy/visuals/tests/test_image_complex.py +36 -0
- vispy/visuals/tests/test_infinite_line.py +53 -0
- vispy/visuals/tests/test_instanced_mesh.py +50 -0
- vispy/visuals/tests/test_isosurface.py +22 -0
- vispy/visuals/tests/test_linear_region.py +152 -0
- vispy/visuals/tests/test_markers.py +54 -0
- vispy/visuals/tests/test_mesh.py +261 -0
- vispy/visuals/tests/test_mesh_normals.py +218 -0
- vispy/visuals/tests/test_polygon.py +112 -0
- vispy/visuals/tests/test_rectangle.py +163 -0
- vispy/visuals/tests/test_regular_polygon.py +111 -0
- vispy/visuals/tests/test_scalable_textures.py +196 -0
- vispy/visuals/tests/test_sdf.py +73 -0
- vispy/visuals/tests/test_spectrogram.py +42 -0
- vispy/visuals/tests/test_surface_plot.py +57 -0
- vispy/visuals/tests/test_text.py +95 -0
- vispy/visuals/tests/test_volume.py +542 -0
- vispy/visuals/tests/test_windbarb.py +33 -0
- vispy/visuals/text/__init__.py +7 -0
- vispy/visuals/text/_sdf_cpu.cpython-313-x86_64-linux-gnu.so +0 -0
- vispy/visuals/text/_sdf_cpu.pyx +112 -0
- vispy/visuals/text/_sdf_gpu.py +316 -0
- vispy/visuals/text/text.py +675 -0
- vispy/visuals/transforms/__init__.py +34 -0
- vispy/visuals/transforms/_util.py +191 -0
- vispy/visuals/transforms/base_transform.py +233 -0
- vispy/visuals/transforms/chain.py +300 -0
- vispy/visuals/transforms/interactive.py +98 -0
- vispy/visuals/transforms/linear.py +564 -0
- vispy/visuals/transforms/nonlinear.py +398 -0
- vispy/visuals/transforms/tests/__init__.py +0 -0
- vispy/visuals/transforms/tests/test_transforms.py +243 -0
- vispy/visuals/transforms/transform_system.py +339 -0
- vispy/visuals/tube.py +173 -0
- vispy/visuals/visual.py +923 -0
- vispy/visuals/volume.py +1366 -0
- vispy/visuals/windbarb.py +291 -0
- vispy/visuals/xyz_axis.py +34 -0
- vispy-0.15.0.dist-info/METADATA +243 -0
- vispy-0.15.0.dist-info/RECORD +521 -0
- vispy-0.15.0.dist-info/WHEEL +6 -0
- vispy-0.15.0.dist-info/licenses/LICENSE.txt +36 -0
- vispy-0.15.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import weakref
|
|
2
|
+
|
|
3
|
+
from .program import ModularProgram
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MultiProgram(object):
|
|
7
|
+
"""A collection of ModularPrograms that emulates the API of a single
|
|
8
|
+
ModularProgram.
|
|
9
|
+
|
|
10
|
+
A single Visual is often drawn in many different ways--viewed under
|
|
11
|
+
different transforms, with different clipping boundaries, or with different
|
|
12
|
+
colors as in picking and anaglyph stereo. Each draw may require a different
|
|
13
|
+
program. To simplify this process, MultiProgram exposes an API that looks
|
|
14
|
+
very much like a single ModularProgram, but internally manages many
|
|
15
|
+
programs.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, vcode='', fcode='', gcode=None):
|
|
19
|
+
self._vcode = vcode
|
|
20
|
+
self._fcode = fcode
|
|
21
|
+
self._gcode = gcode
|
|
22
|
+
self._programs = weakref.WeakValueDictionary()
|
|
23
|
+
self._set_items = {}
|
|
24
|
+
self._next_prog_id = 0
|
|
25
|
+
self._vert = MultiShader(self, 'vert')
|
|
26
|
+
self._frag = MultiShader(self, 'frag')
|
|
27
|
+
self._geom = None if gcode is None else MultiShader(self, 'geom')
|
|
28
|
+
|
|
29
|
+
def add_program(self, name=None):
|
|
30
|
+
"""Create a program and add it to this MultiProgram.
|
|
31
|
+
|
|
32
|
+
It is the caller's responsibility to keep a reference to the returned
|
|
33
|
+
program.
|
|
34
|
+
|
|
35
|
+
The *name* must be unique, but is otherwise arbitrary and used for
|
|
36
|
+
debugging purposes.
|
|
37
|
+
"""
|
|
38
|
+
if name is None:
|
|
39
|
+
name = 'program' + str(self._next_prog_id)
|
|
40
|
+
self._next_prog_id += 1
|
|
41
|
+
|
|
42
|
+
if name in self._programs:
|
|
43
|
+
raise KeyError("Program named '%s' already exists." % name)
|
|
44
|
+
|
|
45
|
+
# create a program and update it to look like the rest
|
|
46
|
+
prog = ModularProgram(self._vcode, self._fcode, self._gcode)
|
|
47
|
+
for key, val in self._set_items.items():
|
|
48
|
+
prog[key] = val
|
|
49
|
+
self.frag._new_program(prog)
|
|
50
|
+
self.vert._new_program(prog)
|
|
51
|
+
if self._geom is not None:
|
|
52
|
+
self.geom._new_program(prog)
|
|
53
|
+
|
|
54
|
+
self._programs[name] = prog
|
|
55
|
+
return prog
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def vert(self):
|
|
59
|
+
"""A wrapper around all vertex shaders contained in this MultiProgram."""
|
|
60
|
+
return self._vert
|
|
61
|
+
|
|
62
|
+
@vert.setter
|
|
63
|
+
def vert(self, code):
|
|
64
|
+
self._vcode = code
|
|
65
|
+
for p in self._programs.values():
|
|
66
|
+
p.vert = code
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def frag(self):
|
|
70
|
+
"""A wrapper around all fragment shaders contained in this MultiProgram."""
|
|
71
|
+
return self._frag
|
|
72
|
+
|
|
73
|
+
@frag.setter
|
|
74
|
+
def frag(self, code):
|
|
75
|
+
self._fcode = code
|
|
76
|
+
for p in self._programs.values():
|
|
77
|
+
p.frag = code
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def geom(self):
|
|
81
|
+
"""A wrapper around all geometry shaders contained in this MultiProgram."""
|
|
82
|
+
return self._geom
|
|
83
|
+
|
|
84
|
+
@geom.setter
|
|
85
|
+
def geom(self, code):
|
|
86
|
+
self._gcode = code
|
|
87
|
+
if self._geom is None:
|
|
88
|
+
self._geom = MultiShader(self, 'geom')
|
|
89
|
+
for p in self._programs.values():
|
|
90
|
+
p.geom = code
|
|
91
|
+
|
|
92
|
+
def __contains__(self, key):
|
|
93
|
+
return any(key in p for p in self._programs.values())
|
|
94
|
+
|
|
95
|
+
def __getitem__(self, key):
|
|
96
|
+
return self._set_items[key]
|
|
97
|
+
|
|
98
|
+
def __setitem__(self, key, value):
|
|
99
|
+
self._set_items[key] = value
|
|
100
|
+
for program in self._programs.values():
|
|
101
|
+
program[key] = value
|
|
102
|
+
|
|
103
|
+
def __iter__(self):
|
|
104
|
+
for p in self._programs.values():
|
|
105
|
+
yield p
|
|
106
|
+
|
|
107
|
+
def bind(self, data):
|
|
108
|
+
for name in data.dtype.names:
|
|
109
|
+
self[name] = data[name]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class MultiShader(object):
|
|
113
|
+
"""Emulates the API of a MainFunction while wrapping all vertex or fragment
|
|
114
|
+
shaders in a MultiProgram.
|
|
115
|
+
|
|
116
|
+
Example::
|
|
117
|
+
|
|
118
|
+
mp = MultiProgram(vert, frag)
|
|
119
|
+
mp.add_program('p1')
|
|
120
|
+
mp.add_program('p2')
|
|
121
|
+
|
|
122
|
+
# applies to all programs
|
|
123
|
+
mp.vert['u_scale'] = (1, 2)
|
|
124
|
+
|
|
125
|
+
# applies to one program
|
|
126
|
+
mp.get_program('p1').frag['u_color'] = (1, 1, 1, 1)
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
def __init__(self, program, shader):
|
|
130
|
+
self._program = program
|
|
131
|
+
self._shader = shader
|
|
132
|
+
self._set_items = {}
|
|
133
|
+
|
|
134
|
+
def __getitem__(self, key):
|
|
135
|
+
return self._set_items[key]
|
|
136
|
+
|
|
137
|
+
def __setitem__(self, key, value):
|
|
138
|
+
self._set_items[key] = value
|
|
139
|
+
for p in self._program._programs.values():
|
|
140
|
+
getattr(p, self._shader)[key] = value
|
|
141
|
+
|
|
142
|
+
def _new_program(self, p):
|
|
143
|
+
"""New program was added to the multiprogram; update items in the shader."""
|
|
144
|
+
for k, v in self._set_items.items():
|
|
145
|
+
getattr(p, self._shader)[k] = v
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (c) Vispy Development Team. All Rights Reserved.
|
|
3
|
+
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
|
|
4
|
+
|
|
5
|
+
from __future__ import division
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
# regular expressions for parsing GLSL
|
|
10
|
+
|
|
11
|
+
re_version_pragma = r'#version\s+(\d+)(.*)?(//.*)?'
|
|
12
|
+
|
|
13
|
+
re_type = r'(?:void|int|float|vec2|vec3|vec4|mat2|mat3|mat4|\
|
|
14
|
+
sampler1D|sampler2D|sampler3D)'
|
|
15
|
+
re_identifier = r'(?:[a-zA-Z_][\w_]*)'
|
|
16
|
+
|
|
17
|
+
# variable qualifiers
|
|
18
|
+
re_qualifier = r'(const|uniform|attribute|varying|in|out|inout)'
|
|
19
|
+
|
|
20
|
+
# template variables like
|
|
21
|
+
# $func_name
|
|
22
|
+
re_template_var = (r"(?:(?:\$" + re_identifier + r")|(?:\$\{" +
|
|
23
|
+
re_identifier + r"\}))")
|
|
24
|
+
|
|
25
|
+
# function names may be either identifier or template var
|
|
26
|
+
re_func_name = r"(" + re_identifier + "|" + re_template_var + ")"
|
|
27
|
+
|
|
28
|
+
# type and identifier like "vec4 var_name"
|
|
29
|
+
re_declaration = "(?:(" + re_type + r")\s+(" + re_identifier + "))"
|
|
30
|
+
|
|
31
|
+
# qualifier, type, and identifier like "uniform vec4 var_name"
|
|
32
|
+
# qualifier is optional.
|
|
33
|
+
# may include multiple names like "attribute float x, y, z"
|
|
34
|
+
re_prog_var_declaration = ("(?:" + re_qualifier + r"?\s*(" + re_type +
|
|
35
|
+
r")\s+(" + re_identifier + r"(\s*,\s*(" +
|
|
36
|
+
re_identifier + "))*))")
|
|
37
|
+
|
|
38
|
+
# list of variable declarations like "vec4 var_name, float other_var_name"
|
|
39
|
+
re_arg_list = "(" + re_declaration + r"(?:,\s*" + re_declaration + ")*)?"
|
|
40
|
+
|
|
41
|
+
# function declaration like "vec4 function_name(float x, float y)"
|
|
42
|
+
re_func_decl = ("(" + re_type + r")\s+" + re_func_name + r"\s*\((void|" +
|
|
43
|
+
re_arg_list + r")\)")
|
|
44
|
+
|
|
45
|
+
# anonymous variable declarations may or may not include a name:
|
|
46
|
+
# "vec4" or "vec4 var_name"
|
|
47
|
+
re_anon_decl = "(?:(" + re_type + r")(?:\s+" + re_identifier + ")?)"
|
|
48
|
+
|
|
49
|
+
# list of anonymous declarations
|
|
50
|
+
re_anon_arg_list = "(" + re_anon_decl + r"(?:,\s*" + re_anon_decl + ")*)?"
|
|
51
|
+
|
|
52
|
+
# function prototype declaration like
|
|
53
|
+
# "vec4 function_name(float, float);"
|
|
54
|
+
re_func_prot = ("(" + re_type + r")\s+" + re_func_name + r"\((void|" +
|
|
55
|
+
re_anon_arg_list + r")\)\s*;")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def parse_function_signature(code):
|
|
59
|
+
"""
|
|
60
|
+
Return the name, arguments, and return type of the first function
|
|
61
|
+
definition found in *code*. Arguments are returned as [(type, name), ...].
|
|
62
|
+
"""
|
|
63
|
+
m = re.search(r"^\s*" + re_func_decl + r"\s*{", code, re.M)
|
|
64
|
+
if m is None:
|
|
65
|
+
print(code)
|
|
66
|
+
raise Exception("Failed to parse function signature. "
|
|
67
|
+
"Full code is printed above.")
|
|
68
|
+
rtype, name, args = m.groups()[:3]
|
|
69
|
+
if args == 'void' or args.strip() == '':
|
|
70
|
+
args = []
|
|
71
|
+
else:
|
|
72
|
+
args = [tuple(arg.strip().split(' ')) for arg in args.split(',')]
|
|
73
|
+
return name, args, rtype
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def find_functions(code):
|
|
77
|
+
"""
|
|
78
|
+
Return a list of (name, arguments, return type) for all function
|
|
79
|
+
definition2 found in *code*. Arguments are returned as [(type, name), ...].
|
|
80
|
+
"""
|
|
81
|
+
regex = r"^\s*" + re_func_decl + r"\s*{"
|
|
82
|
+
|
|
83
|
+
funcs = []
|
|
84
|
+
while True:
|
|
85
|
+
m = re.search(regex, code, re.M)
|
|
86
|
+
if m is None:
|
|
87
|
+
return funcs
|
|
88
|
+
|
|
89
|
+
rtype, name, args = m.groups()[:3]
|
|
90
|
+
if args == 'void' or args.strip() == '':
|
|
91
|
+
args = []
|
|
92
|
+
else:
|
|
93
|
+
args = [tuple(arg.strip().split(' ')) for arg in args.split(',')]
|
|
94
|
+
funcs.append((name, args, rtype))
|
|
95
|
+
|
|
96
|
+
code = code[m.end():]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def find_prototypes(code):
|
|
100
|
+
"""
|
|
101
|
+
Return a list of signatures for each function prototype declared in *code*.
|
|
102
|
+
Format is [(name, [args], rtype), ...].
|
|
103
|
+
"""
|
|
104
|
+
prots = []
|
|
105
|
+
lines = code.split('\n')
|
|
106
|
+
for line in lines:
|
|
107
|
+
m = re.match(r"\s*" + re_func_prot, line)
|
|
108
|
+
if m is not None:
|
|
109
|
+
rtype, name, args = m.groups()[:3]
|
|
110
|
+
if args == 'void' or args.strip() == '':
|
|
111
|
+
args = []
|
|
112
|
+
else:
|
|
113
|
+
args = [tuple(arg.strip().split(' '))
|
|
114
|
+
for arg in args.split(',')]
|
|
115
|
+
prots.append((name, args, rtype))
|
|
116
|
+
|
|
117
|
+
return prots
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def find_program_variables(code):
|
|
121
|
+
"""
|
|
122
|
+
Return a dict describing program variables::
|
|
123
|
+
|
|
124
|
+
{'var_name': ('uniform|attribute|varying', type), ...}
|
|
125
|
+
|
|
126
|
+
"""
|
|
127
|
+
vars = {}
|
|
128
|
+
lines = code.split('\n')
|
|
129
|
+
for line in lines:
|
|
130
|
+
m = re.match(r"\s*" + re_prog_var_declaration + r"\s*(=|;)", line)
|
|
131
|
+
if m is not None:
|
|
132
|
+
vtype, dtype, names = m.groups()[:3]
|
|
133
|
+
for name in names.split(','):
|
|
134
|
+
vars[name.strip()] = (vtype, dtype)
|
|
135
|
+
return vars
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def find_template_variables(code):
|
|
139
|
+
"""Return a list of template variables found in *code*."""
|
|
140
|
+
return re.findall(re_template_var, code)
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (c) Vispy Development Team. All Rights Reserved.
|
|
3
|
+
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
|
|
4
|
+
|
|
5
|
+
from __future__ import division
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from weakref import WeakKeyDictionary
|
|
9
|
+
|
|
10
|
+
from ...gloo import Program
|
|
11
|
+
from ...gloo.preprocessor import preprocess
|
|
12
|
+
from ...util import logger
|
|
13
|
+
from ...util.event import EventEmitter
|
|
14
|
+
from .function import MainFunction
|
|
15
|
+
from .variable import Variable
|
|
16
|
+
from .compiler import Compiler
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ModularProgram(Program):
|
|
20
|
+
"""
|
|
21
|
+
Shader program using Function instances as basis for its shaders.
|
|
22
|
+
|
|
23
|
+
Automatically rebuilds program when functions have changed and uploads
|
|
24
|
+
program variables.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, vcode='', fcode='', gcode=None):
|
|
28
|
+
Program.__init__(self)
|
|
29
|
+
|
|
30
|
+
self.changed = EventEmitter(source=self, type='program_change')
|
|
31
|
+
|
|
32
|
+
# Cache state of Variables so we know which ones require update
|
|
33
|
+
self._variable_cache = WeakKeyDictionary()
|
|
34
|
+
|
|
35
|
+
# List of settable variables to be checked for value changes
|
|
36
|
+
self._variables = []
|
|
37
|
+
|
|
38
|
+
self._vert = MainFunction('vertex', '')
|
|
39
|
+
self._frag = MainFunction('fragment', '')
|
|
40
|
+
self._vert._dependents[self] = None
|
|
41
|
+
self._frag._dependents[self] = None
|
|
42
|
+
self._geom = None
|
|
43
|
+
|
|
44
|
+
self.vert = vcode
|
|
45
|
+
self.frag = fcode
|
|
46
|
+
self.geom = gcode
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def vert(self):
|
|
50
|
+
return self._vert
|
|
51
|
+
|
|
52
|
+
@vert.setter
|
|
53
|
+
def vert(self, vcode):
|
|
54
|
+
vcode = preprocess(vcode)
|
|
55
|
+
self._vert.code = vcode
|
|
56
|
+
self._need_build = True
|
|
57
|
+
self.changed(code_changed=True, value_changed=False)
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def frag(self):
|
|
61
|
+
return self._frag
|
|
62
|
+
|
|
63
|
+
@frag.setter
|
|
64
|
+
def frag(self, fcode):
|
|
65
|
+
fcode = preprocess(fcode)
|
|
66
|
+
self._frag.code = fcode
|
|
67
|
+
self._need_build = True
|
|
68
|
+
self.changed(code_changed=True, value_changed=False)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def geom(self):
|
|
72
|
+
return self._geom
|
|
73
|
+
|
|
74
|
+
@geom.setter
|
|
75
|
+
def geom(self, gcode):
|
|
76
|
+
if gcode is None:
|
|
77
|
+
self._geom = None
|
|
78
|
+
return
|
|
79
|
+
gcode = preprocess(gcode)
|
|
80
|
+
if self._geom is None:
|
|
81
|
+
self._geom = MainFunction('geometry', '')
|
|
82
|
+
self._geom._dependents[self] = None
|
|
83
|
+
self._geom.code = gcode
|
|
84
|
+
self._need_build = True
|
|
85
|
+
self.changed(code_changed=True, value_changed=False)
|
|
86
|
+
|
|
87
|
+
def _dep_changed(self, dep, code_changed=False, value_changed=False):
|
|
88
|
+
if code_changed and logger.level <= logging.DEBUG:
|
|
89
|
+
logger.debug("ModularProgram changed: %s source=%s, values=%s",
|
|
90
|
+
self, code_changed, value_changed)
|
|
91
|
+
import traceback
|
|
92
|
+
traceback.print_stack()
|
|
93
|
+
|
|
94
|
+
if code_changed:
|
|
95
|
+
self._need_build = True
|
|
96
|
+
self.changed(code_changed=code_changed,
|
|
97
|
+
value_changed=value_changed)
|
|
98
|
+
|
|
99
|
+
def draw(self, *args, **kwargs):
|
|
100
|
+
self.build_if_needed()
|
|
101
|
+
self.update_variables()
|
|
102
|
+
Program.draw(self, *args, **kwargs)
|
|
103
|
+
|
|
104
|
+
def build_if_needed(self):
|
|
105
|
+
"""Reset shader source if necesssary."""
|
|
106
|
+
if self._need_build:
|
|
107
|
+
self._build()
|
|
108
|
+
|
|
109
|
+
# after recompile, we need to upload all variables again
|
|
110
|
+
# (some variables may have changed name)
|
|
111
|
+
self._variable_cache.clear()
|
|
112
|
+
|
|
113
|
+
# Collect a list of all settable variables
|
|
114
|
+
settable_vars = 'attribute', 'uniform', 'in'
|
|
115
|
+
deps = [d for d in self.vert.dependencies() if (
|
|
116
|
+
isinstance(d, Variable) and d.vtype in settable_vars)]
|
|
117
|
+
deps += [d for d in self.frag.dependencies() if (
|
|
118
|
+
isinstance(d, Variable) and d.vtype == 'uniform')]
|
|
119
|
+
if self.geom is not None:
|
|
120
|
+
deps += [d for d in self.geom.dependencies() if (
|
|
121
|
+
isinstance(d, Variable) and d.vtype == 'uniform')]
|
|
122
|
+
self._variables = deps
|
|
123
|
+
|
|
124
|
+
self._need_build = False
|
|
125
|
+
|
|
126
|
+
def _build(self):
|
|
127
|
+
logger.debug("Rebuild ModularProgram: %s", self)
|
|
128
|
+
shaders = {'vert': self.vert, 'frag': self.frag}
|
|
129
|
+
if self.geom is not None:
|
|
130
|
+
shaders['geom'] = self.geom
|
|
131
|
+
self.compiler = Compiler(**shaders)
|
|
132
|
+
code = self.compiler.compile()
|
|
133
|
+
|
|
134
|
+
# Update shader code, but don't let the program update variables yet
|
|
135
|
+
code['update_variables'] = False
|
|
136
|
+
self.set_shaders(**code)
|
|
137
|
+
|
|
138
|
+
logger.debug('==== Vertex Shader ====\n\n%s\n', code['vert'])
|
|
139
|
+
if 'geom' in code:
|
|
140
|
+
logger.debug('==== Geometry shader ====\n\n%s\n', code['geom'])
|
|
141
|
+
logger.debug('==== Fragment shader ====\n\n%s\n', code['frag'])
|
|
142
|
+
|
|
143
|
+
def update_variables(self):
|
|
144
|
+
# Set any variables that have a new value
|
|
145
|
+
logger.debug("Apply variables:")
|
|
146
|
+
for dep in sorted(self._variables, key=lambda d: self.compiler[d]):
|
|
147
|
+
name = self.compiler[dep]
|
|
148
|
+
state_id = dep.state_id
|
|
149
|
+
if self._variable_cache.get(dep, None) != state_id:
|
|
150
|
+
self[name] = dep.value
|
|
151
|
+
self._variable_cache[dep] = state_id
|
|
152
|
+
logger.debug(" %s = %s **", name, dep.value)
|
|
153
|
+
else:
|
|
154
|
+
logger.debug(" %s = %s", name, dep.value)
|
|
155
|
+
|
|
156
|
+
# Process any pending variables and discard anything else that is
|
|
157
|
+
# not active in the program (otherwise we get lots of warnings).
|
|
158
|
+
self._process_pending_variables()
|
|
159
|
+
logger.debug("Discarding unused variables before draw: %s" %
|
|
160
|
+
self._pending_variables.keys())
|
|
161
|
+
self._pending_variables = {}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (c) Vispy Development Team. All Rights Reserved.
|
|
3
|
+
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
|
|
4
|
+
from collections import OrderedDict
|
|
5
|
+
from weakref import WeakKeyDictionary
|
|
6
|
+
|
|
7
|
+
from .compiler import Compiler
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ShaderObject(object):
|
|
11
|
+
"""Base class for all objects that may be included in a GLSL program
|
|
12
|
+
(Functions, Variables, Expressions).
|
|
13
|
+
|
|
14
|
+
Shader objects have a *definition* that defines the object in GLSL, an
|
|
15
|
+
*expression* that is used to reference the object, and a set of
|
|
16
|
+
*dependencies* that must be declared before the object is used.
|
|
17
|
+
|
|
18
|
+
Dependencies are tracked hierarchically such that changes to any object
|
|
19
|
+
will be propagated up the dependency hierarchy to trigger a recompile.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def create(self, obj, ref=None):
|
|
24
|
+
"""Convert *obj* to a new ShaderObject. If the output is a Variable
|
|
25
|
+
with no name, then set its name using *ref*.
|
|
26
|
+
"""
|
|
27
|
+
if isinstance(ref, Variable):
|
|
28
|
+
ref = ref.name
|
|
29
|
+
elif isinstance(ref, str) and ref.startswith('gl_'):
|
|
30
|
+
# gl_ names not allowed for variables
|
|
31
|
+
ref = ref[3:].lower()
|
|
32
|
+
|
|
33
|
+
# Allow any type of object to be converted to ShaderObject if it
|
|
34
|
+
# provides a magic method:
|
|
35
|
+
if hasattr(obj, '_shader_object'):
|
|
36
|
+
obj = obj._shader_object()
|
|
37
|
+
|
|
38
|
+
if isinstance(obj, ShaderObject):
|
|
39
|
+
if isinstance(obj, Variable) and obj.name is None:
|
|
40
|
+
obj.name = ref
|
|
41
|
+
elif isinstance(obj, str):
|
|
42
|
+
obj = TextExpression(obj)
|
|
43
|
+
else:
|
|
44
|
+
obj = Variable(ref, obj)
|
|
45
|
+
# Try prepending the name to indicate attribute, uniform, varying
|
|
46
|
+
if obj.vtype and obj.vtype[0] in 'auv':
|
|
47
|
+
obj.name = obj.vtype[0] + '_' + obj.name
|
|
48
|
+
|
|
49
|
+
return obj
|
|
50
|
+
|
|
51
|
+
def __init__(self):
|
|
52
|
+
# objects that must be declared before this object's definition.
|
|
53
|
+
# {obj: refcount}
|
|
54
|
+
self._deps = OrderedDict() # OrderedDict for consistent code output
|
|
55
|
+
|
|
56
|
+
# Objects that depend on this one will be informed of changes.
|
|
57
|
+
self._dependents = WeakKeyDictionary()
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def name(self):
|
|
61
|
+
"""The name of this shader object."""
|
|
62
|
+
return None
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def version_pragma(self):
|
|
66
|
+
"""Return version number and extra qualifiers from pragma if present."""
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
def definition(self, obj_names, version, shader):
|
|
70
|
+
"""Return the GLSL definition for this object. Use *obj_names* to
|
|
71
|
+
determine the names of dependencies, and *version* (number, qualifier)
|
|
72
|
+
to adjust code output.
|
|
73
|
+
"""
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
def expression(self, obj_names):
|
|
77
|
+
"""Return the GLSL expression used to reference this object inline."""
|
|
78
|
+
return obj_names[self]
|
|
79
|
+
|
|
80
|
+
def dependencies(self, sort=False):
|
|
81
|
+
"""Return all dependencies required to use this object. The last item
|
|
82
|
+
in the list is *self*.
|
|
83
|
+
"""
|
|
84
|
+
alldeps = []
|
|
85
|
+
if sort:
|
|
86
|
+
def key(obj):
|
|
87
|
+
# sort deps such that we get functions, variables, self.
|
|
88
|
+
if not isinstance(obj, Variable):
|
|
89
|
+
return (0, 0)
|
|
90
|
+
else:
|
|
91
|
+
return (1, obj.vtype)
|
|
92
|
+
|
|
93
|
+
deps = sorted(self._deps, key=key)
|
|
94
|
+
else:
|
|
95
|
+
deps = self._deps
|
|
96
|
+
|
|
97
|
+
for dep in deps:
|
|
98
|
+
alldeps.extend(dep.dependencies(sort=sort))
|
|
99
|
+
alldeps.append(self)
|
|
100
|
+
return alldeps
|
|
101
|
+
|
|
102
|
+
def static_names(self):
|
|
103
|
+
"""Return a list of names that are declared in this object's
|
|
104
|
+
definition (not including the name of the object itself).
|
|
105
|
+
|
|
106
|
+
These names will be reserved by the compiler when automatically
|
|
107
|
+
determining object names.
|
|
108
|
+
"""
|
|
109
|
+
return []
|
|
110
|
+
|
|
111
|
+
def _add_dep(self, dep):
|
|
112
|
+
"""Increment the reference count for *dep*. If this is a new
|
|
113
|
+
dependency, then connect to its *changed* event.
|
|
114
|
+
"""
|
|
115
|
+
if dep in self._deps:
|
|
116
|
+
self._deps[dep] += 1
|
|
117
|
+
else:
|
|
118
|
+
self._deps[dep] = 1
|
|
119
|
+
dep._dependents[self] = None
|
|
120
|
+
|
|
121
|
+
def _remove_dep(self, dep):
|
|
122
|
+
"""Decrement the reference count for *dep*. If the reference count
|
|
123
|
+
reaches 0, then the dependency is removed and its *changed* event is
|
|
124
|
+
disconnected.
|
|
125
|
+
"""
|
|
126
|
+
refcount = self._deps[dep]
|
|
127
|
+
if refcount == 1:
|
|
128
|
+
self._deps.pop(dep)
|
|
129
|
+
dep._dependents.pop(self)
|
|
130
|
+
else:
|
|
131
|
+
self._deps[dep] -= 1
|
|
132
|
+
|
|
133
|
+
def _dep_changed(self, dep, code_changed=False, value_changed=False):
|
|
134
|
+
"""Called when a dependency's expression has changed."""
|
|
135
|
+
self.changed(code_changed, value_changed)
|
|
136
|
+
|
|
137
|
+
def changed(self, code_changed=False, value_changed=False):
|
|
138
|
+
"""Inform dependents that this shaderobject has changed."""
|
|
139
|
+
for d in self._dependents:
|
|
140
|
+
d._dep_changed(self, code_changed=code_changed,
|
|
141
|
+
value_changed=value_changed)
|
|
142
|
+
|
|
143
|
+
def compile(self):
|
|
144
|
+
"""Return a compilation of this object and its dependencies.
|
|
145
|
+
|
|
146
|
+
Note: this is mainly for debugging purposes; the names in this code
|
|
147
|
+
are not guaranteed to match names in any other compilations. Use
|
|
148
|
+
Compiler directly to ensure consistent naming across multiple objects.
|
|
149
|
+
"""
|
|
150
|
+
compiler = Compiler(obj=self)
|
|
151
|
+
return compiler.compile()['obj']
|
|
152
|
+
|
|
153
|
+
def __repr__(self):
|
|
154
|
+
if self.name is not None:
|
|
155
|
+
return '<%s "%s" at 0x%x>' % (self.__class__.__name__,
|
|
156
|
+
self.name, id(self))
|
|
157
|
+
else:
|
|
158
|
+
return '<%s at 0x%x>' % (self.__class__.__name__, id(self))
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
from .variable import Variable # noqa
|
|
162
|
+
from .expression import TextExpression # noqa
|
|
File without changes
|