|
|
|
@ -17,6 +17,23 @@ const primitives = @import("./primitives.zig"); |
|
|
|
|
const VertexData = primitives.VertexData; |
|
|
|
|
const PrimitiveData = primitives.PrimitiveData; |
|
|
|
|
|
|
|
|
|
const flecszigble = @import("flecs-zig-ble"); |
|
|
|
|
const Entity = flecszigble.Entity(void); |
|
|
|
|
|
|
|
|
|
const Transform = struct { value: Mat }; |
|
|
|
|
const CameraPerspective = struct { |
|
|
|
|
/// Vertical field of view (in degrees). |
|
|
|
|
field_of_view: f32, |
|
|
|
|
/// The near clip plane distance. Objects closer than this value are |
|
|
|
|
/// "cut off". Should be set to a positive value close to zero, depending |
|
|
|
|
/// on how close rendered objects typically get to the camera. |
|
|
|
|
near_plane: f32, |
|
|
|
|
/// The far clip place distance. Objects further than this value are |
|
|
|
|
/// "cut off" and therefore won't be visible. Should be set to a larger |
|
|
|
|
/// positive value, depending on how far objects can get from the camera. |
|
|
|
|
far_plane: f32, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/// Holds data needed to render an object in a rendering pass. |
|
|
|
|
const ObjectData = struct { |
|
|
|
|
/// Bind group which associates model-related buffers with parameters |
|
|
|
@ -39,6 +56,7 @@ depth_texture_view: ?*gpu.TextureView = null, |
|
|
|
|
|
|
|
|
|
primitive_data: []PrimitiveData, |
|
|
|
|
object_data: []ObjectData, |
|
|
|
|
camera_entity: Entity, |
|
|
|
|
|
|
|
|
|
pub fn init(app: *App) !*Renderer { |
|
|
|
|
// A string buffer used to format objects' labels. |
|
|
|
@ -207,6 +225,12 @@ pub fn init(app: *App) !*Renderer { |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_ = try app.world.component(Transform); |
|
|
|
|
_ = try app.world.component(CameraPerspective); |
|
|
|
|
|
|
|
|
|
const camera_entity = try app.world.entity(.{ .name = "Camera" }, .{ Transform, CameraPerspective }); |
|
|
|
|
camera_entity.set(CameraPerspective, .{ .field_of_view = 45.0, .near_plane = 0.05, .far_plane = 80.0 }); |
|
|
|
|
|
|
|
|
|
const result = try app.allocator.create(Renderer); |
|
|
|
|
result.* = .{ |
|
|
|
|
.app = app, |
|
|
|
@ -215,6 +239,7 @@ pub fn init(app: *App) !*Renderer { |
|
|
|
|
.camera_bind_group = camera_bind_group, |
|
|
|
|
.primitive_data = primitive_data, |
|
|
|
|
.object_data = object_data, |
|
|
|
|
.camera_entity = camera_entity, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Initialize the depth texture. |
|
|
|
@ -265,12 +290,23 @@ pub fn update(self: *Renderer) void { |
|
|
|
|
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)); |
|
|
|
|
|
|
|
|
|
// 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 |
|
|
|
|
// outside of the rendering step, and then get and use it here, instead. |
|
|
|
|
self.camera_entity.set(Transform, .{ .value = view_matrix }); |
|
|
|
|
// TODO: Not sure if this is the proper transform, or actually inverted. |
|
|
|
|
|
|
|
|
|
// Set up a projection matrix using the size of the window. |
|
|
|
|
// The perspective projection will make things further away appear smaller. |
|
|
|
|
const width: f32 = @floatFromInt(core.descriptor.width); |
|
|
|
|
const height: f32 = @floatFromInt(core.descriptor.height); |
|
|
|
|
const field_of_view = std.math.degreesToRadians(f32, 45.0); |
|
|
|
|
const proj_matrix = zm.perspectiveFovLh(field_of_view, width / height, 0.05, 80.0); |
|
|
|
|
const perspective = self.camera_entity.get(CameraPerspective).?; |
|
|
|
|
const proj_matrix = zm.perspectiveFovLh( |
|
|
|
|
std.math.degreesToRadians(f32, perspective.field_of_view), |
|
|
|
|
width / height, |
|
|
|
|
perspective.near_plane, |
|
|
|
|
perspective.far_plane, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const view_proj_matrix = zm.mul(view_matrix, proj_matrix); |
|
|
|
|
|
|
|
|
|