diff --git a/Package.swift b/Package.swift index 535788d..37babd0 100644 --- a/Package.swift +++ b/Package.swift @@ -41,8 +41,8 @@ let package = Package( .process("../../../data/shaders/lesson7.metallib"), .process("../../../data/Crate.bmp") ]), .executableTarget(name: "Lesson8", dependencies: [ "NeHe" ], path: "src/swift/Lesson8", resources: [ - .process("../../../data/shaders/lesson6.metallib"), .process("../../../data/shaders/lesson7.metallib"), + .process("../../../data/shaders/lesson8.metallib"), .process("../../../data/Glass.bmp") ]), .executableTarget(name: "Lesson9", dependencies: [ "NeHe" ], path: "src/swift/Lesson9", resources: [ .process("../../../data/shaders/lesson9.metallib"), diff --git a/build.rs b/build.rs index b0f1af0..e704694 100644 --- a/build.rs +++ b/build.rs @@ -53,6 +53,7 @@ pub fn main() "lesson3.metallib", "lesson6.metallib", "lesson7.metallib", + "lesson8.metallib", "lesson9.metallib", ]); } diff --git a/data/shaders/lesson2.metallib b/data/shaders/lesson2.metallib index 0a3f31e..ce09381 100644 Binary files a/data/shaders/lesson2.metallib and b/data/shaders/lesson2.metallib differ diff --git a/data/shaders/lesson3.metallib b/data/shaders/lesson3.metallib index 0733a7b..cd0c8fc 100644 Binary files a/data/shaders/lesson3.metallib and b/data/shaders/lesson3.metallib differ diff --git a/data/shaders/lesson6.metallib b/data/shaders/lesson6.metallib index e5bd78f..6810806 100644 Binary files a/data/shaders/lesson6.metallib and b/data/shaders/lesson6.metallib differ diff --git a/data/shaders/lesson7.metallib b/data/shaders/lesson7.metallib index cb46b92..94829cc 100644 Binary files a/data/shaders/lesson7.metallib and b/data/shaders/lesson7.metallib differ diff --git a/data/shaders/lesson8.metallib b/data/shaders/lesson8.metallib new file mode 100644 index 0000000..429421d Binary files /dev/null and b/data/shaders/lesson8.metallib differ diff --git a/data/shaders/lesson9.metallib b/data/shaders/lesson9.metallib index 36ad95c..5620ffb 100644 Binary files a/data/shaders/lesson9.metallib and b/data/shaders/lesson9.metallib differ diff --git a/scripts/compile_shaders.py b/scripts/compile_shaders.py index 933c893..0adcb44 100755 --- a/scripts/compile_shaders.py +++ b/scripts/compile_shaders.py @@ -134,7 +134,7 @@ def compile_shaders() -> None: build_metal = True build_dxil = False build_dxbc = False - lessons = [ "lesson2", "lesson3", "lesson6", "lesson7", "lesson9" ] + lessons = [ "lesson2", "lesson3", "lesson6", "lesson7", "lesson8", "lesson9" ] src_dir = Path("src/shaders") dest_dir = Path("data/shaders") diff --git a/src/c/CMakeLists.txt b/src/c/CMakeLists.txt index 1926336..6e40d30 100644 --- a/src/c/CMakeLists.txt +++ b/src/c/CMakeLists.txt @@ -7,6 +7,6 @@ add_lesson(lesson04 SOURCES lesson4.c SHADERS lesson3.metallib) add_lesson(lesson05 SOURCES lesson5.c SHADERS lesson3.metallib) add_lesson(lesson06 SOURCES lesson6.c SHADERS lesson6.metallib DATA NeHe.bmp) add_lesson(lesson07 SOURCES lesson7.c SHADERS lesson6.metallib lesson7.metallib DATA Crate.bmp) -add_lesson(lesson08 SOURCES lesson8.c SHADERS lesson6.metallib lesson7.metallib DATA Glass.bmp) +add_lesson(lesson08 SOURCES lesson8.c SHADERS lesson7.metallib lesson8.metallib DATA Glass.bmp) add_lesson(lesson09 SOURCES lesson9.c SHADERS lesson6.metallib lesson9.metallib DATA Star.bmp) add_lesson(lesson10 SOURCES lesson10.c SHADERS lesson6.metallib DATA Mud.bmp World.txt) diff --git a/src/c/lesson10.c b/src/c/lesson10.c index 3df592d..9ea778c 100644 --- a/src/c/lesson10.c +++ b/src/c/lesson10.c @@ -307,10 +307,9 @@ static void Lesson10_Draw(NeHeContext* restrict ctx, SDL_GPUCommandBuffer* restr Mtx_Translate(modelView, -camera.x, -(0.25f + camera.walkBob), -camera.z); // Push shader uniforms - struct { float modelViewProj[16], color[4]; } u; - Mtx_Multiply(u.modelViewProj, projection, modelView); - SDL_memcpy(u.color, (float[4]){ 1.0f, 1.0f, 1.0f, 1.0f }, sizeof(float) * 4); - SDL_PushGPUVertexUniformData(cmd, 0, &u, sizeof(u)); + float modelViewProj[16]; + Mtx_Multiply(modelViewProj, projection, modelView); + SDL_PushGPUVertexUniformData(cmd, 0, &modelViewProj, sizeof(modelViewProj)); // Draw world SDL_DrawGPUPrimitives(pass, 3u * (uint32_t)world.numTriangles, 1, 0, 0); diff --git a/src/c/lesson6.c b/src/c/lesson6.c index 5b91892..21b2234 100644 --- a/src/c/lesson6.c +++ b/src/c/lesson6.c @@ -229,8 +229,7 @@ static void Lesson6_Draw(NeHeContext* restrict ctx, SDL_GPUCommandBuffer* restri .offset = 0 }, SDL_GPU_INDEXELEMENTSIZE_16BIT); - float model[16]; - struct { float modelViewProj[16], color[4]; } u; + float model[16], modelViewProj[16]; // Move cube 5 units into the screen and apply some rotations Mtx_Translation(model, 0.0f, 0.0f, -5.0f); @@ -239,9 +238,8 @@ static void Lesson6_Draw(NeHeContext* restrict ctx, SDL_GPUCommandBuffer* restri Mtx_Rotate(model, zRot, 0.0f, 0.0f, 1.0f); // Push shader uniforms - Mtx_Multiply(u.modelViewProj, projection, model); - SDL_memcpy(u.color, (float[4]){ 1.0f, 1.0f, 1.0f, 1.0f }, sizeof(float) * 4); - SDL_PushGPUVertexUniformData(cmd, 0, &u, sizeof(u)); + Mtx_Multiply(modelViewProj, projection, model); + SDL_PushGPUVertexUniformData(cmd, 0, &modelViewProj, sizeof(modelViewProj)); // Draw textured cube SDL_DrawGPUIndexedPrimitives(pass, SDL_arraysize(indices), 1, 0, 0, 0); diff --git a/src/c/lesson7.c b/src/c/lesson7.c index 21ce59d..983798d 100644 --- a/src/c/lesson7.c +++ b/src/c/lesson7.c @@ -319,10 +319,9 @@ static void Lesson7_Draw(NeHeContext* restrict ctx, SDL_GPUCommandBuffer* restri } else { - struct { float modelViewProj[16], color[4]; } u; - Mtx_Multiply(u.modelViewProj, projection, model); - SDL_memcpy(u.color, (const float[4]){ 1.0f, 1.0f, 1.0f, 1.0f }, sizeof(float) * 4); - SDL_PushGPUVertexUniformData(cmd, 0, &u, sizeof(u)); + float modelViewProj[16]; + Mtx_Multiply(modelViewProj, projection, model); + SDL_PushGPUVertexUniformData(cmd, 0, &modelViewProj, sizeof(modelViewProj)); } // Draw textured cube diff --git a/src/c/lesson8.c b/src/c/lesson8.c index 1fa4aa8..752cc2c 100644 --- a/src/c/lesson8.c +++ b/src/c/lesson8.c @@ -88,7 +88,7 @@ static bool Lesson8_Init(NeHeContext* restrict ctx) { SDL_GPUShader* vertexShaderUnlit, * fragmentShaderUnlit; SDL_GPUShader* vertexShaderLight, * fragmentShaderLight; - if (!NeHe_LoadShaders(ctx, &vertexShaderUnlit, &fragmentShaderUnlit, "lesson6", + if (!NeHe_LoadShaders(ctx, &vertexShaderUnlit, &fragmentShaderUnlit, "lesson8", &(const NeHeShaderProgramCreateInfo){ .vertexUniforms = 1, .fragmentSamplers = 1 })) { return false; diff --git a/src/rust/lesson10.rs b/src/rust/lesson10.rs index d429b90..893d84c 100644 --- a/src/rust/lesson10.rs +++ b/src/rust/lesson10.rs @@ -330,10 +330,10 @@ impl AppImplementation for Lesson10 model_view.translate(-cam_x, -cam_y, -cam_z); // Push shader uniforms - #[allow(dead_code)] - struct Uniforms { model_view_proj: Mtx, color: [f32; 4] } - let u = Uniforms { model_view_proj: self.projection * model_view, color: [1.0; 4] }; - SDL_PushGPUVertexUniformData(cmd, 0, addr_of!(u) as *const c_void, size_of::() as u32); + let model_view_proj = self.projection * model_view; + SDL_PushGPUVertexUniformData(cmd, 0, + addr_of!(model_view_proj) as *const c_void, + size_of::() as u32); // Draw world SDL_DrawGPUPrimitives(pass, self.world.vertices.len() as u32, 1, 0, 0); diff --git a/src/rust/lesson6.rs b/src/rust/lesson6.rs index 01c1352..929ba39 100644 --- a/src/rust/lesson6.rs +++ b/src/rust/lesson6.rs @@ -252,12 +252,11 @@ impl AppImplementation for Lesson6 model.rotate(self.rot.1, 0.0, 1.0, 0.0); model.rotate(self.rot.2, 0.0, 0.0, 1.0); - #[allow(dead_code)] - struct Uniforms { model_view_proj: Mtx, color: [f32; 4] } - // Push shader uniforms - let u = Uniforms { model_view_proj: self.projection * model, color: [1.0; 4] }; - SDL_PushGPUVertexUniformData(cmd, 0, addr_of!(u) as *const c_void, size_of::() as u32); + let model_view_proj = self.projection * model; + SDL_PushGPUVertexUniformData(cmd, 0, + addr_of!(model_view_proj) as *const c_void, + size_of::() as u32); // Draw the textured cube SDL_DrawGPUIndexedPrimitives(pass, INDICES.len() as u32, 1, 0, 0, 0); diff --git a/src/rust/lesson7.rs b/src/rust/lesson7.rs index c430f23..59daf94 100644 --- a/src/rust/lesson7.rs +++ b/src/rust/lesson7.rs @@ -335,10 +335,8 @@ impl AppImplementation for Lesson7 } else { - #[allow(dead_code)] - struct Uniforms { model_view_proj: Mtx, color: [f32; 4] } - let u = Uniforms { model_view_proj: self.projection * model, color: [1.0; 4] }; - SDL_PushGPUVertexUniformData(cmd, 0, addr_of!(u) as *const c_void, size_of::() as u32); + let model_view_proj = self.projection * model; + SDL_PushGPUVertexUniformData(cmd, 0, addr_of!(model_view_proj) as *const c_void, size_of::() as u32); } // Draw the textured cube diff --git a/src/rust/lesson8.rs b/src/rust/lesson8.rs index 6cb249d..2086a7e 100644 --- a/src/rust/lesson8.rs +++ b/src/rust/lesson8.rs @@ -143,7 +143,7 @@ impl AppImplementation for Lesson8 fn init(&mut self, ctx: &NeHeContext) -> Result<(), NeHeError> { - let (vertex_shader_unlit, fragment_shader_unlit) = ctx.load_shaders("lesson6", 1, 0, 1)?; + let (vertex_shader_unlit, fragment_shader_unlit) = ctx.load_shaders("lesson8", 1, 0, 1)?; let (vertex_shader_light, fragment_shader_light) = ctx.load_shaders("lesson7", 2, 0, 1)?; const VERTEX_DESCRIPTIONS: &'static [SDL_GPUVertexBufferDescription] = diff --git a/src/shaders/lesson6.metal b/src/shaders/lesson6.metal index 0b05448..ebefd03 100644 --- a/src/shaders/lesson6.metal +++ b/src/shaders/lesson6.metal @@ -15,14 +15,12 @@ struct VertexInput struct VertexUniform { metal::float4x4 viewproj; - float4 color; }; struct Vertex2Fragment { float4 position [[position]]; float2 texcoord; - half4 color; }; vertex Vertex2Fragment VertexMain( @@ -32,7 +30,6 @@ vertex Vertex2Fragment VertexMain( Vertex2Fragment out; out.position = u.viewproj * float4(in.position, 1.0); out.texcoord = in.texcoord; - out.color = half4(u.color); return out; } @@ -41,5 +38,5 @@ fragment half4 FragmentMain( metal::texture2d texture [[texture(0)]], metal::sampler sampler [[sampler(0)]]) { - return in.color * texture.sample(sampler, in.texcoord); + return texture.sample(sampler, in.texcoord); } diff --git a/src/shaders/lesson8.metal b/src/shaders/lesson8.metal new file mode 100644 index 0000000..0b05448 --- /dev/null +++ b/src/shaders/lesson8.metal @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: (C) 2025 a dinosaur + * SPDX-License-Identifier: Zlib + */ + +#include +#include + +struct VertexInput +{ + float3 position [[attribute(0)]]; + float2 texcoord [[attribute(1)]]; +}; + +struct VertexUniform +{ + metal::float4x4 viewproj; + float4 color; +}; + +struct Vertex2Fragment +{ + float4 position [[position]]; + float2 texcoord; + half4 color; +}; + +vertex Vertex2Fragment VertexMain( + VertexInput in [[stage_in]], + constant VertexUniform& u [[buffer(0)]]) +{ + Vertex2Fragment out; + out.position = u.viewproj * float4(in.position, 1.0); + out.texcoord = in.texcoord; + out.color = half4(u.color); + return out; +} + +fragment half4 FragmentMain( + Vertex2Fragment in [[stage_in]], + metal::texture2d texture [[texture(0)]], + metal::sampler sampler [[sampler(0)]]) +{ + return in.color * texture.sample(sampler, in.texcoord); +} diff --git a/src/swift/Lesson10/lesson10.swift b/src/swift/Lesson10/lesson10.swift index 840b50c..b00b04e 100644 --- a/src/swift/Lesson10/lesson10.swift +++ b/src/swift/Lesson10/lesson10.swift @@ -298,11 +298,8 @@ struct Lesson10: AppDelegate modelView.translate(-camera.position) // Push shader uniforms - struct Uniforms { var modelViewProj: simd_float4x4, color: SIMD4 } - var u = Uniforms( - modelViewProj: self.projection * modelView, - color: .init(repeating: 1.0)) - SDL_PushGPUVertexUniformData(cmd, 0, &u, UInt32(MemoryLayout.size)) + var modelViewProj = self.projection * modelView + SDL_PushGPUVertexUniformData(cmd, 0, &modelViewProj, UInt32(MemoryLayout.size)) // Draw world SDL_DrawGPUPrimitives(pass, UInt32(self.world.vertices.count), 1, 0, 0) diff --git a/src/swift/Lesson6/lesson6.swift b/src/swift/Lesson6/lesson6.swift index f2181d8..422332e 100644 --- a/src/swift/Lesson6/lesson6.swift +++ b/src/swift/Lesson6/lesson6.swift @@ -209,8 +209,6 @@ struct Lesson6: AppDelegate vtxBindings.withUnsafeBufferPointer(\.baseAddress!), UInt32(vtxBindings.count)) SDL_BindGPUIndexBuffer(pass, &idxBinding, SDL_GPU_INDEXELEMENTSIZE_16BIT) - struct Uniforms { var modelViewProj: simd_float4x4, color: SIMD4 } - // Move cube 5 units into the camera and apply some rotations var model: simd_float4x4 = .translation(.init(0.0, 0.0, -5.0)) model.rotate(angle: rot.x, axis: .init(1.0, 0.0, 0.0)) @@ -218,10 +216,8 @@ struct Lesson6: AppDelegate model.rotate(angle: rot.z, axis: .init(0.0, 0.0, 1.0)) // Push shader uniforms - var u = Uniforms( - modelViewProj: self.projection * model, - color: .init(repeating: 1.0)) - SDL_PushGPUVertexUniformData(cmd, 0, &u, UInt32(MemoryLayout.size)) + var modelViewProj = self.projection * model + SDL_PushGPUVertexUniformData(cmd, 0, &modelViewProj, UInt32(MemoryLayout.size)) // Draw textured cube SDL_DrawGPUIndexedPrimitives(pass, UInt32(Self.indices.count), 1, 0, 0, 0) diff --git a/src/swift/Lesson7/lesson7.swift b/src/swift/Lesson7/lesson7.swift index a241f9e..478e978 100644 --- a/src/swift/Lesson7/lesson7.swift +++ b/src/swift/Lesson7/lesson7.swift @@ -266,11 +266,8 @@ struct Lesson7: AppDelegate } else { - struct Uniforms { var modelViewProj: simd_float4x4, color: SIMD4 } - var u = Uniforms( - modelViewProj: self.projection * model, - color: .init(repeating: 1.0)) - SDL_PushGPUVertexUniformData(cmd, 0, &u, UInt32(MemoryLayout.size)) + var modelViewProj = self.projection * model + SDL_PushGPUVertexUniformData(cmd, 0, &modelViewProj, UInt32(MemoryLayout.size)) } // Draw textured cube diff --git a/src/swift/Lesson8/lesson8.swift b/src/swift/Lesson8/lesson8.swift index ae533fd..344d10d 100644 --- a/src/swift/Lesson8/lesson8.swift +++ b/src/swift/Lesson8/lesson8.swift @@ -90,7 +90,7 @@ struct Lesson8: AppDelegate mutating func `init`(ctx: inout NeHeContext) throws(NeHeError) { - let (vertexShaderUnlit, fragmentShaderUnlit) = try ctx.loadShaders(name: "lesson6", + let (vertexShaderUnlit, fragmentShaderUnlit) = try ctx.loadShaders(name: "lesson8", vertexUniforms: 1, fragmentSamplers: 1) defer {