diff options
| author | s-ol <s+removethis@s-ol.nu> | 2021-03-31 15:51:45 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2021-03-31 16:03:44 +0000 |
| commit | dd5b4fdcfdfdb20a352032541f65fb401e73afe9 (patch) | |
| tree | 8ba87d1db5d0d8ae6b306fdaaa19b5a1c7c51f50 /src | |
| parent | better DiligentEngine GLTF interface (diff) | |
| download | openxPriments-dd5b4fdcfdfdb20a352032541f65fb401e73afe9.tar.gz openxPriments-dd5b4fdcfdfdb20a352032541f65fb401e73afe9.zip | |
multiple GLTF Models, EXT_MSFT_controller_model support
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.zig | 57 | ||||
| -rw-r--r-- | src/scene.zig | 144 | ||||
| -rw-r--r-- | src/xrvk.zig | 3 |
3 files changed, 166 insertions, 38 deletions
diff --git a/src/main.zig b/src/main.zig index 7a3a40a..67ce8f0 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,5 +1,6 @@ usingnamespace @import("xrvk.zig"); const std = @import("std"); +const glm = @import("glm"); const gfx = @import("graphics.zig"); const scene = @import("scene.zig"); const renderdoc = @import("renderdoc.zig"); @@ -12,6 +13,26 @@ pub fn main() !void { session.deinit(); } +const Paths = struct { + user_hand_right: xr.Path, + user_hand_left: xr.Path, + user_hand_head: xr.Path, + + pub fn init(xri: xr.InstanceDispatch, inst: xr.Instance) !Paths { + var self: Paths = undefined; + + inline for (@typeInfo(Paths).Struct.fields) |field| { + var buffer: [field.name.len + 2:0]u8 = undefined; + _ = std.mem.replace(u8, field.name, "_", "/", buffer[1..]); + buffer[0] = '/'; + buffer[buffer.len - 1] = 0; + @field(self, field.name) = try xri.stringToPath(inst, buffer[0..]); + } + + return self; + } +}; + const Session = struct { xrb: xr.BaseDispatch, xri: xr.InstanceDispatch, @@ -24,6 +45,7 @@ const Session = struct { state: xr.SessionState, views: ?ViewInfo, + paths: Paths, graphics: gfx.Graphics, layers: []*const xr.CompositionLayerBaseHeader, scene_space: xr.Space, @@ -42,6 +64,7 @@ const Session = struct { const zero = [_:0]u8{}; const extensions = [_][*:0]const u8{ "XR_KHR_vulkan_enable2", + "XR_MSFT_controller_model", }; const xrb = try xr.BaseDispatch.load(xr.getProcAddr); @@ -63,6 +86,8 @@ const Session = struct { const xri = try xr.InstanceDispatch.load(instance, xr.getProcAddr); errdefer xri.destroyInstance(instance) catch unreachable; + const paths = try Paths.init(xri, instance); + const system = try xri.getSystem(instance, .{ .form_factor = .head_mounted_display }); var system_properties = xr.SystemProperties.empty(); @@ -119,6 +144,7 @@ const Session = struct { .state = .idle, .views = null, + .paths = paths, .graphics = graphics, .scene_space = scene_space, .layers = &[_]*const xr.CompositionLayerBaseHeader{}, @@ -225,6 +251,31 @@ const Session = struct { try self.graphics.createSwapchain(self.session, views.configurations); var gfx_scene = try scene.Scene.init(&self.graphics); + var helmet = scene.Model.initFile(&gfx_scene, "assets/DamagedHelmet.gltf"); + helmet.setTransform(glm.translation(glm.Vec3.init([_]f32{ 0, 1.5, -2 }))); + try gfx_scene.models.append(helmet); + + for ([_]xr.Path{ self.paths.user_hand_left, self.paths.user_hand_right }) |path, i| { + var model_state = xr.ControllerModelKeyStateMSFT.empty(); + try self.xri.getControllerModelKeyMSFT(self.session, path, &model_state); + + if (model_state.model_key == 0) + continue; + + const size = try self.xri.loadControllerModelMSFT(self.session, model_state.model_key, 0, null); + const buffer = try self.allocator.alloc(u8, size); + defer self.allocator.free(buffer); + + _ = try self.xri.loadControllerModelMSFT(self.session, model_state.model_key, size, buffer.ptr); + var model = scene.Model.initMemory(&gfx_scene, buffer); + + var transform = glm.Mat4.IDENTITY; + transform = transform.mul(glm.translation(glm.Vec3.init([_]f32{ 0.6 * (@intToFloat(f32, i) - 0.5), 1.5, -0.5 }))); + transform = transform.mul(glm.rotation(0.9, glm.Vec3.init([_]f32{ 1, 0, 0 }))); + model.setTransform(transform); + try gfx_scene.models.append(model); + } + const composition_layer = try self.allocator.create(xr.CompositionLayerProjection); composition_layer.* = .{ .layer_flags = .{ .blend_texture_source_alpha_bit = true }, @@ -256,6 +307,12 @@ const Session = struct { _ = try self.xri.beginFrame(self.session, null); self.graphics.unlockQueue(); + const predicted_seconds = @intToFloat(f32, frame_state.predicted_display_time) / 1_000_000_000; + + var transform = glm.translation(glm.Vec3.init([_]f32{ 0, 1.5, -2 })); + transform = transform.mul(glm.rotation(predicted_seconds, glm.Vec3.init([_]f32{ 0, 1, 0 }))); + gfx_scene.models.items[0].setTransform(transform); + var layer_count: u32 = 0; if (frame_state.should_render > 0) { diff --git a/src/scene.zig b/src/scene.zig index d71dc47..e7fbb5c 100644 --- a/src/scene.zig +++ b/src/scene.zig @@ -169,6 +169,96 @@ const defaultSampler = dg.SamplerDesc{ .MaxLOD = 3.402823466e+38, }; +pub const Model = struct { + model: dg.IGLTFModel_Wrapper, + bindings: dg.GLTF_ModelResourceBindings, + params: dg.GLTF_RenderInfo, + + const DEFAULT_PARAMS = dg.GLTF_RenderInfo{ + .ModelTransform = @bitCast([16]f32, glm.Mat4.IDENTITY), + .AlphaModes = dg.ALPHA_MODE_FLAG_ALL, + .DebugView = 0, + .OcclusionStrength = 1, + .EmissionScale = 1, + .IBLScale = 1, + .AverageLogLum = 0.3, + .MiddleGray = 0.18, + .WhitePoint = 3, + }; + + pub fn initMemory(scene: *const Scene, data: []const u8) Model { + const model = dg.Diligent_IGLTFModel_Create( + @ptrCast(*dg.IRenderDevice, scene.dev.ptr), + scene.ctx.ptr, + &dg.IGLTFModelCreateInfo{ + .FileName = null, + .Data = data.ptr, + .DataSize = data.len, + .FileType = ._BINARY, + .pTextureCache = null, + .pCacheInfo = null, + .LoadAnimationAndSkin = true, + }, + ); + + return .{ + .model = dg.IGLTFModel_Wrapper.wrap(model), + .bindings = scene.renderer.CreateResourceBindings( + model, + scene.camera_ubo.ptr, + scene.light_ubo.ptr, + ), + .params = DEFAULT_PARAMS, + }; + } + + pub fn initFile(scene: *const Scene, path: [:0]const u8) Model { + const model = dg.Diligent_IGLTFModel_Create( + @ptrCast(*dg.IRenderDevice, scene.dev.ptr), + scene.ctx.ptr, + &dg.IGLTFModelCreateInfo{ + .FileName = path.ptr, + .Data = null, + .DataSize = 0, + .FileType = ._UNKNOWN, + .pTextureCache = null, + .pCacheInfo = null, + .LoadAnimationAndSkin = true, + }, + ); + + return .{ + .model = dg.IGLTFModel_Wrapper.wrap(model), + .bindings = scene.renderer.CreateResourceBindings( + model, + scene.camera_ubo.ptr, + scene.light_ubo.ptr, + ), + .params = DEFAULT_PARAMS, + }; + } + + pub fn deinit(self: *Model) void { + self.bindings.Release(); + self.model.Release(); + } + + pub fn setTransform(self: *Model, mat: glm.Mat4) void { + self.params.ModelTransform = @bitCast([16]f32, mat); + } + + pub fn draw(self: *Model, scene: *Scene) void { + scene.renderer.Render( + scene.ctx.ptr, + self.model.ptr, + &self.params, + &self.bindings, + null, + scene.resource_binding.ptr, + ); + } +}; + pub const Scene = struct { viewports: []dg.Viewport, scissors: []dg.Rect, @@ -180,9 +270,7 @@ pub const Scene = struct { views: []ViewUBO, renderer: dg.IGLTF_PBR_Renderer_Wrapper, - render_params: dg.GLTF_RenderInfo, - model: dg.IGLTFModel_Wrapper, - model_bindings: dg.GLTF_ModelResourceBindings, + models: std.ArrayList(Model), envmap: ?*dg.ITextureView, ctx: dg.IDeviceContext_Wrapper, @@ -377,51 +465,27 @@ pub const Scene = struct { self.renderer.PrecomputeCubemaps(@ptrCast(*dg.IRenderDevice, self.dev.ptr), self.ctx.ptr, self.envmap); - const model = dg.Diligent_IGLTFModel_Create( - @ptrCast(*dg.IRenderDevice, self.dev.ptr), - self.ctx.ptr, - &dg.IGLTFModelCreateInfo{ - .FileName = "assets/DamagedHelmet.gltf", - .pTextureCache = null, - .pCacheInfo = null, - .LoadAnimationAndSkin = true, - }, - ); - self.model = dg.IGLTFModel_Wrapper.wrap(model); - - self.model_bindings = self.renderer.CreateResourceBindings( - self.model.ptr, - self.camera_ubo.ptr, - self.light_ubo.ptr, - ); - - self.render_params = .{ - .ModelTransform = @bitCast([16]f32, glm.translation(glm.Vec3.init([_]f32{ 0, 1.5, -2 }))), - .AlphaModes = dg.ALPHA_MODE_FLAG_ALL, - .DebugView = 0, - .OcclusionStrength = 1, - .EmissionScale = 1, - .IBLScale = 1, - .AverageLogLum = 0.3, - .MiddleGray = 0.18, - .WhitePoint = 3, - }; + // model + self.models = std.ArrayList(Model).init(gfx.allocator); return self; } pub fn deinit(self: *const Scene) void { - self.resource_binding.Release(); self.views_ubo.Release(); self.light_ubo.Release(); self.camera_ubo.Release(); - self.model.Release(); + for (self.models.items) |*model| { + model.deinit(); + } + self.models.deinit(); self.renderer.Release(); + self.resource_binding.Release(); - gfx.allocator.free(self.viewports); - gfx.allocator.free(self.scissors); - gfx.allocator.free(self.views); + self.gfx.allocator.free(self.viewports); + self.gfx.allocator.free(self.scissors); + self.gfx.allocator.free(self.views); } pub fn render(self: *Scene, views: []const xr.View) !void { @@ -483,7 +547,11 @@ pub const Scene = struct { // record renderpass self.renderer.Begin(self.ctx.ptr); - self.renderer.Render(self.ctx.ptr, self.model.ptr, &self.render_params, &self.model_bindings, null, self.resource_binding.ptr); + for (self.models.items) |*model| { + model.draw(self); + } + + // self.renderer.Render(self.ctx.ptr, self.model.ptr, &self.render_params, &self.model_bindings, null, self.resource_binding.ptr); } fn createShader( diff --git a/src/xrvk.zig b/src/xrvk.zig index 2a6d8d8..64428bc 100644 --- a/src/xrvk.zig +++ b/src/xrvk.zig @@ -52,6 +52,7 @@ pub const xr = struct { xrDestroyInstance: PfnDestroyInstance, xrGetSystem: PfnGetSystem, xrGetSystemProperties: PfnGetSystemProperties, + xrStringToPath: PfnStringToPath, xrCreateSession: PfnCreateSession, xrDestroySession: PfnDestroySession, xrBeginSession: PfnBeginSession, @@ -73,6 +74,8 @@ pub const xr = struct { xrAcquireSwapchainImage: PfnAcquireSwapchainImage, xrWaitSwapchainImage: PfnWaitSwapchainImage, xrReleaseSwapchainImage: PfnReleaseSwapchainImage, + xrGetControllerModelKeyMSFT: PfnGetControllerModelKeyMSFT, + xrLoadControllerModelMSFT: PfnLoadControllerModelMSFT, usingnamespace InstanceWrapper(@This()); }; |
