change grid shader primitive to line from triangle

This commit is contained in:
Sven Balzer
2026-08-01 09:37:43 +02:00
parent 08b8b397e2
commit f564c14354
7 changed files with 69 additions and 146 deletions
+1
View File
@@ -5,6 +5,7 @@ set(CMAKE_C_STANDARD 23)
set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
option(TRACY_ENABLE "Enable Tracy profiling" OFF) option(TRACY_ENABLE "Enable Tracy profiling" OFF)
+6 -67
View File
@@ -45,8 +45,6 @@ static R_Buffer tint_color_buffer;
static R_Buffer vertex_buffer; static R_Buffer vertex_buffer;
static R_Buffer index_buffer; static R_Buffer index_buffer;
static R_Buffer grid_vertex_buffer;
static R_Buffer grid_index_buffer;
static R_Buffer player_instance_buffer; static R_Buffer player_instance_buffer;
static R_Buffer tile_uvs_buffer; static R_Buffer tile_uvs_buffer;
@@ -185,51 +183,6 @@ static Uint16 indices[] = {
0, 2, 3, 0, 2, 3,
}; };
#define grid_line_size (1.0f / 64.0f)
static Vertex grid_vertices[] = {
// LEFT
{{ -0.5f, 0.5f, 0.0f }},
{{ -0.5f, -0.5f + grid_line_size, 0.0f }},
{{ -0.5f + grid_line_size, -0.5f + grid_line_size, 0.0f }},
{{ -0.5f + grid_line_size, 0.5f, 0.0f }},
// TOP
{{ -0.5f + grid_line_size, 0.5f, 0.0f }},
{{ -0.5f + grid_line_size, 0.5f - grid_line_size, 0.0f }},
{{ 0.5f, 0.5f - grid_line_size, 0.0f }},
{{ 0.5f, 0.5f, 0.0f }},
// RIGHT
{{ 0.5f - grid_line_size, 0.5f - grid_line_size, 0.0f }},
{{ 0.5f - grid_line_size, -0.5f, 0.0f }},
{{ 0.5f, -0.5f, 0.0f }},
{{ 0.5f, 0.5f - grid_line_size, 0.0f }},
// BOTTOM
{{ -0.5f, -0.5f + grid_line_size, 0.0f }},
{{ -0.5f, -0.5f, 0.0f }},
{{ 0.5f - grid_line_size, -0.5f, 0.0f }},
{{ 0.5f - grid_line_size, -0.5f + grid_line_size, 0.0f }},
};
static Uint16 grid_indices[] = {
// LEFT
0, 1, 2,
0, 2, 3,
// TOP
4, 5, 6,
4, 6, 7,
// RIGHT
8, 9, 10,
8, 10, 11,
// BOTTOM
12, 13, 14,
12, 14, 15,
};
struct Instance { struct Instance {
vec2 pos; vec2 pos;
}; };
@@ -255,12 +208,13 @@ struct Player {
static Player player; static Player player;
struct PerFrame { struct alignas(16) PerFrame {
i32vec2 drag_start; i32vec2 drag_start;
i32vec2 mouse; i32vec2 mouse;
vec2 grid_offset; vec2 grid_offset;
Sint32 grid_width; Uint32 grid_width;
Sint32 map_width; Uint32 map_width;
Uint32 grid_height;
}; };
static PerFrame per_frame = {}; static PerFrame per_frame = {};
@@ -928,18 +882,6 @@ static bool init_resources() {
return false; return false;
} }
grid_vertex_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, sizeof(grid_vertices), grid_vertices, "grid_vertex_buffer");
if (!grid_vertex_buffer) {
log_error("Failed to create buffer.");
return false;
}
grid_index_buffer = renderer_buffer_create(R_BUFFER_USAGE_INDEX, sizeof(grid_indices), grid_indices, "grid_index_buffer");
if (!grid_index_buffer) {
log_error("Failed to create buffer.");
return false;
}
player_instance_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, sizeof(player_instance), &player_instance, "player_instance_buffer"); player_instance_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, sizeof(player_instance), &player_instance, "player_instance_buffer");
if (!player_instance_buffer) { if (!player_instance_buffer) {
log_error("Failed to create buffer."); log_error("Failed to create buffer.");
@@ -1329,6 +1271,7 @@ static void render_editor() {
per_frame.map_width = current_map.size.x; per_frame.map_width = current_map.size.x;
per_frame.grid_width = selected_tile != -1 ? current_map.size.x : current_map.size.x + 1; per_frame.grid_width = selected_tile != -1 ? current_map.size.x : current_map.size.x + 1;
per_frame.grid_height = selected_tile != -1 ? current_map.size.y : current_map.size.y + 1;
per_frame.grid_offset = selected_tile != -1 ? vec2(-0.5f, -0.5f) : vec2(-1.0f, -1.0f); per_frame.grid_offset = selected_tile != -1 ? vec2(-0.5f, -0.5f) : vec2(-1.0f, -1.0f);
per_frame.mouse = tile_pos; per_frame.mouse = tile_pos;
@@ -1394,12 +1337,8 @@ static void render_editor() {
if (show_grid) { if (show_grid) {
ZoneScopedN("Draw Grid"); ZoneScopedN("Draw Grid");
Uint32 num_grid_cells = current_map.size.y * current_map.size.x;
if (selected_tile == -1)
num_grid_cells = (current_map.size.y + 1) * (current_map.size.x + 1);
renderer_frame_set_shader(R_SHADER_GRID); renderer_frame_set_shader(R_SHADER_GRID);
renderer_frame_draw(grid_vertex_buffer, grid_index_buffer, NULL, SDL_arraysize(grid_indices), num_grid_cells, &(R_Draw_Resources){ renderer_frame_draw(NULL, NULL, NULL, per_frame.grid_width * 2 + per_frame.grid_height * 2 + 4, 1, &(R_Draw_Resources){
.vertex_uniform_buffers = (R_Buffer[]){ view_projection_matrix_buffer, per_frame_buffer }, .vertex_uniform_buffers = (R_Buffer[]){ view_projection_matrix_buffer, per_frame_buffer },
.num_vertex_uniform_buffers = 2, .num_vertex_uniform_buffers = 2,
}); });
+9 -20
View File
@@ -733,29 +733,14 @@ bool renderer_init(SDL_Window *window_) {
.fragment_shader = fragment_shader, .fragment_shader = fragment_shader,
.vertex_input_state = { .vertex_input_state = {
.vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]){ .vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]){},
{ .num_vertex_buffers = 0,
.slot = 0,
.pitch = 20,
.input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX,
.instance_step_rate = 0, .vertex_attributes = (SDL_GPUVertexAttribute[]){},
}, .num_vertex_attributes = 0,
},
.num_vertex_buffers = 1,
.vertex_attributes = (SDL_GPUVertexAttribute[]){
{
.location = 0,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3,
.offset = 0,
},
},
.num_vertex_attributes = 1,
}, },
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, .primitive_type = SDL_GPU_PRIMITIVETYPE_LINELIST,
.rasterizer_state = { .rasterizer_state = {
.fill_mode = SDL_GPU_FILLMODE_FILL, .fill_mode = SDL_GPU_FILLMODE_FILL,
@@ -824,6 +809,10 @@ bool renderer_init(SDL_Window *window_) {
SDL_ReleaseGPUShader(device, fragment_shader); SDL_ReleaseGPUShader(device, fragment_shader);
} }
for (int i = 0; i < R_SHADER_COUNT; i++) {
SDL_assert(shaders[i]);
}
transfer_buffer = SDL_CreateGPUTransferBuffer(device, &(SDL_GPUTransferBufferCreateInfo){ transfer_buffer = SDL_CreateGPUTransferBuffer(device, &(SDL_GPUTransferBufferCreateInfo){
.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD, .usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
.size = 64 * 1024, .size = 64 * 1024,
+7 -16
View File
@@ -932,25 +932,12 @@ bool renderer_init(SDL_Window *window_) {
.entryPoint = { .data = "main_vertex", .length = WGPU_STRLEN }, .entryPoint = { .data = "main_vertex", .length = WGPU_STRLEN },
.constantCount = 0, .constantCount = 0,
.constants = NULL, .constants = NULL,
.bufferCount = 1, .bufferCount = 0,
.buffers = (WGPUVertexBufferLayout[]){ .buffers = NULL,
{
.stepMode = WGPUVertexStepMode_Vertex,
.arrayStride = 20,
.attributeCount = 1,
.attributes = (WGPUVertexAttribute[]){
{
.format = WGPUVertexFormat_Float32x3,
.offset = 0,
.shaderLocation = 0,
},
},
},
},
}, },
.primitive = { .primitive = {
.topology = WGPUPrimitiveTopology_TriangleList, .topology = WGPUPrimitiveTopology_LineList,
.stripIndexFormat = WGPUIndexFormat_Undefined, .stripIndexFormat = WGPUIndexFormat_Undefined,
.frontFace = WGPUFrontFace_CCW, .frontFace = WGPUFrontFace_CCW,
.cullMode = WGPUCullMode_Back, .cullMode = WGPUCullMode_Back,
@@ -978,6 +965,10 @@ bool renderer_init(SDL_Window *window_) {
wgpuShaderModuleRelease(shader); wgpuShaderModuleRelease(shader);
} }
for (int i = 0; i < R_SHADER_COUNT; i++) {
SDL_assert(shaders[i]);
}
return true; return true;
} }
Binary file not shown.
+21 -12
View File
@@ -1,16 +1,16 @@
#language 2026 #language 2026
struct VertexShaderInput { struct VertexShaderInput {
uint32_t vertex_index : SV_VulkanVertexID; uint32_t vertex_index : SV_VulkanVertexID;
uint32_t instance_index : SV_VulkanInstanceID;
[vk::location(0)] float3 pos;
}; };
struct VertexShaderOutput { struct VertexShaderOutput {
float4 pos : SV_Position; float4 pos : SV_Position;
int selected; nointerpolation int2 selection_min;
nointerpolation int2 selection_max;
float2 tile_pos;
}; };
struct FragmentShaderOutput { struct FragmentShaderOutput {
@@ -23,6 +23,7 @@ struct Per_Frame_Data {
float2 grid_offset; float2 grid_offset;
uint32_t grid_width; uint32_t grid_width;
uint32_t map_width; uint32_t map_width;
uint32_t grid_height;
}; };
[vk::binding(0, 1)] ConstantBuffer<float4x4> view_projection_matrix : register(b0, space1); [vk::binding(0, 1)] ConstantBuffer<float4x4> view_projection_matrix : register(b0, space1);
@@ -31,14 +32,22 @@ struct Per_Frame_Data {
[shader("vertex")] [shader("vertex")]
VertexShaderOutput main_vertex(VertexShaderInput input) { VertexShaderOutput main_vertex(VertexShaderInput input) {
var output: VertexShaderOutput; var output: VertexShaderOutput;
output.selection_min = min(per_frame.drag_start, per_frame.mouse);
output.selection_max = max(per_frame.drag_start, per_frame.mouse);
let tile_pos = float2(float(input.instance_index % per_frame.grid_width), float(input.instance_index / per_frame.grid_width)); let vertex_pos = select(input.vertex_index < (per_frame.grid_height + 1) * 2,
output.pos = mul(float4(tile_pos + per_frame.grid_offset + input.pos.xy, 0, 1), view_projection_matrix); select(input.vertex_index % 2 == 0,
float2( 0, input.vertex_index / 2),
float2(per_frame.grid_width, input.vertex_index / 2)
),
select(input.vertex_index % 2 == 0,
float2((input.vertex_index % ((per_frame.grid_height + 1) * 2)) / 2, 0),
float2((input.vertex_index % ((per_frame.grid_height + 1) * 2)) / 2, per_frame.grid_height)
)
);
let pos = int2(tile_pos + round(per_frame.grid_offset)); output.pos = mul(float4(vertex_pos + per_frame.grid_offset - float2(0.5, 0.5), 0, 1), view_projection_matrix);
let selection_min = min(per_frame.drag_start, per_frame.mouse); output.tile_pos = vertex_pos + round(per_frame.grid_offset);
let selection_max = max(per_frame.drag_start, per_frame.mouse);
output.selected = select(all(pos >= selection_min) && all(pos <= selection_max), 1, 0);
return output; return output;
} }
@@ -50,7 +59,7 @@ static const float4 selected_color = float4(1.0, 0.0, 1.0, 1.0);
FragmentShaderOutput main_fragment(VertexShaderOutput input) { FragmentShaderOutput main_fragment(VertexShaderOutput input) {
var output: FragmentShaderOutput; var output: FragmentShaderOutput;
output.color = input.selected != 0 ? selected_color : color; output.color = select(all(input.tile_pos >= (input.selection_min - float2(0.01, 0.01))) && all(input.tile_pos <= (input.selection_max + float2(1.01, 1.01))), selected_color, color);
return output; return output;
} }
+25 -31
View File
@@ -5,6 +5,7 @@ struct Per_Frame_Data_std140_0
@align(16) grid_offset_0 : vec2<f32>, @align(16) grid_offset_0 : vec2<f32>,
@align(8) grid_width_0 : u32, @align(8) grid_width_0 : u32,
@align(4) map_width_0 : u32, @align(4) map_width_0 : u32,
@align(16) grid_height_0 : u32,
}; };
@binding(1) @group(1) var<uniform> per_frame_0 : Per_Frame_Data_std140_0; @binding(1) @group(1) var<uniform> per_frame_0 : Per_Frame_Data_std140_0;
@@ -17,35 +18,26 @@ struct _MatrixStorage_float4x4_ColMajorstd140_0
struct VertexShaderOutput_0 struct VertexShaderOutput_0
{ {
@builtin(position) pos_0 : vec4<f32>, @builtin(position) pos_0 : vec4<f32>,
@location(0) selected_0 : i32, @interpolate(flat) @location(0) selection_min_0 : vec2<i32>,
}; @interpolate(flat) @location(1) selection_max_0 : vec2<i32>,
@location(2) tile_pos_0 : vec2<f32>,
struct vertexInput_0
{
@location(0) pos_1 : vec3<f32>,
}; };
@vertex @vertex
fn main_vertex( _S1 : vertexInput_0, @builtin(vertex_index) vertex_index_0 : u32, @builtin(instance_index) instance_index_0 : u32) -> VertexShaderOutput_0 fn main_vertex(@builtin(vertex_index) vertex_index_0 : u32) -> VertexShaderOutput_0
{ {
var _S2 : u32 = instance_index_0 % per_frame_0.grid_width_0;
var _S3 : f32 = f32(_S2);
var _S4 : u32 = instance_index_0 / per_frame_0.grid_width_0;
var _S5 : vec2<f32> = vec2<f32>(_S3, f32(_S4));
var output_0 : VertexShaderOutput_0; var output_0 : VertexShaderOutput_0;
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(_S5 + per_frame_0.grid_offset_0 + _S1.pos_1.xy, 0.0f, 1.0f)))); output_0.selection_min_0 = min(per_frame_0.drag_start_0, per_frame_0.mouse_0);
var _S6 : vec2<i32> = vec2<i32>(_S5 + round(per_frame_0.grid_offset_0)); output_0.selection_max_0 = max(per_frame_0.drag_start_0, per_frame_0.mouse_0);
var _S7 : vec2<i32> = max(per_frame_0.drag_start_0, per_frame_0.mouse_0); var _S1 : bool = vertex_index_0 < ((per_frame_0.grid_height_0 + u32(1)) * u32(2));
var _S8 : bool; var _S2 : bool = (vertex_index_0 % u32(2)) == u32(0);
if((all((_S6 >= (min(per_frame_0.drag_start_0, per_frame_0.mouse_0)))))) var _S3 : vec2<f32> = select(vec2<f32>(f32(per_frame_0.grid_width_0), f32(vertex_index_0 / u32(2))), vec2<f32>(0.0f, f32(vertex_index_0 / u32(2))), _S2);
{ var _S4 : u32 = vertex_index_0 % ((per_frame_0.grid_height_0 + u32(1)) * u32(2));
_S8 = (all((_S6 <= _S7))); var _S5 : vec2<f32> = vec2<f32>(f32(_S4 / u32(2)), 0.0f);
} var _S6 : u32 = vertex_index_0 % ((per_frame_0.grid_height_0 + u32(1)) * u32(2));
else var _S7 : vec2<f32> = select(select(vec2<f32>(f32(_S6 / u32(2)), f32(per_frame_0.grid_height_0)), _S5, _S2), _S3, _S1);
{ output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(_S7 + per_frame_0.grid_offset_0 - vec2<f32>(0.5f, 0.5f), 0.0f, 1.0f))));
_S8 = false; output_0.tile_pos_0 = _S7 + round(per_frame_0.grid_offset_0);
}
output_0.selected_0 = select(i32(0), i32(1), _S8);
return output_0; return output_0;
} }
@@ -56,23 +48,25 @@ struct FragmentShaderOutput_0
struct pixelInput_0 struct pixelInput_0
{ {
@location(0) selected_1 : i32, @interpolate(flat) @location(0) selection_min_1 : vec2<i32>,
@interpolate(flat) @location(1) selection_max_1 : vec2<i32>,
@location(2) tile_pos_1 : vec2<f32>,
}; };
@fragment @fragment
fn main_fragment( _S9 : pixelInput_0, @builtin(position) pos_2 : vec4<f32>) -> FragmentShaderOutput_0 fn main_fragment( _S8 : pixelInput_0, @builtin(position) pos_1 : vec4<f32>) -> FragmentShaderOutput_0
{ {
var output_1 : FragmentShaderOutput_0; var output_1 : FragmentShaderOutput_0;
var _S10 : vec4<f32>; var _S9 : bool;
if((_S9.selected_1) != i32(0)) if((all(((_S8.tile_pos_1) >= (vec2<f32>(_S8.selection_min_1) - vec2<f32>(0.00999999977648258f, 0.00999999977648258f))))))
{ {
_S10 = vec4<f32>(1.0f, 0.0f, 1.0f, 1.0f); _S9 = (all(((_S8.tile_pos_1) <= (vec2<f32>(_S8.selection_max_1) + vec2<f32>(1.00999999046325684f, 1.00999999046325684f)))));
} }
else else
{ {
_S10 = vec4<f32>(1.0f, 1.0f, 1.0f, 0.10000000149011612f); _S9 = false;
} }
output_1.color_0 = _S10; output_1.color_0 = select(vec4<f32>(1.0f, 1.0f, 1.0f, 0.10000000149011612f), vec4<f32>(1.0f, 0.0f, 1.0f, 1.0f), _S9);
return output_1; return output_1;
} }