git.s-ol.nu openxPriments / dd5b4fd
multiple GLTF Models, EXT_MSFT_controller_model support s-ol 1 year, 11 months ago
4 changed file(s) with 167 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
(No changes)
00 usingnamespace @import("xrvk.zig");
11 const std = @import("std");
2 const glm = @import("glm");
23 const gfx = @import("graphics.zig");
34 const scene = @import("scene.zig");
45 const renderdoc = @import("renderdoc.zig");
1112 session.deinit();
1213 }
1314
15 const Paths = struct {
16 user_hand_right: xr.Path,
17 user_hand_left: xr.Path,
18 user_hand_head: xr.Path,
19
20 pub fn init(xri: xr.InstanceDispatch, inst: xr.Instance) !Paths {
21 var self: Paths = undefined;
22
23 inline for (@typeInfo(Paths).Struct.fields) |field| {
24 var buffer: [field.name.len + 2:0]u8 = undefined;
25 _ = std.mem.replace(u8, field.name, "_", "/", buffer[1..]);
26 buffer[0] = '/';
27 buffer[buffer.len - 1] = 0;
28 @field(self, field.name) = try xri.stringToPath(inst, buffer[0..]);
29 }
30
31 return self;
32 }
33 };
34
1435 const Session = struct {
1536 xrb: xr.BaseDispatch,
1637 xri: xr.InstanceDispatch,
2344
2445 state: xr.SessionState,
2546 views: ?ViewInfo,
47 paths: Paths,
2648 graphics: gfx.Graphics,
2749 layers: []*const xr.CompositionLayerBaseHeader,
2850 scene_space: xr.Space,
4163 const zero = [_:0]u8{};
4264 const extensions = [_][*:0]const u8{
4365 "XR_KHR_vulkan_enable2",
66 "XR_MSFT_controller_model",
4467 };
4568
4669 const xrb = try xr.BaseDispatch.load(xr.getProcAddr);
6184
6285 const xri = try xr.InstanceDispatch.load(instance, xr.getProcAddr);
6386 errdefer xri.destroyInstance(instance) catch unreachable;
87
88 const paths = try Paths.init(xri, instance);
6489
6590 const system = try xri.getSystem(instance, .{ .form_factor = .head_mounted_display });
6691
118143
119144 .state = .idle,
120145 .views = null,
146 .paths = paths,
121147 .graphics = graphics,
122148 .scene_space = scene_space,
123149 .layers = &[_]*const xr.CompositionLayerBaseHeader{},
224250 try self.graphics.createSwapchain(self.session, views.configurations);
225251 var gfx_scene = try scene.Scene.init(&self.graphics);
226252
253 var helmet = scene.Model.initFile(&gfx_scene, "assets/DamagedHelmet.gltf");
254 helmet.setTransform(glm.translation(glm.Vec3.init([_]f32{ 0, 1.5, -2 })));
255 try gfx_scene.models.append(helmet);
256
257 for ([_]xr.Path{ self.paths.user_hand_left, self.paths.user_hand_right }) |path, i| {
258 var model_state = xr.ControllerModelKeyStateMSFT.empty();
259 try self.xri.getControllerModelKeyMSFT(self.session, path, &model_state);
260
261 if (model_state.model_key == 0)
262 continue;
263
264 const size = try self.xri.loadControllerModelMSFT(self.session, model_state.model_key, 0, null);
265 const buffer = try self.allocator.alloc(u8, size);
266 defer self.allocator.free(buffer);
267
268 _ = try self.xri.loadControllerModelMSFT(self.session, model_state.model_key, size, buffer.ptr);
269 var model = scene.Model.initMemory(&gfx_scene, buffer);
270
271 var transform = glm.Mat4.IDENTITY;
272 transform = transform.mul(glm.translation(glm.Vec3.init([_]f32{ 0.6 * (@intToFloat(f32, i) - 0.5), 1.5, -0.5 })));
273 transform = transform.mul(glm.rotation(0.9, glm.Vec3.init([_]f32{ 1, 0, 0 })));
274 model.setTransform(transform);
275 try gfx_scene.models.append(model);
276 }
277
227278 const composition_layer = try self.allocator.create(xr.CompositionLayerProjection);
228279 composition_layer.* = .{
229280 .layer_flags = .{ .blend_texture_source_alpha_bit = true },
254305 _ = try self.xri.waitFrame(self.session, null, &frame_state);
255306 _ = try self.xri.beginFrame(self.session, null);
256307 self.graphics.unlockQueue();
308
309 const predicted_seconds = @intToFloat(f32, frame_state.predicted_display_time) / 1_000_000_000;
310
311 var transform = glm.translation(glm.Vec3.init([_]f32{ 0, 1.5, -2 }));
312 transform = transform.mul(glm.rotation(predicted_seconds, glm.Vec3.init([_]f32{ 0, 1, 0 })));
313 gfx_scene.models.items[0].setTransform(transform);
257314
258315 var layer_count: u32 = 0;
259316
168168 .MaxLOD = 3.402823466e+38,
169169 };
170170
171 pub const Model = struct {
172 model: dg.IGLTFModel_Wrapper,
173 bindings: dg.GLTF_ModelResourceBindings,
174 params: dg.GLTF_RenderInfo,
175
176 const DEFAULT_PARAMS = dg.GLTF_RenderInfo{
177 .ModelTransform = @bitCast([16]f32, glm.Mat4.IDENTITY),
178 .AlphaModes = dg.ALPHA_MODE_FLAG_ALL,
179 .DebugView = 0,
180 .OcclusionStrength = 1,
181 .EmissionScale = 1,
182 .IBLScale = 1,
183 .AverageLogLum = 0.3,
184 .MiddleGray = 0.18,
185 .WhitePoint = 3,
186 };
187
188 pub fn initMemory(scene: *const Scene, data: []const u8) Model {
189 const model = dg.Diligent_IGLTFModel_Create(
190 @ptrCast(*dg.IRenderDevice, scene.dev.ptr),
191 scene.ctx.ptr,
192 &dg.IGLTFModelCreateInfo{
193 .FileName = null,
194 .Data = data.ptr,
195 .DataSize = data.len,
196 .FileType = ._BINARY,
197 .pTextureCache = null,
198 .pCacheInfo = null,
199 .LoadAnimationAndSkin = true,
200 },
201 );
202
203 return .{
204 .model = dg.IGLTFModel_Wrapper.wrap(model),
205 .bindings = scene.renderer.CreateResourceBindings(
206 model,
207 scene.camera_ubo.ptr,
208 scene.light_ubo.ptr,
209 ),
210 .params = DEFAULT_PARAMS,
211 };
212 }
213
214 pub fn initFile(scene: *const Scene, path: [:0]const u8) Model {
215 const model = dg.Diligent_IGLTFModel_Create(
216 @ptrCast(*dg.IRenderDevice, scene.dev.ptr),
217 scene.ctx.ptr,
218 &dg.IGLTFModelCreateInfo{
219 .FileName = path.ptr,
220 .Data = null,
221 .DataSize = 0,
222 .FileType = ._UNKNOWN,
223 .pTextureCache = null,
224 .pCacheInfo = null,
225 .LoadAnimationAndSkin = true,
226 },
227 );
228
229 return .{
230 .model = dg.IGLTFModel_Wrapper.wrap(model),
231 .bindings = scene.renderer.CreateResourceBindings(
232 model,
233 scene.camera_ubo.ptr,
234 scene.light_ubo.ptr,
235 ),
236 .params = DEFAULT_PARAMS,
237 };
238 }
239
240 pub fn deinit(self: *Model) void {
241 self.bindings.Release();
242 self.model.Release();
243 }
244
245 pub fn setTransform(self: *Model, mat: glm.Mat4) void {
246 self.params.ModelTransform = @bitCast([16]f32, mat);
247 }
248
249 pub fn draw(self: *Model, scene: *Scene) void {
250 scene.renderer.Render(
251 scene.ctx.ptr,
252 self.model.ptr,
253 &self.params,
254 &self.bindings,
255 null,
256 scene.resource_binding.ptr,
257 );
258 }
259 };
260
171261 pub const Scene = struct {
172262 viewports: []dg.Viewport,
173263 scissors: []dg.Rect,
179269 views: []ViewUBO,
180270
181271 renderer: dg.IGLTF_PBR_Renderer_Wrapper,
182 render_params: dg.GLTF_RenderInfo,
183 model: dg.IGLTFModel_Wrapper,
184 model_bindings: dg.GLTF_ModelResourceBindings,
272 models: std.ArrayList(Model),
185273 envmap: ?*dg.ITextureView,
186274
187275 ctx: dg.IDeviceContext_Wrapper,
376464
377465 self.renderer.PrecomputeCubemaps(@ptrCast(*dg.IRenderDevice, self.dev.ptr), self.ctx.ptr, self.envmap);
378466
379 const model = dg.Diligent_IGLTFModel_Create(
380 @ptrCast(*dg.IRenderDevice, self.dev.ptr),
381 self.ctx.ptr,
382 &dg.IGLTFModelCreateInfo{
383 .FileName = "assets/DamagedHelmet.gltf",
384 .pTextureCache = null,
385 .pCacheInfo = null,
386 .LoadAnimationAndSkin = true,
387 },
388 );
389 self.model = dg.IGLTFModel_Wrapper.wrap(model);
390
391 self.model_bindings = self.renderer.CreateResourceBindings(
392 self.model.ptr,
393 self.camera_ubo.ptr,
394 self.light_ubo.ptr,
395 );
396
397 self.render_params = .{
398 .ModelTransform = @bitCast([16]f32, glm.translation(glm.Vec3.init([_]f32{ 0, 1.5, -2 }))),
399 .AlphaModes = dg.ALPHA_MODE_FLAG_ALL,
400 .DebugView = 0,
401 .OcclusionStrength = 1,
402 .EmissionScale = 1,
403 .IBLScale = 1,
404 .AverageLogLum = 0.3,
405 .MiddleGray = 0.18,
406 .WhitePoint = 3,
407 };
467 // model
468 self.models = std.ArrayList(Model).init(gfx.allocator);
408469
409470 return self;
410471 }
411472
412473 pub fn deinit(self: *const Scene) void {
413 self.resource_binding.Release();
414474 self.views_ubo.Release();
415475 self.light_ubo.Release();
416476 self.camera_ubo.Release();
417477
418 self.model.Release();
478 for (self.models.items) |*model| {
479 model.deinit();
480 }
481 self.models.deinit();
419482 self.renderer.Release();
420
421 gfx.allocator.free(self.viewports);
422 gfx.allocator.free(self.scissors);
423 gfx.allocator.free(self.views);
483 self.resource_binding.Release();
484
485 self.gfx.allocator.free(self.viewports);
486 self.gfx.allocator.free(self.scissors);
487 self.gfx.allocator.free(self.views);
424488 }
425489
426490 pub fn render(self: *Scene, views: []const xr.View) !void {
482546
483547 // record renderpass
484548 self.renderer.Begin(self.ctx.ptr);
485 self.renderer.Render(self.ctx.ptr, self.model.ptr, &self.render_params, &self.model_bindings, null, self.resource_binding.ptr);
549 for (self.models.items) |*model| {
550 model.draw(self);
551 }
552
553 // self.renderer.Render(self.ctx.ptr, self.model.ptr, &self.render_params, &self.model_bindings, null, self.resource_binding.ptr);
486554 }
487555
488556 fn createShader(
5151 xrDestroyInstance: PfnDestroyInstance,
5252 xrGetSystem: PfnGetSystem,
5353 xrGetSystemProperties: PfnGetSystemProperties,
54 xrStringToPath: PfnStringToPath,
5455 xrCreateSession: PfnCreateSession,
5556 xrDestroySession: PfnDestroySession,
5657 xrBeginSession: PfnBeginSession,
7273 xrAcquireSwapchainImage: PfnAcquireSwapchainImage,
7374 xrWaitSwapchainImage: PfnWaitSwapchainImage,
7475 xrReleaseSwapchainImage: PfnReleaseSwapchainImage,
76 xrGetControllerModelKeyMSFT: PfnGetControllerModelKeyMSFT,
77 xrLoadControllerModelMSFT: PfnLoadControllerModelMSFT,
7578 usingnamespace InstanceWrapper(@This());
7679 };
7780