mat4 u_window;
};
+layout(std140) uniform u_world_matrix_block {
+ mat4 u_world;
+ mat4 u_model;
+};
+
void main() {
- gl_Position = u_window * vec4(mix(a_pos_top_left, a_pos_bottom_right, a_interp), 0, 1);
+ gl_Position = u_window * u_world * u_model * vec4(mix(a_pos_top_left, a_pos_bottom_right, a_interp), 0, 1);
v_texture = mix(a_tex_top_left, a_tex_bottom_right, a_interp);
}
mat4 u_window;
};
+layout(std140) uniform u_world_matrix_block {
+ mat4 u_world;
+ mat4 u_model;
+};
+
void main() {
- gl_Position = u_window * vec4(a_pos, 0, 1);
+ gl_Position = u_window * u_world * u_model * vec4(a_pos, 0, 1);
v_tex = a_tex;
v_col = a_col;
}
#local render_entity_fields :: (entity: ^Entity, x, y, w, h: f32) {
assert(entity != null, "entity is null");
+ if active_index >= 0 {
+ scrolling_region_start(.{x - sidebar_width, y, w + sidebar_width, h});
+ } else {
+ scrolling_region_start(.{x, y, w, h});
+ }
+ defer scrolling_region_stop();
+
info := cast(^type_info.Type_Info_Struct) type_info.get_type_info(entity.schematic);
if info != null {
font_print(editor_big_font, x + 2, y + 24, info.name);
w := sidebar_width / 2;
h := 200.0f;
x := ~~ window_width - sidebar_width;
- y = math.min(y, ~~ window_height - h);
immediate_set_color(.{.3,.3,.3});
immediate_rectangle(x, y, w, h);
font_shader = shader_make("./assets/shaders/font.glsl");
shader_use(font_shader);
shader_link_window_matrix_block(font_shader);
+ shader_link_world_matrix_block(font_shader);
glGenVertexArrays(1, ^font_vao);
glBindVertexArray(font_vao);
imgui_shader = shader_make(Shader_Path);
shader_use(imgui_shader);
shader_link_window_matrix_block(imgui_shader);
+ shader_link_world_matrix_block(imgui_shader);
shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 0.0f);
shader_set_uniform(imgui_shader, #cstr "u_texture", 0);
}
}
+immediate_set_scroll :: (scroll_x, scroll_y: f32) {
+ offset = .{ scroll_x, scroll_y };
+ update_model_matrix(offset);
+}
+
+immediate_get_scroll :: () => offset;
+
Color :: struct {
r, g, b : f32;
a := 1.0f;
}
scissors: [..] Scissor;
+ offset: Vector2;
+
set_rendering_type :: (new_type: typeof rendering_type) {
if rendering_type != new_type {
immediate_flush();
}
+
+scrolling_region_start :: (r: Rect, max_y_scroll := 10000.0f, site := #callsite, increment := 0) {
+ hash := get_site_hash(site, increment);
+ mx, my := mouse_get_position();
+ state := map.get_ptr(^scroll_states, hash);
+ if state == null {
+ animation_states[hash] = .{};
+ state = ^scroll_states[hash];
+ }
+
+ contains := Rect.contains(r, .{~~mx, ~~my});
+ if contains {
+ scroll_delta := mouse_get_scroll_vector();
+ state.xscroll -= scroll_delta.x * 20;
+ state.yscroll -= scroll_delta.y * 20;
+
+ state.yscroll = math.clamp(state.yscroll, 0, max_y_scroll);
+ }
+
+ immediate_flush();
+ immediate_push_scissor(r.x, r.y, r.w, r.h);
+ immediate_set_scroll(-state.xscroll, -state.yscroll);
+}
+
+scrolling_region_stop :: () {
+ immediate_flush();
+ immediate_pop_scissor();
+ immediate_set_scroll(0, 0);
+}
+
+
+
#local {
hot_item : UI_Id = 0
active_item : UI_Id = 0
return false;
}
+
+ Scroll_State :: struct {
+ xscroll: f32;
+ yscroll: f32;
+ }
+
+ scroll_states : Map(UI_Id, Scroll_State);
+
get_site_hash :: macro (site: CallSite, increment := 0) -> UI_Id {
hash :: package core.hash
file_hash := hash.to_u32(site.file);
use package core
use package glfw3
+// If you are offseting the mouse coordinate for world space
+// or UI scrolling etc., set this function to be the function
+// to ask for the current offset. Currently scaling the mouse
+// coordinate is not supported, only linear translations.
+Mouse_Offset_Function :: immediate_get_scroll
+
+
#local {
keys_this_frame : [..] u32 // Keys currently being pressed this frame
keys_pulse_frame : [..] u32 // Keys pressed during this frame, only set once per keypress
buttons_this_frame: [8] bool // Mouse buttons being pressed this frame
buttons_last_frame: [8] bool // Mouse buttons being pressed last frame
+
+ scroll_x: f64
+ scroll_y: f64
}
input_update :: () {
last_mouse_x = mouse_x;
last_mouse_y = mouse_y;
+ scroll_x = 0;
+ scroll_y = 0;
}
input_get_keys_this_frame :: () -> [] u32 {
}
mouse_get_position :: () -> (f64, f64) {
- return mouse_x, mouse_y;
+ mx, my := mouse_x, mouse_y;
+ #if #defined(Mouse_Offset_Function) {
+ scroll := Mouse_Offset_Function();
+ mx -= ~~ scroll.x;
+ my -= ~~ scroll.y;
+ }
+ return mx, my;
}
mouse_get_position_vector :: () -> Vector2 {
- return .{ ~~mouse_x, ~~mouse_y };
+ mx, my := mouse_x, mouse_y;
+ #if #defined(Mouse_Offset_Function) {
+ scroll := Mouse_Offset_Function();
+ mx -= ~~ scroll.x;
+ my -= ~~ scroll.y;
+ }
+ return .{ ~~mx, ~~my };
}
+mouse_get_scroll :: () -> (f64, f64) {
+ return scroll_x, scroll_y;
+}
+
+mouse_get_scroll_vector :: () -> Vector2 {
+ return .{ ~~scroll_x, ~~scroll_y };
+}
input_bind_glfw_events :: (window: GLFWwindow_p) {
glfwSetKeyCallback(window, INPUT_KEY_EVENT);
glfwSetMouseButtonCallback(window, INPUT_BUTTON_EVENT);
+ glfwSetScrollCallback(window, INPUT_SCROLL_EVENT);
}
#local {
INPUT_BUTTON_EVENT :: "__input_button_event"
INPUT_KEY_EVENT :: "__input_key_event"
+ INPUT_SCROLL_EVENT :: "__input_scroll_event"
}
#export INPUT_BUTTON_EVENT (window: GLFWwindow_p, button, action, mod: u32) {
array.remove(^keys_this_frame, key);
}
}
+
+#export INPUT_SCROLL_EVENT (window: GLFWwindow_p, xoff, yoff: f64) {
+ scroll_x = xoff;
+ scroll_y = yoff;
+}