class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Rotating cube', keys='interactive') self.timer = app.Timer('auto', self.on_timer) def on_initialize(self, event): # Build cube data V, I, O = create_cube() vertices = VertexBuffer(V) self.faces = IndexBuffer(I) self.outline = IndexBuffer(O) # Build program # -------------------------------------- self.program = Program(vertex, fragment) self.program.bind(vertices) # Build view, model, projection & normal # -------------------------------------- view = translate((0, 0, -5)) model = np.eye(4, dtype=np.float32) self.program['u_model'] = model self.program['u_view'] = view self.phi, self.theta = 0, 0 # OpenGL initalization # -------------------------------------- gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00), depth_test=True, polygon_offset=(1, 1), line_width=0.75, blend_func=('src_alpha', 'one_minus_src_alpha')) self.timer.start() def on_draw(self, event): gloo.clear(color=True, depth=True) # Filled cube gloo.set_state(blend=False, depth_test=True, polygon_offset_fill=True) self.program['u_color'] = 1, 1, 1, 1 self.program.draw('triangles', self.faces) # Outlined cube gloo.set_state(blend=True, depth_mask=False, polygon_offset_fill=False) self.program['u_color'] = 0, 0, 0, 1 self.program.draw('lines', self.outline) gloo.set_state(depth_mask=True) def on_resize(self, event): gloo.set_viewport(0, 0, *event.size) projection = perspective(45.0, event.size[0] / float(event.size[1]), 2.0, 10.0) self.program['u_projection'] = projection def on_timer(self, event): self.theta += .02 self.phi += .02 model = rotate(self.phi, (0, 1, 0)) * rotate(self.theta, (0, 0, 1)) self.program['u_model'] = model self.update()
def test_context_sharing(): """Test context sharing""" with Canvas() as c1: vert = "attribute vec4 pos;\nvoid main (void) {gl_Position = pos;}" frag = "void main (void) {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}" program = Program(vert, frag) program['pos'] = [(1, 2, 3, 1), (4, 5, 6, 1)] program.draw('points') def check(): # Do something to program and see if it worked program['pos'] = [(1, 2, 3, 1), (4, 5, 6, 1)] # Do command program.draw('points') check_error() # Check while c1 is active check() # Check while c2 is active (with different context) with Canvas() as c2: # pyglet always shares if 'pyglet' not in c2.app.backend_name.lower(): assert_raises(Exception, check) # Check while c2 is active (with *same* context) with Canvas(shared=c1.context) as c2: assert c1.context.shared is c2.context.shared # same object check()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), keys='interactive') self.image = Program(img_vertex, img_fragment, 4) self.image['position'] = (-1, -1), (-1, +1), (+1, -1), (+1, +1) self.image['texcoord'] = (0, 0), (0, +1), (+1, 0), (+1, +1) self.image['vmin'] = +0.1 self.image['vmax'] = +0.9 self.image['cmap'] = 0 # Colormap index to use self.image['colormaps'] = colormaps self.image['colormaps'].interpolation = 'linear' self.image['colormaps_shape'] = colormaps.shape[1], colormaps.shape[0] self.image['image'] = I.astype('float32') self.image['image'].interpolation = 'linear' set_clear_color('black') self.show() def on_resize(self, event): width, height = event.physical_size set_viewport(0, 0, *event.physical_size) def on_draw(self, event): clear(color=True, depth=True) self.image.draw('triangle_strip')
class Canvas(app.Canvas): def __init__(self): self.image = Program(img_vertex, img_fragment, 4) self.image['position'] = (-1, -1), (-1, +1), (+1, -1), (+1, +1) self.image['texcoord'] = (0, 0), (0, +1), (+1, 0), (+1, +1) self.image['vmin'] = +0.1 self.image['vmax'] = +0.9 self.image['cmap'] = 0 # Colormap index to use self.image['colormaps'] = colormaps self.image['colormaps'].interpolation = 'linear' self.image['colormaps_shape'] = colormaps.shape[1], colormaps.shape[0] self.image['image'] = I.astype('float32') self.image['image'].interpolation = 'linear' app.Canvas.__init__(self, show=True, size=(512, 512), keys='interactive') def on_initialize(self, event): set_clear_color('black') def on_resize(self, event): width, height = event.size set_viewport(0, 0, *event.size) def on_draw(self, event): clear(color=True, depth=True) self.image.draw('triangle_strip')
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Rotating quad', keys='interactive') self.timer = app.Timer('auto', self.on_timer) # Build program & data self.program = Program(vertex, fragment, count=4) self.program['color'] = [(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1), (1, 1, 0, 1)] self.program['position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.program['theta'] = 0.0 gloo.set_viewport(0, 0, *self.physical_size) self.clock = 0 self.timer.start() self.show() def on_draw(self, event): gloo.set_clear_color('white') gloo.clear(color=True) self.program.draw('triangle_strip') def on_resize(self, event): gloo.set_viewport(0, 0, *event.physical_size) def on_timer(self, event): self.clock += 0.001 * 1000.0 / 60. self.program['theta'] = self.clock self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self) # Create program self._program = Program(VERT_SHADER, FRAG_SHADER) # Set uniforms and samplers self._program['a_position'] = VertexBuffer(positions) self._program['a_texcoord'] = VertexBuffer(texcoords) # self._program['u_texture1'] = Texture2D(im1) self._program['u_texture2'] = Texture2D(im2) self._program['u_texture3'] = Texture2D(im3) def on_initialize(self, event): gl.glClearColor(1, 1, 1, 1) def on_resize(self, event): width, height = event.size gl.glViewport(0, 0, width, height) def on_paint(self, event): # Clear gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) # Draw shape with texture, nested context self._program.draw(gl.GL_TRIANGLE_STRIP)
class Canvas(app.Canvas): def __init__(self): self.image = Program(img_vertex, img_fragment, 4) self.image["position"] = (-1, -1), (-1, +1), (+1, -1), (+1, +1) self.image["texcoord"] = (0, 0), (0, +1), (+1, 0), (+1, +1) self.image["vmin"] = +0.1 self.image["vmax"] = +0.9 self.image["cmap"] = 0 # Colormap index to use self.image["colormaps"] = colormaps self.image["colormaps"].interpolation = "linear" self.image["colormaps_shape"] = colormaps.shape[1], colormaps.shape[0] self.image["image"] = I self.image["image"].interpolation = "linear" self.image["image_shape"] = I.shape[1], I.shape[0] app.Canvas.__init__(self, show=True, size=(512, 512), keys="interactive") def on_initialize(self, event): set_clear_color("black") def on_resize(self, event): width, height = event.size set_viewport(0, 0, *event.size) def on_draw(self, event): clear(color=True, depth=True) self.image.draw("triangle_strip")
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Rotating quad', keys='interactive') self.timer = app.Timer('auto', self.on_timer) # Build program & data self.program = Program(vertex, fragment, count=4) self.program['color'] = [(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1), (1, 1, 0, 1)] self.program['position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.program['theta'] = 0.0 gloo.set_viewport(0, 0, *self.physical_size) self.clock = 0 self.timer.start() self.show() def on_draw(self, event): gloo.set_clear_color('white') gloo.clear(color=True) self.program.draw('triangle_strip') def on_resize(self, event): gloo.set_viewport(0, 0, *event.physical_size) def on_timer(self, event): self.clock += 0.001 * 1000.0 / 60. self.program['theta'] = self.clock self.update()
def test_context_sharing(): """Test context sharing""" with Canvas() as c1: vert = "attribute vec4 pos;\nvoid main (void) {gl_Position = pos;}" frag = "void main (void) {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}" program = Program(vert, frag) program['pos'] = [(1, 2, 3, 1), (4, 5, 6, 1)] program.draw('points') def check(): # Do something to program and see if it worked program['pos'] = [(1, 2, 3, 1), (4, 5, 6, 1)] # Do command program.draw('points') check_error() # Check while c1 is active check() # Check while c2 is active (with different context) with Canvas() as c2: # pyglet always shares if 'pyglet' not in c2.app.backend_name.lower(): assert_raises(Exception, check) # Check while c2 is active (with *same* context) with Canvas(shared=c1.context) as c2: assert c1.context.shared is c2.context.shared # same object check()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self) # Create program self._program = Program(VERT_SHADER, FRAG_SHADER) # Set uniforms and samplers self._program['a_position'] = VertexBuffer(positions) self._program['a_texcoord'] = VertexBuffer(texcoords) # self._program['u_texture1'] = Texture2D(im1) self._program['u_texture2'] = Texture2D(im2) self._program['u_texture3'] = Texture2D(im3) def on_initialize(self, event): gl.glClearColor(1,1,1,1) def on_resize(self, event): width, height = event.size gl.glViewport(0, 0, width, height) def on_paint(self, event): # Clear gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) # Draw shape with texture, nested context self._program.draw(gl.GL_TRIANGLE_STRIP)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(750, 750), title='Textured cube', keys='interactive') self.timer = app.Timer('auto', self.on_timer) self.counter = 0 # Build cube data V, I, _ = create_cube() vertices = VertexBuffer(V) self.indices = IndexBuffer(I) # Build program self.program = Program(vertex, fragment) self.program.bind(vertices) # Build view, model, projection & normal view = translate((0, 0, -5)) model = np.eye(4, dtype=np.float32) self.program['model'] = model self.program['view'] = view self.program['texture'] = cam # checkerboard() self.activate_zoom() self.phi, self.theta = 0, 0 # OpenGL initalization gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00), depth_test=True) self.timer.start() self.show() def on_draw(self, event): gloo.clear(color=True, depth=True) self.program.draw('triangles', self.indices) def on_resize(self, event): self.activate_zoom() def activate_zoom(self): gloo.set_viewport(0, 0, *self.physical_size) projection = perspective(45.0, self.size[0] / float(self.size[1]), 2.0, 10.0) self.program['projection'] = projection def on_timer(self, event): self.counter += 1 print("on_timer", self.counter) self.theta += .5 self.phi += .5 self.program['model'] = np.dot(rotate(self.theta, (0, 1, 0)), rotate(self.phi, (0, 1, 0))) # self.program['texture'] = im if self.counter % 200 else checkerboard() self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, title='Rain [Move mouse]', size=(512, 512), keys='interactive') # Build data # -------------------------------------- n = 500 self.data = np.zeros(n, [('a_position', np.float32, 2), ('a_fg_color', np.float32, 4), ('a_size', np.float32, 1)]) self.index = 0 self.program = Program(vertex, fragment) self.vdata = VertexBuffer(self.data) self.program.bind(self.vdata) self.program['u_antialias'] = 1.00 self.program['u_linewidth'] = 1.00 self.program['u_model'] = np.eye(4, dtype=np.float32) self.program['u_view'] = np.eye(4, dtype=np.float32) self.activate_zoom() gloo.set_clear_color('white') gloo.set_state(blend=True, blend_func=('src_alpha', 'one_minus_src_alpha')) self.timer = app.Timer('auto', self.on_timer, start=True) self.show() def on_draw(self, event): gloo.clear() self.program.draw('points') def on_resize(self, event): self.activate_zoom() def activate_zoom(self): gloo.set_viewport(0, 0, *self.physical_size) projection = ortho(0, self.size[0], 0, self.size[1], -1, +1) self.program['u_projection'] = projection def on_timer(self, event): self.data['a_fg_color'][..., 3] -= 0.01 self.data['a_size'] += 1.0 self.vdata.set_data(self.data) self.update() def on_mouse_move(self, event): x, y = event.pos h = self.size[1] self.data['a_position'][self.index] = x, h - y self.data['a_size'][self.index] = 5 self.data['a_fg_color'][self.index] = 0, 0, 0, 1 self.index = (self.index + 1) % 500
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, title='Rain [Move mouse]', size=(512, 512), keys='interactive') # Build data # -------------------------------------- n = 500 self.data = np.zeros(n, [('a_position', np.float32, 2), ('a_fg_color', np.float32, 4), ('a_size', np.float32, 1)]) self.index = 0 self.program = Program(vertex, fragment) self.vdata = VertexBuffer(self.data) self.program.bind(self.vdata) self.program['u_antialias'] = 1.00 self.program['u_linewidth'] = 1.00 self.program['u_model'] = np.eye(4, dtype=np.float32) self.program['u_view'] = np.eye(4, dtype=np.float32) self.activate_zoom() gloo.set_clear_color('white') gloo.set_state(blend=True, blend_func=('src_alpha', 'one_minus_src_alpha')) self.timer = app.Timer('auto', self.on_timer, start=True) self.show() def on_draw(self, event): gloo.clear() self.program.draw('points') def on_resize(self, event): self.activate_zoom() def activate_zoom(self): gloo.set_viewport(0, 0, *self.physical_size) projection = ortho(0, self.size[0], 0, self.size[1], -1, +1) self.program['u_projection'] = projection def on_timer(self, event): self.data['a_fg_color'][..., 3] -= 0.01 self.data['a_size'] += 1.0 self.vdata.set_data(self.data) self.update() def on_mouse_move(self, event): x, y = event.pos h = self.size[1] self.data['a_position'][self.index] = x, h - y self.data['a_size'][self.index] = 5 self.data['a_fg_color'][self.index] = 0, 0, 0, 1 self.index = (self.index + 1) % 500
def test_use_texture3D(): """Test using a 3D texture""" vals = [0, 200, 100, 0, 255, 0, 100] d, h, w = len(vals), 3, 5 data = np.zeros((d, h, w), np.float32) VERT_SHADER = """ attribute vec2 a_pos; varying vec2 v_pos; void main (void) { v_pos = a_pos; gl_Position = vec4(a_pos, 0., 1.); } """ FRAG_SHADER = """ uniform sampler3D u_texture; varying vec2 v_pos; uniform float i; void main() { gl_FragColor = texture3D(u_texture, vec3((v_pos.y+1.)/2., (v_pos.x+1.)/2., i)); gl_FragColor.a = 1.; } """ # populate the depth "slices" with different gray colors in the bottom left for ii, val in enumerate(vals): data[ii, :2, :3] = val / 255. with Canvas(size=(100, 100)) as c: if not has_pyopengl(): t = Texture3D(data) assert_raises(ImportError, t.glir.flush, c.context.shared.parser) return program = Program(VERT_SHADER, FRAG_SHADER) program['a_pos'] = [[-1., -1.], [1., -1.], [-1., 1.], [1., 1.]] tex = Texture3D(data, interpolation='nearest') assert_equal(tex.width, w) assert_equal(tex.height, h) assert_equal(tex.depth, d) program['u_texture'] = tex for ii, val in enumerate(vals): set_viewport(0, 0, w, h) clear(color='black') iii = (ii + 0.5) / float(d) print(ii, iii) program['i'] = iii program.draw('triangle_strip') out = _screenshot()[:, :, 0].astype(int)[::-1] expected = np.zeros_like(out) expected[:2, :3] = val assert_allclose(out, expected, atol=1./255.)
def test_use_texture3D(): """Test using a 3D texture""" vals = [0, 200, 100, 0, 255, 0, 100] d, h, w = len(vals), 3, 5 data = np.zeros((d, h, w), np.float32) VERT_SHADER = """ attribute vec2 a_pos; varying vec2 v_pos; void main (void) { v_pos = a_pos; gl_Position = vec4(a_pos, 0., 1.); } """ FRAG_SHADER = """ uniform sampler3D u_texture; varying vec2 v_pos; uniform float i; void main() { gl_FragColor = texture3D(u_texture, vec3((v_pos.y+1.)/2., (v_pos.x+1.)/2., i)); gl_FragColor.a = 1.; } """ # populate the depth "slices" with different gray colors in the bottom left for ii, val in enumerate(vals): data[ii, :2, :3] = val / 255. with Canvas(size=(100, 100)) as c: if not has_pyopengl(): t = Texture3D(data) assert_raises(ImportError, t.glir.flush, c.context.shared.parser) return program = Program(VERT_SHADER, FRAG_SHADER) program['a_pos'] = [[-1., -1.], [1., -1.], [-1., 1.], [1., 1.]] tex = Texture3D(data, interpolation='nearest') assert_equal(tex.width, w) assert_equal(tex.height, h) assert_equal(tex.depth, d) program['u_texture'] = tex for ii, val in enumerate(vals): set_viewport(0, 0, w, h) clear(color='black') iii = (ii + 0.5) / float(d) print(ii, iii) program['i'] = iii program.draw('triangle_strip') out = _screenshot()[:, :, 0].astype(int)[::-1] expected = np.zeros_like(out) expected[:2, :3] = val assert_allclose(out, expected, atol=1. / 255.)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), keys='interactive') self.image = Program(img_vertex, img_fragment, 4) self.image['position'] = (-1, -1), (-1, +1), (+1, -1), (+1, +1) self.image['texcoord'] = (0, 0), (0, +1), (+1, 0), (+1, +1) #self.image['vmin'] = +0.1 #self.image['vmax'] = +0.9 self.image['vmin'] = 0.1 self.image['vmax'] = 1.0 self.image['cmap'] = 1 # Colormap index to use self.image['colormaps'] = colormaps self.image['colormaps'].interpolation = 'linear' self.image['colormaps_shape'] = colormaps.shape[1], colormaps.shape[0] self.image['image'] = I.astype('float32') self.image['image'].interpolation = 'linear' set_clear_color('black') self.timer = app.Timer(0.25, self.on_timer) self.timer.start() self.show() def on_resize(self, event): width, height = event.physical_size set_viewport(0, 0, *event.physical_size) def on_draw(self, event): clear(color=True, depth=True) self.image.draw('triangle_strip') def on_timer(self, event): #self.clock += 0.001 * 1000.0 / 60. #self.program['theta'] = self.clock global I psi=iterate(psi) I=abs(psi[0]) self.I = I #print psi self.image['image'] = I.astype('float32') self.update() #self.timer.stop() def on_key_press(self, ev): if ev.key.name == 'Space': if self.timer.running: self.timer.stop() else: self.timer.start()
class MyCanvas(app.Canvas): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.timer = app.Timer('auto', connect=self.on_timer, start=True) with open('vertex.glsl') as f: self.vshader = f.read() with open('fragment.glsl') as f: self.fshader = f.read() self.program = Program(self.vshader, self.fshader) v, i, iOutline = create_cube() self.vertices = VertexBuffer(v) self.indices = IndexBuffer(i) self.outlineIndices = IndexBuffer(iOutline) self.program.bind(self.vertices) self.theta, self.phi = 0, 0 self.program['model'] = np.eye(4) self.program['view'] = translate([0, 0, -5]) self.program['texture'] = checkerboard() gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00), polygon_offset=(1, 1), blend_func=('src_alpha', 'one_minus_src_alpha'), line_width=5, depth_test=True) def on_resize(self, event): gloo.set_viewport(0, 0, *self.physical_size) proj = perspective(45.0, self.size[0] / self.size[1], 0.01, 1000) self.program['projection'] = proj def on_draw(self, event): gloo.clear(color=True, depth=True) gloo.set_state(blend=False, depth_test=True, polygon_offset_fill=True) self.program['u_color'] = [1, 1, 1, 1] self.program.draw('triangles', self.indices) gloo.set_state(blend=True, depth_mask=False, polygon_offset_fill=False) self.program['u_color'] = [0, 0, 0, 1] self.program.draw('lines', self.outlineIndices) gloo.set_state(depth_mask=True) def on_timer(self, event): self.theta = event.elapsed * 30 self.phi = 0 self.program['model'] = np.dot( rotate(self.phi, [1, 0, 0]), rotate(self.theta, [0, 1, 0]), ) self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Textured cube', keys='interactive') self.timer = app.Timer('auto', self.on_timer) # Build cube data V, I, _ = create_cube() vertices = VertexBuffer(V) self.indices = IndexBuffer(I) # Build program self.program = Program(vertex, fragment) self.program.bind(vertices) # Build view, model, projection & normal view = translate((0, 0, -5)) model = np.eye(4, dtype=np.float32) self.program['model'] = model self.program['view'] = view self.program['texture'] = checkerboard() self.activate_zoom() self.phi, self.theta = 0, 0 # OpenGL initalization gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00), depth_test=True) self.timer.start() self.show() def on_draw(self, event): gloo.clear(color=True, depth=True) self.program.draw('triangles', self.indices) def on_resize(self, event): self.activate_zoom() def activate_zoom(self): gloo.set_viewport(0, 0, *self.physical_size) projection = perspective(45.0, self.size[0] / float(self.size[1]), 2.0, 10.0) self.program['projection'] = projection def on_timer(self, event): self.theta += .5 self.phi += .5 self.program['model'] = np.dot(rotate(self.theta, (0, 0, 1)), rotate(self.phi, (0, 1, 0))) self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Textured cube', keys='interactive') self.timer = app.Timer('auto', self.on_timer) def on_initialize(self, event): # Build cube data V, I, _ = create_cube() vertices = VertexBuffer(V) self.indices = IndexBuffer(I) # Build program self.program = Program(vertex, fragment) self.program.bind(vertices) # Build view, model, projection & normal view = np.eye(4, dtype=np.float32) model = np.eye(4, dtype=np.float32) translate(view, 0, 0, -5) self.program['model'] = model self.program['view'] = view self.program['texture'] = checkerboard() self.phi, self.theta = 0, 0 # OpenGL initalization gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00), depth_test=True) self.timer.start() def on_draw(self, event): gloo.clear(color=True, depth=True) self.program.draw('triangles', self.indices) def on_resize(self, event): gloo.set_viewport(0, 0, *event.size) projection = perspective(45.0, event.size[0] / float(event.size[1]), 2.0, 10.0) self.program['projection'] = projection def on_timer(self, event): self.theta += .5 self.phi += .5 model = np.eye(4, dtype=np.float32) rotate(model, self.theta, 0, 0, 1) rotate(model, self.phi, 0, 1, 0) self.program['model'] = model self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Textured cube', close_keys='escape') self.timer = app.Timer(1./60., self.on_timer) def on_initialize(self, event): # Build cube data V, I, _ = cube() vertices = VertexBuffer(V) self.indices = IndexBuffer(I) # Build program self.program = Program(vertex, fragment) self.program.bind(vertices) # Build view, model, projection & normal view = np.eye(4, dtype=np.float32) model = np.eye(4, dtype=np.float32) translate(view, 0, 0, -5) self.program['model'] = model self.program['view'] = view self.program['texture'] = checkerboard() self.phi, self.theta = 0, 0 # OpenGL initalization gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00), depth_test=True) self.timer.start() def on_draw(self, event): gloo.clear(color=True, depth=True) self.program.draw('triangles', self.indices) def on_resize(self, event): gloo.set_viewport(0, 0, *event.size) projection = perspective(45.0, event.size[0] / float(event.size[1]), 2.0, 10.0) self.program['projection'] = projection def on_timer(self, event): self.theta += .5 self.phi += .5 model = np.eye(4, dtype=np.float32) rotate(model, self.theta, 0, 0, 1) rotate(model, self.phi, 0, 1, 0) self.program['model'] = model self.update()
class Example(Drawable): '''Draw a cube''' cube_vertex = """ #version 120 uniform mat4 model; uniform mat4 view; uniform mat4 projection; attribute vec3 position; attribute vec2 texcoord; varying vec2 v_texcoord; void main() { gl_Position = projection * view * model * vec4(position, 1.0); v_texcoord = texcoord; } """ cube_fragment = """ #version 120 uniform sampler2D texture; varying vec2 v_texcoord; void main() { float r = texture2D(texture, v_texcoord).r; gl_FragColor = vec4(0, r, r, 1); } """ def __init__(self): vertices, indices, _ = create_cube() vertices = VertexBuffer(vertices) self.indices = IndexBuffer(indices) self.program = Program(self.cube_vertex, self.cube_fragment) self.model = np.eye(4) self.view = np.eye(4) self.program.bind(vertices) self.program['texture'] = utils.checkerboard() self.program['texture'].interpolation = 'linear' self.program['model'] = self.model self.program['view'] = self.view def draw(self): self.program.draw('triangles', self.indices)
class Canvas(app.Canvas): def __init__(self,width=512, height=512, colormaps=None): app.Canvas.__init__(self, size=(width, height), keys='interactive') self.image = Program(img_vertex, img_fragment, 4) self.image['position'] = (-1, -1), (-1, +1), (+1, -1), (+1, +1) self.image['texcoord'] = (0, 0), (0, +1), (+1, 0), (+1, +1) self.index = 0 self.colormaps = colormaps self.image['colormaps'] = self.colormaps[self.index][0] # self.image['colormaps'].interpolation = 'linear' set_clear_color('black') self.show() # --------------------------------------------------------------- title --- def on_key_press(self, event): print (event.text) if event.text == 'w': self.index +=1 if (self.index >= len(self.colormaps)): self.index = 0 if event.text == 'q': self.index -=1 if (self.index < 0 ): self.index = len(self.colormaps) -1 self.image['colormaps'] = self.colormaps[self.index][0] print ("Showing Layer : " , self.colormaps[self.index][1], " : ", self.index) self._backend._vispy_set_title("Layer : %s" % self.colormaps[self.index][1]) self.update() def on_resize(self, event): width, height = event.physical_size set_viewport(0, 0, *event.physical_size) def on_draw(self, event): clear(color=True, depth=True) self.image.draw('triangle_strip')
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Colored quad', keys='interactive') # Build program & data self.program = Program(vertex, fragment, count=4) self.program['color'] = [(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1), (1, 1, 0, 1)] self.program['position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] def on_draw(self, event): gloo.clear(color='white') self.program.draw('triangle_strip') def on_resize(self, event): gloo.set_viewport(0, 0, *event.size)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title="Colored quad", keys="interactive") # Build program & data self.program = Program(vertex, fragment, count=4) self.program["color"] = [(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1), (1, 1, 0, 1)] self.program["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] gloo.set_viewport(0, 0, *self.physical_size) self.show() def on_draw(self, event): gloo.clear(color="white") self.program.draw("triangle_strip") def on_resize(self, event): gloo.set_viewport(0, 0, *event.physical_size)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Colored quad', keys='interactive') def on_initialize(self, event): # Build program & data self.program = Program(vertex, fragment, count=4) self.program['color'] = [(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1), (1, 1, 0, 1)] self.program['position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] def on_draw(self, event): gloo.clear(color='white') self.program.draw('triangle_strip') def on_resize(self, event): gloo.set_viewport(0, 0, *event.size)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Textured quad', keys='interactive') # Build program & data self.program = Program(vertex, fragment, count=4) self.program['position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.program['texcoord'] = [(0, 0), (1, 0), (0, 1), (1, 1)] self.program['texture'] = checkerboard() def on_draw(self, event): gloo.set_clear_color('white') gloo.clear(color=True) self.program.draw('triangle_strip') def on_resize(self, event): gloo.set_viewport(0, 0, *event.size)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Textured quad', close_keys='escape') def on_initialize(self, event): # Build program & data self.program = Program(vertex, fragment, count=4) self.program['position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.program['texcoord'] = [(0, 0), (1, 0), (0, 1), (1, 1)] self.program['texture'] = checkerboard() def on_draw(self, event): gloo.set_clear_color('white') gloo.clear(color=True) self.program.draw('triangle_strip') def on_resize(self, event): gloo.set_viewport(0, 0, *event.size)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(800, 800), title='Colored quad', keys='interactive') self.program = Program(vertex, fragment, count=4) self.program['color'] = [(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1), (1, 1, 0, 1)] self.program['position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] gloo.set_viewport(0, 0, *self.physical_size) self.show() def on_draw(self, event): # gloo.set_clear_color((0.2, 0.4, 0.6, 1.0)) # gloo.clear() gloo.clear(color='white') self.program.draw('triangle_strip') def on_resize(self, event): gloo.set_viewport(0, 0, *event.physical_size)
def test_use_uniforms(): """Test using uniform arrays""" VERT_SHADER = """ attribute vec2 a_pos; varying vec2 v_pos; void main (void) { v_pos = a_pos; gl_Position = vec4(a_pos, 0., 1.); } """ FRAG_SHADER = """ varying vec2 v_pos; uniform vec3 u_color[2]; void main() { gl_FragColor = vec4((u_color[0] + u_color[1]) / 2., 1.); } """ shape = (500, 500) with Canvas(size=shape) as c: c.set_current() c.context.glir.set_verbose(True) assert_equal(c.size, shape[::-1]) shape = (3, 3) set_viewport((0, 0) + shape) program = Program(VERT_SHADER, FRAG_SHADER) program['a_pos'] = [[-1., -1.], [1., -1.], [-1., 1.], [1., 1.]] program['u_color'] = np.ones((2, 3)) c.context.clear('k') c.set_current() program.draw('triangle_strip') out = _screenshot() assert_allclose(out[:, :, 0] / 255., np.ones(shape), atol=1. / 255.) # now set one element program['u_color[1]'] = np.zeros(3, np.float32) c.context.clear('k') program.draw('triangle_strip') out = _screenshot() assert_allclose(out[:, :, 0] / 255., 127.5 / 255. * np.ones(shape), atol=1. / 255.) # and the other assert_raises(ValueError, program.__setitem__, 'u_color', np.zeros(3, np.float32)) program['u_color'] = np.zeros((2, 3), np.float32) program['u_color[0]'] = np.ones(3, np.float32) c.context.clear((0.33, ) * 3) program.draw('triangle_strip') out = _screenshot() assert_allclose(out[:, :, 0] / 255., 127.5 / 255. * np.ones(shape), atol=1. / 255.)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self) self.position = 50, 50 self.size = 512, 512 self.program = Program(VS, FS) self.tex = Texture2D(data1) self.program['a_position'] = VertexBuffer(positions) self.program['a_texcoord'] = VertexBuffer(texcoords) self.program['u_tex'] = self.tex self._timer = app.Timer(.01) self._timer.connect(self.on_timer) self._timer.start() self.measure_fps(.05, callback=self.fps_callback) def fps_callback(self, e): print "{0:.1f} FPS, {1:.1f} MB/s\r".format( e, e * RES * RES * 4 * 3 / (1024.**2)), def on_resize(self, event): width, height = event.size gl.glViewport(0, 0, width, height) def on_paint(self, event): gl.glClearColor(0.2, 0.4, 0.6, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) self.program.draw(gl.GL_TRIANGLE_STRIP) def on_timer(self, event): if event.iteration % 2 == 0: data = data1 else: data = data2 self.tex.set_subdata((0, 0), data) self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self) self.position = 50, 50 self.size = 512, 512 self.program = Program(VS, FS) self.tex = Texture2D(data1) self.program['a_position'] = VertexBuffer(positions) self.program['a_texcoord'] = VertexBuffer(texcoords) self.program['u_tex'] = self.tex self._timer = app.Timer(.01) self._timer.connect(self.on_timer) self._timer.start() self.measure_fps(.05, callback=self.fps_callback) def fps_callback(self, e): print "{0:.1f} FPS, {1:.1f} MB/s\r".format(e, e*RES*RES*4*3/(1024.**2)), def on_resize(self, event): width, height = event.size gl.glViewport(0, 0, width, height) def on_paint(self, event): gl.glClearColor(0.2, 0.4, 0.6, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) self.program.draw(gl.GL_TRIANGLE_STRIP) def on_timer(self, event): if event.iteration % 2 == 0: data = data1 else: data = data2 self.tex.set_subdata((0,0), data) self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self) self.position = 50, 50 self.size = 512, 512 self.program = Program(VS, FS) self.vbo = VertexBuffer(data1) self.program['a_position'] = self.vbo self.clbuf = CLBuffer(self.vbo, kernel) self._timer = app.Timer(.01) self._timer.connect(self.on_timer) self._timer.start() self.measure_fps(.1, callback=self.fps_callback) def fps_callback(self, e): print "{0:.1f} FPS, {1:.1f} MB/s\r".format(e, e*RES*4*2/(1024.**2)), def on_resize(self, event): width, height = event.size gl.glViewport(0, 0, width, height) def on_initialize(self, event): self.clbuf.create() def on_paint(self, event): gl.glClearColor(0.2, 0.4, 0.6, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) self.program.draw(gl.GL_POINTS) def on_timer(self, event): self.clbuf.execute() self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__( self, always_on_top=True, position=(1600,100), size=(300, 300), title='Colored quad', keys='interactive' ) # defaults to PyQt4 # print(app.Application().backend_name) self.program = Program(vertex, fragment) self.program['a_position'] = gloo.VertexBuffer(vertices) self.program['u_color'] = 0.0, 1.0, 0.0 # self.program['color'] = color # self.program['position'] = position gloo.set_viewport(0, 0, *self.physical_size) self.show() def on_draw(self, event): # gloo.set_clear_color((0.2, 0.4, 0.6, 1.0)) # gloo.clear() gloo.clear(color='black') self.program.draw(gl.GL_POINTS) # self.program.draw(gl.GL_TRIANGLES) # self.program.draw('triangle_strip') def on_resize(self, event): gloo.set_viewport(0, 0, *event.physical_size)
class Canvas(app.Canvas): def __init__(self): super().__init__(size=(512, 512), title='Colored quad', keys='interactive') # Build program self.program = Program(vertex, fragment, count=4) # Set uniforms and attributes self.program['color'] = [(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1), (1, 1, 0, 1)] self.program['position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] gloo.set_viewport(0, 0, *self.physical_size) self.show() def on_draw(self, event): gloo.clear() self.program.draw('triangle_strip') def on_resize(self, event): gloo.set_viewport(0, 0, *event.physical_size)
def test_use_uniforms(): """Test using uniform arrays""" VERT_SHADER = """ attribute vec2 a_pos; varying vec2 v_pos; void main (void) { v_pos = a_pos; gl_Position = vec4(a_pos, 0., 1.); } """ FRAG_SHADER = """ varying vec2 v_pos; uniform vec3 u_color[2]; void main() { gl_FragColor = vec4((u_color[0] + u_color[1]) / 2., 1.); } """ shape = (500, 500) with Canvas(size=shape) as c: c.set_current() c.context.glir.set_verbose(True) assert_equal(c.size, shape[::-1]) shape = (3, 3) set_viewport((0, 0) + shape) program = Program(VERT_SHADER, FRAG_SHADER) program['a_pos'] = [[-1., -1.], [1., -1.], [-1., 1.], [1., 1.]] program['u_color'] = np.ones((2, 3)) c.context.clear('k') c.set_current() program.draw('triangle_strip') out = _screenshot() assert_allclose(out[:, :, 0] / 255., np.ones(shape), atol=1. / 255.) # now set one element program['u_color[1]'] = np.zeros(3, np.float32) c.context.clear('k') program.draw('triangle_strip') out = _screenshot() assert_allclose(out[:, :, 0] / 255., 127.5 / 255. * np.ones(shape), atol=1. / 255.) # and the other assert_raises(ValueError, program.__setitem__, 'u_color', np.zeros(3, np.float32)) program['u_color'] = np.zeros((2, 3), np.float32) program['u_color[0]'] = np.ones(3, np.float32) c.context.clear((0.33,) * 3) program.draw('triangle_strip') out = _screenshot() assert_allclose(out[:, :, 0] / 255., 127.5 / 255. * np.ones(shape), atol=1. / 255.)
class Canvas(app.Canvas): _visible_payloads = [ PAYLOADTYPE_INFO_IDS.PAYLOAD_TYPE_IMAGE, PAYLOADTYPE_INFO_IDS.PAYLOAD_TYPE_CHUNK_DATA, PAYLOADTYPE_INFO_IDS.PAYLOAD_TYPE_MULTI_PART, ] def __init__(self, image_acquisition_manager=None, width=640, height=480, fps=30, background_color='gray', vertex_shader=None, fragment_shader=None): """ NOTE: fps should be smaller than or equal to 50 fps. If it's exceed VisPy drags down the acquisition performance. This is the issue we have to investigate. """ """ As far as we know, Vispy refreshes the canvas every 1/30 sec at the fastest no matter which faster number is specified. If we set any value which is greater than 30, then Vispy's callback is randomly called. """ self._vertex_shader = vertex_shader if vertex_shader else """ // Uniforms uniform mat4 u_model; uniform mat4 u_view; uniform mat4 u_projection; // Attributes attribute vec2 a_position; attribute vec2 a_texcoord; // Varyings varying vec2 v_texcoord; // Main void main (void) { v_texcoord = a_texcoord; gl_Position = u_projection * u_view * u_model * vec4(a_position, 0.0, 1.0); } """ self._fragment_shader = fragment_shader if fragment_shader else """ varying vec2 v_texcoord; uniform sampler2D texture; void main() { gl_FragColor = texture2D(texture, v_texcoord); } """ # self._iam = image_acquisition_manager # app.Canvas.__init__(self, size=(width, height), vsync=True, autoswap=True) # self._program = None self._data = None self._coordinate = None self._origin = None self._translate = 0. self._latest_translate = self._translate self._magnification = 1. # self._background_color = background_color self._has_filled_texture = False self._width, self._height = width, height # self._is_dragging = False # If it's True , the canvas keeps image acquisition but do not # draw images on the canvas. self._pause_drawing = False # Apply shaders. self.set_shaders(vertex_shader=self._vertex_shader, fragment_shader=self._fragment_shader) # self._timer = app.Timer(1. / fps, connect=self.update, start=True) @property def iam(self): return self._iam @iam.setter def iam(self, value): self._iam = value def set_shaders(self, vertex_shader=None, fragment_shader=None): # vs = vertex_shader if vertex_shader else self._vertex_shader fs = fragment_shader if fragment_shader else self._fragment_shader self._program = Program(vs, fs, count=4) # self._data = np.zeros(4, dtype=[('a_position', np.float32, 2), ('a_texcoord', np.float32, 2)]) # self._data['a_texcoord'] = np.array([[0., 1.], [1., 1.], [0., 0.], [1., 0.]]) # self._program['u_model'] = np.eye(4, dtype=np.float32) self._program['u_view'] = np.eye(4, dtype=np.float32) # self._coordinate = [0, 0] self._origin = [0, 0] # self._program['texture'] = np.zeros((self._height, self._width), dtype='uint8') # self.apply_magnification() def set_rect(self, width, height): # self._has_filled_texture = False # updated = False # if self._width != width or self._height != height: self._width = width self._height = height updated = True # if updated: self.apply_magnification() def on_draw(self, event): # Clear the canvas in gray. gloo.clear(color=self._background_color) self._update_texture() def _update_texture(self): # Fetch a buffer. try: with self.iam.fetch_buffer(timeout_ms=0.1) as buffer: update = True if buffer.payload_type not in self._visible_payloads: update = False # Set the image as the texture of our canvas. if not self._pause_drawing and buffer: # Update the canvas size if needed. self.set_rect(buffer.payload.components[0].width, buffer.payload.components[0].height) # exponent = 0 # data_format_value = buffer.payload.components[ 0].data_format_value if is_custom(data_format_value): update = False else: data_format = buffer.payload.components[0].data_format bpp = get_bits_per_pixel(data_format) if bpp is not None: exponent = bpp - 8 else: update = False if update: # Convert each data to an 8bit. content = buffer.payload.components[0].data if exponent > 0: # The following code may affect to the rendering # performance: content = (content / (2**exponent)) # Then cast each array element to an uint8: content = content.astype(np.uint8) self._program['texture'] = content # Draw the texture. self._draw() except AttributeError: # Harvester Core has not started image acquisition so # calling fetch_buffer() raises AttributeError because # None object is used for the with statement. # Update on June 15th, 2018: # According to a VisPy developer, they have not finished # porting VisPy to PyQt5. Once they finished the development # we should try it out if it gives us the maximum refresh rate. # See the following URL to check the latest information: # # https://github.com/vispy/vispy/issues/1394 # Draw the texture. self._draw() def _draw(self): self._program.draw('triangle_strip') def on_resize(self, event): self.apply_magnification() def apply_magnification(self): # canvas_w, canvas_h = self.physical_size gloo.set_viewport(0, 0, canvas_w, canvas_h) # ratio = self._magnification w, h = self._width, self._height self._program['u_projection'] = ortho( self._coordinate[0], canvas_w * ratio + self._coordinate[0], self._coordinate[1], canvas_h * ratio + self._coordinate[1], -1, 1) x, y = int((canvas_w * ratio - w) / 2), int( (canvas_h * ratio - h) / 2) # centering x & y # self._data['a_position'] = np.array([[x, y], [x + w, y], [x, y + h], [x + w, y + h]]) # self._program.bind(gloo.VertexBuffer(self._data)) def on_mouse_wheel(self, event): self._translate += event.delta[1] power = 7. if is_running_on_macos() else 5. # 2 ** power stride = 4. if is_running_on_macos() else 7. translate = self._translate translate = min(power * stride, translate) translate = max(-power * stride, translate) self._translate = translate self._magnification = 2**-(self._translate / stride) if self._latest_translate != self._translate: self.apply_magnification() self._latest_translate = self._translate def on_mouse_press(self, event): self._is_dragging = True self._origin = event.pos def on_mouse_release(self, event): self._is_dragging = False def on_mouse_move(self, event): if self._is_dragging: adjustment = 2. if is_running_on_macos() else 1. ratio = self._magnification * adjustment delta = event.pos - self._origin self._origin = event.pos self._coordinate[0] -= (delta[0] * ratio) self._coordinate[1] += (delta[1] * ratio) self.apply_magnification() def pause_drawing(self, pause=True): self._pause_drawing = pause def toggle_drawing(self): self._pause_drawing = False if self._pause_drawing else True @property def is_pausing(self): return True if self._pause_drawing else False def resume_drawing(self): self._pause_drawing = False @property def background_color(self): return self._background_color @background_color.setter def background_color(self, color): self._background_color = color
class Drawable(object): name = "Default Drawable" skip = False def __init__(self, *args, **kwargs): '''Drawable(*args, **kwargs) -> Drawable Everything is tracked internally, different drawables will handle things differently Inherit from this for all drawables. Inheriting: You must define a make_mesh, make_shaders, and draw method. If you do not make shaders, you will get a default If you do not make a mesh, you'll get a square that takes up the screen ''' self.model = np.eye(4) self.view = np.eye(4) self.projection = np.eye(4) self.mesh = self.make_mesh() self.vert_shader, self.frag_shader = self.make_shaders() self.program = Program(self.vert_shader, self.frag_shader) self.program.bind(VertexBuffer(self.mesh)) if hasattr(self, make_texture): self.texture = self.make_texture() assert isinstance(self.texture, Texture2D), "Texture passed is not a texture!" self.program['texture'] = self.texture cube["texture"].interpolation = 'linear' def __setitem__(self, key, value): self.bind(key, value) def translate(self, *args): translate(self.model, *args) self.program['model'] = self.model def rotate(self, *args): rotate(self.model, *args) self.program['model'] = self.model def bind(self, key, value): '''Rebind a single program item to a value''' self.program[key] = value def bind_multiple(self, **kwargs): '''rebind multiple things!''' for key, value in kwargs: self.bind(key, value) def make_mesh(self): '''mesh() Generates a default mesh (a cube) treat it as though it is a property (i.e. not a function) ex: >>> x = Target((100, 100, 100)) >>> mesh = Target.mesh ''' cube = Program(cube_vertex, cube_fragment) cube.bind(vertices) self.program['model'] = model self.program['view'] = view self.program['projection'] = projection if self.mesh is None: vertices, indices, _ = create_cube() # self.mesh = else: return self.mesh def make_shaders(self): '''shader -> (vertex, fragment) Returns vertex and fragment shaders as 2-tuple of strings THIS IS A DEFAULT SHADER ''' fragment = '' vertex = '' return vertex, fragment def make_texture(self): '''Make a texture THIS IS A DEFAULT TEXTURE ''' texture = utils.checkerboard() return texture def update(self): pass def draw(self): self.program.draw()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, title='Grayscott Reaction-Diffusion', size=(512, 512), keys='interactive') self.scale = 4 self.comp_size = self.size comp_w, comp_h = self.comp_size dt = 1.0 dd = 1.5 species = { # name : [r_u, r_v, f, k] 'Bacteria 1': [0.16, 0.08, 0.035, 0.065], 'Bacteria 2': [0.14, 0.06, 0.035, 0.065], 'Coral': [0.16, 0.08, 0.060, 0.062], 'Fingerprint': [0.19, 0.05, 0.060, 0.062], 'Spirals': [0.10, 0.10, 0.018, 0.050], 'Spirals Dense': [0.12, 0.08, 0.020, 0.050], 'Spirals Fast': [0.10, 0.16, 0.020, 0.050], 'Unstable': [0.16, 0.08, 0.020, 0.055], 'Worms 1': [0.16, 0.08, 0.050, 0.065], 'Worms 2': [0.16, 0.08, 0.054, 0.063], 'Zebrafish': [0.16, 0.08, 0.035, 0.060] } P = np.zeros((comp_h, comp_w, 4), dtype=np.float32) P[:, :] = species['Unstable'] UV = np.zeros((comp_h, comp_w, 4), dtype=np.float32) UV[:, :, 0] = 1.0 r = 32 UV[comp_h // 2 - r:comp_h // 2 + r, comp_w // 2 - r:comp_w // 2 + r, 0] = 0.50 UV[comp_h // 2 - r:comp_h // 2 + r, comp_w // 2 - r:comp_w // 2 + r, 1] = 0.25 UV += np.random.uniform(0.0, 0.01, (comp_h, comp_w, 4)) UV[:, :, 2] = UV[:, :, 0] UV[:, :, 3] = UV[:, :, 1] self.pingpong = 1 self.compute = Program(compute_vertex, compute_fragment, 4) self.compute["params"] = P self.compute["texture"] = UV self.compute["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.compute["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.compute['dt'] = dt self.compute['dx'] = 1.0 / comp_w self.compute['dy'] = 1.0 / comp_h self.compute['dd'] = dd self.compute['pingpong'] = self.pingpong self.render = Program(render_vertex, render_fragment, 4) self.render["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.render["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.render["texture"] = self.compute["texture"] self.render['pingpong'] = self.pingpong self.fbo = FrameBuffer(self.compute["texture"], RenderBuffer(self.comp_size)) set_state(depth_test=False, clear_color='black') self._timer = app.Timer('auto', connect=self.update, start=True) self.show() def on_draw(self, event): with self.fbo: set_viewport(0, 0, *self.comp_size) self.compute["texture"].interpolation = 'nearest' self.compute.draw('triangle_strip') clear(color=True) set_viewport(0, 0, *self.physical_size) self.render["texture"].interpolation = 'linear' self.render.draw('triangle_strip') self.pingpong = 1 - self.pingpong self.compute["pingpong"] = self.pingpong self.render["pingpong"] = self.pingpong def on_resize(self, event): set_viewport(0, 0, *self.physical_size)
class Button(Drawable): '''Draw a cube''' button_vertex_shader = """ #version 120 uniform mat4 model; uniform mat4 view; uniform mat4 projection; attribute vec3 vertex_position; attribute vec2 default_texcoord; varying vec2 texcoord; void main() { texcoord = default_texcoord; gl_Position = projection * view * model * vec4(vertex_position, 1.0); } """ button_fragment_shader = """ #version 120 uniform int highlighted; uniform sampler2D texture; varying vec2 texcoord; uniform vec3 background_color; void main() { vec4 color = texture2D(texture, texcoord); // if (color.rgb == vec3(1, 1, 1)) { // gl_FragColor = vec4(background_color, 1); // } else { // gl_FragColor = vec4(color.rgb, 1); // } if (highlighted == 1){ if(color.r == 1 && color.g == 1 && color.b == 1) { gl_FragColor = vec4(color.rgb, 1); } else { gl_FragColor = vec4(1, .29, 0, 1); } } else { gl_FragColor = vec4(color.rgb, 1); } } """ name = "Button" def __init__(self, text, canvas, position=1, color=(0.1, 0.0, 0.7)): ''' Give this the - text to be written - main app.canvas - position (1-9, or which button position this should occupy) ''' # State Controller State.register_button(position, text) self.position = position self.canvas = canvas self.projection = np.eye(4) self.view = np.eye(4) self.model = np.eye(4) height, width = 5.0, 15.0 # Meters orientation_vector = (1, 1, 0) unit_orientation_angle = np.array(orientation_vector) / np.linalg.norm(orientation_vector) scale_factor = 0.2 lowest_button = -5.2 midset = 0.2 scale(self.model, scale_factor) yrotate(self.model, -60) # rotate(self.model, 30, *unit_orientation_angle) offset = (position * ((height + midset) * scale_factor)) translate(self.model, -7.4, lowest_button + offset, -10) pixel_to_length = 10 self.size = map(lambda o: pixel_to_length * o, [width, height]) # Add texture coordinates # Rectangle of height height self.vertices = np.array([ [-width / 2, -height / 2, 0], [ width / 2, -height / 2, 0], [ width / 2, height / 2, 0], [-width / 2, height / 2, 0], ], dtype=np.float32) self.tex_coords = np.array([ [0, 0], [1, 0], [1, 1], [0, 1], ], dtype=np.float32) self.indices = IndexBuffer([ 0, 1, 2, 2, 3, 0, ]) self.program = Program(self.button_vertex_shader, self.button_fragment_shader) self.program['vertex_position'] = self.vertices self.program['default_texcoord'] = self.tex_coords self.program['view'] = self.view self.program['model'] = self.model self.program['projection'] = self.projection self.program['background_color'] = color self.program['highlighted'] = 0 # self.texture = Texture2D(shape=(1000, 1000) + (3,)) # self.text_buffer = FrameBuffer(self.texture, RenderBuffer((1000, 1000))) self.texture = Texture2D(shape=(500, 1500) + (3,)) self.text_buffer = FrameBuffer(self.texture, RenderBuffer((500, 1500))) self.program['texture'] = self.texture self.text = text self.make_text(self.text) self.first = True def update(self): '''Things: - If selected, change color - Hide if I need to be hidden ''' if State.current_button == self.position: self.program['highlighted'] = 1 else: self.program['highlighted'] = 0 def make_text(self, _string): self.font_size = 150 # self.color = (.1, .1, .1, 1.0) self.color = (1, 1, 1, 1.0) self.canvas.text_renderer = visuals.TextVisual('', bold=True, color=self.color) self.tr_sys = visuals.transforms.TransformSystem(self.canvas) self.canvas.text_renderer.text = _string self.canvas.text_renderer.font_size = self.font_size # self.canvas.text_renderer.pos = 200, 200 self.size = 500, 1500 self.canvas.text_renderer.pos = self.size[0] * 1.5, self.size[1] // 1.9 # Logger.log("Color: %s" % (self.canvas.text_renderer.color,)) def make_texture(self): # gloo.clear(color=True, depth=True) with self.text_buffer: # gloo.clear(color=(0.008, 0.435, 0.71)) gloo.clear(color=(0, 0.13, 0.65)) self.canvas.text_renderer.draw(self.tr_sys) def draw(self): if self.first: self.canvas.text_renderer.text = self.text self.make_texture() self.first = False set_state(depth_test=False) self.program.draw('triangles', self.indices) set_state(depth_test=True)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Lighted cube', keys='interactive') self.timer = app.Timer('auto', self.on_timer) # Build cube data V, F, O = create_cube() vertices = VertexBuffer(V) self.faces = IndexBuffer(F) self.outline = IndexBuffer(O) # Build view, model, projection & normal # -------------------------------------- self.view = translate((0, 0, -5)) model = np.eye(4, dtype=np.float32) normal = np.array(np.matrix(np.dot(self.view, model)).I.T) # Build program # -------------------------------------- self.program = Program(vertex, fragment) self.program.bind(vertices) self.program["u_light_position"] = 2, 2, 2 self.program["u_light_intensity"] = 1, 1, 1 self.program["u_model"] = model self.program["u_view"] = self.view self.program["u_normal"] = normal self.phi, self.theta = 0, 0 self.activate_zoom() # OpenGL initialization # -------------------------------------- gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00), depth_test=True, polygon_offset=(1, 1), blend_func=('src_alpha', 'one_minus_src_alpha'), line_width=0.75) self.timer.start() self.show() def on_draw(self, event): gloo.clear(color=True, depth=True) # program.draw(gl.GL_TRIANGLES, indices) # Filled cube gloo.set_state(blend=False, depth_test=True, polygon_offset_fill=True) self.program['u_color'] = 1, 1, 1, 1 self.program.draw('triangles', self.faces) # Outlined cube gloo.set_state(polygon_offset_fill=False, blend=True, depth_mask=False) self.program['u_color'] = 0, 0, 0, 1 self.program.draw('lines', self.outline) gloo.set_state(depth_mask=True) def on_resize(self, event): self.activate_zoom() def activate_zoom(self): gloo.set_viewport(0, 0, *self.physical_size) projection = perspective(45.0, self.size[0] / float(self.size[1]), 2.0, 10.0) self.program['u_projection'] = projection def on_timer(self, event): self.theta += .5 self.phi += .5 model = np.dot(rotate(self.theta, (0, 0, 1)), rotate(self.phi, (0, 1, 0))) normal = np.linalg.inv(np.dot(self.view, model)).T self.program['u_model'] = model self.program['u_normal'] = normal self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, title='Framebuffer post-processing', keys='interactive', size=(512, 512)) # Build cube data # -------------------------------------- vertices, indices, _ = create_cube() vertices = VertexBuffer(vertices) self.indices = IndexBuffer(indices) # Build program # -------------------------------------- view = np.eye(4, dtype=np.float32) model = np.eye(4, dtype=np.float32) translate(view, 0, 0, -7) self.phi, self.theta = 60, 20 rotate(model, self.theta, 0, 0, 1) rotate(model, self.phi, 0, 1, 0) self.cube = Program(cube_vertex, cube_fragment) self.cube.bind(vertices) self.cube["texture"] = checkerboard() self.cube["texture"].interpolation = 'linear' self.cube['model'] = model self.cube['view'] = view color = Texture2D((512, 512, 3), interpolation='linear') self.framebuffer = FrameBuffer(color, RenderBuffer((512, 512))) self.quad = Program(quad_vertex, quad_fragment, count=4) self.quad['texcoord'] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.quad['position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.quad['texture'] = color # OpenGL and Timer initalization # -------------------------------------- set_state(clear_color=(.3, .3, .35, 1), depth_test=True) self.timer = app.Timer('auto', connect=self.on_timer, start=True) self._set_projection(self.size) def on_draw(self, event): with self.framebuffer: set_viewport(0, 0, 512, 512) clear(color=True, depth=True) set_state(depth_test=True) self.cube.draw('triangles', self.indices) set_viewport(0, 0, *self.size) clear(color=True) set_state(depth_test=False) self.quad.draw('triangle_strip') def on_resize(self, event): self._set_projection(event.size) def _set_projection(self, size): width, height = size set_viewport(0, 0, width, height) projection = perspective(30.0, width / float(height), 2.0, 10.0) self.cube['projection'] = projection def on_timer(self, event): self.theta += .5 self.phi += .5 model = np.eye(4, dtype=np.float32) rotate(model, self.theta, 0, 0, 1) rotate(model, self.phi, 0, 1, 0) self.cube['model'] = model self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Rotating cube', keys='interactive') self.timer = app.Timer('auto', self.on_timer) # Build cube data V, I, O = create_cube() vertices = VertexBuffer(V) self.faces = IndexBuffer(I) self.outline = IndexBuffer(O) # Build program # -------------------------------------- self.program = Program(vertex, fragment) self.program.bind(vertices) # Build view, model, projection & normal # -------------------------------------- view = np.eye(4, dtype=np.float32) model = np.eye(4, dtype=np.float32) translate(view, 0, 0, -5) self.program['u_model'] = model self.program['u_view'] = view self.phi, self.theta = 0, 0 # OpenGL initalization # -------------------------------------- gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00), depth_test=True, polygon_offset=(1, 1), line_width=0.75, blend_func=('src_alpha', 'one_minus_src_alpha')) self.timer.start() def on_draw(self, event): gloo.clear(color=True, depth=True) # Filled cube gloo.set_state(blend=False, depth_test=True, polygon_offset_fill=True) self.program['u_color'] = 1, 1, 1, 1 self.program.draw('triangles', self.faces) # Outlined cube gloo.set_state(blend=True, depth_mask=False, polygon_offset_fill=False) self.program['u_color'] = 0, 0, 0, 1 self.program.draw('lines', self.outline) gloo.set_state(depth_mask=True) def on_resize(self, event): gloo.set_viewport(0, 0, *event.size) projection = perspective(45.0, event.size[0] / float(event.size[1]), 2.0, 10.0) self.program['u_projection'] = projection def on_timer(self, event): self.theta += .5 self.phi += .5 model = np.eye(4, dtype=np.float32) rotate(model, self.theta, 0, 0, 1) rotate(model, self.phi, 0, 1, 0) self.program['u_model'] = model self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title='Particle Renderer', keys='interactive') # enable geometry shader gloo.gl.use_gl('gl+') # load and compile shader with open('shader/particleRenderer.frag', 'r') as file: fragmentString = file.read() with open('shader/particleRenderer.geom', 'r') as file: geomString = file.read() with open('shader/particleRenderer.vert', 'r') as file: vertexString = file.read() self.program = Program() self.program.set_shaders(vertexString, fragmentString, geomString, True) ###################################### # settings # when changing near/far or fov you have to call resetProjection() for the changes to take effect # everything closer to the camera than near ot further away than far will not be drawn self.nearDistance = 0.1 self.farDistance = 20 self.fov = 45.0 # field of view in degree # initial camera position # call resetCamera or press "R" to go the initial position self.initialCamPosition = glm.vec3(3, 3, 3) self.initialCamTarget = glm.vec3(0, 0, 0) # you can change settings of the camera yourself with self.cam.xxx = yyy # you can also move the camera by calling setPosition / setTarget and # thereby predefine an animation (eg for videos/talks) # you can also change the camera control mode 1 = fly camera, 0 = trackball camera self.cam = Camera(1, self.initialCamPosition, self.initialCamTarget) # the CameraInputHandler links the camera to keybiard and mouse input, you can also change keybindings there self.camInputHandler = CameraInputHandler(self.cam) # // positions where spheres are rendered self.program['input_position'] = [(0, 0, 0), (1, 1, 1), (1, 1, -1), (1, -1, 1), (1, -1, -1), (-1, 1, 1), (-1, 1, -1), (-1, -1, 1), (-1, -1, -1)] # vector field for color # self.program['input_vector'] = # scalar field, used for color in color mode 3 self.program['input_scalar'] = np.array( [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9], dtype=np.float32) # radius per particle, set self.program['enableSizePerParticle'] = True to enable self.program['input_radius'] = [[0.15], [0.1], [0.2], [0.1], [0.2], [0.05], [0.1], [0.15], [0.1]] # size self.program[ 'enableSizePerParticle'] = False # enable this and set a size for each particle above self.program[ 'sphereRadius'] = 0.15 # radius of the spheres if "size per particle" is disabled # background gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00)) # background color # transfer function / color self.program[ 'colorMode'] = 3 # 1: color by vector field direction, 2: color by vector field magnitude, 3: color by scalar field, 0: constant color self.program['defaultColor'] = (1, 1, 1 ) # particle color in color mode 0 self.program[ 'lowerBound'] = 0.0 # lowest value of scalar field / vector field magnitude self.program[ 'upperBound'] = 1.0 # lowest value of scalar field / vector field magnitude self.program[ 'customTransferFunc'] = True # set to true to use a custom transfer function # Transfer function uses a 1D Texture. # Provide 1D list of colors (r,g,b) as the textures data attribute, colors will be evenly spread over # the range [lowerBound,upperBound]. Meaning particles where the scalar is equal to lowerBound will # have the first specified color, the one with a scalar equal to lowerBound will have the last. Values that # lie in between the colors are interpolated linearly self.program['transferFunc'] = gloo.Texture1D( format='rgba', interpolation='linear', internalformat='rgba8', data=cm.viridis(range(256)).astype(np.float32)) # sphere look self.program['brightness'] = 1 # additional brightness control self.program[ 'materialAlpha'] = 1.0 # set lower than one to make spheres self.program['materialShininess'] = 4.0 # material shininess self.program[ 'useTexture'] = False # use the below texture for coloring (will be tinted according to set color) # provide a numpy array of shaper (x,y,3) for rgb pixels of the 2d image self.program['colorTexture'] = gloo.Texture2D( format='rgb', interpolation='linear', internalformat='rgb8', data=_checkerboard().astype(np.float32)) self.program[ 'uvUpY'] = False # rotates texture by 90 degrees so that sphere poles are along the Y axis # light settings self.program['lightPosition'] = (500, 500, 1000 ) # position of the ligth self.program['lightDiffuse'] = (0.4, 0.4, 0.4 ) # diffuse color of the light self.program['lightSpecular'] = (0.3, 0.3, 0.3 ) # specular color of the light self.program['ambientLight'] = (0.1, 0.1, 0.1) # ambient light color self.program[ 'lightInViewSpace'] = True # should the light move around with the camera? # settings for flat shading self.program[ 'renderFlatDisks'] = False # render flat discs instead of spheres self.program[ 'flatFalloff'] = False # when using flat discs, enable this darken the edges # settings for additional depth cues self.program[ 'enableEdgeHighlights'] = False # add black edge around the particles for better depth perception # style of blending self.useAdditiveBlending(False) # orientation helper self.enableOrientationIndicator = True # enable / disable orientation indicator in the lower left self.enableOriginIndicator = True # enable / disable orientation indicator at the origin self.originIndicatorSize = 1.0 # change size of the origin indicator # other self.program[ 'spriteScale'] = 1.1 # increase this if spheres appear to have cut off edges ############################################ # setup orientation indicator # load and compile shader with open('shader/oriIndicator.frag', 'r') as file: oriFragmentString = file.read() with open('shader/oriIndicator.vert', 'r') as file: oriVertexString = file.read() self._oriProgram = Program(oriVertexString, oriFragmentString) self._oriProgram['input_position'] = [(0, 0, 0), (1, 0, 0), (0, 0, 0), (0, 1, 0), (0, 0, 0), (0, 0, 1)] # model matrix model = np.eye(4, dtype=np.float32) self.program['model'] = model # camera and view matrix self.program['view'] = self.cam.viewMatrix # projection matrix self._projection = glm.mat4(1.0) self._oriProjection = glm.mat4(1.0) self.resetProjection() # timing self._lastTime = time.time() # show window self.show() def resetCamera(self): self.cam.setPosition(self.initialCamPosition, True) self.cam.setTarget(self.initialCamTarget, True) def useAdditiveBlending(self, enable): if enable: gloo.set_blend_func('one', 'one') gloo.set_blend_equation('func_add') gloo.set_state(depth_test=False, blend=True) else: gloo.set_state(depth_test=True, blend=False) def on_mouse_move(self, event): self.camInputHandler.on_mouse_move(event) def on_key_press(self, event): if event.key == 'R': self.resetCamera() event.handled = True else: self.camInputHandler.on_key_pressed(event) def on_key_release(self, event): self.camInputHandler.on_key_released(event) def on_mouse_wheel(self, event): self.camInputHandler.on_mouse_wheel(event) def _drawOrientationIndicator(self): gloo.set_state(line_width=5) # we want the rotation of the camera but not the translation view = glm.inverse( glm.mat4_cast(self.cam._currentTransform.orientation)) view = glm.scale(view, glm.vec3(0.25)) self._oriProgram['projection'] = self._oriProjection self._oriProgram['view'] = view self._oriProgram.draw('lines') def _drawOriginIndicator(self): gloo.set_state(line_width=2) self._oriProgram['projection'] = self._projection self._oriProgram['view'] = glm.scale( self.cam.viewMatrix, glm.vec3(self.originIndicatorSize)) self._oriProgram.draw('lines') def on_draw(self, event): # clear window content gloo.clear(color=True, depth=True) # calculate dt (time since last frame) newTime = time.time() dt = newTime - self._lastTime self._lastTime = newTime # update camera and view matrix self.camInputHandler.on_draw(dt) self.cam.update(dt) self.program['view'] = self.cam.viewMatrix # draw particles self.program.draw('points') # draw orientation indicator if self.enableOrientationIndicator: self._drawOrientationIndicator() if self.enableOriginIndicator: self._drawOriginIndicator() # update window content self.update() def on_resize(self, event): self.resetProjection() def resetProjection(self): # calculate projection gloo.set_viewport(0, 0, *self.physical_size) aspect = self.size[0] / float(self.size[1]) self._projection = perspective(self.fov, aspect, self.nearDistance, self.farDistance) self.program['projection'] = self._projection # calculate projection for the orientation indicator in the lower left orthoScale = 1 / 500 orthoProjection = glm.ortho(-self.size[0] * orthoScale, self.size[0] * orthoScale, -self.size[1] * orthoScale, self.size[1] * orthoScale) self._oriProjection = glm.translate( orthoProjection, glm.vec3(-self.size[0] * orthoScale + 0.28, -self.size[1] * orthoScale + 0.28, 0))
class Battery(Drawable): battery_vertex_shader = """ #version 120 uniform mat4 model; uniform mat4 view; uniform mat4 projection; attribute vec3 vertex_position; attribute vec2 default_texcoord; varying vec2 texcoord; void main() { texcoord = default_texcoord; gl_Position = projection * view * model * vec4(vertex_position, 1.0); } """ battery_fragment_shader = """ #version 120 uniform int hide; uniform sampler2D texture; varying vec2 texcoord; uniform vec3 background_color; void main() { vec4 color = texture2D(texture, texcoord); gl_FragColor = vec4(color.rgb, 1); // if(hide == 1) { // gl_FragColor = vec4(0, 0, 0, 1); // } else { // gl_FragColor = vec4(color.rgb, 1); // } } """ tex_vert_shader = """ #version 120 attribute vec3 vertex_position; attribute vec2 default_texcoord; varying vec2 texcoord; void main() { texcoord = default_texcoord; gl_Position = vec4(vertex_position, 1.0); } """ name = "Battery" def __init__(self): self.projection = np.eye(4) self.view = np.eye(4) self.model = np.eye(4) height, width = 3.0, 6.0 scale_factor = 0.2 x_offset = -8 y_offset = 2 pixel_to_length = 10 color = (1.0, 1.0, 1.0) scale(self.model, scale_factor) yrotate(self.model, -60) translate(self.model, x_offset, y_offset, -10) size = (int(height*100), int(width*100)) self.vertices = np.array([ [-width / 2, -height / 2, 0], [ width / 2, -height / 2, 0], [ width / 2, height / 2, 0], [-width / 2, height / 2, 0], ], dtype=np.float32) self.tex_coords = np.array([ [0, 0], [1, 0], [1, 1], [0, 1], ], dtype=np.float32) self.indices = IndexBuffer([ 0, 1, 2, 2, 3, 0, ]) self.program = Program(self.battery_vertex_shader, self.battery_fragment_shader) self.texture = Texture2D(shape=size + (3,)) self.text_buffer = FrameBuffer(self.texture, RenderBuffer(size)) images = [] images.append(Image.open(os.path.join(Paths.get_path_to_visar(), 'visar', 'images', 'battery', 'battery_low_color.png'))) images.append(Image.open(os.path.join(Paths.get_path_to_visar(), 'visar', 'images', 'battery', 'battery_used_color.png'))) images.append(Image.open(os.path.join(Paths.get_path_to_visar(), 'visar', 'images', 'battery', 'battery_full_color.png'))) self.level_texture = {} # texture for each level for x in range(0, len(images)): default_image = images[x] default_image = default_image.rotate(-90) default_image = default_image.resize(size) default_image = default_image.transpose(Image.FLIP_TOP_BOTTOM) default_image_array = np.asarray(default_image) self.level_texture[x + 1] = default_image_array #default_image_array = imageio.imread(os.path.join(Paths.get_path_to_visar(), 'visar', 'images', 'battery', 'battery_full_color.png')) # self.default_tex = Texture2D(data=default_image_array) # self.default_tex = Texture2D(shape=size + (3,)) # self.default_tex.set_data(self.level_texture[3]) self.program['vertex_position'] = self.vertices self.program['default_texcoord'] = self.tex_coords self.program['view'] = self.view self.program['model'] = self.model self.program['projection'] = self.projection self.program['hide'] = 0 # self.tex_program = Program(self.tex_vert_shader, self.battery_fragment_shader) # self.tex_program['vertex_position'] = self.vertices # self.tex_program['default_texcoord'] = self.tex_coords # self.tex_program['hide'] = 0 # self.tex_program['texture'] = self.default_tex self.flag = True # flag to update the texture self.level = 3 # level of the battery 1 - 3 full_middle_split = 75 # split between levels 2 and 3 middle_low_split = 25 # split between levels 1 and 2 fault_tolerance = 5 self.full_lower = full_middle_split - fault_tolerance # lower limit for going from 3 to 2 self.middle_upper = full_middle_split + fault_tolerance # upper limit for going from 2 to 3 self.middle_lower = middle_low_split - fault_tolerance # lower limit for going from 2 to 1 self.low_upper = middle_low_split + fault_tolerance # upper limit for going from 1 to 2 def update(self): battery_level = State.battery # get current battery level # Logger.log("Battery Level: %s" % (battery,)) if self.level == 3: if battery_level < self.full_lower: self.set_new_level(2) elif self.level == 2: if battery_level > self.middle_upper: self.set_new_level(3) elif battery_level < self.middle_lower: self.set_new_level(1) elif self.level == 1: if battery_level > self.low_upper: self.set_new_level(2) def set_new_level(self, new_level): self.level = new_level self.flag = 1 def make_texture(self): with self.text_buffer: gloo.clear(color=(1, 1, 1)) self.program['texture'] = self.level_texture[self.level] # self.program.draw('triangles', self.indices) def draw(self): if self.flag: self.make_texture() self.flag = False set_state(depth_test=False) self.program.draw('triangles', self.indices) set_state(depth_test=True)
class Canvas(app.Canvas): def __init__(self, image): app.Canvas.__init__(self, title='WaveSyn-ImageViewer', size=(512, 512), keys='interactive') height, width, dumb = image.shape self.__image_ratio = width / height self.__image_size = width + 1j*height self.program = Program(vertex, fragment, 4) self.program['position'] = (-1, -1), (-1, +1), (+1, -1), (+1, +1) self.program['texcoord'] = (0, +1), (0, 0), (+1, +1), (+1, 0) self.program['image'] = image self.program['image'].interpolation = 'linear' set_clear_color('black') self.__scale = 1 self.__last_pos = 0+1j*0 self.__offset = 0+1j*0 self.show() @property def scale(self): return self.__scale @scale.setter def scale(self, val): if val > 0: self.__scale = val def on_resize(self, event): self.__offset = 0+1j*0 self._set_viewport() def on_mouse_wheel(self, event): original_scale = self.scale delta_scale = 0.1*event.delta[1] new_scale = original_scale + delta_scale if new_scale < 0.1: return self.scale = new_scale mouse_pos = event.pos[0] + 1j*(self.size[1]-event.pos[1]) mouse_pos -= self.__offset mouse_pos /= original_scale self.__offset -= mouse_pos * delta_scale self._set_viewport() self.update() def on_mouse_press(self, event): self.__last_pos = (event.pos[0] + 1j*event.pos[1]).conjugate() def on_mouse_move(self, event): if event.is_dragging: pos = event.pos[0] + 1j*event.pos[1] pos = pos.conjugate() self.__offset += pos - self.__last_pos self.__last_pos = pos self._set_viewport() self.update() def on_key_press(self, event): if event.key.name == 'Enter': self.fullscreen = not self.fullscreen def on_draw(self, event): clear(color=True, depth=True) self.program.draw('triangle_strip') def _set_viewport(self): sc = self.size[0] + 1j*self.size[1] scale = self.scale offset = self.__offset rc = sc.real / sc.imag ri = self.__image_ratio if rc >= ri: si = sc.imag * (ri + 1j) else: si = sc.real * (1 + 1j/ri) si *= scale set_viewport(offset.real, offset.imag, si.real, si.imag)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), keys='interactive') self.image = Program(image_vertex, image_fragment, 4) self.image['position'] = (-1, -1), (-1, +1), (+1, -1), (+1, +1) self.image['texcoord'] = (0, 0), (0, +1), (+1, 0), (+1, +1) self.image['vmin'] = +0.0 self.image['vmax'] = +1.0 self.image['cmap'] = 0 # Colormap index to use self.image['colormaps'] = colormaps self.image['n_colormaps'] = colormaps.shape[0] self.image['image'] = idxs.astype('float32') self.image['image'].interpolation = 'linear' set_viewport(0, 0, *self.physical_size) self.lines = Program(lines_vertex, lines_fragment) self.lines["position"] = np.zeros((4 + 4 + 514 + 514, 2), np.float32) color = np.zeros((4 + 4 + 514 + 514, 4), np.float32) color[1:1 + 2, 3] = 0.25 color[5:5 + 2, 3] = 0.25 color[9:9 + 512, 3] = 0.5 color[523:523 + 512, 3] = 0.5 self.lines["color"] = color set_state(clear_color='white', blend=True, blend_func=('src_alpha', 'one_minus_src_alpha')) self.show() def on_resize(self, event): set_viewport(0, 0, *event.physical_size) def on_draw(self, event): clear(color=True, depth=True) self.image.draw('triangle_strip') self.lines.draw('line_strip') def on_mouse_move(self, event): x, y = event.pos w, h = self.size # Make sure the mouse isn't outside of the viewport. x = max(0, min(x, w - 1)) y = max(0, min(y, h - 1)) yf = 1 - y / (h / 2.) xf = x / (w / 2.) - 1 x_norm = int((x * 512) // w) y_norm = int((y * 512) // h) P = np.zeros((4 + 4 + 514 + 514, 2), np.float32) x_baseline = P[:4] y_baseline = P[4:8] x_profile = P[8:522] y_profile = P[522:] x_baseline[...] = (-1, yf), (-1, yf), (1, yf), (1, yf) y_baseline[...] = (xf, -1), (xf, -1), (xf, 1), (xf, 1) x_profile[1:-1, 0] = np.linspace(-1, 1, 512) x_profile[1:-1, 1] = yf + 0.15 * idxs[y_norm, :] x_profile[0] = x_profile[1] x_profile[-1] = x_profile[-2] y_profile[1:-1, 0] = xf + 0.15 * idxs[:, x_norm] y_profile[1:-1, 1] = np.linspace(-1, 1, 512) y_profile[0] = y_profile[1] y_profile[-1] = y_profile[-2] self.lines["position"] = P self.update()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), title="Lighted cube", keys="interactive") self.timer = app.Timer("auto", self.on_timer) # Build cube data V, F, O = create_cube() vertices = VertexBuffer(V) self.faces = IndexBuffer(F) self.outline = IndexBuffer(O) # Build view, model, projection & normal # -------------------------------------- self.view = np.eye(4, dtype=np.float32) model = np.eye(4, dtype=np.float32) translate(self.view, 0, 0, -5) normal = np.array(np.matrix(np.dot(self.view, model)).I.T) # Build program # -------------------------------------- self.program = Program(vertex, fragment) self.program.bind(vertices) self.program["u_light_position"] = 2, 2, 2 self.program["u_light_intensity"] = 1, 1, 1 self.program["u_model"] = model self.program["u_view"] = self.view self.program["u_normal"] = normal self.phi, self.theta = 0, 0 # OpenGL initalization # -------------------------------------- gloo.set_state( clear_color=(0.30, 0.30, 0.35, 1.00), depth_test=True, polygon_offset=(1, 1), blend_func=("src_alpha", "one_minus_src_alpha"), line_width=0.75, ) self.timer.start() def on_draw(self, event): gloo.clear(color=True, depth=True) # program.draw(gl.GL_TRIANGLES, indices) # Filled cube gloo.set_state(blend=False, depth_test=True, polygon_offset_fill=True) self.program["u_color"] = 1, 1, 1, 1 self.program.draw("triangles", self.faces) # Outlined cube gloo.set_state(polygon_offset_fill=False, blend=True, depth_mask=False) self.program["u_color"] = 0, 0, 0, 1 self.program.draw("lines", self.outline) gloo.set_state(depth_mask=True) def on_resize(self, event): gloo.set_viewport(0, 0, *event.size) projection = perspective(45.0, event.size[0] / float(event.size[1]), 2.0, 10.0) self.program["u_projection"] = projection def on_timer(self, event): self.theta += 0.5 self.phi += 0.5 model = np.eye(4, dtype=np.float32) rotate(model, self.theta, 0, 0, 1) rotate(model, self.phi, 0, 1, 0) normal = np.array(np.matrix(np.dot(self.view, model)).I.T) self.program["u_model"] = model self.program["u_normal"] = normal self.update()
class OpenGLRenderer(ABC): def __init__(self, src_fbuffer, src_default): self.default_prog = None self.fbuffer_prog = None self.fbuffer = None self.fbuffer_tex_front = None self.fbuffer_tex_back = None self.vertex_buffer = None self.index_buffer = None # Renderer Globals: STYLE/MATERIAL PROPERTIES # self.style = Style() # Renderer Globals: Curves self.stroke_weight = 1 self.stroke_cap = ROUND self.stroke_join = MITER # Renderer Globals # VIEW MATRICES, ETC # self.viewport = None self.texture_viewport = None self.transform_matrix = np.identity(4) self.projection_matrix = np.identity(4) # Renderer Globals: RENDERING self.draw_queue = [] # Shaders self.fbuffer_prog = Program(src_fbuffer.vert, src_fbuffer.frag) self.default_prog = Program(src_default.vert, src_default.frag) def initialize_renderer(self): self.fbuffer = FrameBuffer() vertices = np.array( [[-1.0, -1.0], [+1.0, -1.0], [-1.0, +1.0], [+1.0, +1.0]], np.float32) texcoords = np.array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]], dtype=np.float32) self.fbuf_vertices = VertexBuffer(data=vertices) self.fbuf_texcoords = VertexBuffer(data=texcoords) self.fbuffer_prog['texcoord'] = self.fbuf_texcoords self.fbuffer_prog['position'] = self.fbuf_vertices self.vertex_buffer = VertexBuffer() self.index_buffer = IndexBuffer() def render_default(self, draw_type, draw_queue): # 1. Get the maximum number of vertices persent in the shapes # in the draw queue. # if len(draw_queue) == 0: return num_vertices = 0 for vertices, _, _ in draw_queue: num_vertices = num_vertices + len(vertices) # 2. Create empty buffers based on the number of vertices. # data = np.zeros(num_vertices, dtype=[('position', np.float32, 3), ('color', np.float32, 4)]) # 3. Loop through all the shapes in the geometry queue adding # it's information to the buffer. # sidx = 0 draw_indices = [] for vertices, idx, color in draw_queue: num_shape_verts = len(vertices) data['position'][sidx:(sidx + num_shape_verts), ] = np.array(vertices) color_array = np.array([color] * num_shape_verts) data['color'][sidx:sidx + num_shape_verts, :] = color_array draw_indices.append(sidx + idx) sidx += num_shape_verts self.vertex_buffer.set_data(data) self.index_buffer.set_data(np.hstack(draw_indices)) # 4. Bind the buffer to the shader. # self.default_prog.bind(self.vertex_buffer) # 5. Draw the shape using the proper shape type and get rid of # the buffers. # self.default_prog.draw(draw_type, indices=self.index_buffer) def cleanup(self): """Run the clean-up routine for the renderer. This method is called when all drawing has been completed and the program is about to exit. """ self.default_prog.delete() self.fbuffer_prog.delete() self.fbuffer.delete() def _transform_vertices(self, vertices, local_matrix, global_matrix): return np.dot(np.dot(vertices, local_matrix.T), global_matrix.T)[:, :3]
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, title='Grayscott Reaction-Diffusion', size=(512, 512), keys='interactive') self.scale = 4 self.comp_size = self.size comp_w, comp_h = self.comp_size dt = 1.0 dd = 1.5 species = { # name : [r_u, r_v, f, k] 'Bacteria 1': [0.16, 0.08, 0.035, 0.065], 'Bacteria 2': [0.14, 0.06, 0.035, 0.065], 'Coral': [0.16, 0.08, 0.060, 0.062], 'Fingerprint': [0.19, 0.05, 0.060, 0.062], 'Spirals': [0.10, 0.10, 0.018, 0.050], 'Spirals Dense': [0.12, 0.08, 0.020, 0.050], 'Spirals Fast': [0.10, 0.16, 0.020, 0.050], 'Unstable': [0.16, 0.08, 0.020, 0.055], 'Worms 1': [0.16, 0.08, 0.050, 0.065], 'Worms 2': [0.16, 0.08, 0.054, 0.063], 'Zebrafish': [0.16, 0.08, 0.035, 0.060] } P = np.zeros((comp_h, comp_w, 4), dtype=np.float32) P[:, :] = species['Unstable'] UV = np.zeros((comp_h, comp_w, 4), dtype=np.float32) UV[:, :, 0] = 1.0 r = 32 UV[comp_h // 2 - r:comp_h // 2 + r, comp_w // 2 - r:comp_w // 2 + r, 0] = 0.50 UV[comp_h // 2 - r:comp_h // 2 + r, comp_w // 2 - r:comp_w // 2 + r, 1] = 0.25 UV += np.random.uniform(0.0, 0.01, (comp_h, comp_w, 4)) UV[:, :, 2] = UV[:, :, 0] UV[:, :, 3] = UV[:, :, 1] self.pingpong = 1 self.compute = Program(compute_vertex, compute_fragment, 4) self.compute["params"] = P self.compute["texture"] = UV self.compute["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.compute["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.compute['dt'] = dt self.compute['dx'] = 1.0 / comp_w self.compute['dy'] = 1.0 / comp_h self.compute['dd'] = dd self.compute['pingpong'] = self.pingpong self.render = Program(render_vertex, render_fragment, 4) self.render["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.render["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.render["texture"] = self.compute["texture"] self.render['pingpong'] = self.pingpong self.fbo = FrameBuffer(self.compute["texture"], RenderBuffer(self.comp_size)) set_state(depth_test=False, clear_color='black') self._timer = app.Timer('auto', connect=self.update, start=True) self.show() def on_draw(self, event): with self.fbo: set_viewport(0, 0, *self.comp_size) self.compute["texture"].interpolation = 'nearest' self.compute.draw('triangle_strip') clear(color=True) set_viewport(0, 0, *self.physical_size) self.render["texture"].interpolation = 'linear' self.render.draw('triangle_strip') self.pingpong = 1 - self.pingpong self.compute["pingpong"] = self.pingpong self.render["pingpong"] = self.pingpong def on_resize(self, event): set_viewport(0, 0, *self.physical_size)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, title='Framebuffer post-processing', keys='interactive', size=(512, 512)) def on_initialize(self, event): # Build cube data # -------------------------------------- vertices, indices, _ = create_cube() vertices = VertexBuffer(vertices) self.indices = IndexBuffer(indices) # Build program # -------------------------------------- view = np.eye(4, dtype=np.float32) model = np.eye(4, dtype=np.float32) translate(view, 0, 0, -7) self.phi, self.theta = 60, 20 rotate(model, self.theta, 0, 0, 1) rotate(model, self.phi, 0, 1, 0) self.cube = Program(cube_vertex, cube_fragment) self.cube.bind(vertices) self.cube["texture"] = checkerboard() self.cube["texture"].interpolation = 'linear' self.cube['model'] = model self.cube['view'] = view color = Texture2D((512, 512, 3), interpolation='linear') self.framebuffer = FrameBuffer(color, RenderBuffer((512, 512))) self.quad = Program(quad_vertex, quad_fragment, count=4) self.quad['texcoord'] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.quad['position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.quad['texture'] = color # OpenGL and Timer initalization # -------------------------------------- set_state(clear_color=(.3, .3, .35, 1), depth_test=True) self.timer = app.Timer('auto', connect=self.on_timer, start=True) self._set_projection(self.size) def on_draw(self, event): with self.framebuffer: set_viewport(0, 0, 512, 512) clear(color=True, depth=True) set_state(depth_test=True) self.cube.draw('triangles', self.indices) set_viewport(0, 0, *self.size) clear(color=True) set_state(depth_test=False) self.quad.draw('triangle_strip') def on_resize(self, event): self._set_projection(event.size) def _set_projection(self, size): width, height = size set_viewport(0, 0, width, height) projection = perspective(30.0, width / float(height), 2.0, 10.0) self.cube['projection'] = projection def on_timer(self, event): self.theta += .5 self.phi += .5 model = np.eye(4, dtype=np.float32) rotate(model, self.theta, 0, 0, 1) rotate(model, self.phi, 0, 1, 0) self.cube['model'] = model self.update()
class Renderer2D: def __init__(self): self.default_prog = None self.fbuffer_prog = None self.texture_prog = None self.line_prog = None self.fbuffer = None self.fbuffer_tex_front = None self.fbuffer_tex_back = None self.vertex_buffer = None self.index_buffer = None ## Renderer Globals: USEFUL CONSTANTS self.COLOR_WHITE = (1, 1, 1, 1) self.COLOR_BLACK = (0, 0, 0, 1) self.COLOR_DEFAULT_BG = (0.8, 0.8, 0.8, 1.0) ## Renderer Globals: STYLE/MATERIAL PROPERTIES ## self.background_color = self.COLOR_DEFAULT_BG self.fill_color = self.COLOR_WHITE self.fill_enabled = True self.stroke_color = self.COLOR_BLACK self.stroke_enabled = True self.tint_color = self.COLOR_BLACK self.tint_enabled = False ## Renderer Globals: Curves self.stroke_weight = 1 self.stroke_cap = 2 self.stroke_join = 0 ## Renderer Globals ## VIEW MATRICES, ETC ## self.viewport = None self.texture_viewport = None self.transform_matrix = np.identity(4) self.modelview_matrix = np.identity(4) self.projection_matrix = np.identity(4) ## Renderer Globals: RENDERING self.draw_queue = [] def initialize_renderer(self): self.fbuffer = FrameBuffer() vertices = np.array( [[-1.0, -1.0], [+1.0, -1.0], [-1.0, +1.0], [+1.0, +1.0]], np.float32) texcoords = np.array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]], dtype=np.float32) self.fbuf_vertices = VertexBuffer(data=vertices) self.fbuf_texcoords = VertexBuffer(data=texcoords) self.fbuffer_prog = Program(src_fbuffer.vert, src_fbuffer.frag) self.fbuffer_prog['texcoord'] = self.fbuf_texcoords self.fbuffer_prog['position'] = self.fbuf_vertices self.vertex_buffer = VertexBuffer() self.index_buffer = IndexBuffer() self.default_prog = Program(src_default.vert, src_default.frag) self.texture_prog = Program(src_texture.vert, src_texture.frag) self.texture_prog['texcoord'] = self.fbuf_texcoords self.reset_view() def reset_view(self): self.viewport = ( 0, 0, int(builtins.width * builtins.pixel_x_density), int(builtins.height * builtins.pixel_y_density), ) self.texture_viewport = ( 0, 0, builtins.width, builtins.height, ) gloo.set_viewport(*self.viewport) cz = (builtins.height / 2) / math.tan(math.radians(30)) self.projection_matrix = matrix.perspective_matrix( math.radians(60), builtins.width / builtins.height, 0.1 * cz, 10 * cz) self.modelview_matrix = matrix.translation_matrix(-builtins.width / 2, \ builtins.height / 2, \ -cz) self.modelview_matrix = self.modelview_matrix.dot( matrix.scale_transform(1, -1, 1)) self.transform_matrix = np.identity(4) self.default_prog['modelview'] = self.modelview_matrix.T.flatten() self.default_prog['projection'] = self.projection_matrix.T.flatten() self.texture_prog['modelview'] = self.modelview_matrix.T.flatten() self.texture_prog['projection'] = self.projection_matrix.T.flatten() self.line_prog = Program(src_line.vert, src_line.frag) self.line_prog['modelview'] = self.modelview_matrix.T.flatten() self.line_prog['projection'] = self.projection_matrix.T.flatten() self.line_prog["height"] = builtins.height self.fbuffer_tex_front = Texture2D( (builtins.height, builtins.width, 3)) self.fbuffer_tex_back = Texture2D((builtins.height, builtins.width, 3)) for buf in [self.fbuffer_tex_front, self.fbuffer_tex_back]: self.fbuffer.color_buffer = buf with self.fbuffer: self.clear() def clear(self, color=True, depth=True): """Clear the renderer background.""" gloo.set_state(clear_color=self.background_color) gloo.clear(color=color, depth=depth) def _comm_toggles(self, state=True): gloo.set_state(blend=state) gloo.set_state(depth_test=state) if state: gloo.set_state(blend_func=('src_alpha', 'one_minus_src_alpha')) gloo.set_state(depth_func='lequal') @contextmanager def draw_loop(self): """The main draw loop context manager. """ self.transform_matrix = np.identity(4) self.default_prog['modelview'] = self.modelview_matrix.T.flatten() self.default_prog['projection'] = self.projection_matrix.T.flatten() self.fbuffer.color_buffer = self.fbuffer_tex_back with self.fbuffer: gloo.set_viewport(*self.texture_viewport) self._comm_toggles() self.fbuffer_prog['texture'] = self.fbuffer_tex_front self.fbuffer_prog.draw('triangle_strip') yield self.flush_geometry() self.transform_matrix = np.identity(4) gloo.set_viewport(*self.viewport) self._comm_toggles(False) self.clear() self.fbuffer_prog['texture'] = self.fbuffer_tex_back self.fbuffer_prog.draw('triangle_strip') self.fbuffer_tex_front, self.fbuffer_tex_back = self.fbuffer_tex_back, self.fbuffer_tex_front def _transform_vertices(self, vertices, local_matrix, global_matrix): return np.dot(np.dot(vertices, local_matrix.T), global_matrix.T)[:, :3] def _add_to_draw_queue_simple(self, stype, vertices, idx, fill, stroke, stroke_weight, stroke_cap, stroke_join): """Adds shape of stype to draw queue """ if stype == 'lines': self.draw_queue.append( (stype, (vertices, idx, stroke, stroke_weight, stroke_cap, stroke_join))) else: self.draw_queue.append((stype, (vertices, idx, fill))) def render(self, shape): fill = shape.fill.normalized if shape.fill else None stroke = shape.stroke.normalized if shape.stroke else None stroke_weight = shape.stroke_weight stroke_cap = shape.stroke_cap stroke_join = shape.stroke_join obj_list = get_render_primitives(shape) for obj in obj_list: stype, vertices, idx = obj # Transform vertices vertices = self._transform_vertices( np.hstack([vertices, np.ones((len(vertices), 1))]), shape._matrix, self.transform_matrix) # Add to draw queue self._add_to_draw_queue_simple(stype, vertices, idx, fill, stroke, stroke_weight, stroke_cap, stroke_join) def flush_geometry(self): """Flush all the shape geometry from the draw queue to the GPU. """ current_queue = [] for index, shape in enumerate(self.draw_queue): current_shape = self.draw_queue[index][0] current_queue.append(self.draw_queue[index][1]) if current_shape == "lines": self.render_line(current_queue) else: self.render_default(current_shape, current_queue) current_queue = [] self.draw_queue = [] def render_default(self, draw_type, draw_queue): # 1. Get the maximum number of vertices persent in the shapes # in the draw queue. # if len(draw_queue) == 0: return num_vertices = 0 for vertices, _, _ in draw_queue: num_vertices = num_vertices + len(vertices) # 2. Create empty buffers based on the number of vertices. # data = np.zeros(num_vertices, dtype=[('position', np.float32, 3), ('color', np.float32, 4)]) # 3. Loop through all the shapes in the geometry queue adding # it's information to the buffer. # sidx = 0 draw_indices = [] for vertices, idx, color in draw_queue: num_shape_verts = len(vertices) data['position'][sidx:(sidx + num_shape_verts), ] = vertices color_array = np.array([color] * num_shape_verts) data['color'][sidx:sidx + num_shape_verts, :] = color_array draw_indices.append(sidx + idx) sidx += num_shape_verts self.vertex_buffer.set_data(data) self.index_buffer.set_data(np.hstack(draw_indices)) # 4. Bind the buffer to the shader. # self.default_prog.bind(self.vertex_buffer) # 5. Draw the shape using the proper shape type and get rid of # the buffers. # self.default_prog.draw(draw_type, indices=self.index_buffer) def render_line(self, queue): ''' This rendering algorithm works by tesselating the line into multiple triangles. Reference: https://blog.mapbox.com/drawing-antialiased-lines-with-opengl-8766f34192dc ''' if len(queue) == 0: return pos = [] posPrev = [] posCurr = [] posNext = [] markers = [] side = [] linewidth = [] join_type = [] cap_type = [] color = [] for line in queue: if len(line[1]) == 0: continue for segment in line[1]: for i in range( len(segment) - 1): # the data is sent to renderer in line segments for j in [0, 0, 1, 0, 1, 1]: # all the vertices of triangles if i + j - 1 >= 0: posPrev.append(line[0][segment[i + j - 1]]) else: posPrev.append(line[0][segment[i + j]]) if i + j + 1 < len(segment): posNext.append(line[0][segment[i + j + 1]]) else: posNext.append(line[0][segment[i + j]]) posCurr.append(line[0][segment[i + j]]) markers.extend( [1.0, -1.0, -1.0, -1.0, 1.0, -1.0]) # Is the vertex up/below the line segment side.extend([1.0, 1.0, -1.0, 1.0, -1.0, -1.0]) # Left or right side of the segment pos.extend([line[0][segment[i]]] * 6) # Left vertex of each segment linewidth.extend([line[3]] * 6) join_type.extend([line[5]] * 6) cap_type.extend([line[4]] * 6) color.extend([line[2]] * 6) if len(pos) == 0: return posPrev = np.array(posPrev, np.float32) posCurr = np.array(posCurr, np.float32) posNext = np.array(posNext, np.float32) markers = np.array(markers, np.float32) side = np.array(side, np.float32) pos = np.array(pos, np.float32) linewidth = np.array(linewidth, np.float32) join_type = np.array(join_type, np.float32) cap_type = np.array(cap_type, np.float32) color = np.array(color, np.float32) self.line_prog['pos'] = gloo.VertexBuffer(pos) self.line_prog['posPrev'] = gloo.VertexBuffer(posPrev) self.line_prog['posCurr'] = gloo.VertexBuffer(posCurr) self.line_prog['posNext'] = gloo.VertexBuffer(posNext) self.line_prog['marker'] = gloo.VertexBuffer(markers) self.line_prog['side'] = gloo.VertexBuffer(side) self.line_prog['linewidth'] = gloo.VertexBuffer(linewidth) self.line_prog['join_type'] = gloo.VertexBuffer(join_type) self.line_prog['cap_type'] = gloo.VertexBuffer(cap_type) self.line_prog["color"] = gloo.VertexBuffer(color) self.line_prog.draw('triangles') def render_image(self, image, location, size): """Render the image. :param image: image to be rendered :type image: builtins.Image :param location: top-left corner of the image :type location: tuple | list | builtins.Vector :param size: target size of the image to draw. :type size: tuple | list | builtins.Vector """ self.flush_geometry() self.texture_prog[ 'fill_color'] = self.tint_color if self.tint_enabled else self.COLOR_WHITE self.texture_prog['transform'] = self.transform_matrix.T.flatten() x, y = location sx, sy = size imx, imy = image.size data = np.zeros(4, dtype=[('position', np.float32, 2), ('texcoord', np.float32, 2)]) data['texcoord'] = np.array( [[0.0, 1.0], [1.0, 1.0], [0.0, 0.0], [1.0, 0.0]], dtype=np.float32) data['position'] = np.array( [[x, y + sy], [x + sx, y + sy], [x, y], [x + sx, y]], dtype=np.float32) self.texture_prog['texture'] = image._texture self.texture_prog.bind(VertexBuffer(data)) self.texture_prog.draw('triangle_strip') def cleanup(self): """Run the clean-up routine for the renderer. This method is called when all drawing has been completed and the program is about to exit. """ self.default_prog.delete() self.fbuffer_prog.delete() self.line_prog.delete() self.fbuffer.delete()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, title="Conway game of life", size=(512, 512), keys='interactive') self._timer = app.Timer('auto', connect=self.update, start=True) def on_initialize(self, event): # Build programs # -------------- self.comp_size = (512, 512) size = self.comp_size + (4, ) Z = np.zeros(size, dtype=np.float32) Z[...] = np.random.randint(0, 2, size) Z[:256, :256, :] = 0 gun = """ ........................O........... ......................O.O........... ............OO......OO............OO ...........O...O....OO............OO OO........O.....O...OO.............. OO........O...O.OO....O.O........... ..........O.....O.......O........... ...........O...O.................... ............OO......................""" x, y = 0, 0 for i in range(len(gun)): if gun[i] == '\n': y += 1 x = 0 elif gun[i] == 'O': Z[y, x] = 1 x += 1 self.pingpong = 1 self.compute = Program(compute_vertex, compute_fragment, 4) self.compute["texture"] = Z self.compute["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.compute["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.compute['dx'] = 1.0 / size[1] self.compute['dy'] = 1.0 / size[0] self.compute['pingpong'] = self.pingpong self.render = Program(render_vertex, render_fragment, 4) self.render["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.render["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.render["texture"] = self.compute["texture"] self.render['pingpong'] = self.pingpong self.fbo = FrameBuffer(self.compute["texture"], DepthBuffer(self.comp_size)) set_state(depth_test=False, clear_color='black') def on_draw(self, event): with self.fbo: set_viewport(0, 0, *self.comp_size) self.compute["texture"].interpolation = 'nearest' self.compute.draw('triangle_strip') clear() set_viewport(0, 0, *self.size) self.render["texture"].interpolation = 'linear' self.render.draw('triangle_strip') self.pingpong = 1 - self.pingpong self.compute["pingpong"] = self.pingpong self.render["pingpong"] = self.pingpong def on_reshape(self, event): set_viewport(0, 0, *event.size)
class TSV_TEST_GLOO(object): def __init__(self, channels=10, timepoints=10000, srate=1017.25): super(TSV_TEST_GLOO, self).__init__() self.n_channels = channels self.n_timepoints = timepoints self.srate = srate self.magrin = 10 self.ticksize = 10 self.height = 0.0 self.width = 0.0 self._is_init = False self.is_on_draw = False self._init_data() # Build program & data # ---------------------------------------- self.data_pgr = Program(vertex, fragment, count=timepoints) #self.data_pgr'color'] = [ (1,0,0,1), (0,1,0,1), (0,0,1,1), (1,1,0,1) ] #self.data_pgr['position'] = [ (-1,-1), (-1,+1), (+1,-1), (+1,+1) ] #self.program['scale'] = 1.0 self.xgrid_pgr = Program(grid_vertex, grid_fragment) self.xgrid_pgr['position'] = self.init_xgrid() self.xgrid_pgr['color'] = np.array([0.0, 0.0, 0.0, 1.0], dtype=np.float32) self.ygrid_pgr = Program(grid_vertex, grid_fragment) self.ygrid_pgr['position'] = self.init_ygrid() self.ygrid_pgr['color'] = np.array([0.50, 0.50, 0.50, 1.0], dtype=np.float32) # v = np.arange(10) # MeshData(vertices=None, faces=None, edges=None, vertex_colors=None, face_colors=None) def _init_data(self): import numpy as np ch = self.n_channels n = self.n_timepoints self.timepoints = np.arange(n, dtype=np.float32) / self.srate self.data = np.zeros((ch, n), dtype=np.float32) self.plot_data = np.zeros((self.timepoints.size, 2), dtype=np.float32) self.plot_data[:, 0] = self.timepoints #x-value for i in range(ch): self.data[i, :] = np.sin(self.timepoints * (2 * i + 1) * 2 * np.pi) self.plot_color = np.repeat(np.random.uniform(size=(ch, 4), low=.5, high=.9), 1, axis=0).astype(np.float32) self.plot_color[:, -2] = 1.0 self.plot_color[:, -1] = 0.0 self.data_min_max = np.array( [self.data.min(axis=0), self.data.max(axis=0)]).T #-- ck for min == max min_eq_max_idx = np.array(self.data_min_max.ptp(axis=1) == 0) if min_eq_max_idx.size: self.data_min_max[min_eq_max_idx] += [-1.0, 1.0] def init_xgrid(self): # x axes grid; time v = np.zeros((40, 2), dtype=np.float32) v[0::2, 0] = np.array(np.linspace(-1.0, 1.0, 20), dtype=np.float32) v[1::2, 0] = np.array(np.linspace(-1.0, 1.0, 20), dtype=np.float32) v[0::2, 1] = -1.0 v[1::2, 1] = 1.0 #x = np.arange(-1, 1, 0.1,dtype=np.float32) #y = np.arange(-1, 1, 0.1,dtype=np.float32) #xx, yy = np.meshgrid(x, y) #print v return v def init_ygrid(self): # y axes grid; time v = np.zeros((40, 2), dtype=np.float32) v[0::2, 1] = np.array(np.linspace(-1.0, 1.0, 20), dtype=np.float32) v[1::2, 1] = np.array(np.linspace(-1.0, 1.0, 20), dtype=np.float32) v[0::2, 0] = -1.0 v[1::2, 0] = 1.0 #x = np.arange(-1, 1, 0.1,dtype=np.float32) #y = np.arange(-1, 1, 0.1,dtype=np.float32) #xx, yy = np.meshgrid(x, y) return v def display(self): if self.is_on_draw: return self.is_on_draw = True if not self._is_init: # self.InitGL() #glut.glutInit(sys.argv) self._is_init = True print "DONE GLOO INIT " gl.glClearColor(1, 1, 1, 1) gl.glClear(gl.GL_COLOR_BUFFER_BIT) #---------------------------------------------------------- tw0 = time.clock() t0 = time.time() #---start sub plots dborder = self.magrin + self.ticksize #--- start first channel at top # !! transpose pixe border magrin to plot coordinates dh = int(self.height / self.data.shape[0]) - 2 * dborder if dh < dborder: dh = int(self.height / self.data.shape[0]) dborder = dh * 0.1 dh -= 2 * dborder w0 = dborder wd = self.width - dborder * 2 if (w0 < 1) or (wd < 50): self.is_on_draw = False return False gl.glLineWidth(2) xmin = self.timepoints[0] xmax = self.timepoints[-1] #-- copy data mvp = np.zeros((self.n_channels, 4), dtype=np.float32) mvp[:, 0] = dborder mvp[:, 1] = np.arange(self.n_channels) * (dh + 2 * dborder) mvp[0, 1] = dborder mvp[:, 2] = wd mvp[:, 3] = dh idx = 0 # glEnable(GL_SCISSOR_TEST); #glViewport(mvp[idx,0],mvp[idx,1],mvp[idx,2],mvp[idx,3]) for idx in range(self.n_channels): self.plot_data[:, 1] = self.data[ idx, :] #!!!!TODO reshape on the fly sub array self.data_pgr['data2d'].set_data(self.plot_data) # self.data_pgr['color'] = self.plot_color[idx,:] self.data_pgr['TrafoMatrix'].set_data( jtr.ortho(xmin, xmax, self.data_min_max[idx, 0], self.data_min_max[idx, 1], 0, 1)) #---TODO viewport to GLS TrafoMatrix like C++ example or Perspective Matrix as GeometryShader split x,y into VBOs cp only y7signal value #--- set border scissor gl.glViewport(mvp[idx, 0], mvp[idx, 1], mvp[idx, 2], mvp[idx, 3]) #self.data_pgr.draw(gl.GL_LINE_STRIP) self.data_pgr.draw('line_strip') self.xgrid_pgr.draw(gl.GL_LINES) self.ygrid_pgr.draw(gl.GL_LINES) gl.glViewport(0, 0, self.width, self.height) #glMatrixMode(GL_PROJECTION) #glLoadIdentity() # print"\n\n" #glScissor( # margin + ticksize, # margin + ticksize, # window_width - margin * 2 - ticksize, # window_height - margin * 2 - ticksize #); #self.set_viewport(w0,wd,h0,dh) #self.set_window(xmin,xmax,ymin,ymax ) # if self.do_plot_axis: #--- draw zero line # glLineWidth(1) # glColor4f(0.0,0.0,0.0,0.0) # self.set_window(xmin,xmax,self.data_min_max[idx,0],self.data_min_max[idx,1]) # dy = self.data_min_max[idx,0] + self.data_min_max[idx,1]/2 # y0 = self.data_min_max[idx,0] - self.data_min_max[idx,0] # self.data_min_max[idx,0],self.data_min_max[idx,1 # glBegin(GL_LINES) #glVertex3f(-1.0,0.50,0.0) #glVertex3f(1.0,0.50,0.0) # glVertex2f(xmin,dy) # glVertex2f(xmax,dy) # glEnd() #glRasterPos2f( 1,mvp[idx,1]+mvp[idx,3]/2) # glRasterPos2f( xmin,dy) # glColor4f(1.0,0.0,0.0,1.0) # for idx_chr in str(idx): #glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, ord(idx) ) # glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord( str(idx_chr) )) self.is_on_draw = False td = time.time() - t0 tdw = time.clock() - tw0 print "done draw Time: %10.3f WallClk: %10.3f \n" % (td, tdw) def reshape(self, width, height): gl.glViewport(0, 0, width, height) #glLineWidth(4) #self.width = width #self.height = height #self.aspect = width/float(height) #gl.glViewport(0, 0, self.width, self.height) #gl.glEnable(GL_DEPTH_TEST) #gl.glDisable(GL_CULL_FACE) #gl.glClearColor(0.8, 0.8, 0.8,1.0) def keyboard(self, key, x, y): if key == '\033': sys.exit()
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, title="Conway game of life", size=(512, 512), keys='interactive') # Build programs # -------------- self.comp_size = self.size size = self.comp_size + (4,) Z = np.zeros(size, dtype=np.float32) Z[...] = np.random.randint(0, 2, size) Z[:256, :256, :] = 0 gun = """ ........................O........... ......................O.O........... ............OO......OO............OO ...........O...O....OO............OO OO........O.....O...OO.............. OO........O...O.OO....O.O........... ..........O.....O.......O........... ...........O...O.................... ............OO......................""" x, y = 0, 0 for i in range(len(gun)): if gun[i] == '\n': y += 1 x = 0 elif gun[i] == 'O': Z[y, x] = 1 x += 1 self.pingpong = 1 self.compute = Program(compute_vertex, compute_fragment, 4) self.compute["texture"] = Z self.compute["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.compute["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.compute['dx'] = 1.0 / size[1] self.compute['dy'] = 1.0 / size[0] self.compute['pingpong'] = self.pingpong self.render = Program(render_vertex, render_fragment, 4) self.render["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.render["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.render["texture"] = self.compute["texture"] self.render['pingpong'] = self.pingpong self.fbo = FrameBuffer(self.compute["texture"], RenderBuffer(self.comp_size)) set_state(depth_test=False, clear_color='black') self._timer = app.Timer('auto', connect=self.update, start=True) self.show() def on_draw(self, event): with self.fbo: set_viewport(0, 0, *self.comp_size) self.compute["texture"].interpolation = 'nearest' self.compute.draw('triangle_strip') clear() set_viewport(0, 0, *self.physical_size) self.render["texture"].interpolation = 'linear' self.render.draw('triangle_strip') self.pingpong = 1 - self.pingpong self.compute["pingpong"] = self.pingpong self.render["pingpong"] = self.pingpong
class TSV_TEST_GLOO(object): def __init__ (self, channels=10,timepoints=10000,srate=1017.25): super(TSV_TEST_GLOO, self).__init__() self.n_channels = channels self.n_timepoints = timepoints self.srate = srate self.magrin = 10 self.ticksize = 10 self.height = 0.0 self.width = 0.0 self._is_init = False self.is_on_draw = False self._init_data() # Build program & data # ---------------------------------------- self.data_pgr = Program(vertex, fragment, count=timepoints) #self.data_pgr'color'] = [ (1,0,0,1), (0,1,0,1), (0,0,1,1), (1,1,0,1) ] #self.data_pgr['position'] = [ (-1,-1), (-1,+1), (+1,-1), (+1,+1) ] #self.program['scale'] = 1.0 self.xgrid_pgr = Program(grid_vertex, grid_fragment) self.xgrid_pgr['position'] = self.init_xgrid() self.xgrid_pgr['color'] = np.array([0.0,0.0,0.0,1.0],dtype=np.float32) self.ygrid_pgr = Program(grid_vertex, grid_fragment) self.ygrid_pgr['position'] = self.init_ygrid() self.ygrid_pgr['color'] = np.array([0.50,0.50,0.50,1.0],dtype=np.float32) # v = np.arange(10) # MeshData(vertices=None, faces=None, edges=None, vertex_colors=None, face_colors=None) def _init_data(self): import numpy as np ch = self.n_channels n = self.n_timepoints self.timepoints = np.arange(n,dtype=np.float32) / self.srate self.data = np.zeros((ch,n), dtype=np.float32) self.plot_data = np.zeros((self.timepoints.size ,2), dtype=np.float32) self.plot_data[:,0]= self.timepoints #x-value for i in range( ch ): self.data[i,:] = np.sin(self.timepoints * (2 * i+1) * 2* np.pi) self.plot_color = np.repeat(np.random.uniform( size=(ch,4) ,low=.5, high=.9),1,axis=0).astype(np.float32) self.plot_color[:,-2] = 1.0 self.plot_color[:,-1] = 0.0 self.data_min_max = np.array( [ self.data.min(axis=0),self.data.max(axis=0) ] ).T #-- ck for min == max min_eq_max_idx = np.array( self.data_min_max.ptp( axis=1 )==0 ) if min_eq_max_idx.size: self.data_min_max[ min_eq_max_idx] += [-1.0,1.0] def init_xgrid(self): # x axes grid; time v = np.zeros((40,2),dtype=np.float32) v[0::2,0] = np.array( np.linspace(-1.0,1.0,20) ,dtype=np.float32) v[1::2,0] = np.array( np.linspace(-1.0,1.0,20) ,dtype=np.float32) v[0::2,1] = -1.0 v[1::2,1] = 1.0 #x = np.arange(-1, 1, 0.1,dtype=np.float32) #y = np.arange(-1, 1, 0.1,dtype=np.float32) #xx, yy = np.meshgrid(x, y) #print v return v def init_ygrid(self): # y axes grid; time v = np.zeros((40,2),dtype=np.float32) v[0::2,1] = np.array( np.linspace(-1.0,1.0,20) ,dtype=np.float32) v[1::2,1] = np.array( np.linspace(-1.0,1.0,20) ,dtype=np.float32) v[0::2,0] = -1.0 v[1::2,0] = 1.0 #x = np.arange(-1, 1, 0.1,dtype=np.float32) #y = np.arange(-1, 1, 0.1,dtype=np.float32) #xx, yy = np.meshgrid(x, y) return v def display(self): if self.is_on_draw: return self.is_on_draw=True if not self._is_init: # self.InitGL() #glut.glutInit(sys.argv) self._is_init = True print"DONE GLOO INIT " gl.glClearColor(1,1,1,1) gl.glClear(gl.GL_COLOR_BUFFER_BIT) #---------------------------------------------------------- tw0 = time.clock() t0 = time.time() #---start sub plots dborder = self.magrin + self.ticksize #--- start first channel at top # !! transpose pixe border magrin to plot coordinates dh = int( self.height / self.data.shape[0] ) - 2 * dborder if dh < dborder: dh = int( self.height / self.data.shape[0] ) dborder= dh * 0.1 dh -= 2 * dborder w0 = dborder wd = self.width - dborder *2 if (w0 < 1) or (wd < 50) : self.is_on_draw=False return False gl.glLineWidth(2) xmin = self.timepoints[0] xmax = self.timepoints[-1] #-- copy data mvp = np.zeros( (self.n_channels,4),dtype=np.float32) mvp[:,0]= dborder mvp[:,1]= np.arange(self.n_channels) * (dh + 2*dborder) mvp[0,1]= dborder mvp[:,2]= wd mvp[:,3]= dh idx = 0 # glEnable(GL_SCISSOR_TEST); #glViewport(mvp[idx,0],mvp[idx,1],mvp[idx,2],mvp[idx,3]) for idx in range( self.n_channels ): self.plot_data[:,1] = self.data[idx,:] #!!!!TODO reshape on the fly sub array self.data_pgr['data2d'].set_data( self.plot_data) # self.data_pgr['color'] = self.plot_color[idx,:] self.data_pgr['TrafoMatrix'].set_data( jtr.ortho(xmin,xmax,self.data_min_max[idx,0],self.data_min_max[idx,1],0,1) ) #---TODO viewport to GLS TrafoMatrix like C++ example or Perspective Matrix as GeometryShader split x,y into VBOs cp only y7signal value #--- set border scissor gl.glViewport(mvp[idx,0],mvp[idx,1],mvp[idx,2],mvp[idx,3]) #self.data_pgr.draw(gl.GL_LINE_STRIP) self.data_pgr.draw('line_strip') self.xgrid_pgr.draw(gl.GL_LINES) self.ygrid_pgr.draw(gl.GL_LINES) gl.glViewport(0, 0, self.width, self.height) #glMatrixMode(GL_PROJECTION) #glLoadIdentity() # print"\n\n" #glScissor( # margin + ticksize, # margin + ticksize, # window_width - margin * 2 - ticksize, # window_height - margin * 2 - ticksize #); #self.set_viewport(w0,wd,h0,dh) #self.set_window(xmin,xmax,ymin,ymax ) # if self.do_plot_axis: #--- draw zero line # glLineWidth(1) # glColor4f(0.0,0.0,0.0,0.0) # self.set_window(xmin,xmax,self.data_min_max[idx,0],self.data_min_max[idx,1]) # dy = self.data_min_max[idx,0] + self.data_min_max[idx,1]/2 # y0 = self.data_min_max[idx,0] - self.data_min_max[idx,0] # self.data_min_max[idx,0],self.data_min_max[idx,1 # glBegin(GL_LINES) #glVertex3f(-1.0,0.50,0.0) #glVertex3f(1.0,0.50,0.0) # glVertex2f(xmin,dy) # glVertex2f(xmax,dy) # glEnd() #glRasterPos2f( 1,mvp[idx,1]+mvp[idx,3]/2) # glRasterPos2f( xmin,dy) # glColor4f(1.0,0.0,0.0,1.0) # for idx_chr in str(idx): #glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, ord(idx) ) # glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord( str(idx_chr) )) self.is_on_draw=False td = time.time() - t0 tdw = time.clock() - tw0 print "done draw Time: %10.3f WallClk: %10.3f \n" % (td,tdw) def reshape(self,width,height): gl.glViewport(0, 0, width, height) #glLineWidth(4) #self.width = width #self.height = height #self.aspect = width/float(height) #gl.glViewport(0, 0, self.width, self.height) #gl.glEnable(GL_DEPTH_TEST) #gl.glDisable(GL_CULL_FACE) #gl.glClearColor(0.8, 0.8, 0.8,1.0) def keyboard(self, key, x, y ): if key == '\033': sys.exit( )
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, title="Grayscott Reaction-Diffusion", size=(512, 512), keys="interactive") self.scale = 4 self.comp_size = self.size comp_w, comp_h = self.comp_size dt = 1.0 dd = 1.5 species = { # name : [r_u, r_v, f, k] "Bacteria 1": [0.16, 0.08, 0.035, 0.065], "Bacteria 2": [0.14, 0.06, 0.035, 0.065], "Coral": [0.16, 0.08, 0.060, 0.062], "Fingerprint": [0.19, 0.05, 0.060, 0.062], "Spirals": [0.10, 0.10, 0.018, 0.050], "Spirals Dense": [0.12, 0.08, 0.020, 0.050], "Spirals Fast": [0.10, 0.16, 0.020, 0.050], "Unstable": [0.16, 0.08, 0.020, 0.055], "Worms 1": [0.16, 0.08, 0.050, 0.065], "Worms 2": [0.16, 0.08, 0.054, 0.063], "Zebrafish": [0.16, 0.08, 0.035, 0.060], } P = np.zeros((comp_h, comp_w, 4), dtype=np.float32) P[:, :] = species["Unstable"] UV = np.zeros((comp_h, comp_w, 4), dtype=np.float32) UV[:, :, 0] = 1.0 r = 32 UV[comp_h / 2 - r : comp_h / 2 + r, comp_w / 2 - r : comp_w / 2 + r, 0] = 0.50 UV[comp_h / 2 - r : comp_h / 2 + r, comp_w / 2 - r : comp_w / 2 + r, 1] = 0.25 UV += np.random.uniform(0.0, 0.01, (comp_h, comp_w, 4)) UV[:, :, 2] = UV[:, :, 0] UV[:, :, 3] = UV[:, :, 1] self.pingpong = 1 self.compute = Program(compute_vertex, compute_fragment, 4) self.compute["params"] = P self.compute["texture"] = UV self.compute["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.compute["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.compute["dt"] = dt self.compute["dx"] = 1.0 / comp_w self.compute["dy"] = 1.0 / comp_h self.compute["dd"] = dd self.compute["pingpong"] = self.pingpong self.render = Program(render_vertex, render_fragment, 4) self.render["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self.render["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.render["texture"] = self.compute["texture"] self.render["pingpong"] = self.pingpong self.fbo = FrameBuffer(self.compute["texture"], RenderBuffer(self.comp_size)) set_state(depth_test=False, clear_color="black") self._timer = app.Timer("auto", connect=self.update, start=True) self.show() def on_draw(self, event): with self.fbo: set_viewport(0, 0, *self.comp_size) self.compute["texture"].interpolation = "nearest" self.compute.draw("triangle_strip") clear(color=True) set_viewport(0, 0, *self.physical_size) self.render["texture"].interpolation = "linear" self.render.draw("triangle_strip") self.pingpong = 1 - self.pingpong self.compute["pingpong"] = self.pingpong self.render["pingpong"] = self.pingpong def on_resize(self, event): set_viewport(0, 0, *self.physical_size)
class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, size=(512, 512), keys='interactive') self.image = Program(image_vertex, image_fragment, 4) self.image['position'] = (-1, -1), (-1, +1), (+1, -1), (+1, +1) self.image['texcoord'] = (0, 0), (0, +1), (+1, 0), (+1, +1) self.image['vmin'] = +0.0 self.image['vmax'] = +1.0 self.image['cmap'] = 0 # Colormap index to use self.image['colormaps'] = colormaps self.image['n_colormaps'] = colormaps.shape[0] self.image['image'] = I.astype('float32') self.image['image'].interpolation = 'linear' set_viewport(0, 0, *self.physical_size) self.lines = Program(lines_vertex, lines_fragment) self.lines["position"] = np.zeros((4+4+514+514, 2), np.float32) color = np.zeros((4+4+514+514, 4), np.float32) color[1:1+2, 3] = 0.25 color[5:5+2, 3] = 0.25 color[9:9+512, 3] = 0.5 color[523:523+512, 3] = 0.5 self.lines["color"] = color set_state(clear_color='white', blend=True, blend_func=('src_alpha', 'one_minus_src_alpha')) self.show() def on_resize(self, event): set_viewport(0, 0, *event.physical_size) def on_draw(self, event): clear(color=True, depth=True) self.image.draw('triangle_strip') self.lines.draw('line_strip') def on_mouse_move(self, event): x, y = event.pos w, h = self.size # Make sure the mouse isn't outside of the viewport. x = max(0, min(x, w - 1)) y = max(0, min(y, h - 1)) yf = 1 - y/(h/2.) xf = x/(w/2.) - 1 x_norm = (x*512)//w y_norm = (y*512)//h P = np.zeros((4+4+514+514, 2), np.float32) x_baseline = P[:4] y_baseline = P[4:8] x_profile = P[8:522] y_profile = P[522:] x_baseline[...] = (-1, yf), (-1, yf), (1, yf), (1, yf) y_baseline[...] = (xf, -1), (xf, -1), (xf, 1), (xf, 1) x_profile[1:-1, 0] = np.linspace(-1, 1, 512) x_profile[1:-1, 1] = yf+0.15*I[y_norm, :] x_profile[0] = x_profile[1] x_profile[-1] = x_profile[-2] y_profile[1:-1, 0] = xf+0.15*I[:, x_norm] y_profile[1:-1, 1] = np.linspace(-1, 1, 512) y_profile[0] = y_profile[1] y_profile[-1] = y_profile[-2] self.lines["position"] = P self.update()