diff --git a/Sources/Voxelotl/Application.swift b/Sources/Voxelotl/Application.swift index d43d0ca..f657d6f 100644 --- a/Sources/Voxelotl/Application.swift +++ b/Sources/Voxelotl/Application.swift @@ -25,10 +25,10 @@ public class Application { // Create SDL window var windowFlags = SDL_WindowFlags(0) - if (cfg.flags.contains(.resizable)) { + if cfg.flags.contains(.resizable) { windowFlags |= SDL_WindowFlags(SDL_WINDOW_RESIZABLE) } - if (cfg.flags.contains(.highDPI)) { + if cfg.flags.contains(.highDPI) { windowFlags |= SDL_WindowFlags(SDL_WINDOW_HIGH_PIXEL_DENSITY) } window = SDL_CreateWindow(cfg.title, cfg.width, cfg.height, windowFlags) @@ -174,7 +174,7 @@ fileprivate enum ApplicationExecutionState { case running } -extension FileHandle: TextOutputStream { +extension FileHandle: @retroactive TextOutputStream { public func write(_ string: String) { self.write(Data(string.utf8)) } diff --git a/Sources/Voxelotl/CMakeLists.txt b/Sources/Voxelotl/CMakeLists.txt index 475d7f5..617335f 100644 --- a/Sources/Voxelotl/CMakeLists.txt +++ b/Sources/Voxelotl/CMakeLists.txt @@ -3,7 +3,14 @@ add_executable(Voxelotl MACOSX_BUNDLE Renderer.swift FPSCalculator.swift Application.swift - main.swift) + main.swift + shader.metal) + +set_source_files_properties( + shader.metal PROPERTIES + LANGUAGE METAL + COMPILE_OPTIONS "-I${PROJECT_SOURCE_DIR}" +) target_link_libraries(Voxelotl PRIVATE SDLSwift) set_target_properties(Voxelotl PROPERTIES @@ -28,4 +35,4 @@ set_target_properties(Voxelotl PROPERTIES set_source_files_properties(Assets.xcassets PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") source_group("Resources" FILES Assets.xcassets) -source_group("Source Files" REGULAR_EXPRESSION "\\.(swift)$") +source_group("Source Files" REGULAR_EXPRESSION "\\.(swift|metal)$") diff --git a/Sources/Voxelotl/FPSCalculator.swift b/Sources/Voxelotl/FPSCalculator.swift index 812765d..5b188a8 100644 --- a/Sources/Voxelotl/FPSCalculator.swift +++ b/Sources/Voxelotl/FPSCalculator.swift @@ -8,7 +8,7 @@ public struct FPSCalculator { _framesCount += 1 _accumulator += deltaTime - if (_accumulator >= 1.0) { + if _accumulator >= 1.0 { result(_framesCount) _framesCount = 0 diff --git a/Sources/Voxelotl/Renderer.swift b/Sources/Voxelotl/Renderer.swift index 5360559..f83a866 100644 --- a/Sources/Voxelotl/Renderer.swift +++ b/Sources/Voxelotl/Renderer.swift @@ -109,12 +109,8 @@ class Renderer { // Create shader library & grab functions do { - //self.lib = try device.makeDefaultLibrary(bundle: Bundle.main) - let options = MTLCompileOptions() - options.fastMathEnabled = true - self.lib = try device.makeLibrary(source: Self.shaderSource, options: options) - } - catch { + self.lib = try device.makeDefaultLibrary(bundle: Bundle.main) + } catch { throw RendererError.initFailure("Metal shader compilation failed:\n\(error.localizedDescription)") } let vertexProgram = lib.makeFunction(name: "vertexMain") @@ -127,8 +123,7 @@ class Renderer { pipeDescription.colorAttachments[0].pixelFormat = layer.pixelFormat do { self.pso = try device.makeRenderPipelineState(descriptor: pipeDescription) - } - catch { + } catch { throw RendererError.initFailure("Failed to create pipeline state: \(error.localizedDescription)") } diff --git a/Sources/Voxelotl/main.swift b/Sources/Voxelotl/main.swift index 20d4cd8..38b2379 100644 --- a/Sources/Voxelotl/main.swift +++ b/Sources/Voxelotl/main.swift @@ -6,6 +6,6 @@ let app = Application( height: 720, title: "Voxelotl Demo", flags: [ .resizable, .highDPI ], - vsyncMode: .on(interval: 1))) + vsyncMode: .off)) exit(app.run()) diff --git a/Sources/Voxelotl/shader.metal b/Sources/Voxelotl/shader.metal new file mode 100644 index 0000000..8e0998f --- /dev/null +++ b/Sources/Voxelotl/shader.metal @@ -0,0 +1,45 @@ +#ifndef SHADERTYPES_H +#define SHADERTYPES_H + +#ifdef __METAL_VERSION__ +# define NS_ENUM(TYPE, NAME) enum NAME : TYPE NAME; enum NAME : TYPE +# define NSInteger metal::int32_t +#else +# import +#endif + +#include + +typedef NS_ENUM(NSInteger, ShaderInputIdx) { + ShaderInputIdxVertices = 0 +}; + +typedef struct { + vector_float4 position; + vector_float4 color; +} ShaderVertex; + +#endif//SHADERTYPES_H + +#include + +using namespace metal; + +struct FragmentInput { + float4 position [[position]]; + float4 color; +}; + +vertex FragmentInput vertexMain( + uint vertexID [[vertex_id]], + device const ShaderVertex* vtx [[buffer(ShaderInputIdxVertices)]] +) { + FragmentInput out; + out.position = vtx[vertexID].position; + out.color = vtx[vertexID].color; + return out; +} + +fragment float4 fragmentMain(FragmentInput in [[stage_in]]) { + return in.color; +}