cursor based tile placement
This commit is contained in:
parent
60608fc3cd
commit
767be8cf03
@ -99,6 +99,30 @@ u32 U32FromVec4(Vec4 v)
|
||||
return result;
|
||||
}
|
||||
|
||||
f32 LinearFromSrgbF32(f32 srgb)
|
||||
{
|
||||
f32 result;
|
||||
if (srgb <= 0.04045f)
|
||||
{
|
||||
result = srgb / 12.92f;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = pow((srgb + 0.055f) / 1.055f, 2.4f);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Vec4 LinearFromSrgb(Vec4 srgb)
|
||||
{
|
||||
Vec4 result;
|
||||
result.x = LinearFromSrgbF32(srgb.x);
|
||||
result.y = LinearFromSrgbF32(srgb.y);
|
||||
result.z = LinearFromSrgbF32(srgb.z);
|
||||
result.w = srgb.w;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Vertex ID helpers
|
||||
|
||||
|
||||
@ -20,6 +20,8 @@
|
||||
@PixelShader V_DQuadPS
|
||||
@VertexShader V_DVertVS
|
||||
@PixelShader V_DVertPS
|
||||
@VertexShader V_OverlayVS
|
||||
@PixelShader V_OverlayPS
|
||||
|
||||
//////////////////////////////
|
||||
//- Api
|
||||
|
||||
@ -67,11 +67,17 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite
|
||||
);
|
||||
gpu_tiles_ref = G_PushTexture2DRef(gpu_perm, gpu_tiles);
|
||||
/* TODO: Clear tiles from GPU (instead of copy from cpu) */
|
||||
G_CopyCpuToTexture(
|
||||
cl,
|
||||
gpu_tiles, VEC3I32(0, 0, 0),
|
||||
tiles, VEC3I32(tiles_dims.x, tiles_dims.y, 1),
|
||||
RNG3I32(VEC3I32(0, 0, 0), VEC3I32(tiles_dims.x, tiles_dims.y, 1))
|
||||
);
|
||||
}
|
||||
G_CommitCommandList(cl);
|
||||
}
|
||||
|
||||
|
||||
for (u32 i = 0; i < countof(V.frames); ++i)
|
||||
{
|
||||
V_Frame *frame = &V.frames[i];
|
||||
@ -439,11 +445,56 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
frame->draw_to_world_xf = InvertXform(frame->world_to_draw_xf);
|
||||
}
|
||||
|
||||
/* Cursors */
|
||||
//////////////////////////////
|
||||
//- Update cursors / selection
|
||||
|
||||
frame->ui_cursor = ui_frame->cursor_pos;
|
||||
frame->draw_cursor = MulXformV2(frame->ui_to_draw_xf, frame->ui_cursor);
|
||||
frame->world_cursor = MulXformV2(frame->ui_to_world_xf, frame->ui_cursor);
|
||||
|
||||
frame->ui_selection_start = frame->ui_cursor;
|
||||
if (frame->is_editing)
|
||||
{
|
||||
frame->selection_mode = V_SelectionMode_Tile;
|
||||
frame->is_selecting = frame->held_buttons[Button_M1];
|
||||
if (frame->is_selecting && last_frame->is_selecting)
|
||||
{
|
||||
frame->ui_selection_start = last_frame->ui_selection_start;
|
||||
}
|
||||
}
|
||||
|
||||
frame->ui_selection.p0.x = MinF32(last_frame->ui_cursor.x, last_frame->ui_selection_start.x);
|
||||
frame->ui_selection.p0.y = MinF32(last_frame->ui_cursor.y, last_frame->ui_selection_start.y);
|
||||
frame->ui_selection.p1.x = MaxF32(last_frame->ui_cursor.x, last_frame->ui_selection_start.x);
|
||||
frame->ui_selection.p1.y = MaxF32(last_frame->ui_cursor.y, last_frame->ui_selection_start.y);
|
||||
|
||||
frame->draw_selection.p0 = MulXformV2(last_frame->ui_to_draw_xf, frame->ui_selection.p0);
|
||||
frame->draw_selection.p1 = MulXformV2(last_frame->ui_to_draw_xf, frame->ui_selection.p1);
|
||||
|
||||
frame->world_selection.p0 = MulXformV2(last_frame->ui_to_world_xf, frame->ui_selection.p0);
|
||||
frame->world_selection.p1 = MulXformV2(last_frame->ui_to_world_xf, frame->ui_selection.p1);
|
||||
|
||||
//////////////////////////////
|
||||
//- Place tiles
|
||||
|
||||
/* TODO: Push vis cmd */
|
||||
|
||||
if (frame->is_editing && last_frame->is_selecting && !frame->is_selecting)
|
||||
{
|
||||
if (last_frame->selection_mode == V_SelectionMode_Tile)
|
||||
{
|
||||
Rng2I32 tile_range = Zi;
|
||||
tile_range.p0 = S_TilePosFromWorldPos(frame->world_selection.p0);
|
||||
tile_range.p1 = S_TilePosFromWorldPos(frame->world_selection.p1);
|
||||
tile_range.p1 = AddVec2I32(tile_range.p1, VEC2I32(1, 1));
|
||||
|
||||
S_Cmd *cmd = V_PushSimCmd(S_CmdKind_Tile);
|
||||
cmd->tile_placement.placement_kind = S_TilePlacementKind_Range;
|
||||
cmd->tile_placement.tile_kind = S_TileKind_Floor;
|
||||
cmd->tile_placement.range = tile_range;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Build command palette
|
||||
|
||||
@ -647,7 +698,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
S_Cmd *cmd = V_PushSimCmd(S_CmdKind_Tile);
|
||||
cmd->tile_placement.placement_kind = S_TilePlacementKind_Range;
|
||||
cmd->tile_placement.tile_kind = S_TileKind_Floor;
|
||||
cmd->tile_placement.tile_kind = S_TileKind_Wall;
|
||||
cmd->tile_placement.range.p0 = VEC2I32(100, 100);
|
||||
cmd->tile_placement.range.p1 = VEC2I32(110, 110);
|
||||
// cmd->tile_placement.range.p0 = VEC2I32(2, 2);
|
||||
@ -702,53 +753,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
UnlockTicketMutex(&S.input_back_tm);
|
||||
|
||||
// LockTicketMutex(&S.input_back_tm);
|
||||
// {
|
||||
// S_InputState *v2s = &S.input_states[S.input_back_idx];
|
||||
|
||||
// /* Submit control cmd */
|
||||
// {
|
||||
// S_Cmd *cmd = 0;
|
||||
// {
|
||||
// S_CmdNode *cmd_node = PushStruct(v2s->arena, S_CmdNode);
|
||||
// SllQueuePush(v2s->first_cmd_node, v2s->last_cmd_node, cmd_node);
|
||||
// ++v2s->cmds_count;
|
||||
// cmd = &cmd_node->cmd;
|
||||
// }
|
||||
// cmd->kind = S_CmdKind_Control;
|
||||
// cmd->target = V.player_key;
|
||||
// cmd->move = frame->move;
|
||||
// cmd->look = frame->look;
|
||||
// }
|
||||
|
||||
// /* Submit tile cmds */
|
||||
|
||||
|
||||
// /* Submit spawn cmds */
|
||||
// if (spawn_ents.count > 0)
|
||||
// {
|
||||
// S_Cmd *cmd = 0;
|
||||
// {
|
||||
// S_CmdNode *cmd_node = PushStruct(v2s->arena, S_CmdNode);
|
||||
// SllQueuePush(v2s->first_cmd_node, v2s->last_cmd_node, cmd_node);
|
||||
// ++v2s->cmds_count;
|
||||
// cmd = &cmd_node->cmd;
|
||||
// }
|
||||
// cmd->kind = S_CmdKind_Spawn;
|
||||
// S_EntList *dst = &cmd->ents;
|
||||
// for (S_EntListNode *src_n = spawn_ents.first; src_n; src_n = src_n->next)
|
||||
// {
|
||||
// S_EntListNode *dst_n = PushStruct(v2s->arena, S_EntListNode);
|
||||
// {
|
||||
// SllQueuePush(dst->first, dst->last, dst_n);
|
||||
// ++dst->count;
|
||||
// }
|
||||
// dst_n->ent = src_n->ent;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// UnlockTicketMutex(&S.input_back_tm);
|
||||
|
||||
//////////////////////////////
|
||||
//- Render
|
||||
|
||||
@ -825,20 +829,20 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
params.world_to_draw_xf = frame->world_to_draw_xf;
|
||||
params.draw_to_world_xf = frame->draw_to_world_xf;
|
||||
|
||||
params.target_cursor_pos = frame->draw_cursor;
|
||||
params.selection_mode = frame->selection_mode;
|
||||
params.ui_cursor = frame->ui_cursor;
|
||||
params.draw_cursor = frame->draw_cursor;
|
||||
params.world_cursor = frame->world_cursor;
|
||||
params.ui_selection = frame->ui_selection;
|
||||
params.draw_selection = frame->draw_selection;
|
||||
params.world_selection = frame->world_selection;
|
||||
|
||||
params.camera_pos = frame->camera_pos;
|
||||
params.camera_zoom = frame->camera_zoom;
|
||||
|
||||
params.world_size = world_size;
|
||||
params.tiles = gpu_tiles_ref;
|
||||
params.shape_verts = dverts_ro;
|
||||
|
||||
params.background_color_a = LinearFromSrgb(VEC4(0.30, 0.30, 0.30, 1));
|
||||
params.background_color_b = LinearFromSrgb(VEC4(0.15, 0.15, 0.15, 1));
|
||||
params.grid_color = LinearFromSrgb(VEC4(0, 0, 0, 1));
|
||||
params.x_axis_color = LinearFromSrgb(VEC4(0.75, 0, 0, 1));
|
||||
params.y_axis_color = LinearFromSrgb(VEC4(0, 0.75, 0, 1));
|
||||
params.bounds_color = LinearFromSrgb(VEC4(0.75, 0.75, 0, 1));
|
||||
}
|
||||
G_ResourceHandle params_buff = G_PushBufferFromString(frame->gpu_arena, frame->cl, StringFromStruct(¶ms));
|
||||
G_StructuredBufferRef params_ro = G_PushStructuredBufferRef(frame->gpu_arena, params_buff, V_DParams);
|
||||
@ -859,7 +863,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
G_DumbMemoryLayoutSync(frame->cl, draw_target, G_Layout_DirectQueue_ShaderReadWrite);
|
||||
|
||||
/* Backdrop pass */
|
||||
{
|
||||
G_Compute(frame->cl, V_BackdropCS, V_BackdropCSThreadSizeFromTexSize(frame->draw_dims));
|
||||
}
|
||||
@ -869,14 +872,29 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
G_DumbMemoryLayoutSync(frame->cl, draw_target, G_Layout_DirectQueue_RenderTargetWrite);
|
||||
|
||||
/* Shapes pass */
|
||||
{
|
||||
G_Rasterize(frame->cl,
|
||||
G_Rasterize(
|
||||
frame->cl,
|
||||
V_DVertVS, V_DVertPS,
|
||||
1, dvert_idxs_ib,
|
||||
1, &draw_target,
|
||||
viewport, scissor,
|
||||
G_RasterMode_TriangleList);
|
||||
G_RasterMode_TriangleList
|
||||
);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Overlay pass
|
||||
|
||||
{
|
||||
G_Rasterize(
|
||||
frame->cl,
|
||||
V_OverlayVS, V_OverlayPS,
|
||||
1, G_QuadIndices(),
|
||||
1, &draw_target,
|
||||
viewport, scissor,
|
||||
G_RasterMode_TriangleList
|
||||
);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
@ -113,7 +113,10 @@ Struct(V_Frame)
|
||||
V_EditMode edit_mode;
|
||||
|
||||
/* Editor */
|
||||
b32 is_selecting;
|
||||
b32 is_panning;
|
||||
V_SelectionMode selection_mode;
|
||||
Vec2 ui_selection_start;
|
||||
Vec2 edit_camera_pos;
|
||||
f32 edit_camera_zoom;
|
||||
|
||||
@ -137,6 +140,9 @@ Struct(V_Frame)
|
||||
Vec2 ui_cursor;
|
||||
Vec2 draw_cursor;
|
||||
Vec2 world_cursor;
|
||||
Rng2 ui_selection;
|
||||
Rng2 draw_selection;
|
||||
Rng2 world_selection;
|
||||
|
||||
/* Control */
|
||||
Vec2 move;
|
||||
|
||||
@ -3,6 +3,12 @@
|
||||
|
||||
G_DeclConstant(G_StructuredBufferRef, V_ShaderConst_Params, 0);
|
||||
|
||||
Enum(V_SelectionMode)
|
||||
{
|
||||
V_SelectionMode_None,
|
||||
V_SelectionMode_Tile,
|
||||
};
|
||||
|
||||
Struct(V_DParams)
|
||||
{
|
||||
Vec2I32 target_size;
|
||||
@ -12,7 +18,14 @@ Struct(V_DParams)
|
||||
Xform world_to_draw_xf;
|
||||
Xform draw_to_world_xf;
|
||||
|
||||
Vec2 target_cursor_pos;
|
||||
V_SelectionMode selection_mode;
|
||||
Vec2 ui_cursor;
|
||||
Vec2 draw_cursor;
|
||||
Vec2 world_cursor;
|
||||
Rng2 ui_selection;
|
||||
Rng2 draw_selection;
|
||||
Rng2 world_selection;
|
||||
|
||||
Vec2 camera_pos;
|
||||
f32 camera_zoom;
|
||||
|
||||
@ -20,13 +33,6 @@ Struct(V_DParams)
|
||||
G_Texture2DRef tiles;
|
||||
G_StructuredBufferRef quads;
|
||||
G_StructuredBufferRef shape_verts;
|
||||
|
||||
Vec4 background_color_a;
|
||||
Vec4 background_color_b;
|
||||
Vec4 grid_color;
|
||||
Vec4 x_axis_color;
|
||||
Vec4 y_axis_color;
|
||||
Vec4 bounds_color;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@ -7,6 +7,13 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
||||
RWTexture2D<Vec4> target = G_Dereference<Vec4>(params.target_rw);
|
||||
Texture2D<uint> tiles = G_Dereference<uint>(params.tiles);
|
||||
|
||||
const Vec4 background_color_a = LinearFromSrgb(Vec4(0.30, 0.30, 0.30, 1));
|
||||
const Vec4 background_color_b = LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1));
|
||||
const Vec4 grid_color = LinearFromSrgb(Vec4(0, 0, 0, 1));
|
||||
const Vec4 x_axis_color = LinearFromSrgb(Vec4(0.75, 0, 0, 1));
|
||||
const Vec4 y_axis_color = LinearFromSrgb(Vec4(0, 0.75, 0, 1));
|
||||
const Vec4 bounds_color = LinearFromSrgb(Vec4(0.75, 0.75, 0, 1));
|
||||
|
||||
Vec2U32 target_pos = SV_DispatchThreadID;
|
||||
Vec2I32 target_size = params.target_size;
|
||||
if (target_pos.x < target_size.x && target_pos.y < target_size.y)
|
||||
@ -29,15 +36,16 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
||||
{
|
||||
i32 color_idx = 0;
|
||||
Vec4 colors[2] = {
|
||||
params.background_color_a,
|
||||
params.background_color_b
|
||||
background_color_a,
|
||||
background_color_b
|
||||
};
|
||||
Vec2 world_pos_modded = fmod(abs(world_pos), Vec2(1.0, 1.0));
|
||||
if (world_pos_modded.x < 0.5)
|
||||
const f32 checker_size = 0.5;
|
||||
Vec2 world_pos_modded = fmod(abs(world_pos), Vec2(checker_size * 2, checker_size * 2));
|
||||
if (world_pos_modded.x < checker_size)
|
||||
{
|
||||
color_idx = !color_idx;
|
||||
}
|
||||
if (world_pos_modded.y < 0.5)
|
||||
if (world_pos_modded.y < checker_size)
|
||||
{
|
||||
color_idx = !color_idx;
|
||||
}
|
||||
@ -62,7 +70,7 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
||||
grid_dist = min(grid_dist, abs(target_pos.y - grid_screen_p1.y));
|
||||
if (grid_dist <= half_thickness)
|
||||
{
|
||||
result = params.grid_color;
|
||||
result = grid_color;
|
||||
}
|
||||
}
|
||||
/* Tile */
|
||||
@ -91,11 +99,11 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
||||
f32 y_dist = abs(target_pos.y - zero_screen.y);
|
||||
if (y_dist <= half_thickness)
|
||||
{
|
||||
result = params.x_axis_color;
|
||||
result = x_axis_color;
|
||||
}
|
||||
else if (x_dist <= half_thickness)
|
||||
{
|
||||
result = params.y_axis_color;
|
||||
result = y_axis_color;
|
||||
}
|
||||
}
|
||||
/* World bounds */
|
||||
@ -107,7 +115,7 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
||||
bounds_dist = min(bounds_dist, abs(target_pos.y - bounds_screen_p1.y));
|
||||
if (bounds_dist <= half_thickness)
|
||||
{
|
||||
result = params.bounds_color;
|
||||
result = bounds_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -189,3 +197,76 @@ PixelShader(V_DVertPS, V_DVertPSOutput, V_DVertPSInput input)
|
||||
output.sv_target0 = input.color_lin;
|
||||
return output;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Overlay shader
|
||||
|
||||
//////////////////////////////
|
||||
//- Vertex shader
|
||||
|
||||
VertexShader(V_OverlayVS, V_OverlayPSInput)
|
||||
{
|
||||
Vec2 uv = RectUvFromVertexId(SV_VertexID);
|
||||
V_OverlayPSInput result;
|
||||
result.sv_position = Vec4(NdcFromUv(uv).xy, 0, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Pixel shader
|
||||
|
||||
PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input)
|
||||
{
|
||||
V_DParams params = G_Dereference<V_DParams>(V_ShaderConst_Params)[0];
|
||||
Vec2 screen_pos = input.sv_position.xy;
|
||||
Vec4 result = 0;
|
||||
|
||||
Vec2 world_pos = mul(params.draw_to_world_xf, Vec3(screen_pos, 1));
|
||||
Vec2I32 tile_pos = S_TilePosFromWorldPos(world_pos);
|
||||
|
||||
f32 half_thickness = 1;
|
||||
Vec4 border_color = LinearFromSrgb(Vec4(1, 1, 1, 1));
|
||||
// Vec4 inner_color = LinearFromSrgb(Vec4(0.4, 0.4, 0.4, 0.25));
|
||||
Vec4 inner_color = LinearFromSrgb(Vec4(0.4, 0.8, 0.4, 0.6));
|
||||
|
||||
Rng2 screen_selection = params.draw_selection;
|
||||
Rng2 world_selection = params.world_selection;
|
||||
|
||||
Rng2I32 tile_selection;
|
||||
tile_selection.p0 = S_TilePosFromWorldPos(world_selection.p0);
|
||||
tile_selection.p1 = S_TilePosFromWorldPos(world_selection.p1);
|
||||
|
||||
if (params.selection_mode == V_SelectionMode_Tile)
|
||||
{
|
||||
f32 dist = 100000000;
|
||||
dist = min(dist, screen_pos.x - screen_selection.p0.x);
|
||||
dist = min(dist, screen_pos.y - screen_selection.p0.y);
|
||||
dist = min(dist, screen_selection.p1.x - screen_pos.x);
|
||||
dist = min(dist, screen_selection.p1.y - screen_pos.y);
|
||||
dist = -dist;
|
||||
|
||||
if (dist > -half_thickness && dist < half_thickness)
|
||||
{
|
||||
result = border_color;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (world_pos.x > -(S_WorldSize / 2) &&
|
||||
world_pos.y > -(S_WorldSize / 2) &&
|
||||
world_pos.x < (S_WorldSize / 2) &&
|
||||
world_pos.y < (S_WorldSize / 2) &&
|
||||
tile_pos.x >= tile_selection.p0.x &&
|
||||
tile_pos.x <= tile_selection.p1.x &&
|
||||
tile_pos.y >= tile_selection.p0.y &&
|
||||
tile_pos.y <= tile_selection.p1.y)
|
||||
{
|
||||
result = inner_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
V_OverlayPSOutput output;
|
||||
output.sv_target0 = result;
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -27,6 +27,20 @@ Struct(V_DVertPSOutput)
|
||||
Semantic(Vec4, sv_target0);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Overlay shader types
|
||||
|
||||
Struct(V_OverlayPSInput)
|
||||
{
|
||||
|
||||
Semantic(Vec4, sv_position);
|
||||
};
|
||||
|
||||
Struct(V_OverlayPSOutput)
|
||||
{
|
||||
Semantic(Vec4, sv_target0);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Shaders
|
||||
|
||||
@ -40,3 +54,7 @@ PixelShader(V_DQuadPS, V_DQuadPSOutput, V_DQuadPSInput input);
|
||||
//- Shape
|
||||
VertexShader(V_DVertVS, V_DVertPSInput);
|
||||
PixelShader(V_DVertPS, V_DVertPSOutput, V_DVertPSInput input);
|
||||
|
||||
//- Overlay
|
||||
VertexShader(V_OverlayVS, V_OverlayPSInput);
|
||||
PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user