diff --git a/module.jai b/module.jai index 28d82c4..bd01a69 100644 --- a/module.jai +++ b/module.jai @@ -15,13 +15,11 @@ PLOT_DATA_STYLE :: enum { EVERY_FRAME; } -draw_plot :: (key: string, xdata: []float64, yarrays: [][]float64, using settings: PlotSettings, data_style := PLOT_DATA_STYLE.ONCE) { - plot_size := ImGui.GetContentRegionAvail(); - +draw_plot :: (key: string, size: Vector2, xdata: []float64, yarrays: [][]float64, using settings: PlotSettings, data_style := PLOT_DATA_STYLE.ONCE) { plot, success := table_find(*plots, key); if !success { plot = New(Plot); - init_plot(plot, key, xx plot_size.x, xx plot_size.y); + init_plot(plot, key, xx size.x, xx size.y); table_set(*plots, key, plot); if data_style == .ONCE { @@ -150,124 +148,132 @@ draw_plot :: (key: string, xdata: []float64, yarrays: [][]float64, using setting ImGui.RadioButton("Tick marks", xx *plot.plot_style, 0); ImGui.SameLine(); ImGui.RadioButton("Scale marker", xx *plot.plot_style, 1); - if plot.plot_style == { - case .TICK_MARKS; - plot.left_bearing = 40; - plot.bottom_bearing = 20; + child_size := ImGui.GetContentRegionAvail(); + child_size.y = 260; - case .SCALE_MARKER; - plot.left_bearing = 0; - plot.bottom_bearing = 20; - } + if ImGui.BeginChild(key.data, child_size, ImGui.ChildFlags.None, ImGui.WindowFlags.HorizontalScrollbar) { - child_pos := ImGui.GetCursorScreenPos(); - plot.x = xx child_pos.x; - plot.y = xx child_pos.y; + if plot.plot_style == { + case .TICK_MARKS; + plot.left_bearing = 40; + plot.bottom_bearing = 20; - //plot_size = .{plot_size.x, min(260.0, plot_size.y / workspace.f64_arrays.count)}; - - if plot_size.x < 0 || plot_size.y < 0 { - log("[Warning] The plot has dimensions lower than 0."); - } else { - if plot.width != cast(s32) plot_size.x || plot.height != cast(s32) plot_size.y { - plot_resize(plot, xx plot_size.x, xx plot_size.y); + case .SCALE_MARKER; + plot.left_bearing = 0; + plot.bottom_bearing = 20; } - ar : float = cast(float) plot.width / cast(float) plot.height; - pixel_size_x : float = (plot.xmax - plot.xmin) / plot.width; - pixel_size_y : float = (plot.ymax - plot.ymin) / plot.height; + child_pos := ImGui.GetCursorScreenPos(); + plot.x = xx child_pos.x; + plot.y = xx child_pos.y; - if is_in_rect(xy(xx plot.x, xx plot.y), xy(xx plot.width, xx plot.height), mouse) { - if mouse_left { - plot.pos.x += mouse_delta.x * pixel_size_x / plot.zoom; - plot.pos.y += -mouse_delta.y * pixel_size_y / plot.zoom; + //plot_size = .{plot_size.x, min(260.0, plot_size.y / workspace.f64_arrays.count)}; + + if plot.width < 0 || plot.height < 0 { + log("[Warning] The plot has dimensions lower than 0."); + } else { + if plot.width != cast(s32) size.x || plot.height != cast(s32) size.y { + plot_resize(plot, xx size.x, xx size.y); } - if !fixed_bounds { - plot.zoom += plot.zoom * (cast(float) mouse_wheel_delta * 0.1); + ar : float = cast(float) plot.width / cast(float) plot.height; + pixel_size_x : float = (plot.xmax - plot.xmin) / plot.width; + pixel_size_y : float = (plot.ymax - plot.ymin) / plot.height; - if plot.zoom < 0.01 { - plot.zoom = 0.01; + if is_in_rect(xy(xx plot.x, xx plot.y), xy(xx plot.width, xx plot.height), mouse) { + if mouse_left { + plot.pos.x += mouse_delta.x * pixel_size_x / plot.zoom; + plot.pos.y += -mouse_delta.y * pixel_size_y / plot.zoom; + } + + if !fixed_bounds { + plot.zoom += plot.zoom * (cast(float) mouse_wheel_delta * 0.1); + + if plot.zoom < 0.01 { + plot.zoom = 0.01; + } } } - } - - glBindFramebuffer(GL_FRAMEBUFFER, plot.fbo); - - glViewport(xx plot.left_bearing, xx plot.bottom_bearing, - xx (plot.width - plot.left_bearing), xx (plot.height - plot.bottom_bearing)); - - glClearColor(colors.background.x, colors.background.y, colors.background.z, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - draw_axis(plot, plot.plot_style, colors); - - if plot.plot_style == .SCALE_MARKER - draw_scale(plot, colors); - - glViewport(xx plot.left_bearing, xx plot.bottom_bearing, - xx (plot.width - plot.left_bearing), xx (plot.height - plot.bottom_bearing)); - - glBindVertexArray(plot.vao); - - glBindBuffer(GL_ARRAY_BUFFER, plot.xvbo); - glEnableVertexAttribArray(0); - glBufferData(GL_ARRAY_BUFFER, plot.xfloat.count * size_of(float), plot.xfloat.data, GL_DYNAMIC_DRAW); - glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, size_of(float), null); - - for yfloat: plot.yfloats { glBindFramebuffer(GL_FRAMEBUFFER, plot.fbo); - glBindBuffer(GL_ARRAY_BUFFER, plot.yvbo); - glEnableVertexAttribArray(1); - glBufferData(GL_ARRAY_BUFFER, yfloat.count * size_of(float), yfloat.data, GL_DYNAMIC_DRAW); - glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, size_of(float), null); + glViewport(xx plot.left_bearing, xx plot.bottom_bearing, + xx (plot.width - plot.left_bearing), xx (plot.height - plot.bottom_bearing)); - model := identity_of(Matrix4); - model = translate(model, .{plot.pos.x, plot.pos.y, 0.0}); - model = translate(model, .{plot.x_avg, plot.y_avg, 0.0}); - model = translate(model, .{-plot.pos.x, -plot.pos.y, 0.0}); - model = scale(model, .{plot.zoom, plot.zoom, 1.0}); - model = translate(model, .{plot.pos.x, plot.pos.y, 0.0}); - model = translate(model, .{-plot.x_avg, -plot.y_avg, 0.0}); + glClearColor(colors.background.x, colors.background.y, colors.background.z, 0.0); + glClear(GL_COLOR_BUFFER_BIT); - proj := orthographic_projection_matrix((plot.xmin), - (plot.xmax), - (plot.ymin), - (plot.ymax), -1.0, 1.0); + draw_axis(plot, plot.plot_style, colors); - glUseProgram(data_shader); + if plot.plot_style == .SCALE_MARKER + draw_scale(plot, colors); - glUniformMatrix4fv(glGetUniformLocation(data_shader, "model"), 1, GL_TRUE, xx *model); - glUniformMatrix4fv(glGetUniformLocation(data_shader, "proj"), 1, GL_TRUE, xx *proj); + glViewport(xx plot.left_bearing, xx plot.bottom_bearing, + xx (plot.width - plot.left_bearing), xx (plot.height - plot.bottom_bearing)); - color := data_colors[it_index % data_colors.count]; + glBindVertexArray(plot.vao); - glUniform4f(glGetUniformLocation(data_shader, "data_color"), color.x, color.y, color.z, color.w); + glBindBuffer(GL_ARRAY_BUFFER, plot.xvbo); + glEnableVertexAttribArray(0); + glBufferData(GL_ARRAY_BUFFER, plot.xfloat.count * size_of(float), plot.xfloat.data, GL_DYNAMIC_DRAW); + glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, size_of(float), null); - glDrawArrays(GL_LINE_STRIP, 0, xx (plot.xfloat.count)); + for yfloat: plot.yfloats { - //glBindFramebuffer(GL_READ_FRAMEBUFFER, plot.msfbo); - //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, plot.fbo); - //glBlitFramebuffer(0, 0, plot.width, plot.height, 0, 0, plot.width, plot.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_FRAMEBUFFER, plot.fbo); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, plot.yvbo); + glEnableVertexAttribArray(1); + glBufferData(GL_ARRAY_BUFFER, yfloat.count * size_of(float), yfloat.data, GL_DYNAMIC_DRAW); + glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, size_of(float), null); + + model := identity_of(Matrix4); + model = translate(model, .{plot.pos.x, plot.pos.y, 0.0}); + model = translate(model, .{plot.x_avg, plot.y_avg, 0.0}); + model = translate(model, .{-plot.pos.x, -plot.pos.y, 0.0}); + model = scale(model, .{plot.zoom, plot.zoom, 1.0}); + model = translate(model, .{plot.pos.x, plot.pos.y, 0.0}); + model = translate(model, .{-plot.x_avg, -plot.y_avg, 0.0}); + + proj := orthographic_projection_matrix((plot.xmin), + (plot.xmax), + (plot.ymin), + (plot.ymax), -1.0, 1.0); + + glUseProgram(data_shader); + + glUniformMatrix4fv(glGetUniformLocation(data_shader, "model"), 1, GL_TRUE, xx *model); + glUniformMatrix4fv(glGetUniformLocation(data_shader, "proj"), 1, GL_TRUE, xx *proj); + + color := data_colors[it_index % data_colors.count]; + + glUniform4f(glGetUniformLocation(data_shader, "data_color"), color.x, color.y, color.z, color.w); + + glDrawArrays(GL_LINE_STRIP, 0, xx (plot.xfloat.count)); + + //glBindFramebuffer(GL_READ_FRAMEBUFFER, plot.msfbo); + //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, plot.fbo); + //glBlitFramebuffer(0, 0, plot.width, plot.height, 0, 0, plot.width, plot.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + ImGui.Image(cast(ImGui.ImTextureID) plot.texture, size, .{0.0, 1.0}, .{1.0, 0.0}); + + plot.last_frame = frame; } - ImGui.Image(cast(ImGui.ImTextureID) plot.texture, plot_size, .{0.0, 1.0}, .{1.0, 0.0}); + if data_style == .EVERY_FRAME { + array_free(plot.xfloat); - plot.last_frame = frame; - } - - if data_style == .EVERY_FRAME { - array_free(plot.xfloat); - - for plot.yfloats { - array_free(it); - remove it; + for plot.yfloats { + array_free(it); + remove it; + } } + } + ImGui.EndChild(); } free_old_plots :: () { @@ -502,9 +508,9 @@ draw_axis :: (using plot: Plot, style: PLOT_STYLE, colors: PlotColors) { x_ticks := 10; for 0..x_ticks { - xpos : s64 = cast(s64) (cast(float) it / cast(float) x_ticks * cast(float) (content_width )); - xxx := (-0.5 + cast(float) it / cast(float) x_ticks) / zoom + 0.5; - xxx = xxx * (xmax - pos.x / zoom) + (1 - xxx) * (xmin - pos.x / zoom); + xpos : s64 = cast(s64) (cast(float) it / cast(float) x_ticks * cast(float) (content_width)); + xxx := (((cast(float) it / cast(float) x_ticks) - 0.5) / zoom) + 0.5; + xxx = xxx * (xmax - (pos.x)) + (1 - xxx) * (xmin - (pos.x)); array_add(*positions, .{cast(float) xpos, 0.0}); array_add(*positions, .{cast(float) xpos, cast(float) (content_height )}); @@ -523,7 +529,7 @@ draw_axis :: (using plot: Plot, style: PLOT_STYLE, colors: PlotColors) { for 0..y_ticks { ypos : s64 = cast(s64) (cast(float) it / cast(float) y_ticks * (content_height )); yyy := ((0.5) - cast(float) it / cast(float) y_ticks) / zoom + 0.5; - yyy = yyy * (ymax - pos.y / zoom) + (1 - yyy) * (ymin - pos.y / zoom); + yyy = yyy * (ymax - pos.y) + (1 - yyy) * (ymin - pos.y); array_add(*positions, .{0.0, cast(float) ypos}); array_add(*positions, .{cast(float) (content_width ), cast(float) ypos});