cursor fixes, add locking/unlocking cursor
This commit is contained in:
parent
b24ff3cb8e
commit
0c8169713d
Binary file not shown.
2
dub.json
2
dub.json
@ -11,7 +11,7 @@
|
||||
"sourceFiles-windows": [],
|
||||
"importPaths": ["src/gears", "src/shared", "src/generated", "external/xxhash", "external/inteli"],
|
||||
"sourcePaths": ["src/gears", "src/shared", "src/generated", "external/xxhash", "external/inteli"],
|
||||
"libs-linux": ["xcb", "X11", "X11-xcb", "vulkan", "stdc++"],
|
||||
"libs-linux": ["xcb", "X11", "X11-xcb", "vulkan", "stdc++", "xcb-xfixes"],
|
||||
"libs-windows": [],
|
||||
"preGenerateCommands-linux": ["./build.sh", "build/Packer"],
|
||||
"preGenerateCommands-windows": [],
|
||||
|
||||
@ -83,7 +83,9 @@ InitGame(PlatformWindow* window)
|
||||
g.ui_pipeline = BuildGfxPipeline(&g.rd, &ui_info);
|
||||
g.compute_pipeline = BuildCompPipeline(&g.rd, &gradient_info);
|
||||
|
||||
g.model = LoadModel(&g.rd, "models/yoda.m3d");
|
||||
PrintShader(&g.rd, &g.pbr_pipeline, VK_SHADER_STAGE_VERTEX_BIT);
|
||||
|
||||
g.model = LoadModel(&g.rd, "models/Tree01.m3d");
|
||||
|
||||
return g;
|
||||
}
|
||||
@ -190,6 +192,7 @@ Cycle(Game* g)
|
||||
void
|
||||
Destroy(Game* g)
|
||||
{
|
||||
WaitIdle(&g.rd);
|
||||
Destroy(&g.rd, &g.pbr_pipeline);
|
||||
Destroy(&g.rd, &g.triangle_pipeline);
|
||||
Destroy(&g.rd, &g.ui_pipeline);
|
||||
|
||||
@ -11,24 +11,13 @@ import math;
|
||||
// TODO:
|
||||
// 1. Remove bindless (informed to be perf death)
|
||||
// 2. Set up VK_AMD_shader_info
|
||||
// 3. Determine how to better handle inputs
|
||||
// 4. Make assets loaded from the disk in debug mode
|
||||
|
||||
void main()
|
||||
void main(string[] argv)
|
||||
{
|
||||
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);
|
||||
|
||||
|
||||
@ -64,6 +64,7 @@ struct PlatformWindow
|
||||
{
|
||||
Display *display;
|
||||
xcb_connection_t *conn;
|
||||
xcb_screen_t *screen;
|
||||
xcb_window_t window;
|
||||
xcb_atom_t close_event;
|
||||
xcb_atom_t minimize_event;
|
||||
@ -71,6 +72,7 @@ struct PlatformWindow
|
||||
u16 h;
|
||||
i32 mouse_prev_x;
|
||||
i32 mouse_prev_y;
|
||||
bool locked_cursor;
|
||||
bool close;
|
||||
InputEvent[10] inputs;
|
||||
u32 input_count;
|
||||
@ -112,7 +114,7 @@ PlatformWindow CreateWindow(string name, u16 width, u16 height)
|
||||
|
||||
xcb_setup_t *setup = xcb_get_setup(window.conn);
|
||||
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
|
||||
xcb_screen_t *screen = iter.data;
|
||||
window.screen = iter.data;
|
||||
|
||||
i32 event_mask = XCB_EVENT_MASK_EXPOSURE |
|
||||
XCB_EVENT_MASK_KEY_PRESS |
|
||||
@ -122,7 +124,7 @@ PlatformWindow CreateWindow(string name, u16 width, u16 height)
|
||||
XCB_EVENT_MASK_POINTER_MOTION |
|
||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||
|
||||
i32[] val_win = [screen.black_pixel, event_mask];
|
||||
i32[] val_win = [window.screen.black_pixel, event_mask];
|
||||
i32 val_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
|
||||
|
||||
window.window = xcb_generate_id(window.conn);
|
||||
@ -131,23 +133,25 @@ PlatformWindow CreateWindow(string name, u16 width, u16 height)
|
||||
window.conn,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
window.window,
|
||||
screen.root,
|
||||
window.screen.root,
|
||||
0, // x pos
|
||||
0, // y pos
|
||||
window.w, // width
|
||||
window.h, // height
|
||||
0,
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||
screen.root_visual,
|
||||
window.screen.root_visual,
|
||||
val_mask,
|
||||
val_win.ptr
|
||||
);
|
||||
error = xcb_request_check(window.conn, cookie);
|
||||
CheckErr(&window, &cookie, error, "xcb_create_window failure");
|
||||
pureFree(error);
|
||||
|
||||
cookie = xcb_map_window_checked(window.conn, window.window);
|
||||
error = xcb_request_check(window.conn, cookie);
|
||||
CheckErr(&window, &cookie, error, "xcb_map_window_checked failure");
|
||||
pureFree(error);
|
||||
|
||||
cookie = xcb_change_property_checked(
|
||||
window.conn,
|
||||
@ -161,19 +165,22 @@ PlatformWindow CreateWindow(string name, u16 width, u16 height)
|
||||
);
|
||||
error = xcb_request_check(window.conn, cookie);
|
||||
CheckErr(&window, &cookie, error, "xcb_change_property_checked failure");
|
||||
pureFree(error);
|
||||
|
||||
xcb_intern_atom_cookie_t c_proto = xcb_intern_atom(window.conn, 1, 12, "WM_PROTOCOLS");
|
||||
xcb_intern_atom_reply_t *r_proto = xcb_intern_atom_reply(window.conn, c_proto, &error);
|
||||
CheckErr(&window, &cookie, error, "xcb_intern_atom WM_PROTOCOLS failure");
|
||||
pureFree(error);
|
||||
|
||||
xcb_intern_atom_cookie_t c_close = xcb_intern_atom(window.conn, 0, 16, "WM_DELETE_WINDOW");
|
||||
xcb_intern_atom_reply_t *r_close = xcb_intern_atom_reply(window.conn, c_close, &error);
|
||||
CheckErr(&window, &cookie, error, "xcb_intern_atom WM_DELETE_WINDOW failure");
|
||||
pureFree(error);
|
||||
|
||||
xcb_intern_atom_cookie_t c_minimize = xcb_intern_atom(window.conn, 0, 20, "_NET_WM_STATE_HIDDEN");
|
||||
xcb_intern_atom_reply_t *r_minimize = xcb_intern_atom_reply(window.conn, c_minimize, &error);
|
||||
CheckErr(&window, &cookie, error, "xcb_intern_atom _NET_WM_STATE_HIDDEN failure");
|
||||
|
||||
pureFree(error);
|
||||
|
||||
cookie = xcb_change_property_checked(
|
||||
window.conn,
|
||||
@ -187,6 +194,7 @@ PlatformWindow CreateWindow(string name, u16 width, u16 height)
|
||||
);
|
||||
error = xcb_request_check(window.conn, cookie);
|
||||
CheckErr(&window, &cookie, error, "xcb_change_property_checked failure");
|
||||
pureFree(error);
|
||||
|
||||
window.close_event = r_close.atom;
|
||||
window.minimize_event = r_minimize.atom;
|
||||
@ -200,11 +208,27 @@ PlatformWindow CreateWindow(string name, u16 width, u16 height)
|
||||
i32 stream_result = xcb_flush(window.conn);
|
||||
assert(stream_result > 0, "xcb_flush failure");
|
||||
|
||||
xcb_xfixes_query_version(window.conn, 4, 0);
|
||||
|
||||
return window;
|
||||
};
|
||||
|
||||
void
|
||||
LockCursor(PlatformWindow* window)
|
||||
{
|
||||
u32 counter = 0;
|
||||
for(;;)
|
||||
{
|
||||
xcb_generic_error_t *error;
|
||||
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);
|
||||
|
||||
scope(exit)
|
||||
{
|
||||
pureFree(error);
|
||||
pureFree(grab_reply);
|
||||
}
|
||||
|
||||
if (grab_reply.status == XCB_GRAB_STATUS_SUCCESS)
|
||||
{
|
||||
break;
|
||||
@ -215,8 +239,36 @@ PlatformWindow CreateWindow(string name, u16 width, u16 height)
|
||||
Thread.sleep(dur!("msecs")(50));
|
||||
}
|
||||
|
||||
return window;
|
||||
};
|
||||
HideCursor(window);
|
||||
window.locked_cursor = true;
|
||||
}
|
||||
|
||||
void
|
||||
UnlockCursor(PlatformWindow* window)
|
||||
{
|
||||
xcb_ungrab_pointer(window.conn, XCB_CURRENT_TIME);
|
||||
ShowCursor(window);
|
||||
window.locked_cursor = false;
|
||||
}
|
||||
|
||||
// TODO: improve error handling for show/hide cursor
|
||||
void
|
||||
HideCursor(PlatformWindow* window)
|
||||
{
|
||||
xcb_void_cookie_t hide_cursor_cookie = xcb_xfixes_hide_cursor_checked(window.conn, window.window);
|
||||
xcb_generic_error_t *error = xcb_request_check(window.conn, hide_cursor_cookie);
|
||||
CheckErr(window, &hide_cursor_cookie, error, "xcb_xfixes_hide_cursor_checked failure");
|
||||
pureFree(error);
|
||||
}
|
||||
|
||||
void
|
||||
ShowCursor(PlatformWindow* window)
|
||||
{
|
||||
xcb_void_cookie_t show_cursor_cookie = xcb_xfixes_show_cursor_checked(window.conn, window.window);
|
||||
xcb_generic_error_t *error = xcb_request_check(window.conn, show_cursor_cookie);
|
||||
CheckErr(window, &show_cursor_cookie, error, "xcb_xfixes_show_cursor_checked failure");
|
||||
pureFree(error);
|
||||
}
|
||||
|
||||
void
|
||||
FlushEvents(PlatformWindow* window)
|
||||
@ -279,6 +331,15 @@ HandleEvents(PlatformWindow* window)
|
||||
window.inputs[window.input_count].key = input;
|
||||
window.inputs[window.input_count].pressed = pressed;
|
||||
window.input_count += 1;
|
||||
|
||||
if (input == KBI.F2)
|
||||
{
|
||||
LockCursor(window);
|
||||
}
|
||||
else if (input == KBI.F3)
|
||||
{
|
||||
UnlockCursor(window);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case XCB_BUTTON_PRESS:
|
||||
@ -333,7 +394,8 @@ HandleEvents(PlatformWindow* window)
|
||||
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)
|
||||
if (window.locked_cursor &&
|
||||
(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);
|
||||
|
||||
@ -4,7 +4,7 @@ import assets;
|
||||
import util;
|
||||
import alloc;
|
||||
import vulkan;
|
||||
import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRender, SetUniform, PrepComputeDrawImage, Dispatch, FinishFrame, BeginFrame;
|
||||
import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRender, SetUniform, PrepComputeDrawImage, Dispatch, FinishFrame, BeginFrame, WaitIdle;
|
||||
import assets;
|
||||
import std.math.traits : isNaN;
|
||||
import util : Logf;
|
||||
@ -522,3 +522,15 @@ Destroy(Renderer* rd, Pipeline* pipeline)
|
||||
{
|
||||
Destroy(&rd.vk, pipeline);
|
||||
}
|
||||
|
||||
void
|
||||
WaitIdle(Renderer* rd)
|
||||
{
|
||||
WaitIdle(&rd.vk);
|
||||
}
|
||||
|
||||
void
|
||||
PrintShader(Renderer* rd, Pipeline* pipeline, VkShaderStageFlagBits stage)
|
||||
{
|
||||
PrintShaderDisassembly(&rd.vk, pipeline, stage);
|
||||
}
|
||||
|
||||
@ -48,12 +48,28 @@ version(Windows)
|
||||
const char*[] VK_INSTANCE_EXT_DEBUG = VK_INSTANCE_EXT ~ [ cast(char*)VK_EXT_DEBUG_UTILS_EXTENSION_NAME ];
|
||||
}
|
||||
|
||||
const char*[] VK_DEVICE_EXTENSIONS = [
|
||||
const char*[] VK_BASE_DEVICE_EXTENSIONS = [
|
||||
cast(char*)VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||
cast(char*)VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME,
|
||||
cast(char*)VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
|
||||
];
|
||||
|
||||
const char*[] VK_AMD_DEVICE_EXTENSIONS = [
|
||||
cast(char*)VK_AMD_SHADER_INFO_EXTENSION_NAME,
|
||||
];
|
||||
|
||||
version(AMD_GPU)
|
||||
{
|
||||
debug
|
||||
{
|
||||
const char*[] VK_DEVICE_EXTENSIONS = VK_AMD_DEVICE_EXTENSIONS ~ VK_BASE_DEVICE_EXTENSIONS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char*[] VK_DEVICE_EXTENSIONS = VK_BASE_DEVICE_EXTENSIONS;
|
||||
}
|
||||
|
||||
const VkFormat[] VK_IMAGE_FORMATS = [
|
||||
VK_FORMAT_R16G16B16A16_UNORM,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
@ -1473,6 +1489,12 @@ SetUniform(Vulkan* vk, GlobalUniforms* globals)
|
||||
vkUpdateDescriptorSets(vk.device, 1, &write, 0, null);
|
||||
}
|
||||
|
||||
void
|
||||
WaitIdle(Vulkan* vk)
|
||||
{
|
||||
vkDeviceWaitIdle(vk.device);
|
||||
}
|
||||
|
||||
void
|
||||
Destroy(Vulkan* vk, Shader shader)
|
||||
{
|
||||
@ -2930,13 +2952,16 @@ PrintShaderDisassembly(Vulkan* vk, Pipeline* pipeline, VkShaderStageFlagBits sta
|
||||
{
|
||||
version(AMD_GPU)
|
||||
{
|
||||
u64 size;
|
||||
VkResult result = vkGetShaderInfoAMD(vk.device, pipeline.handle, stage, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, &size, null);
|
||||
if (result == VK_SUCCESS)
|
||||
debug
|
||||
{
|
||||
u8[] buf = AllocArray!(u8)(vk.frame_arenas[vk.frame_index], size);
|
||||
vkGetShaderInfoAMD(vk.device, pipeline.handle, stage, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, &size, buf.ptr);
|
||||
Logf("DISASSEMBLY:\n%r", buf);
|
||||
u64 size;
|
||||
VkResult result = vkGetShaderInfoAMD(vk.device, pipeline.handle, stage, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, &size, null);
|
||||
if (result == VK_SUCCESS)
|
||||
{
|
||||
u8[] buf = AllocArray!(u8)(&vk.frame_arenas[vk.frame_index], size);
|
||||
vkGetShaderInfoAMD(vk.device, pipeline.handle, stage, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, &size, buf.ptr);
|
||||
Logf("DISASSEMBLY:\n%r", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,9 +43,13 @@ version(Windows)
|
||||
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR = null;
|
||||
};
|
||||
|
||||
debug
|
||||
|
||||
version(AMD_GPU)
|
||||
{
|
||||
PFN_vkGetShaderInfoAMD vkGetShaderInfoAMD = null;
|
||||
debug
|
||||
{
|
||||
PFN_vkGetShaderInfoAMD vkGetShaderInfoAMD = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -212,7 +216,11 @@ LoadDeviceFunctions(Vulkan* vk)
|
||||
|
||||
version(AMD_GPU)
|
||||
{
|
||||
vkGetShaderInfoAMD = cast(PFN_vkGetShaderInfoAMD)vkGetShaderInfoAMD(vk.device, "vkGetShaderInfoAMD");
|
||||
debug
|
||||
{
|
||||
vkGetShaderInfoAMD = cast(PFN_vkGetShaderInfoAMD)vkGetDeviceProcAddr(vk.device, "vkGetShaderInfoAMD");
|
||||
assert(vkGetShaderInfoAMD != null, "vkGetShaderInfoAMD pointer is null");
|
||||
}
|
||||
}
|
||||
|
||||
assert(vkCreateSwapchainKHR != null, "LoadDeviceFunctions failure: function pointer is null");
|
||||
|
||||
@ -29,7 +29,7 @@ void main()
|
||||
if (Materials[nonuniformEXT(PC.mat_id)].albedo_has_texture)
|
||||
{
|
||||
vec4 tex_col = texture(sampler2D(Textures[nonuniformEXT(Materials[nonuniformEXT(PC.mat_id)].albedo_texture)], SamplerNearest), in_uv);
|
||||
col = mix(col, tex_col, 0.5);
|
||||
col = col * tex_col;
|
||||
}
|
||||
|
||||
out_col = col;
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
#ifdef __linux__
|
||||
# include <xcb/xcb.h>
|
||||
# include <xcb/xfixes.h>
|
||||
# include <X11/XKBlib.h>
|
||||
# include <X11/Xlib-xcb.h>
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/keysym.h>
|
||||
# include <X11/extensions/Xfixes.h>
|
||||
#endif
|
||||
|
||||
#if __linux__
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user