// #define V_ParticlesCap Kibi(128) // #define V_ParticlesCap Mebi(1) #define V_ParticlesCap Mebi(2) // #define V_ParticlesCap Mebi(16) //////////////////////////////////////////////////////////// //~ State types G_DeclConstant(G_StructuredBufferRef, V_ShaderConst_Frame, 0); G_DeclConstant(G_Texture3DRef, V_ShaderConst_NoiseTex, 1); Struct(V_TileDesc) { G_Texture2DRef tex; Rng2 tex_slice_uv; }; Enum(V_SelectionMode) { V_SelectionMode_Tile, }; Enum(V_EditMode) { V_EditMode_Tile, V_EditMode_Prefab, }; Struct(V_Affines) { // World <-> screen Affine world_to_screen; Affine screen_to_world; // World <-> shade Affine world_to_shade; Affine shade_to_world; // Shade <-> screen Affine shade_to_screen; Affine screen_to_shade; // World <-> cell Affine world_to_cell; Affine cell_to_world; // World <-> tile Affine world_to_tile; Affine tile_to_world; }; Struct(V_SharedFrame) { //- Time i64 tick; i64 time_ns; i64 dt_ns; f32 dt; //- Modes // TODO: Move to shader-constant flags b32 tiles_dirty; b32 should_clear_particles; b32 is_looking; b32 is_moving; b32 is_editing; b32 ui_debug; b32 show_console; b32 is_selecting; b32 is_panning; b32 has_mouse_focus; b32 has_keyboard_focus; //- Editor state V_EditMode edit_mode; V_SelectionMode selection_mode; P_TileKind equipped_tile; P_PrefabKind equipped_prefab; Vec2 world_selection_start; Vec2 edit_camera_pos; f32 edit_camera_zoom; //- Camera i32 zooms; f32 camera_lerp_rate; Vec2 camera_pos; f32 camera_zoom; //- Dims Vec2 screen_dims; Vec2 shade_dims; //- Affines V_Affines af; //- Cursor Vec2 screen_cursor; Vec2 shade_cursor; Vec2 world_cursor; Rng2 screen_selection; Rng2 shade_selection; Rng2 world_selection; //- Crosshair Vec2 world_guy_origin; Vec2 world_crosshair_base; Vec2 world_crosshair; Vec2 screen_crosshair; Vec2 shade_crosshair; //- Control Vec2 move; Vec2 look; f32 fire_held; f32 fire_presses; //- Gpu data G_SamplerStateRef pt_clamp_sampler; G_SamplerStateRef pt_wrap_sampler; V_TileDesc tile_descs[P_TileKind_COUNT]; G_Texture2DRef tiles; G_Texture2DRef screen_ro; G_Texture2DRef shade_ro; G_RWTexture2DRef shade_rw; G_Texture2DRef albedo_ro; G_RWTexture2DRef albedo_rw; u32 emitters_count; G_StructuredBufferRef emitters; G_RWStructuredBufferRef particles; G_RWTexture2DRef stain_cells; G_RWTexture2DRef ground_cells; G_RWTexture2DRef air_cells; G_RWTexture2DRef stain_densities; G_RWTexture2DRef ground_densities; G_RWTexture2DRef air_densities; G_RWTexture2DRef drynesses; G_RWTexture2DRef occluders; G_StructuredBufferRef dverts; G_StructuredBufferRef quads; }; //////////////////////////////////////////////////////////// //~ Occluder types Enum(V_OccluderKind) { V_OccluderKind_None, V_OccluderKind_Guy, V_OccluderKind_Wall, }; //////////////////////////////////////////////////////////// //~ Particle types #define V_ParticleSimBasis 0xb49f2d9e406873b9ull #define V_ParticleColorBasis 0x569aa8341ecc0ea3ull #define V_ParticleCellBasis 0xf60c0cff344b0c5dull #define V_ParticleStainBasis 0x3c64e8226d98d376ull Enum(V_ParticleFlag) { V_ParticleFlag_None = 0, V_ParticleFlag_Ground = (1 << 0), V_ParticleFlag_Air = (1 << 1), V_ParticleFlag_PruneWhenStill = (1 << 2), V_ParticleFlag_StainWhenPruned = (1 << 3), V_ParticleFlag_NoReflect = (1 << 4), }; // NOTE: Higher particle enum values take priority over lower ones #define V_ParticlesXList(X) \ X( \ /* Name */ None, \ /* Flags */ V_ParticleFlag_None, \ /* Stain rate, pen chance */ 0, 0, \ /* Base color */ 0, 0, 0, 0 \ ) \ \ /* Ground particles */ \ X( \ /* Name */ Blood, \ /* Flags */ V_ParticleFlag_None | V_ParticleFlag_NoReflect, \ /* Stain rate, pen chance */ 500, 0.25, \ /* Base color */ 0.5, 0.1, 0.1, 1 \ ) \ X( \ /* Name */ Debris, \ /* Flags */ V_ParticleFlag_Ground | V_ParticleFlag_PruneWhenStill | V_ParticleFlag_StainWhenPruned, \ /* Stain rate, pen chance */ 0, 0, \ /* Base color */ 1, 0.5, 0, 1 \ ) \ \ /* Air particles */ \ X( \ /* Name */ Smoke, \ /* Flags */ V_ParticleFlag_Air, \ /* Stain rate, pen chance */ 0, 0, \ /* Base color */ 0.15, 0.15, 0.15, 0.5 \ ) \ X( \ /* Name */ BulletTrail, \ /* Flags */ V_ParticleFlag_Air, \ /* Stain rate, pen chance */ 0, 0, \ /* Base color */ 1, 0, 1, 1 \ ) \ \ /* Test particles */ \ X( \ /* Name */ Test, \ /* Flags */ V_ParticleFlag_PruneWhenStill, \ /* Stain rate, pen chance */ 0, 0, \ /* Base color */ 1, 1, 0, 1 \ ) \ /* -------------------------------------------------------------------------- */ Enum(V_ParticleKind) { #define X(name, ...) V_ParticleKind_##name, V_ParticlesXList(X) #undef X V_ParticleKind_COUNT, }; Struct(V_Emitter) { V_ParticleKind kind; u32 first_particle_seq; u32 count; Rng2 pos; Rng speed; Rng angle; }; // TODO: Pack this efficiently Struct(V_Particle) { i32 kind; // If >= 0, then map to V_ParticleKind. Otherwize initialize particle using emitter at index [abs(kind) - 1] f32 life; f32 stain_accum; u32 cells_count; Vec2 pos; Vec2 velocity; }; Struct(V_ParticleDesc) { V_ParticleFlag flags; f32 stain_rate; f32 pen_rate; Vec4 color; }; #if IsCpu Struct(V_EmitterNode) { V_EmitterNode *next; V_Emitter emitter; }; #endif //////////////////////////////////////////////////////////// //~ Quad types Enum(V_QuadFlag) { V_QuadFlag_None = 0, }; Struct(V_Quad) { V_QuadFlag flags; V_OccluderKind occluder; Affine quad_uv_to_world_af; G_Texture2DRef tex; Rng2 tex_slice_uv; }; //////////////////////////////////////////////////////////// //~ Debug vert types Struct(V_DVert) { Vec2 pos; Vec4 color_lin; }; //////////////////////////////////////////////////////////// //~ Helpers #define V_ThreadGroupSizeFromBufferSize(buffer_size) VEC3I32((((buffer_size) + 63) / 64), 1, 1) #define V_ThreadGroupSizeFromTexSize(tex_size) VEC3I32(((tex_size).x + 7) / 8, ((tex_size).y + 7) / 8, 1) V_ParticleDesc V_DescFromParticleKind(V_ParticleKind kind);