/* * Tuxánci 2 - A first person shooter * Copyright (C) 2025-2026 Connor Thomson * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ struct ShapeVertexUniforms { float4 bounds; float4 points[3]; float4 viewport; float4 color; float4 params; }; [[vk::binding(0, 1)]] ConstantBuffer uniforms : register(b0, space1); struct VSOutput { float4 position : SV_Position; float2 uv : TEXCOORD0; }; float2 to_clip(float2 point) { return float2( 2.0 * point.x / uniforms.viewport.x - 1.0, 1.0 - 2.0 * point.y / uniforms.viewport.y ); } float2 line_vertex(float2 first, float2 second, uint vertexID) { float2 direction = normalize(second - first); float2 normal = float2(-direction.y, direction.x) * uniforms.params.y * 0.5; static const float2 corners[6] = { float2( 1.0, 1.0), float2( 1.0, -1.0), float2(-1.0, 1.0), float2(-1.0, 1.0), float2( 1.0, -1.0), float2(-1.0, -1.0) }; float2 corner = corners[vertexID]; return lerp(first, second, corner.x * 0.5 + 0.5) + normal * corner.y; } VSOutput main(uint vertexID : SV_VertexID) { static const float2 quad_positions[6] = { float2(0.0, 0.0), float2(1.0, 0.0), float2(0.0, 1.0), float2(0.0, 1.0), float2(1.0, 0.0), float2(1.0, 1.0) }; uint shape_type = (uint)uniforms.params.x; float2 position; float2 uv = float2(0.0, 0.0); if (shape_type <= 1 || shape_type >= 3 && shape_type <= 4) { uv = quad_positions[vertexID]; position = uniforms.bounds.xy + uv * uniforms.bounds.zw; } else if (shape_type == 2) { position = line_vertex(uniforms.points[0].xy, uniforms.points[1].xy, vertexID); } else if (shape_type == 5) { position = uniforms.points[vertexID].xy; } else { uint edge = vertexID / 6; uint edge_vertex = vertexID % 6; uint first_index = edge; uint second_index = (edge + 1) % 3; position = line_vertex( uniforms.points[first_index].xy, uniforms.points[second_index].xy, edge_vertex ); } VSOutput output; output.position = float4(to_clip(position), 0.0, 1.0); output.uv = uv; return output; }