diff --git a/src/gears/game.d b/src/gears/game.d index 5b9e7c3..68e6c37 100644 --- a/src/gears/game.d +++ b/src/gears/game.d @@ -32,9 +32,6 @@ struct Game Camera camera; - u16 prev_x; - u16 prev_y; - Model model; } @@ -105,14 +102,9 @@ ProcessInputs(Game* g, Camera* cam) case Input.D: cam.velocity.x = pressed ? +1.0 : 0.0; break; case Input.MouseMotion: { - f32 x = cast(f32)(g.window.inputs[i].x) - cast(f32)(g.prev_x); - f32 y = cast(f32)(g.window.inputs[i].y) - cast(f32)(g.prev_y); - - cam.yaw += x / 200.0; - cam.pitch -= y / 200.0; - - g.prev_x = g.window.inputs[i].x; - g.prev_y = g.window.inputs[i].y; + // (0, 0) top left + cam.yaw -= cast(f32)(g.window.inputs[i].rel_x) / 200.0; + cam.pitch += cast(f32)(g.window.inputs[i].rel_y) / 200.0; } break; default: break; } @@ -123,12 +115,11 @@ void Update(Game* g, Camera* cam) { Mat4 rotation = RotationMatrix(cam); - cam.pos += (rotation * Vec4(cam.velocity * 0.5, 0.0)).xyz * g.delta; + cam.pos += (rotation * Vec4(cam.velocity, 0.0)).xyz * g.delta; Extent ext = GetExtent(&g.rd); g.globals.view_matrix = ViewMatrix(cam); - Mat4Identity(&g.globals.projection_matrix); Perspective(&g.globals.projection_matrix, Radians(70.0), cast(f32)(ext.x), cast(f32)(ext.y), 10000.0, 0.1); g.globals.projection_matrix[1, 1] *= -1.0; @@ -144,7 +135,7 @@ RotationMatrix(Camera* cam) Quat pitch_rotation, yaw_rotation; QuatFromAxis(&pitch_rotation, cam.pitch, Vec3(1.0, 0.0, 0.0)); QuatFromAxis(&yaw_rotation, cam.yaw, Vec3(0.0, -1.0, 0.0)); - return Inverse(cast(Mat4)(yaw_rotation) * cast(Mat4)(pitch_rotation)); + return cast(Mat4)(yaw_rotation) * cast(Mat4)(pitch_rotation); } pragma(inline): Mat4 @@ -153,7 +144,7 @@ ViewMatrix(Camera* cam) Mat4 translation; Translate(&translation, cam.pos); Mat4 rotation = RotationMatrix(cam); - return translation * rotation; + return Inverse(translation * rotation); } void diff --git a/src/gears/main.d b/src/gears/main.d index adb1f79..85ac218 100644 --- a/src/gears/main.d +++ b/src/gears/main.d @@ -16,6 +16,19 @@ void main() { PlatformWindow window = CreateWindow("Video Game", 1920, 1080); + Vec4 vec = Vec4(Vec3(22.0, 53.0, 3.0), 12.0); + + Mat4 mat = Mat4( + 1.0, 55.0, 23.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 123.0, 0.0, 13.0, 0.0, + 0.0, 77.0, 0.0, 17.0 + ); + + Vec4 res = mat * vec; + + Logf("%s", res.v); + Game g = InitGame(&window); scope(exit) Destroy(&g); diff --git a/src/gears/platform.d b/src/gears/platform.d index 21a6137..2be6df7 100644 --- a/src/gears/platform.d +++ b/src/gears/platform.d @@ -2,6 +2,10 @@ import aliases; import includes; import std.stdio; import core.memory; +import core.thread.osthread; +import core.time; + +const WINDOW_EDGE_BUFFER = 50; enum Input { @@ -48,6 +52,8 @@ struct InputEvent }; struct { + i32 rel_x; + i32 rel_y; u16 x; u16 y; }; @@ -63,6 +69,8 @@ struct PlatformWindow xcb_atom_t minimize_event; u16 w; u16 h; + i32 mouse_prev_x; + i32 mouse_prev_y; bool close; InputEvent[10] inputs; u32 input_count; @@ -189,20 +197,45 @@ PlatformWindow CreateWindow(string name, u16 width, u16 height) xcb_map_window(window.conn, window.window); - xcb_grab_pointer(window.conn, 1, window.window, 0, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, window.window, XCB_NONE, XCB_CURRENT_TIME); - i32 stream_result = xcb_flush(window.conn); assert(stream_result > 0, "xcb_flush failure"); + u32 counter = 0; + for(;;) + { + xcb_grab_pointer_cookie_t grab_cookie = xcb_grab_pointer(window.conn, true, window.window, 0, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, window.window, XCB_NONE, XCB_CURRENT_TIME); + xcb_grab_pointer_reply_t* grab_reply = xcb_grab_pointer_reply(window.conn, grab_cookie, &error); + if (grab_reply.status == XCB_GRAB_STATUS_SUCCESS) + { + break; + } + + assert(counter < 5, "Unable to grab cursor"); + counter += 1; + Thread.sleep(dur!("msecs")(50)); + } + return window; }; +void +FlushEvents(PlatformWindow* window) +{ + xcb_generic_event_t* e; + do + { + e = xcb_poll_for_event(window.conn); + } while (e); +} + void HandleEvents(PlatformWindow* window) { window.input_count = 0; xcb_generic_event_t* e; + + bool ignore_mouse_events = false; do { @@ -272,15 +305,52 @@ HandleEvents(PlatformWindow* window) } break; case XCB_MOTION_NOTIFY: { + if (ignore_mouse_events) continue; + xcb_motion_notify_event_t* move_event = cast(xcb_motion_notify_event_t*)e; - if (move_event.event_x > 0 || move_event.event_y > 0) + i16 x = move_event.event_x; + i16 y = move_event.event_y; + + static bool first = true; + if (first) + { + window.mouse_prev_x = x; + window.mouse_prev_y = y; + first = false; + } + + if (x > 0 || y > 0) { window.inputs[window.input_count].key = Input.MouseMotion; window.inputs[window.input_count].x = move_event.event_x; window.inputs[window.input_count].y = move_event.event_y; + window.inputs[window.input_count].rel_x = window.mouse_prev_x - x; + window.inputs[window.input_count].rel_y = window.mouse_prev_y - y; window.input_count += 1; } + + window.mouse_prev_x = x; + window.mouse_prev_y = y; + + if (x < WINDOW_EDGE_BUFFER || y < WINDOW_EDGE_BUFFER || x > window.w - WINDOW_EDGE_BUFFER || y > window.h - WINDOW_EDGE_BUFFER) + { + i16 new_x = cast(i16)(window.w / 2); + i16 new_y = cast(i16)(window.h / 2); + xcb_warp_pointer(window.conn, window.window, window.window, 0, 0, cast(i16)window.w, cast(i16)window.h, new_x, new_y); + window.mouse_prev_x = new_x; + window.mouse_prev_y = new_y; + ignore_mouse_events = true; + } + } break; + case XCB_CONFIGURE_NOTIFY: + { + xcb_configure_notify_event_t* config_event = cast(xcb_configure_notify_event_t*)e; + if (window.w != config_event.width || window.h != config_event.height) + { + window.w = config_event.width; + window.h = config_event.height; + } } break; default: break; diff --git a/src/gears/renderer.d b/src/gears/renderer.d index 41b3349..6243c16 100644 --- a/src/gears/renderer.d +++ b/src/gears/renderer.d @@ -198,8 +198,7 @@ DrawModel(Renderer* rd, Model* model) BindBuffers(&rd.vk, &model.index_buffer, &model.vertex_buffer); rd.push_const.model_matrix = Mat4Identity(); - //rd.push_const.model_matrix.translate(Vec3(1.0, 0.0, 0.0)); - //rd.push_const.model_matrix = rd.push_const.model_matrix.transposed(); + Translate(&rd.push_const.model_matrix, Vec3(0.0, 0.0, 0.0)); foreach(i, part; model.parts) {