class MyController(Controller): def init(self): Controller.init(self) self.shaperenderer = ShapeRenderer(self.camera) self.shaperenderer.gl_init() self.first = True self.frame_buffer = Framebuffer(self.camera, self.camera.screensize, record_mode=Framebuffer.RECORD_BLIT) self.frame_buffer.init() shape = Rectangle() texture = NumpyTexture(np.random.random_sample(4*10000).reshape(100,100,4)) texture.gl_init() self.shaperenderer.draw_instance(ShapeInstance(shape, **{ 'size': (200,200), 'position': (100,200), 'color': [0,0,0,1], 'border': { 'size': 10, 'color': [1,0,0,1], }, 'texture': self.frame_buffer })) self.shaperenderer.draw_instance(ShapeInstance(shape, (200,200),(300,100), border={ 'size': 20, 'color': [1,1,0,0.5], })) def run(self): self.frame_buffer.use() self.shaperenderer.render() self.frame_buffer.unuse() self.frame_buffer.render()
def gl_init(self): self.framebuffer = Framebuffer( self.plotter.camera, self.size, capture_size=(self.INNER_SCALING * self.size[0], self.INNER_SCALING * self.size[1]), clear_color=[1,1,1,1], multisampling = 8, blit_texture=True ) self.framebuffer.init() self.framebuffer.inner_camera.set_scaling((self.size[0], self.size[1])) self.framebuffer.inner_camera.set_screensize((self.INNER_SCALING * self.size[0], self.INNER_SCALING * self.size[1])) self.font_renderer = FontRenderer() self.font_renderer.set_camera(self.framebuffer.inner_camera) self.font_renderer.init() self.shape_renderer = ShapeRenderer(self.plotter.camera) self.shape_renderer.shapes['default_rectangle'] = Rectangle() self.shape_renderer.gl_init() self.plane = ShapeInstance('default_rectangle', **{ 'size': self.size, 'position': self.position, 'border': { 'size': 1, 'color': [0,0,0,1] }, 'color': [1,1,1,1], 'texture': self.framebuffer }) self.shape_renderer.draw_instance(self.plane)
def gl_init(self): program = Program() program.shaders.append(Shader(GL_VERTEX_SHADER, load_lib_file('glsl/shaperenderer/vert.glsl'))) program.shaders.append(Shader(GL_FRAGMENT_SHADER, load_lib_file('glsl/shaperenderer/frag.glsl'))) program.link() program.uniform('mat_camera', self.camera.get_matrix()) self.program = program border_program = Program() border_program.shaders.append(Shader(GL_VERTEX_SHADER, load_lib_file('glsl/shaperenderer/vert.glsl'))) border_program.shaders.append(Shader(GL_FRAGMENT_SHADER, load_lib_file('glsl/shaperenderer/border.frag.glsl'))) border_program.link() border_program.uniform('mat_camera', self.camera.get_matrix()) self.border_program = border_program self._borderframe = Framebuffer(self.camera, self.camera.screensize, clear_color=[0,0,0,0], blit_texture=True) self._borderframe.init()
class ShapeRenderer(object): def __init__(self, camera): self._instances = {} self._shape_vaos = {} self.on_instances_changed = Event() self.on_instances_changed.append(ShapeRenderer.update_shape_vaos) self.camera = camera self.shapes = {} def gl_init(self): program = Program() program.shaders.append(Shader(GL_VERTEX_SHADER, load_lib_file('glsl/shaperenderer/vert.glsl'))) program.shaders.append(Shader(GL_FRAGMENT_SHADER, load_lib_file('glsl/shaperenderer/frag.glsl'))) program.link() program.uniform('mat_camera', self.camera.get_matrix()) self.program = program border_program = Program() border_program.shaders.append(Shader(GL_VERTEX_SHADER, load_lib_file('glsl/shaperenderer/vert.glsl'))) border_program.shaders.append(Shader(GL_FRAGMENT_SHADER, load_lib_file('glsl/shaperenderer/border.frag.glsl'))) border_program.link() border_program.uniform('mat_camera', self.camera.get_matrix()) self.border_program = border_program self._borderframe = Framebuffer(self.camera, self.camera.screensize, clear_color=[0,0,0,0], blit_texture=True) self._borderframe.init() def update_shape_vaos(self, instance, show): """ creates a vao if the instance has a shape where we did not create an vao yet """ shape = self._shape(instance) shape_object_id = id(shape) if not shape_object_id in self._shape_vaos: self._shape_vaos[shape_object_id] = VertexArray({ 'vertex_position': VertexBuffer.from_numpy(shape.verticies), 'texture_coords': VertexBuffer.from_numpy(shape.texture_coords), }, self.program.attributes) def _shape(self, instance): shape = instance.shape if type(shape) is str: if not instance.shape in self.shapes: raise NameError('invalid shape id "{}". Available ids are {}'.format( instance.shape, ', '.join(self.shapes.keys()) )) shape = self.shapes[shape] return shape def draw_instance(self, instance): shape = self._shape(instance) shape_object_id = id(shape) if not shape_object_id in self._instances: self._instances[shape_object_id] = [] if not instance in self._instances[shape_object_id]: self._instances[shape_object_id].append(instance) self.on_instances_changed(self, instance, True) def erase_instance(self, instance): shape = self._shape(instance) shape_object_id = id(shape) if shape_object_id in self._instances: self._instances[shape_object_id].remove(instance) self.on_instances_changed(self, instance, False) def update_camera(self): # XXX # - clean me. maybe watch some events or so... self.program.uniform('mat_camera', self.camera.get_matrix()) self.border_program.uniform('mat_camera', self.camera.get_matrix()) self._borderframe.capture_size = self.camera.screensize def render(self): # Render border texture # XXX # - only do if neccessary. self._borderframe.use() self._render_borders() self._borderframe.unuse() self.program.use() glActiveTexture(GL_TEXTURE0); for shape_object_id, instances in self._instances.items(): self._shape_vaos[shape_object_id].bind() for instance in instances: # XXX # - define the exact behavior of mix_texture. if instance.texture is not None: self.program.uniform('mix_texture', 1) self.program.uniform('tex', 0) glBindTexture(GL_TEXTURE_2D, instance.texture.gl_texture_id) else: self.program.uniform('mix_texture', 0) glBindTexture(GL_TEXTURE_2D, 0) # XXX # - cache the modelview matrix modelview = ModelView() modelview.set_scaling(*instance.size) modelview.set_position(*instance.position) self.program.uniform('color', instance.color) self.program.uniform('mat_modelview', modelview.mat4) glDrawArrays(GL_TRIANGLES, 0, 6) self._shape_vaos[shape_object_id].unbind() self.program.unuse() # render borders # XXX # - only if neccessary self._borderframe.render() def _render_borders(self): """ renders a texture containing the borders of all shapes. """ # XXX # - read the old glBlendFunc value and restore it if neccessary. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.border_program.use() for shape_object_id, instances in self._instances.items(): self._shape_vaos[shape_object_id].bind() for instance in instances: border_size = instance.border['size'] if len(instance.border) > 0: glEnable(GL_BLEND) # XXX # - cache the modelview matrix modelview = ModelView() modelview.set_scaling(instance.size[0]+2*border_size, instance.size[1]+2*border_size) modelview.set_position(instance.position[0]-border_size, instance.position[1]-border_size) self.border_program.uniform('mat_modelview', modelview.mat4) self.border_program.uniform('color', instance.border['color']) glDrawArrays(GL_TRIANGLES, 0, 6) glDisable(GL_BLEND) # XXX # - cache the modelview matrix modelview = ModelView() modelview.set_scaling(*instance.size) modelview.set_position(*instance.position) self.border_program.uniform('color', [0,0,0,0]) self.border_program.uniform('mat_modelview', modelview.mat4) glDrawArrays(GL_TRIANGLES, 0, 6) self._shape_vaos[shape_object_id].unbind() self.border_program.unuse() glEnable(GL_BLEND)
class LegendWidget(PlotterWidget): INNER_SCALING = 16 def __init__(self, *args, **kwargs): self.font_renderer = None self.graphs = [] self.size = (400, 100) self.framebuffer = None self.shape_renderer = None self.position = (100, 100) if 'position' not in kwargs else kwargs['position'] self.grid = None self.plane = None self._render_frame = False self._is_clicked = False self._relative = (0, 0) def cursor(self, cursor): if self._is_clicked: self.position = (cursor[0] - self._relative[0], cursor[1] - self._relative[1]) self.plane.position = self.position def mouse(self, cursor, button, action, mod): if not self._is_clicked: is_clicked = ( cursor[0] > self.position[0] and cursor[0] < self.position[0] + self.size[0] and cursor[1] > self.position[1] and cursor[1] < self.position[1] + self.size[1]) if is_clicked: if button == 0 and action == 1: self._is_clicked = True self._relative = (cursor[0] - self.position[0], cursor[1] - self.position[1]) return False elif self._is_clicked and button == 0 and action == 0: self._is_clicked = False return False def gl_init(self): self.framebuffer = Framebuffer( self.plotter.camera, self.size, capture_size=(self.INNER_SCALING * self.size[0], self.INNER_SCALING * self.size[1]), clear_color=[1,1,1,1], multisampling = 8, blit_texture=True ) self.framebuffer.init() self.framebuffer.inner_camera.set_scaling((self.size[0], self.size[1])) self.framebuffer.inner_camera.set_screensize((self.INNER_SCALING * self.size[0], self.INNER_SCALING * self.size[1])) self.font_renderer = FontRenderer() self.font_renderer.set_camera(self.framebuffer.inner_camera) self.font_renderer.init() self.shape_renderer = ShapeRenderer(self.plotter.camera) self.shape_renderer.shapes['default_rectangle'] = Rectangle() self.shape_renderer.gl_init() self.plane = ShapeInstance('default_rectangle', **{ 'size': self.size, 'position': self.position, 'border': { 'size': 1, 'color': [0,0,0,1] }, 'color': [1,1,1,1], 'texture': self.framebuffer }) self.shape_renderer.draw_instance(self.plane) def _create_shape(self): self.font_renderer.clear_texts() if len(self.graphs) == 0: self.size = (10, 10) self._render_frame = True return offsetx = 50 yskip = 4 maxx = 0 y = 0 self.grid = [] gridy = 0 dirty = [] for gid, graph in self.graphs.items(): label = graph.label if hasattr(graph, 'label') and graph.label is not None else gid text = self.font_renderer.create_text(label, 12, (offsetx, y), enable_simple_tex=True) w, h = text.get_boxsize() self.grid.append([(0, gridy), (45, gridy + h)]) gridy += h dirty.append([graph, y, h+2]) y += h + yskip maxx = max(maxx, w) self.size = (maxx + offsetx, y+3+yskip) self.plane.size = self.size self.framebuffer.screensize = self.size self.framebuffer.capture_size = (int(self.INNER_SCALING * self.size[0]), int(self.INNER_SCALING * self.size[1])) self.framebuffer.init() self.font_renderer.set_camera(self.framebuffer.inner_camera) self.graph_shape_render = ShapeRenderer(self.framebuffer.inner_camera) self.graph_shape_render.gl_init() rect = Rectangle() for g, y, h in dirty: if g.draw_lines: self.graph_shape_render.draw_instance(ShapeInstance(rect, position=(10,y+6), size=(30,3), color=g.color, )) if g.draw_dots: self.graph_shape_render.draw_instance(ShapeInstance(rect, position=(22,y+4), size=(6,7), color=g.color, )) self._render_frame = True def run(self): graphs = self.plotter.graphs if graphs != self.graphs: self.graphs = graphs self._create_shape() def update_camera(self): self.shape_renderer.update_camera() def draw(self): if self._render_frame: self.font_renderer.set_camera(self.framebuffer.inner_camera) self.framebuffer.use() self.font_renderer.render() self.graph_shape_render.render() # for i, graph in enumerate(self.graphs.values()): # graph.render_legend_graph(self.plotter, self.plotter._plotframe.camera, self.framebuffer.inner_camera, *self.grid[i]) self.framebuffer.unuse() self._render_frame = False self.shape_renderer.render()