fixed wrong tick marks issue when zoomed

This commit is contained in:
Vicente Ferrari Smith 2024-12-17 14:56:21 +01:00
parent d9e44bca22
commit ce61ac812d

View File

@ -15,13 +15,11 @@ PLOT_DATA_STYLE :: enum {
EVERY_FRAME; EVERY_FRAME;
} }
draw_plot :: (key: string, xdata: []float64, yarrays: [][]float64, using settings: PlotSettings, data_style := PLOT_DATA_STYLE.ONCE) { draw_plot :: (key: string, size: Vector2, xdata: []float64, yarrays: [][]float64, using settings: PlotSettings, data_style := PLOT_DATA_STYLE.ONCE) {
plot_size := ImGui.GetContentRegionAvail();
plot, success := table_find(*plots, key); plot, success := table_find(*plots, key);
if !success { if !success {
plot = New(Plot); 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); table_set(*plots, key, plot);
if data_style == .ONCE { 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("Tick marks", xx *plot.plot_style, 0); ImGui.SameLine();
ImGui.RadioButton("Scale marker", xx *plot.plot_style, 1); ImGui.RadioButton("Scale marker", xx *plot.plot_style, 1);
if plot.plot_style == { child_size := ImGui.GetContentRegionAvail();
case .TICK_MARKS; child_size.y = 260;
plot.left_bearing = 40;
plot.bottom_bearing = 20;
case .SCALE_MARKER; if ImGui.BeginChild(key.data, child_size, ImGui.ChildFlags.None, ImGui.WindowFlags.HorizontalScrollbar) {
plot.left_bearing = 0;
plot.bottom_bearing = 20;
}
child_pos := ImGui.GetCursorScreenPos(); if plot.plot_style == {
plot.x = xx child_pos.x; case .TICK_MARKS;
plot.y = xx child_pos.y; plot.left_bearing = 40;
plot.bottom_bearing = 20;
//plot_size = .{plot_size.x, min(260.0, plot_size.y / workspace.f64_arrays.count)}; case .SCALE_MARKER;
plot.left_bearing = 0;
if plot_size.x < 0 || plot_size.y < 0 { plot.bottom_bearing = 20;
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);
} }
ar : float = cast(float) plot.width / cast(float) plot.height; child_pos := ImGui.GetCursorScreenPos();
pixel_size_x : float = (plot.xmax - plot.xmin) / plot.width; plot.x = xx child_pos.x;
pixel_size_y : float = (plot.ymax - plot.ymin) / plot.height; 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) { //plot_size = .{plot_size.x, min(260.0, plot_size.y / workspace.f64_arrays.count)};
if mouse_left {
plot.pos.x += mouse_delta.x * pixel_size_x / plot.zoom; if plot.width < 0 || plot.height < 0 {
plot.pos.y += -mouse_delta.y * pixel_size_y / plot.zoom; 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 { ar : float = cast(float) plot.width / cast(float) plot.height;
plot.zoom += plot.zoom * (cast(float) mouse_wheel_delta * 0.1); 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 { if is_in_rect(xy(xx plot.x, xx plot.y), xy(xx plot.width, xx plot.height), mouse) {
plot.zoom = 0.01; 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); glBindFramebuffer(GL_FRAMEBUFFER, plot.fbo);
glBindBuffer(GL_ARRAY_BUFFER, plot.yvbo); glViewport(xx plot.left_bearing, xx plot.bottom_bearing,
glEnableVertexAttribArray(1); xx (plot.width - plot.left_bearing), xx (plot.height - plot.bottom_bearing));
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); glClearColor(colors.background.x, colors.background.y, colors.background.z, 0.0);
model = translate(model, .{plot.pos.x, plot.pos.y, 0.0}); glClear(GL_COLOR_BUFFER_BIT);
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), draw_axis(plot, plot.plot_style, colors);
(plot.xmax),
(plot.ymin),
(plot.ymax), -1.0, 1.0);
glUseProgram(data_shader); if plot.plot_style == .SCALE_MARKER
draw_scale(plot, colors);
glUniformMatrix4fv(glGetUniformLocation(data_shader, "model"), 1, GL_TRUE, xx *model); glViewport(xx plot.left_bearing, xx plot.bottom_bearing,
glUniformMatrix4fv(glGetUniformLocation(data_shader, "proj"), 1, GL_TRUE, xx *proj); 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_FRAMEBUFFER, plot.fbo);
//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); 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; for plot.yfloats {
} array_free(it);
remove it;
if data_style == .EVERY_FRAME { }
array_free(plot.xfloat);
for plot.yfloats {
array_free(it);
remove it;
} }
} }
ImGui.EndChild();
} }
free_old_plots :: () { free_old_plots :: () {
@ -502,9 +508,9 @@ draw_axis :: (using plot: Plot, style: PLOT_STYLE, colors: PlotColors) {
x_ticks := 10; x_ticks := 10;
for 0..x_ticks { for 0..x_ticks {
xpos : s64 = cast(s64) (cast(float) it / cast(float) x_ticks * cast(float) (content_width )); 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 := (((cast(float) it / cast(float) x_ticks) - 0.5) / zoom) + 0.5;
xxx = xxx * (xmax - pos.x / zoom) + (1 - xxx) * (xmin - pos.x / zoom); xxx = xxx * (xmax - (pos.x)) + (1 - xxx) * (xmin - (pos.x));
array_add(*positions, .{cast(float) xpos, 0.0}); array_add(*positions, .{cast(float) xpos, 0.0});
array_add(*positions, .{cast(float) xpos, cast(float) (content_height )}); 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 { for 0..y_ticks {
ypos : s64 = cast(s64) (cast(float) it / cast(float) y_ticks * (content_height )); 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 := ((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, .{0.0, cast(float) ypos});
array_add(*positions, .{cast(float) (content_width ), cast(float) ypos}); array_add(*positions, .{cast(float) (content_width ), cast(float) ypos});