@ -2,10 +2,18 @@ const std = @import("std");
const core = @import ( " mach-core " ) ;
const gpu = core . gpu ;
const zm = @import ( " zmath " ) ;
const vec = zm . f32x4 ;
const Mat = zm . Mat ;
pub const App = @This ( ) ;
app_timer : core . Timer ,
title_timer : core . Timer ,
pipeline : * gpu . RenderPipeline ,
mvp_uniform_buffer : * gpu . Buffer ,
mvp_bind_group : * gpu . BindGroup ,
pub fn init ( app : * App ) ! void {
try core . init ( . { } ) ;
@ -32,13 +40,32 @@ pub fn init(app: *App) !void {
. fragment = & fragment ,
} ;
app . app_timer = try core . Timer . start ( ) ;
app . title_timer = try core . Timer . start ( ) ;
app . pipeline = core . device . createRenderPipeline ( & pipeline_descriptor ) ;
app . mvp_uniform_buffer = core . device . createBuffer ( & . {
. usage = . { . copy_dst = true , . uniform = true } ,
. size = @sizeOf ( zm . Mat ) ,
. mapped_at_creation = . false ,
} ) ;
app . mvp_bind_group = core . device . createBindGroup (
& gpu . BindGroup . Descriptor . init ( . {
. layout = app . pipeline . getBindGroupLayout ( 0 ) ,
. entries = & . {
gpu . BindGroup . Entry . buffer ( 0 , app . mvp_uniform_buffer , 0 , @sizeOf ( zm . Mat ) ) ,
} ,
} ) ,
) ;
}
pub fn deinit ( app : * App ) void {
defer core . deinit ( ) ;
defer app . pipeline . release ( ) ;
defer app . mvp_uniform_buffer . release ( ) ;
defer app . mvp_bind_group . release ( ) ;
}
pub fn update ( app : * App ) ! bool {
@ -50,6 +77,24 @@ pub fn update(app: *App) !bool {
}
}
/ / Set up a view matrix from the camera transform .
/ / This moves everything to be relative to the camera .
/ / TODO : Actually implement camera transform instead of hardcoding a look - at matrix .
/ / const view_matrix = zm . inverse ( app . camera_transform ) ;
const time = app . app_timer . read ( ) ;
const x = @cos ( time * std . math . tau / 10 ) ;
const y = @sin ( time * std . math . tau / 10 ) ;
const view_matrix = zm . lookAtLh ( vec ( x , y , - 2 , 1 ) , vec ( 0 , 0 , 0 , 1 ) , vec ( 0 , 1 , 0 , 1 ) ) ;
/ / 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.1 , 10 ) ;
const view_proj_matrix = zm . mul ( view_matrix , proj_matrix ) ;
/ / Get back buffer texture to render to .
const back_buffer_view = core . swap_chain . getCurrentTextureView ( ) . ? ;
defer back_buffer_view . release ( ) ;
@ -70,15 +115,18 @@ pub fn update(app: *App) !bool {
const encoder = core . device . createCommandEncoder ( null ) ;
defer encoder . release ( ) ;
encoder . writeBuffer ( app . mvp_uniform_buffer , 0 , & [ _ ] zm . Mat { zm . transpose ( view_proj_matrix ) } ) ;
{
const pass = encoder . beginRenderPass ( & render_pass_info ) ;
defer pass . release ( ) ;
defer pass . end ( ) ;
pass . setPipeline ( app . pipeline ) ;
pass . setBindGroup ( 0 , app . mvp_bind_group , & . { } ) ;
/ / Draw a triangle with the help of a specialized shader .
pass . draw ( 3 , 1 , 0 , 0 ) ;
/ / Draw three triangles with the help of a specialized shader .
pass . draw ( 9 , 1 , 0 , 0 ) ;
}
/ / Finish recording commands , creating a ` WGPUCommandBuffer ` .