diff --git a/src/base/base_shader.gh b/src/base/base_shader.gh index 302a6c45..7be63cd7 100644 --- a/src/base/base_shader.gh +++ b/src/base/base_shader.gh @@ -193,7 +193,7 @@ Inline Vec4 BlendPremul(Vec4 src, Vec4 dst) //////////////////////////////////////////////////////////// //~ Vertex ID helpers -Inline Vec2 RectUvFromVertexId(u32 id) +Inline Vec2 RectUvFromIdx(u32 idx) { static const Vec2 uvs[4] = { Vec2(0, 0), @@ -201,7 +201,7 @@ Inline Vec2 RectUvFromVertexId(u32 id) Vec2(1, 1), Vec2(0, 1) }; - return uvs[id]; + return uvs[idx]; } //////////////////////////////////////////////////////////// diff --git a/src/pp/pp.c b/src/pp/pp.c index 5710a20d..99051437 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -197,6 +197,36 @@ P_Shape P_WorldShapeFromEnt(P_Ent *ent) return world; } +//////////////////////////////////////////////////////////// +//~ Animation helpers + +P_Anim P_AnimFromEnt(P_Ent *ent, i64 time_ns) +{ + P_Anim result = Zi; + + // result.slice_to_world_xf = XformIdentity; + // result.slice_to_world_xf = ent->xf; + + { + Vec2 world_dims = VEC2(0.5, 0.5); + result.slice_to_world_xf = XformIdentity; + result.slice_to_world_xf.og = ent->xf.og; + // result.slice_to_world_xf.og = SubVec2(result.slice_to_world_xf.og, MulVec2(world_dims, 0.25)); + result.slice_to_world_xf = XformWithWorldRotation(result.slice_to_world_xf, AngleFromVec2(ent->control.look)); + result.slice_to_world_xf = TranslateXform(result.slice_to_world_xf, MulVec2(world_dims, -0.5)); + result.slice_to_world_xf = ScaleXform(result.slice_to_world_xf, world_dims); + + ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, Lit("sprite/bla3.ase")); + SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); + result.slice = SPR_SliceFromSheet(sheet, Lit("")); + } + + + + + return result; +} + //////////////////////////////////////////////////////////// //~ Collision diff --git a/src/pp/pp.h b/src/pp/pp.h index 58337b86..0267f5b2 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -166,6 +166,15 @@ Struct(P_EntBin) P_Ent *last; }; +//////////////////////////////////////////////////////////// +//~ Animation types + +Struct(P_Anim) +{ + Xform slice_to_world_xf; + SPR_Slice slice; +}; + //////////////////////////////////////////////////////////// //~ Constraint types @@ -476,6 +485,11 @@ Rng2 P_BoundingBoxFromShape(P_Shape shape); P_Shape P_LocalShapeFromEnt(P_Ent *ent); P_Shape P_WorldShapeFromEnt(P_Ent *ent); +//////////////////////////////////////////////////////////// +//~ Animation helpers + +P_Anim P_AnimFromEnt(P_Ent *ent, i64 time_ns); + //////////////////////////////////////////////////////////// //~ Collision diff --git a/src/pp/pp.lay b/src/pp/pp.lay index cb73d670..32243ab2 100644 --- a/src/pp/pp.lay +++ b/src/pp/pp.lay @@ -4,6 +4,7 @@ //- Dependencies @Dep net +@Dep sprite ////////////////////////////// //- Resources diff --git a/src/pp/pp_res/sprite/bla3.ase b/src/pp/pp_res/sprite/bla3.ase index 2d093f14..fc94d834 100644 --- a/src/pp/pp_res/sprite/bla3.ase +++ b/src/pp/pp_res/sprite/bla3.ase @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1b981f00ffbe8976def03aacd7a79f99265a98899dfb2bbc20cedac0d7698d29 -size 2837 +oid sha256:434e4debf471f71a2fa05213d7a8b53535964ab340e541d38a734686c82f6363 +size 3059 diff --git a/src/pp/pp_sim/pp_sim.lay b/src/pp/pp_sim/pp_sim.lay index 388ab284..17ffb70b 100644 --- a/src/pp/pp_sim/pp_sim.lay +++ b/src/pp/pp_sim/pp_sim.lay @@ -5,6 +5,7 @@ @Dep pp @Dep net +@Dep sprite @Dep platform ////////////////////////////// diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index e7b6aa3f..07dafc0f 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -67,10 +67,6 @@ void V_PushParticles(V_Emitter src) V_Frame *frame = V_CurrentFrame(); i64 split_threshold = 256; // Arbitrary threshold. Lower counts cause less shader work but more cpu -> gpu upload bandwidth. src.count = MinU64(src.count, V_ParticlesCap); - if (src.seed == 0) - { - src.seed = RandU64FromState(&frame->rand); - } i64 remaining_particles = src.count; while (remaining_particles > 0) { @@ -488,6 +484,7 @@ void V_TickForever(WaveLaneCtx *lane) { V_Frame *frame = &V.frames[i]; frame->arena = AcquireArena(Gibi(64)); + frame->quads_arena = AcquireArena(Gibi(64)); frame->dverts_arena = AcquireArena(Gibi(64)); frame->dvert_idxs_arena = AcquireArena(Gibi(64)); frame->gpu_arena = G_AcquireArena(); @@ -545,17 +542,20 @@ void V_TickForever(WaveLaneCtx *lane) { Arena *old_arena = frame->arena; + Arena *old_quads_arena = frame->quads_arena; Arena *old_dverts_arena = frame->dverts_arena; Arena *old_dvert_idxs_arena = frame->dvert_idxs_arena; G_ArenaHandle old_gpu_arena = frame->gpu_arena; ZeroStruct(frame); frame->arena = old_arena; + frame->quads_arena = old_quads_arena; frame->dverts_arena = old_dverts_arena; frame->dvert_idxs_arena = old_dvert_idxs_arena; frame->gpu_arena = old_gpu_arena; } frame->cl = G_PrepareCommandList(G_QueueKind_Direct); ResetArena(frame->arena); + ResetArena(frame->quads_arena); ResetArena(frame->dverts_arena); ResetArena(frame->dvert_idxs_arena); G_ResetArena(frame->cl, frame->gpu_arena); @@ -1828,8 +1828,27 @@ void V_TickForever(WaveLaneCtx *lane) + ////////////////////////////// + //- Push guy quads + for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) + { + if (ent->is_guy) + { + P_Anim anim = P_AnimFromEnt(ent, local_frame->time_ns); + // Push weapon quad + { + } + + // Push body quad + { + V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); + quad->to_shade_xf = MulXform(frame->xf.world_to_shade, anim.slice_to_world_xf); + quad->slice = anim.slice; + } + } + } @@ -4104,8 +4123,8 @@ void V_TickForever(WaveLaneCtx *lane) .flags = G_ResourceFlag_AllowRenderTarget ); G_Texture2DRef screen_target_ro = G_PushTexture2DRef(frame->gpu_arena, screen_target); - Rng3 viewport = RNG3(VEC3(0, 0, 0), VEC3(frame->screen_dims.x, frame->screen_dims.y, 1)); - Rng2 scissor = RNG2(VEC2(viewport.p0.x, viewport.p0.y), VEC2(viewport.p1.x, viewport.p1.y)); + Rng3 screen_viewport = RNG3(VEC3(0, 0, 0), VEC3(frame->screen_dims.x, frame->screen_dims.y, 1)); + Rng2 screen_scissor = RNG2(VEC2(screen_viewport.p0.x, screen_viewport.p0.y), VEC2(screen_viewport.p1.x, screen_viewport.p1.y)); // Shade texture G_ResourceHandle shade_target = G_PushTexture2D( @@ -4117,6 +4136,8 @@ void V_TickForever(WaveLaneCtx *lane) ); G_Texture2DRef shade_target_ro = G_PushTexture2DRef(frame->gpu_arena, shade_target); G_RWTexture2DRef shade_target_rw = G_PushRWTexture2DRef(frame->gpu_arena, shade_target); + Rng3 shade_viewport = RNG3(VEC3(0, 0, 0), VEC3(frame->shade_dims.x, frame->shade_dims.y, 1)); + Rng2 shade_scissor = RNG2(VEC2(shade_viewport.p0.x, shade_viewport.p0.y), VEC2(shade_viewport.p1.x, shade_viewport.p1.y)); // Albedo texture G_ResourceHandle albedo_target = G_PushTexture2D( @@ -4128,10 +4149,14 @@ void V_TickForever(WaveLaneCtx *lane) ); G_Texture2DRef albedo_target_ro = G_PushTexture2DRef(frame->gpu_arena, albedo_target); + // Quad buffers + G_ResourceHandle quads_buff = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromArena(frame->quads_arena)); + G_StructuredBufferRef quads_ref = G_PushStructuredBufferRef(frame->gpu_arena, quads_buff, V_Quad); + // Debug shape buffers G_ResourceHandle dverts_buff = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromArena(frame->dverts_arena)); G_ResourceHandle dvert_idxs_buff = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromArena(frame->dvert_idxs_arena)); - G_StructuredBufferRef dverts_ro = G_PushStructuredBufferRef(frame->gpu_arena, dverts_buff, V_DVert); + G_StructuredBufferRef dverts_ref = G_PushStructuredBufferRef(frame->gpu_arena, dverts_buff, V_DVert); G_IndexBufferDesc dvert_idxs_ib = G_IdxBuff32(dvert_idxs_buff); // Emitters @@ -4185,7 +4210,8 @@ void V_TickForever(WaveLaneCtx *lane) params.screen_dims = frame->screen_dims; params.tiles = gpu_tiles_ref; - params.shape_verts = dverts_ro; + params.quads = quads_ref; + params.shape_verts = dverts_ref; params.emitters_count = frame->emitters_count; params.emitters = gpu_emitters_ref; @@ -4246,27 +4272,46 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Setup pass - // Prepare shade - G_Compute(frame->cl, V_PrepareShadeCS, V_ThreadGroupSizeFromTexSize(frame->shade_dims)); - - // Prepare cells - G_Compute(frame->cl, V_PrepareCellsCS, V_ThreadGroupSizeFromTexSize(cells_dims)); - - // Clear particles - if (should_clear_particles) { - G_Compute(frame->cl, V_ClearParticlesCS, V_ThreadGroupSizeFromBufferSize(V_ParticlesCap)); + // Prepare shade + G_Compute(frame->cl, V_PrepareShadeCS, V_ThreadGroupSizeFromTexSize(frame->shade_dims)); + + // Prepare cells + G_Compute(frame->cl, V_PrepareCellsCS, V_ThreadGroupSizeFromTexSize(cells_dims)); + + // Clear particles + if (should_clear_particles) + { + G_Compute(frame->cl, V_ClearParticlesCS, V_ThreadGroupSizeFromBufferSize(V_ParticlesCap)); + } + + // Clear albedo RT + G_ClearRenderTarget(frame->cl, albedo_target, VEC4(0, 0, 0, 0)); + + // Discard screen RT + G_DiscardRenderTarget(frame->cl, screen_target); } - // Clear albedo RT - G_ClearRenderTarget(frame->cl, albedo_target, VEC4(0, 0, 0, 0)); - - // Discard screen RT - G_DiscardRenderTarget(frame->cl, screen_target); - // Sync G_DumbGlobalMemorySync(frame->cl); + ////////////////////////////// + //- Quads pass + + { + G_Rasterize( + frame->cl, + V_QuadVS, V_QuadPS, + G_CountBuffer(quads_buff, V_Quad), G_QuadIndices(), + 1, &G_Rt(albedo_target, G_BlendMode_CompositeStraightAlpha), + shade_viewport, shade_scissor, + G_RasterMode_TriangleList + ); + + // Transition albedo to readonly + G_DumbMemoryLayoutSync(frame->cl, albedo_target, G_Layout_DirectQueue_ShaderRead); + } + ////////////////////////////// //- Particle simulation pass @@ -4305,7 +4350,7 @@ void V_TickForever(WaveLaneCtx *lane) V_CompositeVS, V_CompositePS, 1, G_QuadIndices(), 1, &G_Rt(screen_target, G_BlendMode_CompositeStraightAlpha), - viewport, scissor, + screen_viewport, screen_scissor, G_RasterMode_TriangleList ); } @@ -4319,7 +4364,7 @@ void V_TickForever(WaveLaneCtx *lane) V_DVertVS, V_DVertPS, 1, dvert_idxs_ib, 1, &G_Rt(screen_target, G_BlendMode_CompositeStraightAlpha), - viewport, scissor, + screen_viewport, screen_scissor, G_RasterMode_TriangleList ); } @@ -4330,8 +4375,8 @@ void V_TickForever(WaveLaneCtx *lane) G_DumbMemoryLayoutSync(frame->cl, screen_target, G_Layout_DirectQueue_ShaderRead); { Rng2 uv = Zi; - uv.p0 = Vec2FromVec(viewport.p0); - uv.p1 = Vec2FromVec(viewport.p1); + uv.p0 = Vec2FromVec(screen_viewport.p0); + uv.p1 = Vec2FromVec(screen_viewport.p1); uv = DivRng2Vec2(uv, Vec2FromVec(frame->screen_dims)); UI_SetRawTexture(vis_box, screen_target_ro, uv); } diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 71b7324c..f55699c3 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -224,6 +224,7 @@ Enum(V_EditMode) Struct(V_Frame) { Arena *arena; + Arena *quads_arena; Arena *dverts_arena; Arena *dvert_idxs_arena; G_ArenaHandle gpu_arena; diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index c02dfe88..b398f7ab 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -88,14 +88,16 @@ VertexShader(V_QuadVS, V_QuadPSInput) V_Quad quad = quads[SV_InstanceID]; - Vec2 rect_uv = RectUvFromVertexId(SV_VertexID); - // Vec2 tex_uv = lerp(quad.tex_uv0, quad.tex_uv1, rect_uv); - // Vec2 screen_pos = lerp(quad.p0, quad.p1, rect_uv); - Vec2 screen_pos = 0; + Vec2 rect_uv = RectUvFromIdx(SV_VertexID); + Vec2 shade_pos = mul(quad.to_shade_xf, Vec3(rect_uv, 1)); + + Vec2 tex_uv = lerp(quad.slice.uv_rect.p0, quad.slice.uv_rect.p1, rect_uv); + // Vec2 shade_pos = lerp(quad.p0, quad.p1, rect_uv); V_QuadPSInput result; - result.sv_position = Vec4(NdcFromPos(screen_pos, params.screen_dims).xy, 0, 1); + result.sv_position = Vec4(NdcFromPos(shade_pos, params.shade_dims).xy, 0, 1); result.quad_idx = SV_InstanceID; + result.tex_uv = tex_uv; return result; } @@ -106,12 +108,17 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input) { V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; StructuredBuffer quads = G_Dereference(params.quads); + SamplerState clamp_sampler = G_Dereference(params.pt_clamp_sampler); + V_Quad quad = quads[input.quad_idx]; - Vec4 final_color = 0; + // Texture2D tex = G_Dereference(quad.slice.tex); + // Vec4 albedo = tex.Sample(clamp_sampler, input.tex_uv); + + Vec4 albedo = Color_Cyan; V_QuadPSOutput output; - output.sv_target0 = final_color; + output.sv_target0 = albedo; return output; } @@ -377,7 +384,7 @@ ComputeShader(V_SimParticlesCS, 64) { V_Emitter emitter = G_Dereference(params.emitters)[particle.emitter_init_num - 1]; - u64 seed0 = MixU64(emitter.seed + particle.seq); + u64 seed0 = MixU64(particle.seq); u64 seed1 = MixU64(seed0); f32 rand_speed = (f32)((seed0 >> 0) & 0xFFFF) / (f32)0xFFFF; @@ -586,9 +593,10 @@ ComputeShader2D(V_ShadeCS, 8, 8) //- Composite albedo albedo = BlendPremul(!tile_is_wall * tile_color, albedo); // Blend floor tile + albedo = BlendPremul(!tile_is_wall * stain_color, albedo); // Blend floor stain albedo = BlendPremul(albedo_tex_color, albedo); albedo = BlendPremul(tile_is_wall * tile_color, albedo); // Blend wall tile - albedo = BlendPremul(stain_color, albedo); + albedo = BlendPremul(tile_is_wall * stain_color, albedo); // Blend wall stain } ////////////////////////////// @@ -613,7 +621,7 @@ ComputeShader2D(V_ShadeCS, 8, 8) VertexShader(V_CompositeVS, V_CompositePSInput) { - Vec2 uv = RectUvFromVertexId(SV_VertexID); + Vec2 uv = RectUvFromIdx(SV_VertexID); V_CompositePSInput result; result.sv_position = Vec4(NdcFromUv(uv).xy, 0, 1); return result; diff --git a/src/pp/pp_vis/pp_vis_gpu.gh b/src/pp/pp_vis/pp_vis_gpu.gh index eae331a4..2b0e4197 100644 --- a/src/pp/pp_vis/pp_vis_gpu.gh +++ b/src/pp/pp_vis/pp_vis_gpu.gh @@ -5,6 +5,7 @@ Struct(V_QuadPSInput) { Semantic(Vec4, sv_position); Semantic(nointerpolation u32, quad_idx); + Semantic(Vec2, tex_uv); }; Struct(V_QuadPSOutput) @@ -31,7 +32,6 @@ Struct(V_DVertPSOutput) Struct(V_CompositePSInput) { - Semantic(Vec4, sv_position); }; diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index 3c1cc334..4bf95d88 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -123,7 +123,6 @@ Struct(V_Emitter) u32 first_particle_seq; u32 count; - u64 seed; Vec2 start; Vec2 end; @@ -182,8 +181,7 @@ Struct(V_Quad) { V_QuadFlag flags; - - + Xform to_shade_xf; SPR_Slice slice; }; diff --git a/src/ui/ui_gpu.g b/src/ui/ui_gpu.g index 431e45b2..354f7562 100644 --- a/src/ui/ui_gpu.g +++ b/src/ui/ui_gpu.g @@ -10,7 +10,7 @@ VertexShader(UI_DRectVS, UI_DRectPSInput) StructuredBuffer rects = G_Dereference(params.rects); UI_GpuRect rect = rects[SV_InstanceID]; - Vec2 rect_uv = RectUvFromVertexId(SV_VertexID); + Vec2 rect_uv = RectUvFromIdx(SV_VertexID); Vec2 tex_uv = lerp(rect.tex_slice_uv.p0, rect.tex_slice_uv.p1, rect_uv); Vec2 target_pos = lerp(rect.bounds.p0, rect.bounds.p1, rect_uv); @@ -122,7 +122,7 @@ PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input) VertexShader(UI_BlitVS, UI_BlitPSInput) { - Vec2 uv = RectUvFromVertexId(SV_VertexID); + Vec2 uv = RectUvFromIdx(SV_VertexID); UI_BlitPSInput result; result.sv_position = Vec4(NdcFromUv(uv).xy, 0, 1); result.src_uv = uv;