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()
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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()