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
vispy/gloo/context.py
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
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
|
+
"""
|
|
6
|
+
Functionality to deal with GL Contexts in vispy. This module is defined
|
|
7
|
+
in gloo, because gloo (and the layers that depend on it) need to be
|
|
8
|
+
context aware. The vispy.app module "provides" a context, and therefore
|
|
9
|
+
depends on this module. Although the GLContext class is aimed for use
|
|
10
|
+
by vispy.app (for practical reasons), it should be possible to use
|
|
11
|
+
GLContext without using vispy.app by overloading it in an appropriate
|
|
12
|
+
manner.
|
|
13
|
+
|
|
14
|
+
An GLContext object acts as a placeholder on which different parts
|
|
15
|
+
of vispy (or other systems) can keep track of information related to
|
|
16
|
+
an OpenGL context.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from copy import deepcopy
|
|
20
|
+
import weakref
|
|
21
|
+
|
|
22
|
+
from .glir import GlirQueue, BaseGlirParser, GlirParser, glir_logger
|
|
23
|
+
from .wrappers import BaseGlooFunctions
|
|
24
|
+
from .. import config
|
|
25
|
+
|
|
26
|
+
_default_dict = dict(red_size=8, green_size=8, blue_size=8, alpha_size=8,
|
|
27
|
+
depth_size=24, stencil_size=0, double_buffer=True,
|
|
28
|
+
stereo=False, samples=0)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
canvasses = []
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_default_config():
|
|
35
|
+
"""Get the default OpenGL context configuration
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
config : dict
|
|
40
|
+
Dictionary of config values.
|
|
41
|
+
"""
|
|
42
|
+
return deepcopy(_default_dict)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_current_canvas():
|
|
46
|
+
"""Get the currently active canvas
|
|
47
|
+
|
|
48
|
+
Returns None if there is no canvas available. A canvas is made
|
|
49
|
+
active on initialization and before the draw event is emitted.
|
|
50
|
+
|
|
51
|
+
When a gloo object is created, it is associated with the currently
|
|
52
|
+
active Canvas, or with the next Canvas to be created if there is
|
|
53
|
+
no current Canvas. Use Canvas.set_current() to manually activate a
|
|
54
|
+
canvas.
|
|
55
|
+
"""
|
|
56
|
+
cc = [c() for c in canvasses if c() is not None]
|
|
57
|
+
if cc:
|
|
58
|
+
return cc[-1]
|
|
59
|
+
else:
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def set_current_canvas(canvas):
|
|
64
|
+
"""Make a canvas active. Used primarily by the canvas itself."""
|
|
65
|
+
# Notify glir
|
|
66
|
+
canvas.context._do_CURRENT_command = True
|
|
67
|
+
# Try to be quick
|
|
68
|
+
if canvasses and canvasses[-1]() is canvas:
|
|
69
|
+
return
|
|
70
|
+
# Make this the current
|
|
71
|
+
cc = [c() for c in canvasses if c() is not None]
|
|
72
|
+
while canvas in cc:
|
|
73
|
+
cc.remove(canvas)
|
|
74
|
+
cc.append(canvas)
|
|
75
|
+
canvasses[:] = [weakref.ref(c) for c in cc]
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def forget_canvas(canvas):
|
|
79
|
+
"""Forget about the given canvas. Used by the canvas when closed."""
|
|
80
|
+
cc = [c() for c in canvasses if c() is not None]
|
|
81
|
+
while canvas in cc:
|
|
82
|
+
cc.remove(canvas)
|
|
83
|
+
canvasses[:] = [weakref.ref(c) for c in cc]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class GLContext(BaseGlooFunctions):
|
|
87
|
+
"""An object encapsulating data necessary for a OpenGL context
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
config : dict | None
|
|
92
|
+
The requested configuration.
|
|
93
|
+
shared : instance of GLContext | None
|
|
94
|
+
The shared context.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
def __init__(self, config=None, shared=None):
|
|
98
|
+
self._set_config(config)
|
|
99
|
+
self._shared = shared if (shared is not None) else GLShared()
|
|
100
|
+
assert isinstance(self._shared, GLShared)
|
|
101
|
+
self._glir = GlirQueue()
|
|
102
|
+
self._do_CURRENT_command = False # flag that CURRENT cmd must be given
|
|
103
|
+
self._last_viewport = None
|
|
104
|
+
|
|
105
|
+
def __repr__(self):
|
|
106
|
+
return "<GLContext at 0x%x>" % id(self)
|
|
107
|
+
|
|
108
|
+
def _set_config(self, config):
|
|
109
|
+
self._config = deepcopy(_default_dict)
|
|
110
|
+
self._config.update(config or {})
|
|
111
|
+
# Check the config dict
|
|
112
|
+
for key, val in self._config.items():
|
|
113
|
+
if key not in _default_dict:
|
|
114
|
+
raise KeyError('Key %r is not a valid GL config key.' % key)
|
|
115
|
+
if not isinstance(val, type(_default_dict[key])):
|
|
116
|
+
raise TypeError('Context value of %r has invalid type.' % key)
|
|
117
|
+
|
|
118
|
+
def create_shared(self, name, ref):
|
|
119
|
+
"""For the app backends to create the GLShared object.
|
|
120
|
+
|
|
121
|
+
Parameters
|
|
122
|
+
----------
|
|
123
|
+
name : str
|
|
124
|
+
The name.
|
|
125
|
+
ref : object
|
|
126
|
+
The reference.
|
|
127
|
+
"""
|
|
128
|
+
if self._shared is not None:
|
|
129
|
+
raise RuntimeError('Can only set_shared once.')
|
|
130
|
+
self._shared = GLShared(name, ref)
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def config(self):
|
|
134
|
+
"""A dictionary describing the configuration of this GL context."""
|
|
135
|
+
return self._config
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def glir(self):
|
|
139
|
+
"""The glir queue for the context. This queue is for objects
|
|
140
|
+
that can be shared accross canvases (if they share a contex).
|
|
141
|
+
"""
|
|
142
|
+
return self._glir
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def shared(self):
|
|
146
|
+
"""Get the object that represents the namespace that can
|
|
147
|
+
potentially be shared between multiple contexts.
|
|
148
|
+
"""
|
|
149
|
+
return self._shared
|
|
150
|
+
|
|
151
|
+
@property
|
|
152
|
+
def capabilities(self):
|
|
153
|
+
"""The OpenGL capabilities"""
|
|
154
|
+
return deepcopy(self.shared.parser.capabilities)
|
|
155
|
+
|
|
156
|
+
def flush_commands(self, event=None):
|
|
157
|
+
"""Flush
|
|
158
|
+
|
|
159
|
+
Parameters
|
|
160
|
+
----------
|
|
161
|
+
event : instance of Event
|
|
162
|
+
The event.
|
|
163
|
+
"""
|
|
164
|
+
if self._do_CURRENT_command:
|
|
165
|
+
self._do_CURRENT_command = False
|
|
166
|
+
canvas = get_current_canvas()
|
|
167
|
+
if canvas and hasattr(canvas, '_backend'):
|
|
168
|
+
fbo = canvas._backend._vispy_get_fb_bind_location()
|
|
169
|
+
else:
|
|
170
|
+
fbo = 0
|
|
171
|
+
self.shared.parser.parse([('CURRENT', 0, fbo)])
|
|
172
|
+
self.glir.flush(self.shared.parser)
|
|
173
|
+
|
|
174
|
+
def set_viewport(self, *args):
|
|
175
|
+
BaseGlooFunctions.set_viewport(self, *args)
|
|
176
|
+
self._last_viewport = args
|
|
177
|
+
|
|
178
|
+
def get_viewport(self):
|
|
179
|
+
return self._last_viewport
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class GLShared(object):
|
|
183
|
+
"""Representation of a "namespace" that can be shared between
|
|
184
|
+
different contexts. App backends can associate themselves with this
|
|
185
|
+
object via add_ref().
|
|
186
|
+
|
|
187
|
+
This object can be used to establish whether two contexts/canvases
|
|
188
|
+
share objects, and can be used as a placeholder to store shared
|
|
189
|
+
information, such as glyph atlasses.
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
# We keep a (weak) ref of each backend that gets associated with
|
|
193
|
+
# this object. In theory, this means that multiple canvases can
|
|
194
|
+
# be created and also deleted; as long as there is at least one
|
|
195
|
+
# left, things should Just Work.
|
|
196
|
+
|
|
197
|
+
def __init__(self):
|
|
198
|
+
glir_file = config['glir_file']
|
|
199
|
+
|
|
200
|
+
parser_cls = GlirParser
|
|
201
|
+
if glir_file:
|
|
202
|
+
parser_cls = glir_logger(parser_cls, glir_file)
|
|
203
|
+
|
|
204
|
+
self._parser = parser_cls()
|
|
205
|
+
self._name = None
|
|
206
|
+
self._refs = []
|
|
207
|
+
|
|
208
|
+
def __repr__(self):
|
|
209
|
+
return "<GLShared of %s backend at 0x%x>" % (str(self.name), id(self))
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def parser(self):
|
|
213
|
+
"""The GLIR parser (shared between contexts)"""
|
|
214
|
+
return self._parser
|
|
215
|
+
|
|
216
|
+
@parser.setter
|
|
217
|
+
def parser(self, parser):
|
|
218
|
+
assert isinstance(parser, BaseGlirParser) or parser is None
|
|
219
|
+
self._parser = parser
|
|
220
|
+
|
|
221
|
+
def add_ref(self, name, ref):
|
|
222
|
+
"""Add a reference for the backend object that gives access
|
|
223
|
+
to the low level context. Used in vispy.app.canvas.backends.
|
|
224
|
+
The given name must match with that of previously added
|
|
225
|
+
references.
|
|
226
|
+
"""
|
|
227
|
+
if self._name is None:
|
|
228
|
+
self._name = name
|
|
229
|
+
elif name != self._name:
|
|
230
|
+
raise RuntimeError('Contexts can only share between backends of '
|
|
231
|
+
'the same type')
|
|
232
|
+
self._refs.append(weakref.ref(ref))
|
|
233
|
+
|
|
234
|
+
@property
|
|
235
|
+
def name(self):
|
|
236
|
+
"""The name of the canvas backend that this shared namespace is
|
|
237
|
+
associated with. Can be None.
|
|
238
|
+
"""
|
|
239
|
+
return self._name
|
|
240
|
+
|
|
241
|
+
@property
|
|
242
|
+
def ref(self):
|
|
243
|
+
"""A reference (stored internally via a weakref) to an object
|
|
244
|
+
that the backend system can use to obtain the low-level
|
|
245
|
+
information of the "reference context". In Vispy this will
|
|
246
|
+
typically be the CanvasBackend object.
|
|
247
|
+
"""
|
|
248
|
+
# Clean
|
|
249
|
+
self._refs = [r for r in self._refs if (r() is not None)]
|
|
250
|
+
# Get ref
|
|
251
|
+
ref = self._refs[0]() if self._refs else None
|
|
252
|
+
if ref is not None:
|
|
253
|
+
return ref
|
|
254
|
+
else:
|
|
255
|
+
raise RuntimeError('No reference for available for GLShared')
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class FakeCanvas(object):
|
|
259
|
+
"""Fake canvas to allow using gloo without vispy.app
|
|
260
|
+
|
|
261
|
+
Instantiate this class to collect GLIR commands from gloo
|
|
262
|
+
interactions. Call flush() in your draw event handler to execute
|
|
263
|
+
the commands in the active contect.
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
def __init__(self):
|
|
267
|
+
self.context = GLContext()
|
|
268
|
+
set_current_canvas(self)
|
|
269
|
+
|
|
270
|
+
def flush(self):
|
|
271
|
+
"""Flush commands. Call this after setting to context to current."""
|
|
272
|
+
self.context.flush_commands()
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# -----------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Vispy Development Team. All Rights Reserved.
|
|
4
|
+
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
|
|
5
|
+
# -----------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
from .globject import GLObject
|
|
8
|
+
from .texture import Texture2D
|
|
9
|
+
from .wrappers import _check_valid, read_pixels
|
|
10
|
+
from .context import get_current_canvas
|
|
11
|
+
|
|
12
|
+
# ------------------------------------------------------ RenderBuffer class ---
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class RenderBuffer(GLObject):
|
|
16
|
+
"""Base class for render buffer object
|
|
17
|
+
|
|
18
|
+
A render buffer can be in color, depth or stencil format. If this
|
|
19
|
+
format is not specified, it is set when attached to the FrameBuffer.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
shape : tuple
|
|
24
|
+
The shape of the render buffer.
|
|
25
|
+
format : {None, 'color', 'depth', 'stencil'}
|
|
26
|
+
The format of the render buffer. See resize.
|
|
27
|
+
resizeable : bool
|
|
28
|
+
Indicates whether texture can be resized
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
_GLIR_TYPE = 'RenderBuffer'
|
|
32
|
+
|
|
33
|
+
def __init__(self, shape=None, format=None, resizeable=True):
|
|
34
|
+
GLObject.__init__(self)
|
|
35
|
+
self._format = None
|
|
36
|
+
self._resizeable = True
|
|
37
|
+
self.resize(shape, format)
|
|
38
|
+
self._resizeable = bool(resizeable)
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def shape(self):
|
|
42
|
+
"""Render Buffer shape"""
|
|
43
|
+
return self._shape
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def format(self):
|
|
47
|
+
"""Render Buffer format"""
|
|
48
|
+
return self._format
|
|
49
|
+
|
|
50
|
+
def resize(self, shape, format=None):
|
|
51
|
+
"""Set the render-buffer size and format
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
shape : tuple of integers
|
|
56
|
+
New shape in yx order. A render buffer is always 2D. For
|
|
57
|
+
symmetry with the texture class, a 3-element tuple can also
|
|
58
|
+
be given, in which case the last dimension is ignored.
|
|
59
|
+
format : {None, 'color', 'depth', 'stencil'}
|
|
60
|
+
The buffer format. If None, the current format is maintained.
|
|
61
|
+
If that is also None, the format will be set upon attaching
|
|
62
|
+
it to a framebuffer. One can also specify the explicit enum:
|
|
63
|
+
GL_RGB565, GL_RGBA4, GL_RGB5_A1, GL_DEPTH_COMPONENT16, or
|
|
64
|
+
GL_STENCIL_INDEX8
|
|
65
|
+
"""
|
|
66
|
+
if not self._resizeable:
|
|
67
|
+
raise RuntimeError("RenderBuffer is not resizeable")
|
|
68
|
+
# Check shape
|
|
69
|
+
if not (isinstance(shape, tuple) and len(shape) in (2, 3)):
|
|
70
|
+
raise ValueError('RenderBuffer shape must be a 2/3 element tuple')
|
|
71
|
+
# Check format
|
|
72
|
+
if format is None:
|
|
73
|
+
format = self._format # Use current format (may be None)
|
|
74
|
+
elif isinstance(format, int):
|
|
75
|
+
pass # Do not check, maybe user needs desktop GL formats
|
|
76
|
+
elif isinstance(format, str):
|
|
77
|
+
if format not in ('color', 'depth', 'stencil'):
|
|
78
|
+
raise ValueError('RenderBuffer format must be "color", "depth"'
|
|
79
|
+
' or "stencil", not %r' % format)
|
|
80
|
+
else:
|
|
81
|
+
raise ValueError('Invalid RenderBuffer format: %r' % format)
|
|
82
|
+
|
|
83
|
+
# Store and send GLIR command
|
|
84
|
+
self._shape = tuple(shape[:2])
|
|
85
|
+
self._format = format
|
|
86
|
+
if self._format is not None:
|
|
87
|
+
self._glir.command('SIZE', self._id, self._shape, self._format)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# ------------------------------------------------------- FrameBuffer class ---
|
|
91
|
+
class FrameBuffer(GLObject):
|
|
92
|
+
"""Frame buffer object
|
|
93
|
+
|
|
94
|
+
Parameters
|
|
95
|
+
----------
|
|
96
|
+
color : RenderBuffer (optional)
|
|
97
|
+
The color buffer to attach to this frame buffer
|
|
98
|
+
depth : RenderBuffer (optional)
|
|
99
|
+
The depth buffer to attach to this frame buffer
|
|
100
|
+
stencil : RenderBuffer (optional)
|
|
101
|
+
The stencil buffer to attach to this frame buffer
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
_GLIR_TYPE = 'FrameBuffer'
|
|
105
|
+
|
|
106
|
+
def __init__(self, color=None, depth=None, stencil=None):
|
|
107
|
+
GLObject.__init__(self)
|
|
108
|
+
# Init buffers
|
|
109
|
+
self._color_buffer = None
|
|
110
|
+
self._depth_buffer = None
|
|
111
|
+
self._stencil_buffer = None
|
|
112
|
+
if color is not None:
|
|
113
|
+
self.color_buffer = color
|
|
114
|
+
if depth is not None:
|
|
115
|
+
self.depth_buffer = depth
|
|
116
|
+
if stencil is not None:
|
|
117
|
+
self.stencil_buffer = stencil
|
|
118
|
+
|
|
119
|
+
def activate(self):
|
|
120
|
+
"""Activate/use this frame buffer."""
|
|
121
|
+
# Send command
|
|
122
|
+
self._glir.command('FRAMEBUFFER', self._id, True)
|
|
123
|
+
# Associate canvas now
|
|
124
|
+
canvas = get_current_canvas()
|
|
125
|
+
if canvas is not None:
|
|
126
|
+
canvas.context.glir.associate(self.glir)
|
|
127
|
+
|
|
128
|
+
def deactivate(self):
|
|
129
|
+
"""Stop using this frame buffer, the previous framebuffer will be
|
|
130
|
+
made active.
|
|
131
|
+
"""
|
|
132
|
+
self._glir.command('FRAMEBUFFER', self._id, False)
|
|
133
|
+
|
|
134
|
+
def __enter__(self):
|
|
135
|
+
self.activate()
|
|
136
|
+
return self
|
|
137
|
+
|
|
138
|
+
def __exit__(self, t, val, trace):
|
|
139
|
+
self.deactivate()
|
|
140
|
+
|
|
141
|
+
def _set_buffer(self, buffer, format):
|
|
142
|
+
formats = ('color', 'depth', 'stencil')
|
|
143
|
+
assert format in formats
|
|
144
|
+
# Auto-format or check render buffer
|
|
145
|
+
if isinstance(buffer, RenderBuffer):
|
|
146
|
+
if buffer.format is None:
|
|
147
|
+
buffer.resize(buffer.shape, format)
|
|
148
|
+
elif buffer.format in formats and buffer.format != format:
|
|
149
|
+
raise ValueError('Cannot attach a %s buffer as %s buffer.' %
|
|
150
|
+
(buffer.format, format))
|
|
151
|
+
# Attach
|
|
152
|
+
if buffer is None:
|
|
153
|
+
setattr(self, '_%s_buffer' % format, None)
|
|
154
|
+
self._glir.command('ATTACH', self._id, format, 0)
|
|
155
|
+
elif isinstance(buffer, (Texture2D, RenderBuffer)):
|
|
156
|
+
self.glir.associate(buffer.glir)
|
|
157
|
+
setattr(self, '_%s_buffer' % format, buffer)
|
|
158
|
+
self._glir.command('ATTACH', self._id, format, buffer.id)
|
|
159
|
+
else:
|
|
160
|
+
raise TypeError("Buffer must be a RenderBuffer, Texture2D or None."
|
|
161
|
+
" (got %s)" % type(buffer))
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def color_buffer(self):
|
|
165
|
+
"""Color buffer attachment"""
|
|
166
|
+
return self._color_buffer
|
|
167
|
+
|
|
168
|
+
@color_buffer.setter
|
|
169
|
+
def color_buffer(self, buffer):
|
|
170
|
+
self._set_buffer(buffer, 'color')
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def depth_buffer(self):
|
|
174
|
+
"""Depth buffer attachment"""
|
|
175
|
+
return self._depth_buffer
|
|
176
|
+
|
|
177
|
+
@depth_buffer.setter
|
|
178
|
+
def depth_buffer(self, buffer):
|
|
179
|
+
self._set_buffer(buffer, 'depth')
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def stencil_buffer(self):
|
|
183
|
+
"""Stencil buffer attachment"""
|
|
184
|
+
return self._stencil_buffer
|
|
185
|
+
|
|
186
|
+
@stencil_buffer.setter
|
|
187
|
+
def stencil_buffer(self, buffer):
|
|
188
|
+
self._set_buffer(buffer, 'stencil')
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def shape(self):
|
|
192
|
+
"""The shape of the Texture/RenderBuffer attached to this FrameBuffer"""
|
|
193
|
+
if self.color_buffer is not None:
|
|
194
|
+
return self.color_buffer.shape[:2] # in case its a texture
|
|
195
|
+
if self.depth_buffer is not None:
|
|
196
|
+
return self.depth_buffer.shape[:2]
|
|
197
|
+
if self.stencil_buffer is not None:
|
|
198
|
+
return self.stencil_buffer.shape[:2]
|
|
199
|
+
raise RuntimeError('FrameBuffer without buffers has undefined shape')
|
|
200
|
+
|
|
201
|
+
def resize(self, shape):
|
|
202
|
+
"""Resize all attached buffers with the given shape
|
|
203
|
+
|
|
204
|
+
Parameters
|
|
205
|
+
----------
|
|
206
|
+
shape : tuple of two integers
|
|
207
|
+
New buffer shape (h, w), to be applied to all currently
|
|
208
|
+
attached buffers. For buffers that are a texture, the number
|
|
209
|
+
of color channels is preserved.
|
|
210
|
+
"""
|
|
211
|
+
# Check
|
|
212
|
+
if not (isinstance(shape, tuple) and len(shape) == 2):
|
|
213
|
+
raise ValueError('RenderBuffer shape must be a 2-element tuple')
|
|
214
|
+
# Resize our buffers
|
|
215
|
+
for buf in (self.color_buffer, self.depth_buffer, self.stencil_buffer):
|
|
216
|
+
if buf is None:
|
|
217
|
+
continue
|
|
218
|
+
shape_ = shape
|
|
219
|
+
if isinstance(buf, Texture2D):
|
|
220
|
+
shape_ = shape + (buf._inv_formats[buf.format], )
|
|
221
|
+
buf.resize(shape_, buf.format)
|
|
222
|
+
|
|
223
|
+
def read(self, mode='color', alpha=True, crop=None):
|
|
224
|
+
"""Return array of pixel values in an attached buffer
|
|
225
|
+
|
|
226
|
+
Parameters
|
|
227
|
+
----------
|
|
228
|
+
mode : str
|
|
229
|
+
The buffer type to read. May be 'color', 'depth', or 'stencil'.
|
|
230
|
+
alpha : bool
|
|
231
|
+
If True, returns RGBA array. Otherwise, returns RGB.
|
|
232
|
+
crop : array-like
|
|
233
|
+
If not None, specifies pixels to read from buffer.
|
|
234
|
+
Format is (x, y, w, h).
|
|
235
|
+
|
|
236
|
+
Returns
|
|
237
|
+
-------
|
|
238
|
+
buffer : array
|
|
239
|
+
3D array of pixels in np.uint8 format.
|
|
240
|
+
The array shape is (h, w, 3) or (h, w, 4), with the top-left
|
|
241
|
+
corner of the framebuffer at index [0, 0] in the returned array if
|
|
242
|
+
crop was not specified. If crop was given, the result will match
|
|
243
|
+
the offset and dimensions of the crop.
|
|
244
|
+
|
|
245
|
+
"""
|
|
246
|
+
_check_valid('mode', mode, ['color', 'depth', 'stencil'])
|
|
247
|
+
buffer = getattr(self, mode + '_buffer')
|
|
248
|
+
if buffer is None:
|
|
249
|
+
raise ValueError("Can't read pixels for buffer {}, "
|
|
250
|
+
"buffer does not exist.".format(mode))
|
|
251
|
+
if crop is None:
|
|
252
|
+
h, w = buffer.shape[:2]
|
|
253
|
+
crop = (0, 0, w, h)
|
|
254
|
+
|
|
255
|
+
# todo: this is ostensibly required, but not available in gloo.gl
|
|
256
|
+
# gl.glReadBuffer(buffer._target)
|
|
257
|
+
return read_pixels(crop, alpha=alpha, mode=mode)
|