From a5cfcee03d9cb829d9f69c556370c8c834ab3d94 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Mon, 5 Jan 2026 09:01:39 +0000 Subject: [PATCH] feat: Add solid shader support and update room dimensions in cube logic --- scripts/cube_logic.lua | 23 +++++++++------ scripts/dev_commands.py | 64 +++++++++++++++++++++++++++++++++++++--- shaders/solid.frag | 10 +++++++ shaders/solid.frag.spv | Bin 0 -> 560 bytes shaders/solid.vert | 19 ++++++++++++ shaders/solid.vert.spv | Bin 0 -> 1600 bytes 6 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 shaders/solid.frag create mode 100644 shaders/solid.frag.spv create mode 100644 shaders/solid.vert create mode 100644 shaders/solid.vert.spv diff --git a/scripts/cube_logic.lua b/scripts/cube_logic.lua index ad3826e..c448235 100644 --- a/scripts/cube_logic.lua +++ b/scripts/cube_logic.lua @@ -204,6 +204,10 @@ local shader_variants = { vertex = "shaders/cube.vert.spv", fragment = "shaders/cube.frag.spv", }, + solid = { + vertex = "shaders/solid.vert.spv", + fragment = "shaders/solid.frag.spv", + }, } local camera = { @@ -232,10 +236,10 @@ local last_frame_time = nil local movement_log_cooldown = 0.0 local world_up = {0.0, 1.0, 0.0} local room = { - half_size = 6.0, - wall_thickness = 0.3, - wall_height = 2.5, - floor_half_thickness = 0.2, + half_size = 15.0, + wall_thickness = 0.5, + wall_height = 4.0, + floor_half_thickness = 0.3, floor_top = 0.0, } local player_state = { @@ -250,7 +254,7 @@ local player_state = { camera.position[1] = 0.0 camera.position[2] = room.floor_top + player_state.eye_height -camera.position[3] = 4.0 +camera.position[3] = 10.0 local function clamp(value, minValue, maxValue) if value < minValue then @@ -491,15 +495,16 @@ local rotation_speed = 0.9 local function create_spinning_cube() local function compute_model_matrix(time) local rotation = math3d.rotation_y(time * rotation_speed) - local position = math3d.translation(0.0, 3.4, 0.0) - return math3d.multiply(position, rotation) + local scale = scale_matrix(1.5, 1.5, 1.5) -- Make cube 3x3x3 units + local position = math3d.translation(0.0, 3.0, 0.0) + return math3d.multiply(position, math3d.multiply(rotation, scale)) end return { vertices = cube_vertices, indices = cube_indices, compute_model_matrix = compute_model_matrix, - shader_key = "default", + shader_key = "default", -- Rainbow shader for spinning cube } end @@ -533,7 +538,7 @@ local function create_static_cube(position, scale, color) vertices = vertices, indices = cube_indices, compute_model_matrix = compute_model_matrix, - shader_key = "default", + shader_key = "solid", -- Use solid color shader for room objects } end diff --git a/scripts/dev_commands.py b/scripts/dev_commands.py index 6aa27f3..f6a876f 100644 --- a/scripts/dev_commands.py +++ b/scripts/dev_commands.py @@ -254,6 +254,61 @@ def msvc_quick(args: argparse.Namespace) -> None: run_argvs([cmd], args.dry_run) +def _compile_shaders(dry_run: bool) -> None: + """ + Compile GLSL shaders to SPIR-V format using glslangValidator. + Compiles all .vert and .frag files in the shaders directory. + """ + shaders_dir = Path("shaders") + if not shaders_dir.exists(): + return + + # Find shader compiler + compiler = None + for cmd in ["glslangValidator", "glslc"]: + try: + result = subprocess.run([cmd, "--version"], + capture_output=True, + timeout=5) + if result.returncode == 0: + compiler = cmd + break + except (FileNotFoundError, subprocess.TimeoutExpired): + continue + + if not compiler: + print("⚠️ No shader compiler found (glslangValidator or glslc)") + print(" Skipping shader compilation") + return + + print("\n=== Compiling Shaders ===") + shader_files = list(shaders_dir.glob("*.vert")) + list(shaders_dir.glob("*.frag")) + + for shader_file in shader_files: + output_file = shader_file.with_suffix(shader_file.suffix + ".spv") + + # Check if compilation is needed + if output_file.exists(): + if output_file.stat().st_mtime >= shader_file.stat().st_mtime: + continue # Skip if .spv is newer than source + + print(f" Compiling {shader_file.name} -> {output_file.name}") + + if not dry_run: + if compiler == "glslangValidator": + cmd = [compiler, "-V", str(shader_file), "-o", str(output_file)] + else: # glslc + cmd = [compiler, str(shader_file), "-o", str(output_file)] + + result = subprocess.run(cmd, capture_output=True, text=True) + if result.returncode != 0: + print(f" ❌ Failed: {result.stderr}") + else: + print(f" ✓ Success") + + print("=== Shaders Compiled ===\n") + + def _sync_assets(build_dir: str, dry_run: bool) -> None: """ Sync asset files (scripts, shaders, models) from the project root to the @@ -302,13 +357,14 @@ def run_demo(args: argparse.Namespace) -> None: executable is `sdl3_app` (or `sdl3_app.exe` on Windows). Additional arguments can be passed to the executable after `--`. - By default, syncs asset files (scripts, shaders, models) before running. - Use --no-sync to skip asset synchronization. + By default, compiles shaders and syncs asset files before running. + Use --no-sync to skip shader compilation and asset synchronization. """ build_dir = _as_build_dir(args.build_dir, DEFAULT_BUILD_DIR) - # Sync assets unless --no-sync is specified + # Compile shaders and sync assets unless --no-sync is specified if not args.no_sync: + _compile_shaders(args.dry_run) _sync_assets(build_dir, args.dry_run) exe_name = args.target or ("sdl3_app.exe" if IS_WINDOWS else "sdl3_app") @@ -430,7 +486,7 @@ def main() -> int: runp.add_argument( "--no-sync", action="store_true", - help="skip syncing assets (scripts, shaders, models) before running", + help="skip shader compilation and asset syncing before running", ) runp.add_argument( "args", diff --git a/shaders/solid.frag b/shaders/solid.frag new file mode 100644 index 0000000..9791877 --- /dev/null +++ b/shaders/solid.frag @@ -0,0 +1,10 @@ +#version 450 + +layout(location = 0) in vec3 fragColor; +layout(location = 1) in vec3 fragWorldPos; +layout(location = 0) out vec4 outColor; + +void main() { + // Use vertex color directly for solid colors + outColor = vec4(fragColor, 1.0); +} diff --git a/shaders/solid.frag.spv b/shaders/solid.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..45f555f2e28f4a831e90a4d635856454d46bc3b4 GIT binary patch literal 560 zcmYk1y-EXN5JktVn?$4eF`}JBEQMfULN&dDd^@*3gTS$vA)liS${H=y_^=VqIe(iu7eGTW9Id2t`PTAV zWOs?nx7L%`Iknt25%GCf_4R1~ire+)Za+1@K~nM!sG9qPdJmv#bxMr%k9A8-&5GA6 aG4*F$<2?t2^YZQM>z1wFXYU7B*TgT%q8_aP literal 0 HcmV?d00001 diff --git a/shaders/solid.vert b/shaders/solid.vert new file mode 100644 index 0000000..39930c3 --- /dev/null +++ b/shaders/solid.vert @@ -0,0 +1,19 @@ +#version 450 + +layout(location = 0) in vec3 inPos; +layout(location = 1) in vec3 inColor; + +layout(location = 0) out vec3 fragColor; +layout(location = 1) out vec3 fragWorldPos; + +layout(push_constant) uniform PushConstants { + mat4 model; + mat4 viewProj; +} pushConstants; + +void main() { + fragColor = inColor; + vec4 worldPos = pushConstants.model * vec4(inPos, 1.0); + fragWorldPos = worldPos.xyz; + gl_Position = pushConstants.viewProj * worldPos; +} diff --git a/shaders/solid.vert.spv b/shaders/solid.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..986dc4b04f5cd8937137050dac8c08fff3d84970 GIT binary patch literal 1600 zcmZ9M+fEZv6o$7z3yOk>98`o>R74aoQDb5}1rxX+v4%u14UrMY3^SxHV!ZMdd?laC z8xy~8IvYqgSzYV@*Kx1eVQ^q^ID~UyG>n8tp?4<208D_ZmwI!1XM45N-CKS9WZj6d zFjxi}GafFK_7J}ZyJ;>skBlPMkS4N>4DvUC{zFnN4DojwUxP8{OM7>JqsWRjwlUU7 z^B!Z&IQY0|XM3%pg9%d)6X@1a=j%q1ce=ZIS4SO>yyu|UOEPr5igo7iX>#0Z7vJ<- zV-kJXSHu3!pXR-0#(5WK{Ma|c68wJlsg<-pB<*hU16cNx_vkA+X*Vr$_~9V$93`LT z-JSGjVqEmOCwv=OdiXZ=R-cm-pPScrlw~Kr8oPDJo=xUn*xO#_HqrXyJy)>3r+ba}e1I(<>p#S{ew=3&+ZcK4tfAKt Qzm@y4kJz|>bbp5Y2OtM$p8x;= literal 0 HcmV?d00001