File: instanced_quad_visual.py

package info (click to toggle)
python-vispy 0.15.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,868 kB
  • sloc: python: 59,799; javascript: 6,800; makefile: 69; sh: 6
file content (81 lines) | stat: -rw-r--r-- 2,689 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
# -----------------------------------------------------------------------------
"""
Custom Visual for instanced rendering of a colored quad
=======================================================

# this example is based on the tutorial: T01_basic_visual.py
"""

from vispy import app, gloo, visuals, scene, use
import numpy as np

# full gl+ context is required for instanced rendering
use(gl='gl+')


vertex_shader = """
// both these attributes will be defined on an instance basis (not per vertex)
attribute vec2 shift;
attribute vec4 color;

varying vec4 v_color;
void main() {
    v_color = color;
    gl_Position = $transform(vec4($position + shift, 0, 1));
}
"""

fragment_shader = """
varying vec4 v_color;

void main() {
  gl_FragColor = v_color;
}
"""


class InstancedRectVisual(visuals.Visual):
    def __init__(self, x, y, w, h):
        visuals.Visual.__init__(self, vertex_shader, fragment_shader)

        # vertices for two triangles forming a rectangle
        self.vbo = gloo.VertexBuffer(np.array([
            [x, y], [x+w, y], [x+w, y+h],
            [x, y], [x+w, y+h], [x, y+h]
        ], dtype=np.float32))

        self.shared_program.vert['position'] = self.vbo
        self._draw_mode = 'triangles'

        # create a vertex buffer with a divisor argument of 1. This means that the
        # attribute value is set to the next element of the array every 1 instance.
        # The length of the array multiplied by the divisor determines the number
        # of instances
        self.shifts = gloo.VertexBuffer(np.random.rand(100, 2).astype(np.float32) * 500, divisor=1)
        self.shared_program['shift'] = self.shifts

        # we can provide additional buffers with different divisors, as long as the
        # amount of instances (length * divisor) is the same. In this case, we will change
        # color every 5 instances
        self.color = gloo.VertexBuffer(np.random.rand(20, 4).astype(np.float32), divisor=5)
        self.shared_program['color'] = self.color

    def _prepare_transforms(self, view):
        view.view_program.vert['transform'] = view.get_transform()


# create a visual node class to add it to the canvas
InstancedRect = scene.visuals.create_visual_node(InstancedRectVisual)

canvas = scene.SceneCanvas(keys='interactive', show=True)

rect = InstancedRect(0, 0, 20, 40, parent=canvas.scene)

if __name__ == '__main__':
    import sys
    if sys.flags.interactive != 1:
        app.run()