|  |  | @ -18,7 +18,12 @@ const VertexData = primitives.VertexData; | 
			
		
	
		
		
			
				
					
					|  |  |  | const PrimitiveData = primitives.PrimitiveData; |  |  |  | const PrimitiveData = primitives.PrimitiveData; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | const flecszigble = @import("flecs-zig-ble"); |  |  |  | const flecszigble = @import("flecs-zig-ble"); | 
			
		
	
		
		
			
				
					
					|  |  |  | const Entity = flecszigble.Entity(void); |  |  |  | const Context = flecszigble.Context(void); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | const Entity = Context.Entity; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | const Iter = Context.Iter; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | const flecs = flecszigble.flecs; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | const OnStore = flecs.pipeline.OnStore; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | const Transform = struct { value: Mat }; |  |  |  | const Transform = struct { value: Mat }; | 
			
		
	
		
		
			
				
					
					|  |  |  | const CameraPerspective = struct { |  |  |  | const CameraPerspective = struct { | 
			
		
	
	
		
		
			
				
					|  |  | @ -46,6 +51,7 @@ const ObjectData = struct { | 
			
		
	
		
		
			
				
					
					|  |  |  | const Renderer = @This(); |  |  |  | const Renderer = @This(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | app: *App, |  |  |  | app: *App, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | time: f32 = 0.0, | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | pipeline: *gpu.RenderPipeline, |  |  |  | pipeline: *gpu.RenderPipeline, | 
			
		
	
		
		
			
				
					
					|  |  |  | view_proj_buffer: *gpu.Buffer, |  |  |  | view_proj_buffer: *gpu.Buffer, | 
			
		
	
	
		
		
			
				
					|  |  | @ -56,7 +62,6 @@ depth_texture_view: ?*gpu.TextureView = null, | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | primitive_data: []PrimitiveData, |  |  |  | primitive_data: []PrimitiveData, | 
			
		
	
		
		
			
				
					
					|  |  |  | object_data: []ObjectData, |  |  |  | object_data: []ObjectData, | 
			
		
	
		
		
			
				
					
					|  |  |  | camera_entity: Entity, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | pub fn init(app: *App) !*Renderer { |  |  |  | pub fn init(app: *App) !*Renderer { | 
			
		
	
		
		
			
				
					
					|  |  |  |     // A string buffer used to format objects' labels. |  |  |  |     // A string buffer used to format objects' labels. | 
			
		
	
	
		
		
			
				
					|  |  | @ -225,11 +230,22 @@ pub fn init(app: *App) !*Renderer { | 
			
		
	
		
		
			
				
					
					|  |  |  |         }; |  |  |  |         }; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     _ = try app.world.component(Transform); |  |  |  |     // Register components necessary for the camera. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     _ = try app.world.component(CameraPerspective); |  |  |  |     _ = try app.world.component("Transform", Transform); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     _ = try app.world.component("CameraPerspective", CameraPerspective); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     const camera_entity = try app.world.entity( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         .{ .name = "Camera", .symbol = "Camera" }, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         .{ Transform, CameraPerspective }, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     camera_entity.set(CameraPerspective, .{ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         .field_of_view = 45.0, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         .near_plane = 0.05, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         .far_plane = 80.0, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     }); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     const camera_entity = try app.world.entity(.{ .name = "Camera" }, .{ Transform, CameraPerspective }); |  |  |  |     const render_expr = "App, [in] CameraPerspective(Camera), [out] Transform(Camera)"; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     camera_entity.set(CameraPerspective, .{ .field_of_view = 45.0, .near_plane = 0.05, .far_plane = 80.0 }); |  |  |  |     _ = try app.world.system("Render", render, OnStore, render_expr); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     const result = try app.allocator.create(Renderer); |  |  |  |     const result = try app.allocator.create(Renderer); | 
			
		
	
		
		
			
				
					
					|  |  |  |     result.* = .{ |  |  |  |     result.* = .{ | 
			
		
	
	
		
		
			
				
					|  |  | @ -239,7 +255,6 @@ pub fn init(app: *App) !*Renderer { | 
			
		
	
		
		
			
				
					
					|  |  |  |         .camera_bind_group = camera_bind_group, |  |  |  |         .camera_bind_group = camera_bind_group, | 
			
		
	
		
		
			
				
					
					|  |  |  |         .primitive_data = primitive_data, |  |  |  |         .primitive_data = primitive_data, | 
			
		
	
		
		
			
				
					
					|  |  |  |         .object_data = object_data, |  |  |  |         .object_data = object_data, | 
			
		
	
		
		
			
				
					
					|  |  |  |         .camera_entity = camera_entity, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     }; |  |  |  |     }; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Initialize the depth texture. |  |  |  |     // Initialize the depth texture. | 
			
		
	
	
		
		
			
				
					|  |  | @ -250,8 +265,8 @@ pub fn init(app: *App) !*Renderer { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | pub fn deinit(self: *Renderer) void { |  |  |  | pub fn deinit(self: *Renderer) void { | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Using `defer` here, so we can specify them |  |  |  |     // Using `defer` here, so we can specify resources we | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     // in the order they were created in `init`. |  |  |  |     // want to free in the order they were created in `init`. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     defer self.app.allocator.destroy(self); |  |  |  |     defer self.app.allocator.destroy(self); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     defer self.pipeline.release(); |  |  |  |     defer self.pipeline.release(); | 
			
		
	
	
		
		
			
				
					|  |  | @ -278,34 +293,39 @@ pub fn resize(self: *Renderer) void { | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.recreateDepthTexture(); |  |  |  |     self.recreateDepthTexture(); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | pub fn update(self: *Renderer) void { |  |  |  | pub fn render(it: Iter) void { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     const app = it.field(*App, 1)[0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     const camera_perspective = it.field(CameraPerspective, 2)[0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     const camera_transform = &it.field(Transform, 3)[0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     const self = app.renderer; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.time += it.deltaTime(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Set up a view matrix from the camera transform. |  |  |  |     // Set up a view matrix from the camera transform. | 
			
		
	
		
		
			
				
					
					|  |  |  |     // This moves everything to be relative to the camera. |  |  |  |     // This moves everything to be relative to the camera. | 
			
		
	
		
		
			
				
					
					|  |  |  |     // TODO: Actually implement camera transform instead of hardcoding a look-at matrix. |  |  |  |     // TODO: Actually implement camera transform instead of hardcoding a look-at matrix. | 
			
		
	
		
		
			
				
					
					|  |  |  |     // const view_matrix = zm.inverse(app.camera_transform); |  |  |  |     // const view_matrix = zm.inverse(app.camera_transform); | 
			
		
	
		
		
			
				
					
					|  |  |  |     const time = self.app.app_timer.read(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     const camera_distance = 8.0; |  |  |  |     const camera_distance = 8.0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     const x = @cos(time * std.math.tau / 20) * camera_distance; |  |  |  |     const x = @cos(self.time * std.math.tau / 20) * camera_distance; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     const z = @sin(time * std.math.tau / 20) * camera_distance; |  |  |  |     const z = @sin(self.time * std.math.tau / 20) * camera_distance; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     const camera_pos = vec(x, 2.0, z, 1.0); |  |  |  |     const camera_pos = vec(x, 2.0, z, 1.0); | 
			
		
	
		
		
			
				
					
					|  |  |  |     const view_matrix = zm.lookAtLh(camera_pos, vec(0, 0, 0, 1), vec(0, 1, 0, 1)); |  |  |  |     const view_matrix = zm.lookAtLh(camera_pos, vec(0, 0, 0, 1), vec(0, 1, 0, 1)); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Setting the transform here doesn't do anything because it's not used |  |  |  |     // Setting the transform here doesn't do anything because it's not used | 
			
		
	
		
		
			
				
					
					|  |  |  |     // anywhere. In the future we would want to set the camera transform |  |  |  |     // anywhere. In the future we would want to set the camera transform | 
			
		
	
		
		
			
				
					
					|  |  |  |     // outside of the rendering step, and then get and use it here, instead. |  |  |  |     // outside of the rendering step, and then get and use it here, instead. | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.camera_entity.set(Transform, .{ .value = view_matrix }); |  |  |  |     camera_transform.* = .{ .value = view_matrix }; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     // TODO: Not sure if this is the proper transform, or actually inverted. |  |  |  |     // TODO: Not sure if this is the proper transform, or actually inverted. | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Set up a projection matrix using the size of the window. |  |  |  |     // Set up a projection matrix using the size of the window. | 
			
		
	
		
		
			
				
					
					|  |  |  |     // The perspective projection will make things further away appear smaller. |  |  |  |     // The perspective projection will make things further away appear smaller. | 
			
		
	
		
		
			
				
					
					|  |  |  |     const width: f32 = @floatFromInt(core.descriptor.width); |  |  |  |     const width: f32 = @floatFromInt(core.descriptor.width); | 
			
		
	
		
		
			
				
					
					|  |  |  |     const height: f32 = @floatFromInt(core.descriptor.height); |  |  |  |     const height: f32 = @floatFromInt(core.descriptor.height); | 
			
		
	
		
		
			
				
					
					|  |  |  |     const perspective = self.camera_entity.get(CameraPerspective).?; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     const proj_matrix = zm.perspectiveFovLh( |  |  |  |     const proj_matrix = zm.perspectiveFovLh( | 
			
		
	
		
		
			
				
					
					|  |  |  |         std.math.degreesToRadians(f32, perspective.field_of_view), |  |  |  |         std.math.degreesToRadians(f32, camera_perspective.field_of_view), | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         width / height, |  |  |  |         width / height, | 
			
		
	
		
		
			
				
					
					|  |  |  |         perspective.near_plane, |  |  |  |         camera_perspective.near_plane, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         perspective.far_plane, |  |  |  |         camera_perspective.far_plane, | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     ); |  |  |  |     ); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     const view_proj_matrix = zm.mul(view_matrix, proj_matrix); |  |  |  |     const view_proj_matrix = zm.mul(view_matrix, proj_matrix); | 
			
		
	
	
		
		
			
				
					|  |  | 
 |