diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fc25fe4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+
+# Xcode
+# this ignores dummy workspace files in xcodeproj dir
+ParticleCam.xcodeproj/*
+!ParticleCam.xcodeproj/project.pbxproj
diff --git a/ParticleCam.xcodeproj/project.pbxproj b/ParticleCam.xcodeproj/project.pbxproj
index 5fc1472..f70d0de 100644
--- a/ParticleCam.xcodeproj/project.pbxproj
+++ b/ParticleCam.xcodeproj/project.pbxproj
@@ -121,12 +121,14 @@
3EA930931B75BFFA0067276D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0700;
+ LastUpgradeCheck = 1010;
ORGANIZATIONNAME = "Simon Gladman";
TargetAttributes = {
3EA9309A1B75BFFA0067276D = {
CreatedOnToolsVersion = 7.0;
- DevelopmentTeam = ZBFYF9JG5V;
+ DevelopmentTeam = 6CFA54MQCP;
+ LastSwiftMigration = 1010;
+ ProvisioningStyle = Manual;
};
};
};
@@ -206,13 +208,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -251,13 +263,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -276,6 +298,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
TARGETED_DEVICE_FAMILY = 2;
VALIDATE_PRODUCT = YES;
};
@@ -287,11 +310,15 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ CODE_SIGN_STYLE = Manual;
+ DEVELOPMENT_TEAM = 6CFA54MQCP;
INFOPLIST_FILE = ParticleCam/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = uk.co.flexmonkey.ParticleCam;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
+ PROVISIONING_PROFILE_SPECIFIER = "(dan jan 16) Dev Any App";
+ SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@@ -302,11 +329,15 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ CODE_SIGN_STYLE = Manual;
+ DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = ParticleCam/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = uk.co.flexmonkey.ParticleCam;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
diff --git a/ParticleCam.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ParticleCam.xcodeproj/project.xcworkspace/contents.xcworkspacedata
deleted file mode 100644
index a08862e..0000000
--- a/ParticleCam.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
diff --git a/ParticleCam.xcodeproj/project.xcworkspace/xcuserdata/simongladman.xcuserdatad/UserInterfaceState.xcuserstate b/ParticleCam.xcodeproj/project.xcworkspace/xcuserdata/simongladman.xcuserdatad/UserInterfaceState.xcuserstate
deleted file mode 100644
index 564866f..0000000
Binary files a/ParticleCam.xcodeproj/project.xcworkspace/xcuserdata/simongladman.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ
diff --git a/ParticleCam.xcodeproj/xcuserdata/simongladman.xcuserdatad/xcschemes/ParticleCam.xcscheme b/ParticleCam.xcodeproj/xcuserdata/simongladman.xcuserdatad/xcschemes/ParticleCam.xcscheme
deleted file mode 100644
index 3703cc7..0000000
--- a/ParticleCam.xcodeproj/xcuserdata/simongladman.xcuserdatad/xcschemes/ParticleCam.xcscheme
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ParticleCam.xcodeproj/xcuserdata/simongladman.xcuserdatad/xcschemes/xcschememanagement.plist b/ParticleCam.xcodeproj/xcuserdata/simongladman.xcuserdatad/xcschemes/xcschememanagement.plist
deleted file mode 100644
index 15756a3..0000000
--- a/ParticleCam.xcodeproj/xcuserdata/simongladman.xcuserdatad/xcschemes/xcschememanagement.plist
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- SchemeUserState
-
- ParticleCam.xcscheme
-
- orderHint
- 0
-
-
- SuppressBuildableAutocreation
-
- 3EA9309A1B75BFFA0067276D
-
- primary
-
-
-
-
-
diff --git a/ParticleCam/AppDelegate.swift b/ParticleCam/AppDelegate.swift
index 7693892..081511c 100644
--- a/ParticleCam/AppDelegate.swift
+++ b/ParticleCam/AppDelegate.swift
@@ -13,34 +13,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
-
- func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
- // Override point for customization after application launch.
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
-
- func applicationWillResignActive(application: UIApplication) {
- // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
- // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
- }
-
- func applicationDidEnterBackground(application: UIApplication) {
- // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
- // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
- }
-
- func applicationWillEnterForeground(application: UIApplication) {
- // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
- }
-
- func applicationDidBecomeActive(application: UIApplication) {
- // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
- }
-
- func applicationWillTerminate(application: UIApplication) {
- // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
- }
-
-
}
-
diff --git a/ParticleCam/Info.plist b/ParticleCam/Info.plist
index 879c6cf..39e0209 100644
--- a/ParticleCam/Info.plist
+++ b/ParticleCam/Info.plist
@@ -42,5 +42,7 @@
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
+ NSCameraUsageDescription
+ Camera access is used to get live video feed for particle processing
diff --git a/ParticleCam/ParticleLab.swift b/ParticleCam/ParticleLab.swift
index e392c2e..1b9e425 100644
--- a/ParticleCam/ParticleLab.swift
+++ b/ParticleCam/ParticleLab.swift
@@ -25,12 +25,12 @@ import MetalPerformanceShaders
class ParticleCamFilter: MetalImageFilter
{
- let particleCount = ParticleCount.OneMillion.rawValue
+ let particleCount = ParticleCount.oneMillion.rawValue
let alignment:Int = 0x4000
let particlesMemoryByteSize:Int
- var particlesMemory:UnsafeMutablePointer = nil
- let particlesVoidPtr: COpaquePointer
+ var particlesMemory:UnsafeMutableRawPointer? = nil
+ let particlesVoidPtr: OpaquePointer
let particlesParticlePtr: UnsafeMutablePointer
let particlesParticleBufferPtr: UnsafeMutableBufferPointer
@@ -38,23 +38,23 @@ class ParticleCamFilter: MetalImageFilter
{
[unowned self] in
- return self.device.newBufferWithBytesNoCopy(self.particlesMemory,
+ return self.device.makeBuffer(bytesNoCopy: self.particlesMemory!,
length: Int(self.particlesMemoryByteSize),
- options: .CPUCacheModeDefaultCache,
- deallocator: nil)
+ options: MTLResourceOptions(),
+ deallocator: nil)!
}()
- let particleSize = sizeof(Particle)
+ let particleSize = MemoryLayout.size
// MARK: Initialisation
init()
{
- particlesMemoryByteSize = particleCount * sizeof(Particle)
+ particlesMemoryByteSize = particleCount * MemoryLayout.size
posix_memalign(&particlesMemory, alignment, particlesMemoryByteSize)
- particlesVoidPtr = COpaquePointer(particlesMemory)
+ particlesVoidPtr = OpaquePointer(particlesMemory!)
particlesParticlePtr = UnsafeMutablePointer(particlesVoidPtr)
particlesParticleBufferPtr = UnsafeMutableBufferPointer(start: particlesParticlePtr, count: particleCount)
@@ -109,11 +109,11 @@ class ParticleCamFilter: MetalImageFilter
enum ParticleCount: Int
{
- case QuarterMillion = 262144
- case HalfMillion = 524288
- case OneMillion = 1048576
- case TwoMillion = 2097152
- case FourMillion = 4194304
+ case quarterMillion = 262144
+ case halfMillion = 524288
+ case oneMillion = 1048576
+ case twoMillion = 2097152
+ case fourMillion = 4194304
}
// Particles use x and y for position and z and w for velocity
diff --git a/ParticleCam/ViewController.swift b/ParticleCam/ViewController.swift
index cc06395..0be3cae 100644
--- a/ParticleCam/ViewController.swift
+++ b/ParticleCam/ViewController.swift
@@ -12,7 +12,7 @@ class ViewController: UIViewController, CameraCaptureHelperDelegate
{
let imageView = MetalImageView()
- let cameraCaptureHelper = CameraCaptureHelper(cameraPosition: .Front)
+ let cameraCaptureHelper = CameraCaptureHelper(cameraPosition: .front)
let particleCamFilter = ParticleCamFilter()
@@ -36,7 +36,7 @@ class ViewController: UIViewController, CameraCaptureHelperDelegate
}
- func newCameraImage(cameraCaptureHelper: CameraCaptureHelper, image: CIImage)
+ func newCameraImage(_ cameraCaptureHelper: CameraCaptureHelper, image: CIImage)
{
particleCamFilter.inputImage = image
diff --git a/ParticleCam/classes/CameraCaptureHelper.swift b/ParticleCam/classes/CameraCaptureHelper.swift
index cdb1b4e..1852c74 100644
--- a/ParticleCam/classes/CameraCaptureHelper.swift
+++ b/ParticleCam/classes/CameraCaptureHelper.swift
@@ -20,24 +20,36 @@ import UIKit
class CameraCaptureHelper: NSObject
{
let captureSession = AVCaptureSession()
- let cameraPosition: AVCaptureDevicePosition
+ let cameraPosition: AVCaptureDevice.Position
weak var delegate: CameraCaptureHelperDelegate?
+ var videoOrientation: AVCaptureVideoOrientation = .landscapeLeft
- required init(cameraPosition: AVCaptureDevicePosition)
+ var statusBarObserveHandle: NSObjectProtocol?
+
+ deinit {
+ statusBarObserveHandle.map { NotificationCenter.default.removeObserver($0) }
+ }
+
+ required init(cameraPosition: AVCaptureDevice.Position)
{
self.cameraPosition = cameraPosition
super.init()
initialiseCaptureSession()
+
+ videoOrientation = AVCaptureVideoOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue)!
+ statusBarObserveHandle = NotificationCenter.default.addObserver(forName: UIApplication.didChangeStatusBarOrientationNotification, object: nil, queue: nil) { [weak self] _ in
+ self?.videoOrientation = AVCaptureVideoOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue)!
+ }
}
- private func initialiseCaptureSession()
+ fileprivate func initialiseCaptureSession()
{
- captureSession.sessionPreset = AVCaptureSessionPresetiFrame1280x720
+ captureSession.sessionPreset = .iFrame1280x720
- guard let camera = (AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! [AVCaptureDevice])
+ guard let camera = AVCaptureDevice.devices(for: .video)
.filter({ $0.position == cameraPosition })
.first else
{
@@ -58,7 +70,7 @@ class CameraCaptureHelper: NSObject
let videoOutput = AVCaptureVideoDataOutput()
videoOutput.setSampleBufferDelegate(self,
- queue: dispatch_queue_create("sample buffer delegate", DISPATCH_QUEUE_SERIAL))
+ queue: DispatchQueue(label: "sample buffer delegate", attributes: []))
if captureSession.canAddOutput(videoOutput)
{
@@ -71,19 +83,19 @@ class CameraCaptureHelper: NSObject
extension CameraCaptureHelper: AVCaptureVideoDataOutputSampleBufferDelegate
{
- func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!)
+ func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)
{
- connection.videoOrientation = AVCaptureVideoOrientation(rawValue: UIApplication.sharedApplication().statusBarOrientation.rawValue)!
+ connection.videoOrientation = videoOrientation
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else
{
return
}
- dispatch_async(dispatch_get_main_queue())
+ DispatchQueue.main.async
{
self.delegate?.newCameraImage(self,
- image: CIImage(CVPixelBuffer: pixelBuffer))
+ image: CIImage(cvPixelBuffer: pixelBuffer))
}
}
@@ -91,5 +103,5 @@ extension CameraCaptureHelper: AVCaptureVideoDataOutputSampleBufferDelegate
protocol CameraCaptureHelperDelegate: class
{
- func newCameraImage(cameraCaptureHelper: CameraCaptureHelper, image: CIImage)
+ func newCameraImage(_ cameraCaptureHelper: CameraCaptureHelper, image: CIImage)
}
diff --git a/ParticleCam/classes/ImageView.swift b/ParticleCam/classes/ImageView.swift
index eb0fcdb..7c1238d 100644
--- a/ParticleCam/classes/ImageView.swift
+++ b/ParticleCam/classes/ImageView.swift
@@ -16,26 +16,26 @@ import MetalKit
class MetalImageView: MTKView
{
- let colorSpace = CGColorSpaceCreateDeviceRGB()!
+ let colorSpace = CGColorSpaceCreateDeviceRGB()
lazy var commandQueue: MTLCommandQueue =
- {
- [unowned self] in
-
- return self.device!.newCommandQueue()
- }()
+ {
+ [unowned self] in
+
+ return self.device!.makeCommandQueue()!
+ }()
lazy var ciContext: CIContext =
- {
- [unowned self] in
-
- return CIContext(MTLDevice: self.device!)
- }()
+ {
+ [unowned self] in
+
+ return CIContext(mtlDevice: self.device!)
+ }()
override init(frame frameRect: CGRect, device: MTLDevice?)
{
super.init(frame: frameRect,
- device: device ?? MTLCreateSystemDefaultDevice())
+ device: device ?? MTLCreateSystemDefaultDevice())
if super.device == nil
{
@@ -52,25 +52,19 @@ class MetalImageView: MTKView
/// The image to display
var image: CIImage?
- {
- didSet
- {
- renderImage()
- }
- }
-
- func renderImage()
- {
- guard let
- image = image,
- targetTexture = currentDrawable?.texture else
+
+ override func draw() {
+ super.draw()
+
+ guard let image = image,
+ let targetTexture = currentDrawable?.texture else
{
return
}
- let commandBuffer = commandQueue.commandBuffer()
+ let commandBuffer = commandQueue.makeCommandBuffer()!
- let bounds = CGRect(origin: CGPointZero, size: drawableSize)
+ let bounds = CGRect(origin: CGPoint.zero, size: drawableSize)
let originX = image.extent.origin.x
let originY = image.extent.origin.y
@@ -80,16 +74,16 @@ class MetalImageView: MTKView
let scale = min(scaleX, scaleY)
let scaledImage = image
- .imageByApplyingTransform(CGAffineTransformMakeTranslation(-originX, -originY))
- .imageByApplyingTransform(CGAffineTransformMakeScale(scale, scale))
+ .transformed(by: CGAffineTransform(translationX: -originX, y: -originY))
+ .transformed(by: CGAffineTransform(scaleX: scale, y: scale))
ciContext.render(scaledImage,
- toMTLTexture: targetTexture,
- commandBuffer: commandBuffer,
- bounds: bounds,
- colorSpace: colorSpace)
+ to: targetTexture,
+ commandBuffer: commandBuffer,
+ bounds: bounds,
+ colorSpace: colorSpace)
- commandBuffer.presentDrawable(currentDrawable!)
+ commandBuffer.present(currentDrawable!)
commandBuffer.commit()
}
@@ -105,21 +99,21 @@ class MetalImageView: MTKView
class OpenGLImageView: GLKView
{
- let eaglContext = EAGLContext(API: .OpenGLES2)
+ let eaglContext = EAGLContext(api: .openGLES2)
lazy var ciContext: CIContext =
- {
- [unowned self] in
-
- return CIContext(EAGLContext: self.eaglContext,
- options: [kCIContextWorkingColorSpace: NSNull()])
- }()
+ {
+ [unowned self] in
+
+ return CIContext(eaglContext: self.eaglContext!,
+ options: [.workingColorSpace: NSNull()])
+ }()
override init(frame: CGRect)
{
- super.init(frame: frame, context: eaglContext)
+ super.init(frame: frame, context: eaglContext!)
- context = self.eaglContext
+ context = self.eaglContext!
delegate = self
}
@@ -135,7 +129,7 @@ class OpenGLImageView: GLKView
/// The image to display
var image: CIImage?
- {
+ {
didSet
{
setNeedsDisplay()
@@ -145,7 +139,7 @@ class OpenGLImageView: GLKView
extension OpenGLImageView: GLKViewDelegate
{
- func glkView(view: GLKView, drawInRect rect: CGRect)
+ func glkView(_ view: GLKView, drawIn rect: CGRect)
{
guard let image = image else
{
@@ -153,32 +147,32 @@ extension OpenGLImageView: GLKViewDelegate
}
let targetRect = image.extent.aspectFitInRect(
- target: CGRect(origin: CGPointZero,
- size: CGSize(width: drawableWidth,
- height: drawableHeight)))
+ target: CGRect(origin: CGPoint.zero,
+ size: CGSize(width: drawableWidth,
+ height: drawableHeight)))
let ciBackgroundColor = CIColor(
- color: backgroundColor ?? UIColor.whiteColor())
-
- ciContext.drawImage(CIImage(color: ciBackgroundColor),
- inRect: CGRect(x: 0,
- y: 0,
- width: drawableWidth,
- height: drawableHeight),
- fromRect: CGRect(x: 0,
- y: 0,
- width: drawableWidth,
- height: drawableHeight))
-
- ciContext.drawImage(image,
- inRect: targetRect,
- fromRect: image.extent)
+ color: backgroundColor ?? UIColor.white)
+
+ ciContext.draw(CIImage(color: ciBackgroundColor),
+ in: CGRect(x: 0,
+ y: 0,
+ width: drawableWidth,
+ height: drawableHeight),
+ from: CGRect(x: 0,
+ y: 0,
+ width: drawableWidth,
+ height: drawableHeight))
+
+ ciContext.draw(image,
+ in: targetRect,
+ from: image.extent)
}
}
extension CGRect
{
- func aspectFitInRect(target target: CGRect) -> CGRect
+ func aspectFitInRect(target: CGRect) -> CGRect
{
let scale: CGFloat =
{
@@ -195,8 +189,8 @@ extension CGRect
let y = target.midY - height / 2
return CGRect(x: x,
- y: y,
- width: width,
- height: height)
+ y: y,
+ width: width,
+ height: height)
}
}
diff --git a/ParticleCam/classes/MetalFilter.swift b/ParticleCam/classes/MetalFilter.swift
index 0632d79..1f00ce1 100644
--- a/ParticleCam/classes/MetalFilter.swift
+++ b/ParticleCam/classes/MetalFilter.swift
@@ -19,38 +19,38 @@ import CoreImage
class MetalFilter: CIFilter
{
let device: MTLDevice = MTLCreateSystemDefaultDevice()!
- let colorSpace = CGColorSpaceCreateDeviceRGB()!
+ let colorSpace = CGColorSpaceCreateDeviceRGB()
lazy var ciContext: CIContext =
{
[unowned self] in
- return CIContext(MTLDevice: self.device)
+ return CIContext(mtlDevice: self.device)
}()
lazy var commandQueue: MTLCommandQueue =
{
[unowned self] in
- return self.device.newCommandQueue()
+ return self.device.makeCommandQueue()!
}()
lazy var defaultLibrary: MTLLibrary =
{
[unowned self] in
- return self.device.newDefaultLibrary()!
+ return self.device.makeDefaultLibrary()!
}()
lazy var pipelineState: MTLComputePipelineState =
{
[unowned self] in
- let kernelFunction = self.defaultLibrary.newFunctionWithName(self.functionName)!
+ let kernelFunction = self.defaultLibrary.makeFunction(name: self.functionName)!
do
{
- let pipelineState = try self.device.newComputePipelineStateWithFunction(kernelFunction)
+ let pipelineState = try self.device.makeComputePipelineState(function: kernelFunction)
return pipelineState
}
catch
@@ -85,7 +85,7 @@ class MetalFilter: CIFilter
}
if let imageFilter = self as? MetalImageFilter,
- inputImage = imageFilter.inputImage
+ let inputImage = imageFilter.inputImage
{
return imageFromComputeShader(width: inputImage.extent.width,
height: inputImage.extent.height,
@@ -124,17 +124,18 @@ class MetalFilter: CIFilter
fatalError("textureInvalid() not implemented in MetalFilter")
}
- func imageFromComputeShader(width width: CGFloat, height: CGFloat, inputImage: CIImage?) -> CIImage
+ func imageFromComputeShader(width: CGFloat, height: CGFloat, inputImage: CIImage?) -> CIImage
{
if textureDescriptor == nil
{
- textureDescriptor = MTLTextureDescriptor.texture2DDescriptorWithPixelFormat(.RGBA8Unorm,
+ textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .rgba8Unorm,
width: Int(width),
height: Int(height),
mipmapped: false)
- kernelInputTexture = device.newTextureWithDescriptor(textureDescriptor!)
- kernelOutputTexture = device.newTextureWithDescriptor(textureDescriptor!)
+ textureDescriptor?.usage = [.shaderRead, .shaderWrite]
+ kernelInputTexture = device.makeTexture(descriptor: textureDescriptor!)
+ kernelOutputTexture = device.makeTexture(descriptor: textureDescriptor!)
threadgroupsPerGrid = MTLSizeMake(
textureDescriptor!.width / threadsPerThreadgroup.width,
@@ -143,55 +144,55 @@ class MetalFilter: CIFilter
if clearOnStep
{
- kernelOutputTexture = device.newTextureWithDescriptor(textureDescriptor!)
+ kernelOutputTexture = device.makeTexture(descriptor: textureDescriptor!)
}
- let commandBuffer = commandQueue.commandBuffer()
+ let commandBuffer = commandQueue.makeCommandBuffer()!
if let imageFilter = self as? MetalImageFilter,
- inputImage = imageFilter.inputImage
+ let inputImage = imageFilter.inputImage
{
ciContext.render(inputImage,
- toMTLTexture: kernelInputTexture!,
+ to: kernelInputTexture!,
commandBuffer: commandBuffer,
bounds: inputImage.extent,
colorSpace: colorSpace)
}
- let commandEncoder = commandBuffer.computeCommandEncoder()
+ let commandEncoder = commandBuffer.makeComputeCommandEncoder()!
commandEncoder.setComputePipelineState(pipelineState)
// populate float buffers using kCIAttributeIdentity as buffer index
- for inputKey in inputKeys where attributes[inputKey]?[kCIAttributeClass] == "NSNumber"
+ for inputKey in inputKeys where (attributes[inputKey] as? NSDictionary)?[kCIAttributeClass] as? String == "NSNumber"
{
if let bufferIndex = (attributes[inputKey] as! [String:AnyObject])[kCIAttributeIdentity] as? Int,
- var bufferValue = valueForKey(inputKey) as? Float
+ var bufferValue = value(forKey: inputKey) as? Float
{
- let buffer = device.newBufferWithBytes(&bufferValue,
- length: sizeof(Float),
- options: MTLResourceOptions.CPUCacheModeDefaultCache)
+ let buffer = device.makeBuffer(bytes: &bufferValue,
+ length: MemoryLayout.size,
+ options: MTLResourceOptions())
- commandEncoder.setBuffer(buffer, offset: 0, atIndex: bufferIndex)
+ commandEncoder.setBuffer(buffer, offset: 0, index: bufferIndex)
}
}
// populate color buffers using kCIAttributeIdentity as buffer index
- for inputKey in inputKeys where attributes[inputKey]?[kCIAttributeClass] == "CIColor"
+ for inputKey in inputKeys where (attributes[inputKey] as? NSDictionary)?[kCIAttributeClass] as? String == "CIColor"
{
if let bufferIndex = (attributes[inputKey] as! [String:AnyObject])[kCIAttributeIdentity] as? Int,
- bufferValue = valueForKey(inputKey) as? CIColor
+ let bufferValue = value(forKey: inputKey) as? CIColor
{
var color = float4(Float(bufferValue.red),
Float(bufferValue.green),
Float(bufferValue.blue),
Float(bufferValue.alpha))
- let buffer = device.newBufferWithBytes(&color,
- length: sizeof(float4),
- options: MTLResourceOptions.CPUCacheModeDefaultCache)
+ let buffer = device.makeBuffer(bytes: &color,
+ length: MemoryLayout.size,
+ options: MTLResourceOptions())
- commandEncoder.setBuffer(buffer, offset: 0, atIndex: bufferIndex)
+ commandEncoder.setBuffer(buffer, offset: 0, index: bufferIndex)
}
}
@@ -201,18 +202,18 @@ class MetalFilter: CIFilter
{
for indexedBuffer in indexedBuffers
{
- commandEncoder.setBuffer(indexedBuffer.buffer, offset: 0, atIndex: indexedBuffer.index)
+ commandEncoder.setBuffer(indexedBuffer.buffer, offset: 0, index: indexedBuffer.index)
}
}
if self is MetalImageFilter
{
- commandEncoder.setTexture(kernelInputTexture, atIndex: 0)
- commandEncoder.setTexture(kernelOutputTexture, atIndex: 1)
+ commandEncoder.setTexture(kernelInputTexture, index: 0)
+ commandEncoder.setTexture(kernelOutputTexture, index: 1)
}
else if self is MetalGeneratorFilter
{
- commandEncoder.setTexture(kernelOutputTexture, atIndex: 0)
+ commandEncoder.setTexture(kernelOutputTexture, index: 0)
}
commandEncoder.dispatchThreadgroups(customThreadgroupsPerGrid() ?? threadgroupsPerGrid!,
@@ -222,8 +223,8 @@ class MetalFilter: CIFilter
commandBuffer.commit()
- return CIImage(MTLTexture: kernelOutputTexture!,
- options: [kCIImageColorSpace: colorSpace])
+ return CIImage(mtlTexture: kernelOutputTexture!,
+ options: [.colorSpace: colorSpace])!
}
}
@@ -236,7 +237,7 @@ class MetalGeneratorFilter: MetalFilter
override func textureInvalid() -> Bool
{
- if let textureDescriptor = textureDescriptor where
+ if let textureDescriptor = textureDescriptor,
textureDescriptor.width != Int(inputWidth) ||
textureDescriptor.height != Int(inputHeight)
{
@@ -254,7 +255,7 @@ class MetalImageFilter: MetalFilter
override func textureInvalid() -> Bool
{
if let textureDescriptor = textureDescriptor,
- inputImage = inputImage where
+ let inputImage = inputImage,
textureDescriptor.width != Int(inputImage.extent.width) ||
textureDescriptor.height != Int(inputImage.extent.height)
{
@@ -264,4 +265,3 @@ class MetalImageFilter: MetalFilter
return false
}
}
-