class Politics(Window): title = "Mandates graph" gl_version = (3, 3) def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.imgui = ModernglWindowRenderer(self.wnd) self.prog = self.ctx.program(vertex_shader=''' #version 330 in vec2 in_vert; uniform int inSeats[10]; uniform int size; flat out int colIndex; int compare = inSeats[0]; int selector = 0; void main() { gl_Position = vec4(in_vert,0.0,1.0); gl_PointSize = size; if (gl_VertexID < inSeats[0]) { colIndex = 0; } else if (gl_VertexID < inSeats[1]) { colIndex = 1; } else if (gl_VertexID < inSeats[2]) { colIndex = 2; } else if (gl_VertexID < inSeats[3]) { colIndex = 3; } else if (gl_VertexID < inSeats[4]) { colIndex = 4; } else if (gl_VertexID < inSeats[5]) { colIndex = 5; } else if (gl_VertexID < inSeats[6]) { colIndex = 6; } else if (gl_VertexID < inSeats[7]) { colIndex = 7; } else if (gl_VertexID < inSeats[8]) { colIndex = 8; } else if (gl_VertexID < inSeats[9]) { colIndex = 9; } } ''', fragment_shader=''' #version 330 flat in int colIndex; uniform vec3 back; uniform bool round; out vec4 outColor; vec3 ano = vec3(0,255,251); vec3 ods = vec3(0,0,255); vec3 pir = vec3(0,0,0); vec3 spd = vec3(97,75,3); vec3 ksc = vec3(255,0,0); vec3 csd = vec3(255,123,0); vec3 kdu = vec3(255,255,0); vec3 top = vec3(136,0,255); vec3 stn = vec3(0,158,18); vec3 nan = vec3(255,255,255); vec3 colors[10] = vec3[](ano,ods,pir,spd,ksc,csd,kdu,top,stn,nan); vec3 color; void main() { color = colors[colIndex]; float r = color.x / 255; float g = color.y / 255; float b = color.z / 255; vec3 normColor = vec3(r,g,b); if (round) { float dist = step(length(gl_PointCoord.xy - vec2(0.5)), 0.5); if (dist == 0.0) { outColor = vec4(back ,1.0); } else { outColor = vec4(dist * normColor, dist); } } else { outColor = vec4(normColor,1.0); } } ''') self.seats = self.prog['inSeats'] self.back = self.prog['back'] self.size = self.prog['size'] self.round = self.prog['round'] self.round.value = True self.size.value = 20 self.gridx = 0.5 self.gridy = 0.1 self.seats.value = calculateCumulative( [78, 23, 22, 19, 15, 14, 10, 7, 6, 6]) self.states = { self.wnd.keys.UP: False, self.wnd.keys.DOWN: False, self.wnd.keys.W: False, self.wnd.keys.S: False, self.wnd.keys.A: False, self.wnd.keys.D: False, } def changeSize(self, bigger: bool): if (bigger): self.size.value = self.size.value + 1 else: self.size.value = self.size.value - 1 def changePointShape(self): self.round.value = not self.round.value def changeGrid(self, bigger: bool, horiz: bool): if (horiz): if (bigger): self.gridx = self.gridx + 0.01 else: self.gridx = self.gridx - 0.01 else: if (bigger): self.gridy = self.gridy + 0.001 else: self.gridy = self.gridy - 0.001 def control(self): if self.states.get(self.wnd.keys.UP): self.changeSize(True) if self.states.get(self.wnd.keys.DOWN): self.changeSize(False) if self.states.get(self.wnd.keys.W): self.changeGrid(bigger=True, horiz=False) if self.states.get(self.wnd.keys.S): self.changeGrid(bigger=False, horiz=False) if self.states.get(self.wnd.keys.A): self.changeGrid(bigger=True, horiz=True) if self.states.get(self.wnd.keys.D): self.changeGrid(bigger=False, horiz=True) def key_event(self, key, action, modifiers): if key not in self.states: if key == self.wnd.keys.P and action == self.wnd.keys.ACTION_PRESS: self.changePointShape() return if action == self.wnd.keys.ACTION_PRESS: self.states[key] = True else: self.states[key] = False def render(self, time: float, frame_time: float): self.fps = 1 / frame_time self.control() self.vbo = self.ctx.buffer( grid(self.gridx, 0.8, 20, 10, self.gridy).astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'in_vert') self.ctx.enable_only(moderngl.PROGRAM_POINT_SIZE) back = (0.2, 0.2, 0.2) self.back.value = back self.ctx.clear(back[0], back[1], back[2]) self.vao.render(mode=moderngl.POINTS) self.render_ui() def render_ui(self): imgui.new_frame() imgui.begin("Description - Political parties", False) imgui.text( "Visualisation of the number of mandates held by different political parties" ) imgui.text("FPS: %.2f" % self.fps) imgui.text("Parties:") imgui.text_colored("ANO", 0, 1, 251 / 255) imgui.text_colored("ODS", 0, 0, 1) imgui.text_colored("Pirate party", 0.5, 0.5, 0.5) imgui.text_colored("SPD", 97 / 255, 75 / 255, 3 / 255) imgui.text_colored("Communist party", 1, 0, 0) imgui.text_colored("CSSD", 1, 123 / 255, 0) imgui.text_colored("KDU-CLS", 1, 1, 0) imgui.text_colored("TOP 09", 136 / 255, 0, 1) imgui.text_colored("STAN", 0, 158 / 255, 18 / 255) imgui.text_colored("Other", 1, 1, 1) imgui.end() imgui.begin("Controls - Political parties", False) imgui.text("Press A/D to change size horizontaly") imgui.text("Press W/S to change size vertically") imgui.text("Press UP/DOWN to change size of the points") imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button)
class SlimeWindow(mglw.WindowConfig): title = "Slimes" gl_version = (4, 5) window_size = (1280, 720) resource_dir = (pathlib.Path(__file__).parent / "resources").resolve() map_size = (2560, 1440) local_size = 1024 vsync = True def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) imgui.create_context() self.wnd.ctx.error self.imgui = ModernglWindowRenderer(self.wnd) self.world_texture01 = self.ctx.texture(self.map_size, 1, dtype="f1") self.world_texture01.repeat_x, self.world_texture01.repeat_y = False, False self.world_texture01.filter = mgl.NEAREST, mgl.NEAREST self.world_texture02 = self.ctx.texture(self.map_size, 1, dtype="f1") self.world_texture02.repeat_x, self.world_texture02.repeat_y = False, False self.world_texture02.filter = mgl.NEAREST, mgl.NEAREST data = gen_data(SlimeConfig.N, self.map_size).astype("f4") self.slimes = self.ctx.buffer(data) # each slime has a position and angle self.load_programs() self.update_uniforms() self.quad_fs = quad_fs(normals=False) def restart_sim(self): self.world_texture01.release() self.world_texture02.release() self.world_texture01 = self.ctx.texture(self.map_size, 1, dtype="f1") self.world_texture01.repeat_x, self.world_texture01.repeat_y = False, False self.world_texture01.filter = mgl.NEAREST, mgl.NEAREST self.world_texture02 = self.ctx.texture(self.map_size, 1, dtype="f1") self.world_texture02.repeat_x, self.world_texture02.repeat_y = False, False self.world_texture02.filter = mgl.NEAREST, mgl.NEAREST data = gen_data(SlimeConfig.N, self.map_size).astype("f4") self.slimes.orphan(SlimeConfig.N * 4 * 4) self.slimes.write(data) def update_uniforms(self): self.blurr["diffuseSpeed"] = SlimeConfig.diffusion_speed self.blurr["evaporateSpeed"] = SlimeConfig.evaporation_speed self.compute_shader["moveSpeed"] = SlimeConfig.move_speed self.compute_shader["turnSpeed"] = SlimeConfig.turn_speed self.compute_shader["senorAngleSpacing"] = SlimeConfig.sensor_angle self.compute_shader["sensorDst"] = SlimeConfig.sensor_distance self.compute_shader["sensorSize"] = SlimeConfig.sensor_size self.render_program["color1"] = SlimeConfig.color1 self.render_program["color2"] = SlimeConfig.color2 self.compute_shader["N"] = SlimeConfig.N def load_programs(self): self.render_program = self.load_program("render_texture.glsl") self.render_program["texture0"] = 0 self.compute_shader = self.load_compute_shader( "update.glsl", { "width": self.map_size[0], "height": self.map_size[1], "local_size": self.local_size, }, ) self.blurr = self.load_compute_shader("blur.glsl") def render(self, time: float, frame_time: float): self.world_texture01.use(0) self.quad_fs.render(self.render_program) self.world_texture01.bind_to_image(1, read=True, write=False) self.world_texture02.bind_to_image(0, read=False, write=True) self.slimes.bind_to_storage_buffer(2) self.compute_shader["dt"] = frame_time self.blurr["dt"] = frame_time group_size = int(math.ceil(SlimeConfig.N / self.local_size)) self.compute_shader.run(group_size, 1, 1) self.world_texture01.bind_to_image(0, read=True, write=False) self.world_texture02.bind_to_image(1, read=True, write=True) self.blurr.run(self.map_size[0] // 16 + 1, self.map_size[1] // 16 + 1) self.world_texture01, self.world_texture02 = ( self.world_texture02, self.world_texture01, ) self.render_ui() def render_ui(self): imgui.new_frame() if imgui.begin("Settings"): imgui.push_item_width(imgui.get_window_width() * 0.33) changed = False c, SlimeConfig.move_speed = imgui.slider_float( "Movement speed", SlimeConfig.move_speed, 0.5, 50 ) changed = changed or c c, SlimeConfig.turn_speed = imgui.slider_float( "Turn speed", SlimeConfig.turn_speed, 0.5, 50, ) changed = changed or c c, SlimeConfig.evaporation_speed = imgui.slider_float( "Evaporation speed", SlimeConfig.evaporation_speed, 0.1, 10 ) changed = changed or c c, SlimeConfig.diffusion_speed = imgui.slider_float( "Diffusion speed", SlimeConfig.diffusion_speed, 0.1, 10, ) changed = changed or c c, SlimeConfig.sensor_angle = imgui.slider_float( "Sensor-angle", SlimeConfig.sensor_angle, 0, np.pi, ) changed = changed or c c, SlimeConfig.sensor_size = imgui.slider_int( "Sensor-size", SlimeConfig.sensor_size, 1, 3, ) changed = changed or c c, SlimeConfig.sensor_distance = imgui.slider_int( "Sensor distance", SlimeConfig.sensor_distance, 1, 10, ) changed = changed or c if changed: self.update_uniforms() imgui.pop_item_width() imgui.end() if imgui.begin("Appearance"): imgui.push_item_width(imgui.get_window_width() * 0.33) changed_c1, SlimeConfig.color1 = imgui.color_edit3( "Color1", *SlimeConfig.color1 ) changed_c2, SlimeConfig.color2 = imgui.color_edit3( "Color2", *SlimeConfig.color2 ) if changed_c1 or changed_c2: self.update_uniforms() imgui.end() if imgui.begin("Actions"): imgui.push_item_width(imgui.get_window_width() * 0.33) changed, SlimeConfig.N = imgui.input_int( "Number of Slimes", SlimeConfig.N, step=1024, step_fast=2**15 ) SlimeConfig.N = min(max(2048, SlimeConfig.N), 2**24) if imgui.button("Restart Slimes"): self.restart_sim() imgui.pop_item_width() imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) def resize(self, width: int, height: int): self.imgui.resize(width, height) def key_event(self, key, action, modifiers): self.imgui.key_event(key, action, modifiers) def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) def unicode_char_entered(self, char): self.imgui.unicode_char_entered(char)
class Histogram(Window): title = "Histogram" gl_version = (3, 3) def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.imgui = ModernglWindowRenderer(self.wnd) self.prog2 = self.ctx.program( vertex_shader=''' #version 330 in vec2 vert; out vec2 v_text; void main() { gl_Position = vec4(vert, 0.0, 1.0); v_text = vert.xy*2; } ''', fragment_shader=''' #version 330 in vec2 v_text; out vec4 outColor; uniform sampler2D Texture; void main() { outColor = texture(Texture, v_text, 0.0); } ''' ) self.prog = self.ctx.program( vertex_shader=''' #version 330 in vec2 vert; uniform float histogram[256]; void main() { if ((gl_VertexID % 2) == 0) { gl_Position = vec4(vert.x, histogram[gl_VertexID/2]-0.7, 0.0, 1.0); } else { gl_Position = vec4(vert, 0.0, 1.0); } } ''', geometry_shader=""" #version 330 uniform vec2 resolution; uniform float width; layout(lines) in; layout(triangle_strip, max_vertices=4) out; void main() { vec2 p1 = gl_in[0].gl_Position.xy; vec2 p2 = gl_in[1].gl_Position.xy; vec2 dir = p2 - p1; vec2 normal = vec2(dir.y, -dir.x); vec2 step = normalize(normal) / resolution * width; gl_Position = vec4(p2 - step, 0, 1); EmitVertex(); gl_Position = vec4(p1 - step, 0, 1); EmitVertex(); gl_Position = vec4(p2 + step, 0, 1); EmitVertex(); gl_Position = vec4(p1 + step, 0, 1); EmitVertex(); EndPrimitive(); } """, fragment_shader=''' #version 330 uniform vec2 resolution; out vec4 outColor; void main() { vec2 coord = (gl_FragCoord.xy/resolution)-0.1; outColor = vec4(coord.y,coord.y,1.0,1.0); } ''', ) self.histo = self.prog['histogram'] self.prog2['Texture'] = 0 self.histo.value = self.countPix('data/i8.jpg') self.texture = self.load_texture_2d('i8.jpg') vertices = np.array([ 1.0, 1.0, 0.5, 1.0, 0.5, 0.5, 1.0, 0.5, ], dtype='f4') self.vbo2 = self.ctx.buffer(vertices) self.vao2 = self.ctx.simple_vertex_array(self.prog2, self.vbo2, 'vert') self.vbo = self.ctx.buffer(self.initLines().astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') def render(self, time: float, frame_time: float): self.fps = 1/frame_time self.texture.use(0) self.prog["resolution"] = self.wnd.buffer_size self.prog["width"] = 3.0 back = (0.2, 0.2, 0.2) self.ctx.clear(back[0],back[1],back[2]) self.vao.render(mode=moderngl.LINES) self.vao2.render(mode=moderngl.TRIANGLE_FAN) self.render_ui() def initLines(self): u = np.linspace(-0.8, 0.8, 256) u = np.array(list(zip(u,u))).flatten() v_down = np.repeat(-0.8,256) v_up = np.repeat(-0.7,256) v = np.array(list(zip(v_down,v_up))).flatten() return np.array(list(zip(u,v))).flatten() def countPix(self,path): hist = np.zeros(256) im = Image.open(path) pix = im.load() print(im.size) for x in range(im.size[0]): for y in range(im.size[1]): index = int((pix[x,y][0]+pix[x,y][1]+pix[x,y][2])/3) hist[index] += 1 max = np.max(hist) hist = hist * (1/max) return hist.tolist() def render_ui(self): imgui.new_frame() imgui.begin("Description - Histogram", False) imgui.text("Shows the histogram of a selected photo") imgui.text("FPS: %.2f" % self.fps) imgui.end() imgui.begin("Controls - Histogram", False) imgui.text("Press P to select a photo") imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) # Events for imgui def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) # Events to interact with the visualisation def key_event(self, key, action, modifiers): if key == self.wnd.keys.P and action == self.wnd.keys.ACTION_PRESS: # Show file dialog root = tk.Tk() root.withdraw() path = filedialog.askopenfilename(filetypes=[("Picture files", ".png .jpg .jpeg .bmp")]) self.histo.value = self.countPix(path) self.texture = self.load_texture_2d('warn.png')
class Logmap(Window): title = "Logistic map" gl_version = (3, 3) def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.imgui = ModernglWindowRenderer(self.wnd) self.prog = self.ctx.program( vertex_shader=''' #version 330 in vec2 vert; void main() { gl_Position = vec4(vert, 0.0, 1.0); } ''', fragment_shader=''' #version 330 out vec4 color; void main() { color = vec4(1.0, 0.0, 0.0, 1.0); } ''', ) self.picProg = self.ctx.program( vertex_shader=''' #version 330 in vec2 vert; out vec2 v_text; void main() { gl_Position = vec4(vert, 0.0, 1.0); v_text = vec2(vert.x+0.5,vert.y-0.1); } ''', fragment_shader=''' #version 330 uniform sampler2D Texture; in vec2 v_text; out vec4 outColor; void main() { outColor = texture(Texture, v_text, 0.0); } ''', ) self.picProg['Texture'] = 0 self.texture = self.load_texture_2d('logmap.png') self.r = 3 vertices = np.array([ 0.5, 1.0, -0.5, 1.0, -0.5, 0.1, 0.5, 0.1, ], dtype='f4') self.line = np.array([ -0.0845, 0.25, -0.0845, 0.925, ], dtype='f4') self.pic_vbo = self.ctx.buffer(vertices) self.pic_vao = self.ctx.simple_vertex_array(self.picProg, self.pic_vbo, 'vert') self.line_vbo = self.ctx.buffer(self.line) self.line_vao = self.ctx.simple_vertex_array(self.prog, self.line_vbo, 'vert') self.vbo = self.ctx.buffer(self.generateFunc().astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') def render(self, time: float, frame_time: float): self.fps = 1 / frame_time back = (0.2, 0.2, 0.2) self.ctx.clear(back[0], back[1], back[2]) self.vao.render(mode=moderngl.LINE_STRIP) self.texture.use(0) self.pic_vao.render(moderngl.TRIANGLE_FAN) self.line_vao.render(mode=moderngl.LINES) self.render_ui() def generateFunc(self): positions = np.linspace(-0.9, 0.9, 100) out = [] x = 0.5 for pos in range(100): out.append(positions[pos]) out.append(x - 1) x = self.r * x * (1 - x) return np.array(out) def render_ui(self): imgui.new_frame() imgui.begin("Description - Logistic map ", False) imgui.text("R: %.2f" % self.r) imgui.text("FPS: %.2f" % self.fps) imgui.text("==========================") imgui.text("The top picture shows the ") imgui.text("Bifurcation diagram of the Logistic map.") imgui.text("The bottom graph shows the first") imgui.text("64 values with x starting at 0,5.") imgui.text("For R > 3, the values in the population") imgui.text("will approach oscilation between two values") imgui.text("this later changes to 4, 8 etc. values.") imgui.text("At roughly R > 3.57 there are no longer") imgui.text("oscilations with a finite period,") imgui.text("with the exceptions of small islands") imgui.text("where values oscilate, before becoming") imgui.text("chaotic once again.") imgui.end() imgui.begin("Controls - Logistic map", False) imgui.text("Press LEFT and RIGHT to") imgui.text("change the value of R") imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) # Events for imgui def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) # Events to interact with the visualisation def key_event(self, key, action, modifiers): if key == self.wnd.keys.RIGHT and action == self.wnd.keys.ACTION_PRESS: self.changeR(True) if key == self.wnd.keys.LEFT and action == self.wnd.keys.ACTION_PRESS: self.changeR(False) def changeR(self, up): if (up and self.r < 3.99): self.r = self.r + 0.01 self.line[0] = self.line[0] + 0.00485 self.line[2] = self.line[2] + 0.00485 self.updateVao() if ((not up) and self.r > 2.4): self.r = self.r - 0.01 self.line[0] = self.line[0] - 0.00485 self.line[2] = self.line[2] - 0.00485 self.updateVao() def updateVao(self): self.vbo = self.ctx.buffer(self.generateFunc().astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') self.line_vbo = self.ctx.buffer(self.line) self.line_vao = self.ctx.simple_vertex_array(self.prog, self.line_vbo, 'vert')
class WindowEvents(mglw.WindowConfig): gl_version = (3, 3) title = "imgui Integration" resource_dir = (Path(__file__).parent / 'resources').resolve() aspect_ratio = None def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.wnd.ctx.error self.imgui = ModernglWindowRenderer(self.wnd) self.cube = geometry.cube(size=(2, 2, 2)) self.prog = self.load_program('programs/cube_simple.glsl') self.prog['color'].value = (1.0, 1.0, 1.0, 1.0) self.prog['m_camera'].write(Matrix44.identity(dtype='f4')) self.prog['m_proj'].write( Matrix44.perspective_projection(75, self.wnd.aspect_ratio, 1, 100, dtype='f4')) def render(self, time: float, frametime: float): rotation = Matrix44.from_eulers((time, time, time), dtype='f4') translation = Matrix44.from_translation((0.0, 0.0, -3.5), dtype='f4') model = translation * rotation self.ctx.enable(moderngl.DEPTH_TEST | moderngl.CULL_FACE) self.prog['m_model'].write(model) self.cube.render(self.prog) self.render_ui() def render_ui(self): imgui.new_frame() if imgui.begin_main_menu_bar(): if imgui.begin_menu("File", True): clicked_quit, selected_quit = imgui.menu_item( "Quit", 'Cmd+Q', False, True) if clicked_quit: exit(1) imgui.end_menu() imgui.end_main_menu_bar() imgui.show_test_window() imgui.begin("Custom window", True) imgui.text("Bar") imgui.text_colored("Eggs", 0.2, 1., 0.) imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) def resize(self, width: int, height: int): self.prog['m_proj'].write( Matrix44.perspective_projection(75, self.wnd.aspect_ratio, 1, 100, dtype='f4')) self.imgui.resize(width, height) def key_event(self, key, action, modifiers): self.imgui.key_event(key, action, modifiers) def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) def unicode_char_entered(self, char): self.imgui.unicode_char_entered(char)
class Water(Window): title = "Water flow graph" gl_version = (3, 3) def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.imgui = ModernglWindowRenderer(self.wnd) self.prog = self.ctx.program( vertex_shader=''' #version 330 in vec2 in_vert; void main() { gl_Position = vec4(in_vert,0.0,1.0); } ''', fragment_shader=''' #version 330 out vec4 outColor; uniform bool graph; uniform bool opac; void main() { float op = 1; if (opac) { op = 0.5; } if (graph) { vec2 res = vec2(1280,720); vec2 coord = (gl_FragCoord.xy/res)-0.1; outColor = vec4(coord.y,coord.y,1.0,op); } else { outColor = vec4(0.0,0.0,0.0,1.0); } } ''' ) self.graph = self.prog['graph'] self.opac = self.prog['opac'] self.setData(3) self.opac.value = False def render(self, time: float, frame_time: float): self.fps = 1/frame_time back = (1.0, 1.0, 1.0) self.ctx.clear(back[0],back[1],back[2]) self.graph.value = False self.vao_grid.render(moderngl.LINES) self.graph.value = True self.vao_graph.render(moderngl.TRIANGLE_STRIP) self.render_ui() def render_ui(self): imgui.new_frame() imgui.begin("Description - Water levels", False) imgui.text("This graph displays the streamflow of a river") imgui.text("in cubic meters per second") imgui.text("Source of data:") imgui.text("http://www.pla.cz/portal/sap/") imgui.text("FPS: %.2f" % self.fps) imgui.end() imgui.begin("Controls - Water levels", False) imgui.text("Press P to toggle opacity") imgui.text("Press 1,2,3,4 to change dataset") imgui.text(self.data_name) imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) def key_event(self, key, action, modifiers): if key == self.wnd.keys.P and action == self.wnd.keys.ACTION_PRESS: self.toggleOpacity() if key == 49 and action == self.wnd.keys.ACTION_PRESS: self.setData(1) if key == 50 and action == self.wnd.keys.ACTION_PRESS: self.setData(2) if key == 51 and action == self.wnd.keys.ACTION_PRESS: self.setData(3) if key == 52 and action == self.wnd.keys.ACTION_PRESS: self.setData(4) def toggleOpacity(self): self.opac.value = not self.opac.value def setData(self,data_index): if data_index == 1: data = readData("data/Water_data.txt") self.initVertBuffers(data) self.data_name = "Cidlina" if data_index == 2: data = readData("data/Water_data2.txt") self.initVertBuffers(data) self.data_name = "Doubrava" if data_index == 3: data = readData("data/Water_data3.txt") self.initVertBuffers(data) self.data_name = "Metuje" if data_index == 4: data = readData("data/Water_data4.txt") self.initVertBuffers(data) self.data_name = "Ostravice" def initVertBuffers(self,data): self.vbo_grid = self.ctx.buffer(gridInit(0.8,len(data),20).astype('f4')) self.vao_grid = self.ctx.simple_vertex_array(self.prog, self.vbo_grid, 'in_vert') self.vbo_graph = self.ctx.buffer(dataInit(data).astype('f4')) self.vao_graph = self.ctx.simple_vertex_array(self.prog, self.vbo_graph, 'in_vert')
class WindowEvents(mglw.WindowConfig): gl_version = (3, 3) title = "imgui Integration" resource_dir = (Path(__file__).parent / '../examples/resources').resolve() aspect_ratio = None def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.wnd.ctx.error self.imgui = ModernglWindowRenderer(self.wnd) self.cube = geometry.cube(size=(2, 2, 2)) self.prog = self.load_program('programs/cube_simple.glsl') self.prog['color'].value = (1.0, 1.0, 1.0, 1.0) self.prog['m_camera'].write(Matrix44.identity(dtype='f4')) self.prog['m_proj'].write( Matrix44.perspective_projection(75, 1.0, 1, 100, dtype='f4')) self.fbo = self.ctx.framebuffer( color_attachments=self.ctx.texture((512, 512), 4), depth_attachment=self.ctx.depth_texture((512, 512)), ) # Ensure imgui knows about this texture # This is the color layer in the framebuffer self.imgui.register_texture(self.fbo.color_attachments[0]) def render(self, time: float, frametime: float): # Rotate/move cube rotation = Matrix44.from_eulers((time, time, time), dtype='f4') translation = Matrix44.from_translation((0.0, 0.0, -3.5), dtype='f4') model = translation * rotation # Render cube to offscreen texture / fbo self.fbo.use() self.fbo.clear() self.ctx.enable(moderngl.DEPTH_TEST | moderngl.CULL_FACE) self.prog['m_model'].write(model) self.cube.render(self.prog) # Render UI to screen self.wnd.use() self.render_ui() def render_ui(self): """Render the UI""" imgui.new_frame() if imgui.begin_main_menu_bar(): if imgui.begin_menu("File", True): clicked_quit, selected_quit = imgui.menu_item( "Quit", 'Cmd+Q', False, True) if clicked_quit: exit(1) imgui.end_menu() imgui.end_main_menu_bar() imgui.show_test_window() imgui.begin("Custom window", True) imgui.text("Bar") imgui.text_colored("Eggs", 0.2, 1., 0.) imgui.end() # Create window with the framebuffer image imgui.begin("Custom window with Image", True) # Create an image control by passing in the OpenGL texture ID (glo) # and pass in the image size as well. # The texture needs to he registered using register_texture for this to work imgui.image(self.fbo.color_attachments[0].glo, *self.fbo.size) imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) def resize(self, width: int, height: int): self.imgui.resize(width, height) def key_event(self, key, action, modifiers): self.imgui.key_event(key, action, modifiers) def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) def unicode_char_entered(self, char): self.imgui.unicode_char_entered(char)
class Cars(Window): title = "Car production" gl_version = (3, 3) def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.imgui = ModernglWindowRenderer(self.wnd) self.prog = self.ctx.program( vertex_shader=''' #version 330 uniform mat4 Mvp; in vec3 in_position; in vec3 in_normal; out vec3 v_vert; out vec3 v_norm; void main() { gl_Position = Mvp * vec4(in_position, 1.0); v_vert = in_position; v_norm = in_normal; } ''', fragment_shader=''' #version 330 uniform vec3 Light; uniform float gradient; in vec3 v_vert; in vec3 v_norm; out vec4 f_color; void main() { float lum = clamp(dot(normalize(Light - v_vert), normalize(v_norm)), 0.0, 1.0) * 0.8 + 0.2; vec3 color = mix(vec3(1.0,0.0,0.0),vec3(0.0,1.0,0.0),gradient); f_color = vec4(color.xyz * lum, 1.0); } ''', ) self.prog_map = self.ctx.program( vertex_shader=''' #version 330 uniform mat4 Mvp; in vec3 vert; out vec2 v_text; void main() { gl_Position = Mvp * vec4(vert, 1.0); v_text = vec2(vert.x/400,vert.y/400); } ''', fragment_shader=''' #version 330 out vec4 outColor; in vec2 v_text; uniform sampler2D Texture; void main() { outColor = texture(Texture, v_text, 0.0); } ''', ) vertices = np.array([ 0.0, 0.0, 0.0, 400.0, 0.0, 0.0, 400.0, 400.0, 0.0, 0.0, 400.0, 0.0, ], dtype='f4') self.prog_map['Texture'] = 0 self.texture = self.load_texture_2d('EU.jpg') self.mvp = self.prog['Mvp'] self.mvp_map = self.prog_map['Mvp'] self.light = self.prog['Light'] self.gradient = self.prog['gradient'] self.gradient.value = 0 self.vbo_map = self.ctx.buffer(vertices.astype('f4')) self.vao_map = self.ctx.simple_vertex_array(self.prog_map, self.vbo_map, 'vert') self.obj = self.load_scene('car3.obj', cache=True) self.vao = self.obj.root_nodes[0].mesh.vao.instance(self.prog) self.movX = 200 self.movY = -200 self.movZ = 300 self.fps = 0 self.production = self.loadData() self.positions = np.array([ [195, 105, 0], [160, 135, 0], [250, 260, 0], [150, 100, 0], [185, 135, 0], [200, 60, 0], [165, 150, 0], [105, 45, 0], [130, 50, 0], [205, 260, 0], [135, 155, 0], [205, 125, 0], [225, 100, 0], [225, 150, 0], [250, 90, 0], [220, 118, 0], [202, 92, 0], [220, 80, 0], [280, 120, 0], [300, 190, 0], ]) self.states = { self.wnd.keys.UP: False, self.wnd.keys.DOWN: False, self.wnd.keys.W: False, self.wnd.keys.S: False, self.wnd.keys.A: False, self.wnd.keys.D: False, } def render(self, time, frame_time): self.ctx.clear(0.2, 0.2, 0.2) self.ctx.enable(moderngl.DEPTH_TEST) self.fps = 1 / frame_time self.control() proj = Matrix44.perspective_projection(45.0, self.aspect_ratio, 0.1, 1000.0) lookat = Matrix44.look_at( (self.movX, self.movY, self.movZ), (200.0, 200.0, 0.0), (0.0, 0.0, 1.0), ) self.light.value = (100, 0, 200) self.texture.use(0) self.mvp_map.write((proj * lookat).astype('f4')) self.vao_map.render(moderngl.TRIANGLE_FAN) model_rot = Matrix44.from_z_rotation( 3.14 / 4) * Matrix44.from_x_rotation(-3.14 / 2) for x in range(int(self.positions.size / 3)): size = 1 + self.production[x] * (2.5 - 1) model_size = Matrix44.from_scale(np.array([size, size, size])) self.gradient.value = self.production[x] model = Matrix44.from_translation(np.array( self.positions[x])) * model_rot * model_size self.mvp.write((proj * lookat * model).astype('f4')) self.vao.render() self.render_ui() def control(self): if self.states.get(self.wnd.keys.UP): self.movZ += 1 if self.states.get(self.wnd.keys.DOWN): if self.movZ > 1: self.movZ -= 1 if self.states.get(self.wnd.keys.W): if self.movY < 100: self.movY += 1 if self.states.get(self.wnd.keys.S): self.movY -= 1 if self.states.get(self.wnd.keys.A): self.movX -= 1 if self.states.get(self.wnd.keys.D): self.movX += 1 def key_event(self, key, action, modifiers): if key not in self.states: pass if action == self.wnd.keys.ACTION_PRESS: self.states[key] = True else: self.states[key] = False def loadData(self): out = [] with open('data/cars2019.csv', newline='') as csvfile: spamreader = csv.reader(csvfile, delimiter=';') for row in spamreader: out.append(int(row[1].replace(" ", ""))) maximum = max(out) out = np.array(out) / maximum return out def render_ui(self): imgui.new_frame() imgui.begin("Description - Car Production", False) imgui.text("This is a visualisation of car production") imgui.text("in Europe for the year 2019") imgui.text("Size and color of cars shows the relative") imgui.text("production of vehicles in a country") imgui.text("FPS: %.2f" % self.fps) imgui.end() imgui.begin("Controls - Car Production", False) imgui.text("W and S to move forward and back") imgui.text("A and D to move left and right") imgui.text("UP and DOWN to change height") imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) # Events for imgui def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button)
class Heatmap(Window): title = "Functions/Heatmaps" gl_version = (3, 3) def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.imgui = ModernglWindowRenderer(self.wnd) self.prog = self.ctx.program( vertex_shader=''' #version 330 in vec3 vert; out float gradient; uniform mat4 Mvp; uniform int size; void main() { gl_PointSize = size; gradient = (vert.z+1)*0.5; gl_Position = Mvp * vec4(vert, 1.0); } ''', fragment_shader=''' #version 330 in float gradient; uniform vec3 colorA; uniform vec3 colorB; out vec4 outColor; void main() { vec3 color = mix(colorA,colorB,gradient); outColor = vec4(color, 1.0); } ''', ) # Camera setup self.camera = Camera(self.aspect_ratio) self.camera._camera_position = Vector3([0.0, 0.0, -20.0]) self.camera._move_horizontally = 20 self.camera.build_look_at() self.mvp = self.prog['Mvp'] self.colorA = self.prog['colorA'] self.colorB = self.prog['colorB'] self.size = self.prog['size'] self.colorA.value = (0.1,1.0,0.0) self.colorB.value = (0.0,0.0,1.0) self.colorSelector = 0 self.size.value = 5 self.vbo = self.ctx.buffer(self.initData(1).astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') def initData(self,function): x = np.linspace(-8, 8, 200) y = np.linspace(-8, 8, 200) out = [] for i in range(len(x)): for j in range(len(y)): out = np.append(out,[x[i],y[j],self.calcFunc(x[i],y[j],function)]) return out def calcFunc(self,x,y,func): if func == 1: return math.sin(math.sqrt(x ** 2 + y ** 2)) if func == 2: return math.cos(x)*math.sin(y) if func == 3: return math.cos(40*math.sqrt(x**2+y**2)) if func == 4: return math.cos(math.fabs(x) + math.fabs(y)) if func == 5: return 8*math.exp(-x**2-y**2)*(0.1+x*(y-0.5)) if func == 6: return math.exp(math.sin(x*2)*math.sin(y*0.2))*0.9 * math.exp(math.sin(y*2) * math.sin(x*0.2))*0.9-0.7 def render(self, time: float, frame_time: float): self.fps = 1/frame_time # Camera animation self.camera.move_forward() self.camera.rotate_left() self.camera.move_backwards() self.mvp.write((self.camera.mat_projection * self.camera.mat_lookat).astype('f4')) self.ctx.enable_only(moderngl.PROGRAM_POINT_SIZE | moderngl.DEPTH_TEST) back = (0.2, 0.2, 0.2) self.ctx.clear(back[0],back[1],back[2]) self.vao.render(mode=moderngl.POINTS) self.render_ui() def render_ui(self): imgui.new_frame() imgui.begin("Description - Functions", False) imgui.text("This is a visualisation of two variable functions") imgui.text("Points are colored based on their Z coordinate") imgui.text("Same visualisation could be used for heatmaps or simillar data") imgui.text("FPS: %.2f" % self.fps) imgui.end() imgui.begin("Controls - Functions", False) imgui.text("UP and DOWN to change colors") imgui.text("Press 1,2,3,4,5,6 to change function") imgui.text("LEFT and RIGHT to change point size") imgui.text_colored("Warning:", 1,0,0) imgui.text("Depending on your machine, this may take a while") imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) # Events for imgui def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) # Events to interact with the visualisation def key_event(self, key, action, modifiers): if key == 49 and action == self.wnd.keys.ACTION_PRESS: self.vbo = self.ctx.buffer(self.initData(1).astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') if key == 50 and action == self.wnd.keys.ACTION_PRESS: self.vbo = self.ctx.buffer(self.initData(2).astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') if key == 51 and action == self.wnd.keys.ACTION_PRESS: self.vbo = self.ctx.buffer(self.initData(3).astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') if key == 52 and action == self.wnd.keys.ACTION_PRESS: self.vbo = self.ctx.buffer(self.initData(4).astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') if key == 53 and action == self.wnd.keys.ACTION_PRESS: self.vbo = self.ctx.buffer(self.initData(5).astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') if key == 54 and action == self.wnd.keys.ACTION_PRESS: self.vbo = self.ctx.buffer(self.initData(6).astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') if key == self.wnd.keys.UP and action == self.wnd.keys.ACTION_PRESS: self.colorSelect(True) if key == self.wnd.keys.DOWN and action == self.wnd.keys.ACTION_PRESS: self.colorSelect(False) if key == self.wnd.keys.LEFT and action == self.wnd.keys.ACTION_PRESS: self.sizeSelect(True) if key == self.wnd.keys.RIGHT and action == self.wnd.keys.ACTION_PRESS: self.sizeSelect(False) def sizeSelect(self,up): if up: self.size.value = self.size.value + 1 else: self.size.value = self.size.value - 1 def colorSelect(self,up): if up: self.colorSelector = self.colorSelector + 1 else: self.colorSelector = self.colorSelector - 1 if self.colorSelector % 4 == 0: self.colorA.value = (0.1,1.0,0.0) self.colorB.value = (0.0,0.0,1.0) elif self.colorSelector % 4 == 1: self.colorA.value = (1.0,0.5,0.0) self.colorB.value = (0.25,0.0,0.4) elif self.colorSelector % 4 == 2: self.colorA.value = (1.0,1.0,1.0) self.colorB.value = (0.0,0.0,0.0) elif self.colorSelector % 4 == 3: self.colorA.value = (1.0,0.0,0.0) self.colorB.value = (1.0,1.0,0.0)
class MMVShaderMGLWindowHandlers: INTENSITY_RESPONSIVENESS = 0.2 ROTATION_RESPONSIVENESS = 0.2 ZOOM_RESPONSIVENESS = 0.2 DRAG_RESPONSIVENESS = 0.3 DRAG_MOMENTUM = 0.6 DEVELOPER = False def __init__(self, mmv_shader_mgl): self.mmv_shader_mgl = mmv_shader_mgl # Mouse related controls self.target_drag = np.array([0.0, 0.0]) self.target_intensity = 1 self.target_rotation = 0 self.target_zoom = 1 # Multiplier on top of multiplier, configurable real time self.drag_momentum = np.array([0.0, 0.0]) self.drag = np.array([0.0, 0.0]) self.intensity = 1 self.rotation = 0 self.zoom = 1 # Keys self.shift_pressed = False self.ctrl_pressed = False self.alt_pressed = False # Mouse self.mouse_buttons_pressed = [] self.mouse_exclusivity = False # Gui self.hide_gui = True # Which "mode" to render, window loader class, msaa, ssaa, vsync, force res? def mode(self, window_class, msaa=1, vsync=True, strict=False, icon=None): debug_prefix = "[MMVShaderMGLWindowHandlers.mode]" logging.info( f"{debug_prefix} \"i\" Set window mode [window_class={window_class}] [msaa={msaa}] [vsync={vsync}] [strict={strict}] [icon={icon}]" ) # Get function arguments self.headless = window_class == "headless" self.strict = strict self.vsync = vsync self.msaa = msaa # Headless we disable vsync because we're rendering only..? # And also force aspect ratio just in case (strict option) if self.headless: self.strict = True self.vsync = False # Assign the function arguments settings.WINDOW[ "class"] = f"moderngl_window.context.{window_class}.Window" settings.WINDOW[ "aspect_ratio"] = self.mmv_shader_mgl.width / self.mmv_shader_mgl.height settings.WINDOW["vsync"] = self.vsync settings.WINDOW["title"] = "MMVShaderMGL Real Time Window" settings.WINDOW["size"] = (self.mmv_shader_mgl.width, self.mmv_shader_mgl.height) # Create the window self.window = moderngl_window.create_window_from_settings() # Make sure we render strictly into the resolution we asked if strict: self.window.fbo.viewport = (0, 0, self.mmv_shader_mgl.width, self.mmv_shader_mgl.height) # self.window.set_default_viewport() # Set the icon if icon is not None: # Absolute path icon = Path(icon).resolve() resources.register_dir(icon.parent) self.window.set_icon(icon_path=icon.name) # The context we'll use is the one from the window self.gl_context = self.window.ctx self.mmv_shader_mgl.gl_context = self.gl_context self.window_should_close = False # Functions of the window if not headless if not self.headless: self.window.resize_func = self.window_resize self.window.key_event_func = self.key_event self.window.mouse_position_event_func = self.mouse_position_event self.window.mouse_drag_event_func = self.mouse_drag_event self.window.mouse_scroll_event_func = self.mouse_scroll_event self.window.mouse_press_event_func = self.mouse_press_event self.window.mouse_release_event_func = self.mouse_release_event self.window.unicode_char_entered_func = self.unicode_char_entered self.window.close_func = self.close imgui.create_context() self.imgui = ModernglWindowRenderer(self.window) # [NOT HEADLESS] Window was resized, update the width and height so we render with the new config def window_resize(self, width, height): if hasattr(self, "strict"): if self.strict: return # Set width and height self.mmv_shader_mgl.width = int(width) self.mmv_shader_mgl.height = int(height) # Recursively call this function on every shader on textures dictionary for index in self.mmv_shader_mgl.textures.keys(): if self.mmv_shader_mgl.textures[index]["loader"] == "shader": self.mmv_shader_mgl.textures[index][ "shader_as_texture"].window_handlers.window_resize( width=self.mmv_shader_mgl.width, height=self.mmv_shader_mgl.height) # Search for dynamic shaders and update them for index in self.mmv_shader_mgl.textures.keys(): # Release Dynamic Shaders and update their target render if self.mmv_shader_mgl.textures[index].get("dynamic", False): target = self.mmv_shader_mgl.textures[index][ "shader_as_texture"] target.texture.release() target.fbo.release() target._create_assing_texture_fbo_render_buffer(verbose=False) # Master shader has window and imgui if self.mmv_shader_mgl.master_shader: if not self.headless: self.imgui.resize(self.mmv_shader_mgl.width, self.mmv_shader_mgl.height) # Window viewport self.window.fbo.viewport = (0, 0, self.mmv_shader_mgl.width, self.mmv_shader_mgl.height) # Release everything def drop_textures(self): for index in self.mmv_shader_mgl.textures.keys(): if "shader_as_texture" in self.mmv_shader_mgl.textures[index].keys( ): target = self.mmv_shader_mgl.textures[index][ "shader_as_texture"] target.fullscreen_buffer.release() target.program.release() target.texture.release() target.fbo.release() target.vao.release() else: self.mmv_shader_mgl.textures[index]["texture"].release() # Delete items for index in list(self.mmv_shader_mgl.textures.keys()): del self.mmv_shader_mgl.textures[index] gc.collect() # Close the window def close(self, *args, **kwargs): logging.info(f"[MMVShaderMGLWindowHandlers.close] Window should close") self.window_should_close = True # Swap the window buffers, be careful if vsync is False and you have a heavy # shader, it will consume all of your GPU computation and will most likely freeze # the video def update_window(self): self.window.swap_buffers() # Interpolate stuff self.intensity += ( self.target_intensity - self.intensity ) * MMVShaderMGLWindowHandlers.INTENSITY_RESPONSIVENESS self.rotation += ( self.target_rotation - self.rotation) * MMVShaderMGLWindowHandlers.ROTATION_RESPONSIVENESS self.zoom += (self.target_zoom - self.zoom ) * MMVShaderMGLWindowHandlers.ZOOM_RESPONSIVENESS self.drag += (self.target_drag - self.drag ) * MMVShaderMGLWindowHandlers.DRAG_RESPONSIVENESS self.drag_momentum *= MMVShaderMGLWindowHandlers.DRAG_MOMENTUM # Drag momentum if not 1 in self.mouse_buttons_pressed: self.target_drag += self.drag_momentum # # Interactive events def key_event(self, key, action, modifiers): debug_prefix = "[MMVShaderMGLWindowHandlers.key_event]" self.imgui.key_event(key, action, modifiers) logging.info( f"{debug_prefix} Key [{key}] Action [{action}] Modifier [{modifiers}]" ) # Shift and control if key == 340: self.shift_pressed = bool(action) if key == 341: self.ctrl_pressed = bool(action) if key == 342: self.alt_pressed = bool(action) # "c" key pressed, reset target rotation if (key == 67) and (action == 1): logging.info( f"{debug_prefix} \"c\" key pressed [Set target rotation to 0]") self.target_rotation = 0 # "e" key pressed, toggle mouse exclusive mode if (key == 69) and (action == 1): logging.info( f"{debug_prefix} \"e\" key pressed [Toggle mouse exclusive]") self.mouse_exclusivity = not self.mouse_exclusivity self.window.mouse_exclusivity = self.mouse_exclusivity # "f" key pressed, toggle fullscreen mode if (key == 70) and (action == 1): logging.info( f"{debug_prefix} \"f\" key pressed [Toggle fullscreen]") self.window.fullscreen = not self.window.fullscreen # "g" key pressed, toggle gui if (key == 71) and (action == 1): if MMVShaderMGLWindowHandlers.DEVELOPER: logging.info(f"{debug_prefix} \"g\" key pressed [Toggle gui]") self.hide_gui = not self.hide_gui # "h" key pressed, toggle mouse visible if (key == 72) and (action == 1): logging.info( f"{debug_prefix} \"h\" key pressed [Toggle mouse hidden]") self.window.cursor = not self.window.cursor # "p" key pressed, screenshot if (key == 80) and (action == 1): m = self.mmv_shader_mgl # Lazy # Where to save now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") saveto = m.screenshots_dir / f"{now}.jpg" logging.info( f"{debug_prefix} \"r\" key pressed, taking screenshot, saving to [{saveto}]" ) # Get data ib the scree's size viewport size = (m.width, m.height) data = self.window.fbo.read(viewport=(0, 0, size[0], size[1])) logging.info( f"{debug_prefix} [Resolution: {size}] [WxHx3: {size[0] * size[1] * 3}] [len(data): {len(data)}]" ) # Multiprocess save image to file so we don't lock def save_image_to_file(size, data, path): img = Image.frombytes('RGB', size, data, 'raw').transpose(Image.FLIP_TOP_BOTTOM) img.save(path, quality=95) # Start the process multiprocessing.Process(target=save_image_to_file, args=(size, data, saveto)).start() # "q" key pressed, quit if (key == 81) and (action == 1): logging.info(f"{debug_prefix} \"r\" key pressed, quitting") self.window_should_close = True # "r" key pressed, reload shaders if (key == 82) and (action == 1): logging.info( f"{debug_prefix} \"r\" key pressed [Reloading shaders]") self.mmv_shader_mgl._read_shaders_from_paths_again() # "s" key pressed, don't pipe pipeline if (key == 83) and (action == 1): logging.info( f"{debug_prefix} \"s\" key pressed [Freezing time and pipelines but resolution, zoom]" ) self.mmv_shader_mgl.freezed_pipeline = not self.mmv_shader_mgl.freezed_pipeline for index in self.mmv_shader_mgl.textures.keys(): if self.mmv_shader_mgl.textures[index]["loader"] == "shader": self.mmv_shader_mgl.textures[index][ "shader_as_texture"].freezed_pipeline = self.mmv_shader_mgl.freezed_pipeline # "t" key pressed, reset time to zero if (key == 84) and (action == 1): logging.info(f"{debug_prefix} \"t\" key pressed [Set time to 0]") self.mmv_shader_mgl.pipeline["mmv_frame"] = 0 self.mmv_shader_mgl.pipeline["mmv_time"] = 0 # "v" key pressed, reset target intensity if (key == 86) and (action == 1): logging.info( f"{debug_prefix} \"v\" key pressed [Set target intensity to 1]" ) self.target_intensity = 1 # "z" key pressed, reset zoom if (key == 90) and (action == 1): logging.info( f"{debug_prefix} \"z\" key pressed [Set target zoom to 1]") self.target_zoom = 1 # "x" key, reset drag if (key == 88) and (action == 1): logging.info( f"{debug_prefix} \"z\" key pressed [Set target drag to [0, 0]]" ) self.target_drag = np.array([0.0, 0.0]) # Mouse position changed def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) self.mmv_shader_mgl.pipeline["mmv_mouse"] = [x, y] # Drag if on mouse exclusivity if self.mouse_exclusivity: if self.shift_pressed: self.target_zoom += (dy / 1000) * self.target_zoom elif self.alt_pressed: self.target_rotation += dy / 20 else: self.__apply_rotated_drag(dx=dx, dy=dy, howmuch=0.5, inverse=True) # Apply drag with the target rotation (because dx and dy are relative to the window itself not the rendered contents) def __apply_rotated_drag(self, dx, dy, howmuch=1, inverse=False): # Inverse drag? Feels more natural when mouse exclusivity is on inverse = -1 if inverse else 1 # Add to the mmv_drag pipeline item the dx and dy multiplied by the square of the current zoom square_current_zoom = (self.mmv_shader_mgl.pipeline["mmv_zoom"]**2) # dx and dy on zoom and SSAA dx = (dx * square_current_zoom) * self.mmv_shader_mgl.ssaa dy = (dy * square_current_zoom) * self.mmv_shader_mgl.ssaa # Cosine and sine c = math.cos(math.radians(self.rotation)) s = math.sin(math.radians(self.rotation)) # mat2 rotation times the dx, dy vector drag_rotated = np.array([(dx * c) + (dy * -s), (dx * s) + (dy * c)]) * howmuch * inverse # Add to target drag the dx, dy relative to current zoom and SSAA level self.target_drag += drag_rotated self.drag_momentum += drag_rotated # Mouse drag, add to pipeline drag def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) if 1 in self.mouse_buttons_pressed: if self.shift_pressed: self.target_zoom += (dy / 1000) * self.target_zoom elif self.alt_pressed: self.target_rotation += dy / 20 else: self.__apply_rotated_drag(dx=dx, dy=dy, inverse=True) # Change SSAA def change_ssaa(self, value): debug_prefix = "[MMVShaderMGLWindowHandlers.change_ssaa]" self.mmv_shader_mgl.ssaa = value self.mmv_shader_mgl._read_shaders_from_paths_again() logging.info(f"{debug_prefix} Changed SSAA to [{value}]") # Zoom in or out (usually) def mouse_scroll_event(self, x_offset, y_offset): debug_prefix = "[MMVShaderMGLWindowHandlers.mouse_scroll_event]" if self.shift_pressed: self.target_intensity += y_offset / 10 logging.info( f"{debug_prefix} Mouse scroll with shift Target Intensity: [{self.target_intensity}]" ) elif self.ctrl_pressed: change_to = self.mmv_shader_mgl.ssaa + ( (y_offset / 20) * self.mmv_shader_mgl.ssaa) logging.info( f"{debug_prefix} Mouse scroll with shift change SSAA to: [{change_to}]" ) self.change_ssaa(change_to) elif self.alt_pressed: self.target_rotation -= y_offset * 5 logging.info( f"{debug_prefix} Mouse scroll with alt change target rotation to: [{self.target_rotation}]" ) else: logging.info( f"{debug_prefix} Mouse scroll without shift and ctrl Target Zoom: [{self.target_zoom}]" ) self.target_zoom -= (y_offset * 0.05) * self.target_zoom self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): debug_prefix = "[MMVShaderMGLWindowHandlers.mouse_press_event]" logging.info( f"{debug_prefix} Mouse press (x, y): [{x}, {y}] Button [{button}]") self.imgui.mouse_press_event(x, y, button) if not button in self.mouse_buttons_pressed: self.mouse_buttons_pressed.append(button) if not self.mouse_exclusivity: self.window.mouse_exclusivity = True def mouse_release_event(self, x, y, button): debug_prefix = "[MMVShaderMGLWindowHandlers.mouse_release_event]" logging.info( f"{debug_prefix} Mouse release (x, y): [{x}, {y}] Button [{button}]" ) self.imgui.mouse_release_event(x, y, button) if button in self.mouse_buttons_pressed: self.mouse_buttons_pressed.remove(button) if not self.mouse_exclusivity: self.window.mouse_exclusivity = False def unicode_char_entered(self, char): self.imgui.unicode_char_entered(char) # Render the user interface def render_ui(self): # Test window imgui.new_frame() imgui.begin("Custom window", True) imgui.text("Bar") imgui.text_colored("Eggs", 0.2, 1., 0.) imgui.end() # Render imgui.render() self.imgui.render(imgui.get_draw_data())
class App(mglw.WindowConfig, ABC): gl_version = (3, 3) title = "App" resource_dir = (Path(__file__).parent.parent / 'resources').resolve() aspect_ratio = None scene: [SceneObject] camera: OrthographicCamera def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.imgui = ModernglWindowRenderer(self.wnd) self.scene = [] self.camera = OrthographicCamera((0, 0), 5, self.wnd) def render(self, time: float, frametime: float): imgui.new_frame() self.render_callback(time) imgui.render() self.imgui.render(imgui.get_draw_data()) pass @abstractmethod def render_callback(self, time: float): pass def resize(self, width: int, height: int): self.imgui.resize(width, height) def key_event(self, key, action, modifiers): self.imgui.key_event(key, action, modifiers) def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) if not imgui.get_io().want_capture_mouse: wd = self.camera.unproject_distance(dx, dy) control_camera = True for o in self.scene: o.mouse_drag_event(wd[0], wd[1]) if o.want_use_mouse: control_camera = False if control_camera: self.camera.mouse_drag_event(dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) if not imgui.get_io().want_capture_mouse: control_camera = True for o in self.scene: o.mouse_scroll_event(x_offset, y_offset) if o.want_use_mouse: control_camera = False if control_camera: self.camera.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) if not imgui.get_io().want_capture_mouse: sp = x, self.camera.viewport()[1] - y wp = self.camera.unproject(sp[0], sp[1]) for o in self.scene: o.mouse_press_event(wp[0], wp[1], button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) if not imgui.get_io().want_capture_mouse: sp = x, self.camera.viewport()[1] - y wp = self.camera.unproject(sp[0], sp[1]) for o in self.scene: o.mouse_release_event(wp[0], wp[1], button) def unicode_char_entered(self, char): self.imgui.unicode_char_entered(char)
class WindowEvents(mglw.WindowConfig): gl_version = (3, 3) title = "imgui Integration" resource_dir = (Path(__file__).parent / 'resources').resolve() aspect_ratio = None def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.imgui = ModernglWindowRenderer(self.wnd) self.petr4_h = pd.read_csv("../data/" + selected_symbol + '_yf_data') self.candlestick_chart = CandleStickChart(self) self.candlestick_chart.set_data(self.petr4_h, csl[csl.Symbol == selected_symbol]) def render(self, time: float, frametime: float): global selected_symbol global input_text self.candlestick_chart.render() imgui.new_frame() if imgui.begin_main_menu_bar(): if imgui.begin_menu("File", True): clicked_quit, selected_quit = imgui.menu_item( "Quit", 'Cmd+Q', False, True ) if clicked_quit: exit(1) imgui.end_menu() changed, value = imgui.input_text("", input_text, 30) if changed: imgui.set_next_window_position(imgui.get_item_rect_min().x, imgui.get_item_rect_max().y) imgui.set_next_window_size(imgui.get_item_rect_size().x, 0) if imgui.begin("##popup", False, imgui.WINDOW_NO_TITLE_BAR | imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE): for index, row in symbol_list.iterrows(): if value.upper() in row[0]: opened, selected = imgui.selectable(row[0] + " - " + row[2]) if imgui.is_item_clicked(): input_text = row[0] selected_symbol = row[0] imgui.end() if imgui.button("download"): yfc.download(selected_symbol, symbol_data_file()) imgui.end_main_menu_bar() if not imgui.get_io().want_capture_mouse: self.candlestick_chart.render_gui() # if len(df): # graphics.draw_table(df, 0) imgui.show_test_window() imgui.render() self.imgui.render(imgui.get_draw_data()) def resize(self, width: int, height: int): self.imgui.resize(width, height) def key_event(self, key, action, modifiers): self.imgui.key_event(key, action, modifiers) def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) if not imgui.get_io().want_capture_mouse: self.candlestick_chart.mouse_drag_event(dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) if not imgui.get_io().want_capture_mouse: self.candlestick_chart.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) if not imgui.get_io().want_capture_mouse: self.candlestick_chart.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) if not imgui.get_io().want_capture_mouse: self.candlestick_chart.mouse_release_event(x, y, button) def unicode_char_entered(self, char): self.imgui.unicode_char_entered(char)
class Music(Window): title = "Title" gl_version = (3, 3) def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.imgui = ModernglWindowRenderer(self.wnd) self.prog = self.ctx.program( vertex_shader=''' #version 330 in vec2 vert; uniform float dataPlot[1000]; uniform bool up; out float gradient; void main() { gl_PointSize = 3; if (up) { gl_Position = vec4(vert.x, (dataPlot[gl_VertexID]+1)/2, 0.0, 1.0); } else { gl_Position = vec4(vert.x, (dataPlot[gl_VertexID]-1)/2, 0.0, 1.0); } gradient = dataPlot[gl_VertexID]*4; } ''', fragment_shader=''' #version 330 uniform vec2 resolution; in float gradient; out vec4 outColor; void main() { vec3 color = mix(vec3(1.0,1.0,1.0),vec3(1.0,0.0,0.0),abs(gradient)); outColor = vec4(color,1.0); } ''', ) self.dataPlot = self.prog['dataPlot'] self.up = self.prog['up'] self.up.value = True self.audio = np.zeros((1000, 2)) self.rate = 0 self.startTime = 0 self.songTime = 0 self.vbo = self.ctx.buffer(self.initLines().astype('f4')) self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert') def render(self, time: float, frame_time: float): self.ctx.enable_only(moderngl.PROGRAM_POINT_SIZE) self.fps = 1 / frame_time self.ctx.clear(0.2, 0.2, 0.2) if ((time - self.startTime) < (self.songTime)): self.up.value = True self.calculateSample(self.audio[:, 0], time - self.startTime) self.vao.render(mode=moderngl.POINTS) self.up.value = False self.calculateSample(self.audio[:, 1], time - self.startTime) self.vao.render(mode=moderngl.POINTS) self.render_ui(time) def calculateSample(self, channel, time): bigTime = int(time * self.rate) value = (channel[0 + bigTime:1000 + bigTime] / (32767 * 2)).tolist() self.dataPlot.value = value def initLines(self): u = np.linspace(-0.8, 0.8, 1000) v = np.repeat(0.0, 1000) return np.array(list(zip(u, v))).flatten() def playSong(self, index, time): self.startTime = time winsound.PlaySound(None, winsound.SND_PURGE) if (index == 0): path = 'data/songs/sweet_dreams.wav' if (index == 1): path = 'data/songs/omnissiah.wav' if (index == 2): path = 'data/songs/lift.wav' self.rate, self.audio = scipyio.read(path) winsound.PlaySound(path, winsound.SND_ASYNC | winsound.SND_ALIAS) self.songTime = (len(self.audio) / self.rate) - 2 def render_ui(self, time): imgui.new_frame() imgui.begin("Description - Music", False) imgui.text("Pick a song to vizualize:") comboOut = imgui.listbox("", -1, [ "Sweet Dreams", "Children of the Omnissiah", "We all lift together" ]) imgui.text("FPS: %.2f" % self.fps) imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) if comboOut[0]: self.playSong(comboOut[1], time) # Events for imgui def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) # Events to interact with the visualisation def key_event(self, key, action, modifiers): print(key)
class WindowEvents(mglw.WindowConfig): gl_version = (3, 3) window_size = (1200, 600) aspect_ratio = window_size[0] / window_size[1] title = "Neural Renderer" def __init__(self, **kwargs): super().__init__(**kwargs) imgui.create_context() self.wnd.ctx.error self.imgui = ModernglWindowRenderer(self.wnd) self.space_down = False self.prog = self.ctx.program( vertex_shader=""" #version 330 uniform mat4 transform; uniform vec3 clr; uniform float aspect; in vec3 in_vert; out vec3 color; out vec2 uv; void main() { vec3 pos = vec3(in_vert.x, in_vert.y * aspect, 0.0); gl_Position = transform * vec4(pos, 1.0); uv = vec2(in_vert.x * 0.5 + 0.5, in_vert.y * 0.5 + 0.5); uv.y = 1.0 - uv.y; color = vec3(1, 0, 0); } """, fragment_shader=""" #version 330 uniform sampler2D tex_sampler; out vec4 fragColor; in vec3 color; in vec2 uv; void main() { fragColor = vec4(texture(tex_sampler, uv).rgb, 1.0); } """, ) self.reference_texture = self.ctx.texture( (dataset.render_size, dataset.render_size), components=3) self.prediction_texture = self.ctx.texture( (dataset.render_size, dataset.render_size), components=3) self.reference_texture.repeat_x = False self.reference_texture.repeat_y = False self.prediction_texture.repeat_x = False self.prediction_texture.repeat_y = False self.reference_texture.use(5) self.prediction_texture.use(6) self.prog['aspect'].value = 12 / 6 T = pyrr.matrix44.create_from_translation(np.array([-0.5, 0.15, 0])) T2 = pyrr.matrix44.create_from_translation(np.array([0.5, 0.15, 0])) S = pyrr.matrix44.create_from_scale(np.array([0.4, 0.4, 1])) self.M = pyrr.matrix44.multiply(S, T) self.M2 = pyrr.matrix44.multiply(S, T2) self.transform = self.prog['transform'] self.transform.value = tuple(self.M.flatten()) self.observation_textures = [] self.observation_transforms = [] for i in range(1, settings.views_per_scene): self.observation_textures.append( self.ctx.texture((dataset.render_size, dataset.render_size), components=3)) self.observation_textures[-1].repeat_x = False self.observation_textures[-1].repeat_y = False self.observation_textures[-1].use(6 + i) T = pyrr.matrix44.create_from_translation( np.array([-0.825 + (i - 1) * 0.165, -0.825, 0])) S = pyrr.matrix44.create_from_scale(np.array([0.075, 0.075, 1])) M = pyrr.matrix44.multiply(S, T) self.observation_transforms.append(M) self.buffer_textures = [] self.buffer_transforms = [] for i in range(len(settings.model.generators[-1].query_passes)): self.buffer_textures.append( self.ctx.texture((dataset.render_size, dataset.render_size), components=3)) self.buffer_textures[-1].repeat_x = False self.buffer_textures[-1].repeat_y = False self.buffer_textures[-1].use(6 + settings.views_per_scene + i) T = pyrr.matrix44.create_from_translation( np.array([0.175 + i * 0.165, -0.825, 0])) S = pyrr.matrix44.create_from_scale(np.array([0.075, 0.075, 1])) M = pyrr.matrix44.multiply(S, T) self.buffer_transforms.append(M) self.camera = KeyboardCamera(self.wnd.keys, 45.0, 1.0, 0.1, 100.0) self.camera.position[0] = 1.5 self.camera.position[1] = 1.5 self.camera.position[2] = -1.5 self.camera._velocity = -2.5 self.camera._mouse_sensitivity = -0.1 self.quad = np.array([ -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0, 1.0, 0.0 ], dtype='f4') self.quad_vao = self.ctx.simple_vertex_array( self.prog, self.ctx.buffer(self.quad), 'in_vert') def render(self, time: float, frametime: float): # Load transform view = self.camera.matrix view_inverse = pyrr.matrix44.inverse(view) position = pyrr.matrix44.apply_to_vector( view_inverse, np.array([0.0, 0.0, 0.0, 1.0])) lookat = pyrr.matrix44.apply_to_vector(view_inverse, np.array([0.0, 0.0, 1.0, 1.0])) dataset.renderer.renderer.set_camera(position[:3], lookat[:3]) # Get reference and draw dataset.samples = samples queries = dataset.get_current_view() data["query_images"] = queries[0] data["query_poses"] = queries[1] reference = format_buffer( data["query_images"][settings.model.output_pass][0]) reference = reference.clamp(0, 1).numpy() reference = (reference * 255).astype(np.uint8) self.reference_texture.write(reference.tobytes()) self.prog['tex_sampler'].value = 5 self.transform.value = tuple(self.M.flatten()) self.quad_vao.render(mode=moderngl.TRIANGLES) # Draw observations for i in range(len(self.observation_textures)): observation = format_buffer( data["observation_images"][settings.model.output_pass][0][i]) observation = observation.clamp(0, 1).numpy() observation = (observation * 255).astype(np.uint8) self.observation_textures[i].write(observation.tobytes()) self.prog['tex_sampler'].value = 6 + 1 + i self.transform.value = tuple( self.observation_transforms[i].flatten()) self.quad_vao.render(mode=moderngl.TRIANGLES) # Draw G-buffer (TODO) for i in range(len(self.buffer_textures)): buffer = format_buffer(data["query_images"][ settings.model.generators[-1].query_passes[i]][0]) buffer = buffer.clamp(0, 1).numpy() buffer = (buffer * 255).astype(np.uint8) self.buffer_textures[i].write(buffer.tobytes()) self.prog['tex_sampler'].value = 6 + settings.views_per_scene + i self.transform.value = tuple(self.buffer_transforms[i].flatten()) self.quad_vao.render(mode=moderngl.TRIANGLES) # Network sample and draw prediction = net.sample(data) pred = format_buffer(prediction[-1][settings.model.output_pass][0]) pred = pred.clamp(0, 1).numpy() pred = (pred * 255).astype(np.uint8) self.prediction_texture.write(pred.tobytes()) self.prog['tex_sampler'].value = 6 self.transform.value = tuple(self.M2.flatten()) self.quad_vao.render(mode=moderngl.TRIANGLES) self.render_ui() def render_ui(self): global samples, observation_samples imgui.new_frame() imgui.begin("Options", True) if imgui.button("Random Scene"): random_scene() if imgui.button("Randomize Observations"): random_observations() _, samples = imgui.drag_int("Query SPP", samples, min_value=1, max_value=1024) _, observation_samples = imgui.drag_int("Observation SPP", observation_samples, min_value=1, max_value=1024) imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) def resize(self, width: int, height: int): self.imgui.resize(width, height) def key_event(self, key, action, modifiers): global samples, observation_samples self.imgui.key_event(key, action, modifiers) if action == self.wnd.keys.ACTION_PRESS: if key == self.wnd.keys.SPACE: self.space_down = True if key == self.wnd.keys.R: random_scene() if key == self.wnd.keys.O: random_observations() if key == self.wnd.keys.J: samples += 10 if key == self.wnd.keys.H: samples = max(1, samples - 10) if key == self.wnd.keys.M: observation_samples += 10 if key == self.wnd.keys.N: observation_samples = max(1, observation_samples - 10) if action == self.wnd.keys.ACTION_RELEASE: if key == self.wnd.keys.SPACE: self.space_down = False imgui.set_window_focus() if self.space_down: self.camera.key_input(key, action, modifiers) def mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) def mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) if self.space_down: self.camera.rot_state(dx, dy) def mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) def mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) def mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) def unicode_char_entered(self, char): self.imgui.unicode_char_entered(char)