class Controller(): def __init__(self, camera=None): """ initializes basic controller events """ self.camera = camera self.on_init = Event() self.on_pre_cycle = Event() self.on_post_cycle = Event() self.on_request_cycle = Event() self.on_pre_render = Event() self.on_post_render = Event() self.on_render = Event() self.on_cycle = Event() self.on_mouse = Event() self.on_cursor = Event() self.on_destroy = Event() self.on_keyboard = Event() self.initialized = False self.host_controller = None self.cursor = (0,0) self.on_pre_render.append(self.clear_gl) def init(self): self.on_init(self) self.camera.on_change_matrix.append(self.camera_updated) self.initialized = True def camera_updated(self, camera): if self.host_controller is None: self.cycle() def clear_gl(self): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) def run(self): self.on_cycle() self.on_render() def cycle(self, keyboard_active=set(), keyboard_pressed=set(), cursor=(0,0)): self.on_pre_cycle(self) if len(keyboard_pressed) or len(keyboard_active): self.on_keyboard(keyboard_active, keyboard_pressed) if self.cursor != cursor: self.on_cursor(cursor) self.cursor = cursor self.on_pre_render() self.run() self.on_post_render() self.on_post_cycle()
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 = {}
class PlotTicker2(): TPS_COUNT = 20 """ simple object which can be attached to plotter on_pre_cycle event forcing the plotter to replot when time changes. """ def __init__(self, *tick_events): self.on_tick = Event() for tick_event in tick_events: self.on_tick.append(tick_event) self.pause = False self.start_time = time() self.tick_count = 0 self.ticks_per_second = 0 self._ticks_per_second_time = self.start_time self._ticks_per_second_ticks = 0 def __call__(self, plotter): if self.pause: return time_now = time() - self.start_time self.on_tick(self, time_now, self.tick_count, self.ticks_per_second) for graph in plotter.graphs.values(): if hasattr(graph, 'set_time'): graph.set_time(time_now) plotter.render_graphs = True if self.tick_count % self.TPS_COUNT == 0: self.ticks_per_second = (self.tick_count-self._ticks_per_second_ticks)/(time() - self._ticks_per_second_time) self._ticks_per_second_time = time() self._ticks_per_second_ticks = self.tick_count self.tick_count += 1
def __init__(self, *tick_events): self.on_tick = Event() for tick_event in tick_events: self.on_tick.append(tick_event) self.pause = False self.start_time = time() self.tick_count = 0 self.ticks_per_second = 0 self._ticks_per_second_time = self.start_time self._ticks_per_second_ticks = 0
def __init__(self, camera=None): """ initializes basic controller events """ self.camera = camera self.on_init = Event() self.on_pre_cycle = Event() self.on_post_cycle = Event() self.on_request_cycle = Event() self.on_pre_render = Event() self.on_post_render = Event() self.on_render = Event() self.on_cycle = Event() self.on_mouse = Event() self.on_cursor = Event() self.on_destroy = Event() self.on_keyboard = Event() self.initialized = False self.host_controller = None self.cursor = (0,0) self.on_pre_render.append(self.clear_gl)
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)