diff --git a/iOSSwiftOpenGLCamera.xcodeproj/project.pbxproj b/iOSSwiftOpenGLCamera.xcodeproj/project.pbxproj
index b6741b5..48d9596 100644
--- a/iOSSwiftOpenGLCamera.xcodeproj/project.pbxproj
+++ b/iOSSwiftOpenGLCamera.xcodeproj/project.pbxproj
@@ -185,6 +185,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
+ English,
en,
Base,
);
@@ -346,9 +347,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
INFOPLIST_FILE = iOSSwiftOpenGLCamera/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 7.1;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -358,9 +360,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
INFOPLIST_FILE = iOSSwiftOpenGLCamera/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 7.1;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
};
name = Release;
};
diff --git a/iOSSwiftOpenGLCamera/AppDelegate.swift b/iOSSwiftOpenGLCamera/AppDelegate.swift
index 04f0016..ff19d04 100644
--- a/iOSSwiftOpenGLCamera/AppDelegate.swift
+++ b/iOSSwiftOpenGLCamera/AppDelegate.swift
@@ -1,135 +1,46 @@
//
// AppDelegate.swift
-// iOSSwiftOpenGLCamera
+// JaraCam
//
-// Created by Bradley Griffith on 7/1/14.
-// Copyright (c) 2014 Bradley Griffith. All rights reserved.
+// Created by INITED on 05/07/2019.
+// Copyright © 2019 INITED. All rights reserved.
//
import UIKit
-import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
-
- var window: UIWindow?
-
-
- func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
- // Override point for customization after application launch.
- 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:.
- // Saves changes in the application's managed object context before the application terminates.
- self.saveContext()
- }
-
- func saveContext () {
- var error: NSError? = nil
- let managedObjectContext = self.managedObjectContext
- if managedObjectContext != nil {
- if managedObjectContext.hasChanges && !managedObjectContext.save(&error) {
- // Replace this implementation with code to handle the error appropriately.
- // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
- //println("Unresolved error \(error), \(error.userInfo)")
- abort()
- }
- }
- }
-
- // #pragma mark - Core Data stack
-
- // Returns the managed object context for the application.
- // If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
- var managedObjectContext: NSManagedObjectContext {
- if !_managedObjectContext {
- let coordinator = self.persistentStoreCoordinator
- if coordinator != nil {
- _managedObjectContext = NSManagedObjectContext()
- _managedObjectContext!.persistentStoreCoordinator = coordinator
- }
- }
- return _managedObjectContext!
- }
- var _managedObjectContext: NSManagedObjectContext? = nil
-
- // Returns the managed object model for the application.
- // If the model doesn't already exist, it is created from the application's model.
- var managedObjectModel: NSManagedObjectModel {
- if !_managedObjectModel {
- let modelURL = NSBundle.mainBundle().URLForResource("iOSSwiftOpenGLCamera", withExtension: "momd")
- _managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)
- }
- return _managedObjectModel!
- }
- var _managedObjectModel: NSManagedObjectModel? = nil
-
- // Returns the persistent store coordinator for the application.
- // If the coordinator doesn't already exist, it is created and the application's store added to it.
- var persistentStoreCoordinator: NSPersistentStoreCoordinator {
- if !_persistentStoreCoordinator {
- let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("iOSSwiftOpenGLCamera.sqlite")
- var error: NSError? = nil
- _persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
- if _persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &error) == nil {
- /*
- Replace this implementation with code to handle the error appropriately.
-
- abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
-
- Typical reasons for an error here include:
- * The persistent store is not accessible;
- * The schema for the persistent store is incompatible with current managed object model.
- Check the error message to determine what the actual problem was.
-
-
- If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
-
- If you encounter schema incompatibility errors during development, you can reduce their frequency by:
- * Simply deleting the existing store:
- NSFileManager.defaultManager().removeItemAtURL(storeURL, error: nil)
-
- * Performing automatic lightweight migration by passing the following dictionary as the options parameter:
- [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true}
-
- Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
-
- */
- //println("Unresolved error \(error), \(error.userInfo)")
- abort()
- }
- }
- return _persistentStoreCoordinator!
- }
- var _persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil
-
- // #pragma mark - Application's Documents directory
-
- // Returns the URL to the application's Documents directory.
- var applicationDocumentsDirectory: NSURL {
- let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
- return urls[urls.endIndex-1] as NSURL
- }
-
+
+ var window: UIWindow?
+
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ // Override point for customization after application launch.
+ 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 invalidate graphics rendering callbacks. 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 active 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/iOSSwiftOpenGLCamera/CameraSessionController.swift b/iOSSwiftOpenGLCamera/CameraSessionController.swift
index 1c9d8d5..d3ce982 100644
--- a/iOSSwiftOpenGLCamera/CameraSessionController.swift
+++ b/iOSSwiftOpenGLCamera/CameraSessionController.swift
@@ -12,17 +12,16 @@ import CoreMedia
import CoreImage
@objc protocol CameraSessionControllerDelegate {
- @optional func cameraSessionDidOutputSampleBuffer(sampleBuffer: CMSampleBuffer!)
+ @objc optional func cameraSessionDidOutputSampleBuffer(sampleBuffer: CMSampleBuffer!)
}
class CameraSessionController: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {
var session: AVCaptureSession!
- var sessionQueue: dispatch_queue_t!
+ var sessionQueue: DispatchQueue!
var videoDeviceInput: AVCaptureDeviceInput!
var videoDeviceOutput: AVCaptureVideoDataOutput!
- var stillImageOutput: AVCaptureStillImageOutput!
- var runtimeErrorHandlingObserver: AnyObject?
+ var runtimeErrorHandlingObserver: Any!
var sessionDelegate: CameraSessionControllerDelegate?
@@ -30,43 +29,40 @@ class CameraSessionController: NSObject, AVCaptureVideoDataOutputSampleBufferDel
/* Class Methods
------------------------------------------*/
- class func deviceWithMediaType(mediaType: NSString, position: AVCaptureDevicePosition) -> AVCaptureDevice {
- var devices: NSArray = AVCaptureDevice.devicesWithMediaType(mediaType)
- var captureDevice: AVCaptureDevice = devices.firstObject as AVCaptureDevice
-
- for object:AnyObject in devices {
- let device = object as AVCaptureDevice
- if (device.position == position) {
- captureDevice = device
- break
- }
- }
-
- return captureDevice
- }
+ class func getCaptureDevice() -> AVCaptureDevice {
+ var cameraDevice: AVCaptureDevice?
+
+ let cameraDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back)
+ for device in cameraDevices.devices {
+ if device.position == .back {
+ cameraDevice = device
+ break
+ }
+ }
+ return cameraDevice!
+ }
/* Lifecycle
------------------------------------------*/
- init() {
+ override init() {
super.init();
session = AVCaptureSession()
- session.sessionPreset = AVCaptureSessionPresetMedium;
+ session.sessionPreset = AVCaptureSession.Preset.medium
authorizeCamera();
- sessionQueue = dispatch_queue_create("CameraSessionController Session", DISPATCH_QUEUE_SERIAL)
+ sessionQueue = DispatchQueue(label:"CameraSessionController Session")
- dispatch_async(sessionQueue, {
+ sessionQueue.async {
self.session.beginConfiguration()
self.addVideoInput()
self.addVideoOutput()
- self.addStillImageOutput()
self.session.commitConfiguration()
- })
+ }
}
@@ -74,144 +70,78 @@ class CameraSessionController: NSObject, AVCaptureVideoDataOutputSampleBufferDel
------------------------------------------*/
func authorizeCamera() {
- AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: {
+ AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: {
(granted: Bool) -> Void in
// If permission hasn't been granted, notify the user.
if !granted {
- dispatch_async(dispatch_get_main_queue(), {
+ DispatchQueue.main.async {
UIAlertView(
title: "Could not use camera!",
message: "This application does not have permission to use camera. Please update your privacy settings.",
delegate: self,
cancelButtonTitle: "OK").show()
- })
+ }
}
});
}
- func addVideoInput() -> Bool {
- var success: Bool = false
- var error: NSError?
-
- var videoDevice: AVCaptureDevice = CameraSessionController.deviceWithMediaType(AVMediaTypeVideo, position: AVCaptureDevicePosition.Back)
- videoDeviceInput = AVCaptureDeviceInput.deviceInputWithDevice(videoDevice, error: &error) as AVCaptureDeviceInput;
- if !error {
- if session.canAddInput(videoDeviceInput) {
- session.addInput(videoDeviceInput)
- success = true
- }
- }
-
- return success
+ func addVideoInput() {
+ let videoDevice: AVCaptureDevice = CameraSessionController.getCaptureDevice()
+ videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice) as AVCaptureDeviceInput;
+ if session.canAddInput(videoDeviceInput) {
+ session.addInput(videoDeviceInput)
+ }
}
func addVideoOutput() {
-
videoDeviceOutput = AVCaptureVideoDataOutput()
-
- videoDeviceOutput.videoSettings = NSDictionary(object: Int(kCVPixelFormatType_32BGRA), forKey:kCVPixelBufferPixelFormatTypeKey)
-
+ videoDeviceOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String : kCVPixelFormatType_32BGRA]
videoDeviceOutput.alwaysDiscardsLateVideoFrames = true
-
videoDeviceOutput.setSampleBufferDelegate(self, queue: sessionQueue)
-
if session.canAddOutput(videoDeviceOutput) {
session.addOutput(videoDeviceOutput)
}
}
-
- func addStillImageOutput() {
- stillImageOutput = AVCaptureStillImageOutput()
- stillImageOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
-
- if session.canAddOutput(stillImageOutput) {
- session.addOutput(stillImageOutput)
- }
- }
-
- func startCamera() {
- dispatch_async(sessionQueue, {
- var weakSelf: CameraSessionController? = self
- self.runtimeErrorHandlingObserver = NSNotificationCenter.defaultCenter().addObserverForName(AVCaptureSessionRuntimeErrorNotification, object: self.sessionQueue, queue: nil, usingBlock: {
- (note: NSNotification!) -> Void in
-
- let strongSelf: CameraSessionController = weakSelf!
-
- dispatch_async(strongSelf.sessionQueue, {
- strongSelf.session.startRunning()
- })
+
+ func startCamera() {
+ sessionQueue.async {
+ let weakSelf: CameraSessionController? = self
+ self.runtimeErrorHandlingObserver =
+ NotificationCenter.default.addObserver(forName: NSNotification.Name.AVCaptureSessionRuntimeError, object: self.sessionQueue, queue: nil, using: {
+ (note: Notification!) -> Void in
+
+ let strongSelf: CameraSessionController = weakSelf!
+
+ strongSelf.sessionQueue.async {
+ strongSelf.session.startRunning()
+ }
})
self.session.startRunning()
- })
+ }
}
func teardownCamera() {
- dispatch_async(sessionQueue, {
+ sessionQueue.async {
self.session.stopRunning()
- NSNotificationCenter.defaultCenter().removeObserver(self.runtimeErrorHandlingObserver)
- })
- }
-
- func focusAndExposeAtPoint(point: CGPoint) {
- dispatch_async(sessionQueue, {
- var device: AVCaptureDevice = self.videoDeviceInput.device
- var error: NSErrorPointer!
-
- if device.lockForConfiguration(error) {
- if device.focusPointOfInterestSupported && device.isFocusModeSupported(AVCaptureFocusMode.AutoFocus) {
- device.focusPointOfInterest = point
- device.focusMode = AVCaptureFocusMode.AutoFocus
- }
-
- if device.exposurePointOfInterestSupported && device.isExposureModeSupported(AVCaptureExposureMode.AutoExpose) {
- device.exposurePointOfInterest = point
- device.exposureMode = AVCaptureExposureMode.AutoExpose
- }
-
- device.unlockForConfiguration()
- }
- else {
- // TODO: Log error.
- }
- })
- }
-
- func captureImage(completion:((image: UIImage?, error: NSError?) -> Void)?) {
- if !completion || !stillImageOutput {
- return
+ NotificationCenter.default.removeObserver(self.runtimeErrorHandlingObserver!)
}
-
- dispatch_async(sessionQueue, {
- self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(
- self.stillImageOutput.connectionWithMediaType(AVMediaTypeVideo),completionHandler: {
- (imageDataSampleBuffer: CMSampleBuffer?, error: NSError?) -> Void in
- if !imageDataSampleBuffer || error {
- completion!(image:nil, error:nil)
- }
- else if imageDataSampleBuffer {
- var imageData: NSData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer?)
- var image: UIImage = UIImage(data: imageData)
- completion!(image:image, error:nil)
- }
- }
- )
- })
}
+
/* AVCaptureVideoDataOutput Delegate
------------------------------------------*/
- func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {
- if (connection.supportsVideoOrientation){
- //connection.videoOrientation = AVCaptureVideoOrientation.PortraitUpsideDown
- connection.videoOrientation = AVCaptureVideoOrientation.Portrait
+ public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
+ if (connection.isVideoOrientationSupported){
+ //connection.videoOrientation = AVCaptureVideoOrientation.portraitUpsideDown
+ connection.videoOrientation = AVCaptureVideoOrientation.portrait
}
- if (connection.supportsVideoMirroring) {
+ if (connection.isVideoMirroringSupported) {
//connection.videoMirrored = true
- connection.videoMirrored = false
+ connection.isVideoMirrored = false
}
- sessionDelegate?.cameraSessionDidOutputSampleBuffer?(sampleBuffer)
+ sessionDelegate?.cameraSessionDidOutputSampleBuffer?(sampleBuffer: sampleBuffer)
}
-}
\ No newline at end of file
+}
diff --git a/iOSSwiftOpenGLCamera/CameraViewController.swift b/iOSSwiftOpenGLCamera/CameraViewController.swift
index 328a4d9..cb1417b 100644
--- a/iOSSwiftOpenGLCamera/CameraViewController.swift
+++ b/iOSSwiftOpenGLCamera/CameraViewController.swift
@@ -14,7 +14,7 @@ class CameraViewController: UIViewController, CameraSessionControllerDelegate {
var cameraSessionController: CameraSessionController!
@IBOutlet var openGLView: OpenGLView!
- @IBOutlet var togglerSwitch: UISwitch
+ @IBOutlet var togglerSwitch: UISwitch!
/* Lifecycle
@@ -27,13 +27,13 @@ class CameraViewController: UIViewController, CameraSessionControllerDelegate {
cameraSessionController.sessionDelegate = self
}
- override func viewWillAppear(animated: Bool) {
+ override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
cameraSessionController.startCamera()
}
- override func viewWillDisappear(animated: Bool) {
+ override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
cameraSessionController.teardownCamera()
@@ -43,12 +43,12 @@ class CameraViewController: UIViewController, CameraSessionControllerDelegate {
/* Instance Methods
------------------------------------------*/
- @IBAction func toggleShader(sender: AnyObject) {
- openGLView.shouldShowShader(togglerSwitch.on)
+ @objc func toggleShader(_ sender: AnyObject) {
+ openGLView.shouldShowShader(show: togglerSwitch.isOn)
}
func cameraSessionDidOutputSampleBuffer(sampleBuffer: CMSampleBuffer!) {
- openGLView.updateUsingSampleBuffer(sampleBuffer)
+ openGLView.updateUsingSampleBuffer(sampleBuffer: sampleBuffer)
}
-}
\ No newline at end of file
+}
diff --git a/iOSSwiftOpenGLCamera/Info.plist b/iOSSwiftOpenGLCamera/Info.plist
index e07e57c..35acff4 100644
--- a/iOSSwiftOpenGLCamera/Info.plist
+++ b/iOSSwiftOpenGLCamera/Info.plist
@@ -28,6 +28,8 @@
armv7
+ NSCameraUsageDescription
+ We need camera for input data
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
diff --git a/iOSSwiftOpenGLCamera/OpenGLView.swift b/iOSSwiftOpenGLCamera/OpenGLView.swift
index 583d710..1e9f642 100644
--- a/iOSSwiftOpenGLCamera/OpenGLView.swift
+++ b/iOSSwiftOpenGLCamera/OpenGLView.swift
@@ -46,10 +46,10 @@ class OpenGLView: UIView {
var indexBuffer: GLuint = GLuint()
var vertexBuffer: GLuint = GLuint()
var unmanagedVideoTexture: Unmanaged?
- var videoTexture: CVOpenGLESTextureRef?
+ var videoTexture: CVOpenGLESTexture?
var videoTextureID: GLuint?
var unmanagedCoreVideoTextureCache: Unmanaged?
- var coreVideoTextureCache: CVOpenGLESTextureCacheRef?
+ var coreVideoTextureCache: CVOpenGLESTextureCache?
var textureWidth: UInt?
var textureHeight: UInt?
@@ -62,7 +62,7 @@ class OpenGLView: UIView {
/* Class Methods
------------------------------------------*/
- override class func layerClass() -> AnyClass {
+ override final class var layerClass: AnyClass {
// In order for our view to display OpenGL content, we need to set it's
// default layer to be a CAEAGLayer
return CAEAGLLayer.self
@@ -72,8 +72,8 @@ class OpenGLView: UIView {
/* Lifecycle
------------------------------------------*/
- init(coder aDecoder: NSCoder!) {
- super.init(coder: aDecoder)
+ required init(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)!
setupLayer()
setupContext()
@@ -83,7 +83,7 @@ class OpenGLView: UIView {
setupVBOs()
setupDisplayLink()
- self.contentScaleFactor = UIScreen.mainScreen().scale
+ self.contentScaleFactor = UIScreen.main.scale
}
@@ -93,8 +93,8 @@ class OpenGLView: UIView {
func setupLayer() {
// CALayer's are, by default, non-opaque, which is 'bad for performance with OpenGL',
// so let's set our CAEAGLLayer layer to be opaque.
- eaglLayer = layer as CAEAGLLayer
- eaglLayer.opaque = true
+ eaglLayer = layer as! CAEAGLLayer
+ eaglLayer.isOpaque = true
}
@@ -102,21 +102,20 @@ class OpenGLView: UIView {
// Just like with CoreGraphics, in order to do much with OpenGL, we need a context.
// Here we create a new context with the version of the rendering API we want and
// tells OpenGL that when we draw, we want to do so within this context.
- let api: EAGLRenderingAPI = EAGLRenderingAPI.OpenGLES2
- context = EAGLContext(API: api)
+ let api: EAGLRenderingAPI = EAGLRenderingAPI.openGLES2
+ context = EAGLContext(api: api)
- if (!self.context) {
- println("Failed to initialize OpenGLES 2.0 context!")
+ if (self.context == nil) {
+ print("Failed to initialize OpenGLES 2.0 context!")
exit(1)
}
- if (!EAGLContext.setCurrentContext(context)) {
- println("Failed to set current OpenGL context!")
+ if (!EAGLContext.setCurrent(context)) {
+ print("Failed to set current OpenGL context!")
exit(1)
}
- let err: CVReturn = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, nil, context, nil, &unmanagedCoreVideoTextureCache)
- coreVideoTextureCache = unmanagedCoreVideoTextureCache!.takeUnretainedValue()
+ CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, nil, context, nil, &coreVideoTextureCache)
}
func setupRenderBuffer() {
@@ -125,9 +124,9 @@ class OpenGLView: UIView {
// So we call the glGenRenderbuffers function and pass it a reference to our colorRenderBuffer.
glGenRenderbuffers(1, &colorRenderBuffer)
// Then we tell OpenGL that whenever we refer to GL_RENDERBUFFER, it should treat that as our colorRenderBuffer.
- glBindRenderbuffer(GL_RENDERBUFFER.asUnsigned(), colorRenderBuffer)
+ glBindRenderbuffer(GLenum(GL_RENDERBUFFER), colorRenderBuffer)
// Finally, we tell our context that the render buffer for our layer is our colorRenderBuffer.
- context.renderbufferStorage(Int(GL_RENDERBUFFER), fromDrawable:eaglLayer)
+ context.renderbufferStorage(Int(GL_RENDERBUFFER), from:eaglLayer)
}
func setupFrameBuffer() {
@@ -137,69 +136,70 @@ class OpenGLView: UIView {
var frameBuffer: GLuint = GLuint()
glGenFramebuffers(1, &frameBuffer)
// Then we tell OpenGL that whenever we refer to GL_FRAMEBUFFER, it should treat that as our frameBuffer.
- glBindFramebuffer(GL_FRAMEBUFFER.asUnsigned(), frameBuffer)
+ glBindFramebuffer(GLenum(GL_FRAMEBUFFER), frameBuffer)
// Finally we tell the frame buffer that it's GL_COLOR_ATTACHMENT0 is our colorRenderBuffer. Oh.
- glFramebufferRenderbuffer(GL_FRAMEBUFFER.asUnsigned(), GL_COLOR_ATTACHMENT0.asUnsigned(), GL_RENDERBUFFER.asUnsigned(), colorRenderBuffer)
+ glFramebufferRenderbuffer(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_RENDERBUFFER), colorRenderBuffer)
}
- func compileShader(shaderName: NSString, shaderType: GLenum) -> GLuint {
-
- // Get NSString with contents of our shader file.
- let shaderPath: NSString = NSBundle.mainBundle().pathForResource(shaderName, ofType: "glsl")
-
- var shaderString: NSString? = NSString.stringWithContentsOfFile(shaderPath, encoding:NSUTF8StringEncoding, error: nil)
- if (!shaderString) {
- println("Failed to set contents shader of shader file!")
- }
-
- // Tell OpenGL to create an OpenGL object to represent the shader, indicating if it's a vertex or a fragment shader.
- let shaderHandle: GLuint = glCreateShader(shaderType)
-
- // Conver shader string to CString and call glShaderSource to give OpenGL the source for the shader.
- var shaderStringUTF8: CString = shaderString!.UTF8String
- var shaderStringLength: GLint = GLint.convertFromIntegerLiteral(Int32(shaderString!.length))
- glShaderSource(shaderHandle, 1, &shaderStringUTF8, &shaderStringLength)
-
- // Tell OpenGL to compile the shader.
- glCompileShader(shaderHandle)
-
- // But compiling can fail! If we have errors in our GLSL code, we can here and output any errors.
- var compileSuccess: GLint = GLint()
- glGetShaderiv(shaderHandle, GL_COMPILE_STATUS.asUnsigned(), &compileSuccess)
- if (compileSuccess == GL_FALSE) {
- var value: GLint = 0
- glGetShaderiv(shaderHandle, GLenum(GL_INFO_LOG_LENGTH), &value)
- var infoLog: [GLchar] = [GLchar](count: Int(value), repeatedValue: 0)
- var infoLogLength: GLsizei = 0
- glGetShaderInfoLog(shaderHandle, value, &infoLogLength, &infoLog)
- var messageString = NSString(bytes: infoLog, length: Int(infoLogLength), encoding: NSASCIIStringEncoding)
-
- println("Failed to compile shader!")
- println(messageString)
-
- exit(1);
- }
-
- return shaderHandle
- }
+
+ func compileShader(_ shaderName: String, shaderType: GLenum) -> GLuint {
+
+ // Get NSString with contents of our shader file.
+ let shaderPath = Bundle.main.path(forResource: shaderName, ofType: "glsl")
+ let shaderString = try! String(contentsOfFile: shaderPath!)
+
+ // Tell OpenGL to create an OpenGL object to represent the shader, indicating if it's a vertex or a fragment shader.
+ let shaderHandle = glCreateShader(shaderType)
+
+ if shaderHandle == 0 {
+ NSLog("Couldn't create shader")
+ }
+
+ // Conver shader string to CString and call glShaderSource to give OpenGL the source for the shader.
+ let cString = shaderString.utf8CString
+ cString.withUnsafeBufferPointer { (pointer) -> Void in
+ pointer.withMemoryRebound(to: GLchar.self) { (p: UnsafeBufferPointer) -> Void in
+ var p: UnsafePointer? = p.baseAddress
+ var shaderStringLength: GLint = GLint(Int32(shaderString.utf8CString.count))
+ glShaderSource(shaderHandle, 1, &p, &shaderStringLength)
+
+ // Tell OpenGL to compile the shader.
+ glCompileShader(shaderHandle)
+
+ // But compiling can fail! If we have errors in our GLSL code, we can here and output any errors.
+ var compileSuccess: GLint = GLint()
+ glGetShaderiv(shaderHandle, GLenum(GL_COMPILE_STATUS), &compileSuccess)
+ if (compileSuccess == GL_FALSE) {
+ var buffer: [GLchar] = Array(repeating: 0, count: 1024)
+ var length: GLsizei = 0
+ glGetShaderInfoLog(shaderHandle, GLsizei(buffer.count), &length, &buffer)
+ print("Failed to compile shader: \(String(cString: buffer))")
+
+ exit(1)
+ }
+ }
+ }
+
+ return shaderHandle
+ }
func compileShaders() {
// Compile our vertex and fragment shaders.
- let vertexShader: GLuint = compileShader("SimpleVertex", shaderType: GL_VERTEX_SHADER.asUnsigned())
- let fragmentShader: GLuint = compileShader("SimpleFragment", shaderType: GL_FRAGMENT_SHADER.asUnsigned())
+ let vertexShader: GLuint = compileShader("SimpleVertex", shaderType: GLenum(GL_VERTEX_SHADER))
+ let fragmentShader: GLuint = compileShader("SimpleFragment", shaderType: GLenum(GL_FRAGMENT_SHADER))
// Call glCreateProgram, glAttachShader, and glLinkProgram to link the vertex and fragment shaders into a complete program.
- var programHandle: GLuint = glCreateProgram()
+ let programHandle: GLuint = glCreateProgram()
glAttachShader(programHandle, vertexShader)
glAttachShader(programHandle, fragmentShader)
glLinkProgram(programHandle)
// Check for any errors.
var linkSuccess: GLint = GLint()
- glGetProgramiv(programHandle, GL_LINK_STATUS.asUnsigned(), &linkSuccess)
+ glGetProgramiv(programHandle, GLenum(GL_LINK_STATUS), &linkSuccess)
if (linkSuccess == GL_FALSE) {
- println("Failed to create shader program!")
+ print("Failed to create shader program!")
// TODO: Actually output the error that we can get from the glGetProgramInfoLog function.
exit(1);
}
@@ -209,33 +209,33 @@ class OpenGLView: UIView {
// Finally, call glGetAttribLocation to get a pointer to the input values for the vertex shader, so we
// can set them in code. Also call glEnableVertexAttribArray to enable use of these arrays (they are disabled by default).
- positionSlot = glGetAttribLocation(programHandle, "Position").asUnsigned()
+ positionSlot = GLuint(glGetAttribLocation(programHandle, "Position"))
glEnableVertexAttribArray(positionSlot)
- texCoordSlot = glGetAttribLocation(programHandle, "TexCoordIn").asUnsigned()
+ texCoordSlot = GLuint(glGetAttribLocation(programHandle, "TexCoordIn"))
glEnableVertexAttribArray(texCoordSlot);
- textureUniform = glGetUniformLocation(programHandle, "Texture").asUnsigned()
+ textureUniform = GLuint(glGetUniformLocation(programHandle, "Texture"))
- timeUniform = glGetUniformLocation(programHandle, "time").asUnsigned()
+ //timeUniform = GLuint(glGetUniformLocation(programHandle, "time"))
- showShaderBoolUniform = glGetUniformLocation(programHandle, "showShader").asUnsigned()
+ showShaderBoolUniform = GLuint(glGetUniformLocation(programHandle, "showShader"))
}
// Setup Vertex Buffer Objects
func setupVBOs() {
glGenBuffers(1, &vertexBuffer)
- glBindBuffer(GL_ARRAY_BUFFER.asUnsigned(), vertexBuffer)
- glBufferData(GL_ARRAY_BUFFER.asUnsigned(), Int(sizeofValue(Vertices)), &Vertices, GL_STATIC_DRAW.asUnsigned())
+ glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer)
+ glBufferData(GLenum(GL_ARRAY_BUFFER), MemoryLayout.size(ofValue: Vertices), &Vertices, GLenum(GL_STATIC_DRAW))
glGenBuffers(1, &indexBuffer)
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER.asUnsigned(), indexBuffer)
- glBufferData(GL_ELEMENT_ARRAY_BUFFER.asUnsigned(), Int(sizeofValue(Indices)), &Indices, GL_STATIC_DRAW.asUnsigned())
+ glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), indexBuffer)
+ glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), MemoryLayout.size(ofValue: Indices), &Indices, GLenum(GL_STATIC_DRAW))
}
func setupDisplayLink() {
- let displayLink: CADisplayLink = CADisplayLink(target: self, selector: "render:")
- displayLink.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
+ let displayLink: CADisplayLink = CADisplayLink(target: self, selector: #selector(OpenGLView.render))
+ displayLink.add(to: RunLoop.current, forMode: RunLoop.Mode.default)
}
@@ -244,128 +244,120 @@ class OpenGLView: UIView {
func getTextureFromImageWithName(fileName: NSString) -> GLuint {
- var spriteImage: CGImageRef? = UIImage(named: fileName).CGImage
-
- if !spriteImage {
- println("Failed to load image!")
+ guard let spriteImage: CGImage = (UIImage(named: fileName as String)?.cgImage) else {
+ print("Failed to load image!")
exit(1)
}
- let width: UInt = CGImageGetWidth(spriteImage)
- let height: UInt = CGImageGetHeight(spriteImage)
- let spriteData = UnsafePointer(calloc(UInt(CGFloat(width) * CGFloat(height) * 4), sizeof(GLubyte).asUnsigned()))
-
- let bitmapInfo = CGBitmapInfo.fromRaw(CGImageAlphaInfo.PremultipliedLast.toRaw())!
- let spriteContext: CGContextRef = CGBitmapContextCreate(spriteData, width, height, 8, width*4, CGImageGetColorSpace(spriteImage), bitmapInfo)
-
- CGContextDrawImage(spriteContext, CGRectMake(0, 0, CGFloat(width) , CGFloat(height)), spriteImage)
- CGContextRelease(spriteContext)
-
- var texName: GLuint = GLuint()
+ let width: Int = spriteImage.width
+ let height: Int = spriteImage.height
+ let spriteData = calloc(width * height * 4, MemoryLayout.size)
+ guard let spriteContext: CGContext = CGContext(data: spriteData,
+ width: width,
+ height: height,
+ bitsPerComponent: 8,
+ bytesPerRow: width * 4,
+ space: spriteImage.colorSpace!,
+ bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
+ print("Failed to create image context!")
+ exit(1)
+ }
+
+
+ spriteContext.draw(spriteImage, in: CGRect(x: 0, y: 0, width: width, height: height))
+
+ var texName: GLuint = GLuint()
glGenTextures(1, &texName)
- glBindTexture(GL_TEXTURE_2D.asUnsigned(), texName)
+ glBindTexture(GLenum(GL_TEXTURE_2D), texName)
- glTexParameteri(GL_TEXTURE_2D.asUnsigned(), GL_TEXTURE_MIN_FILTER.asUnsigned(), GL_NEAREST)
- glTexImage2D(GL_TEXTURE_2D.asUnsigned(), 0, GL_RGBA, GLsizei(width), GLsizei(height), 0, GL_RGBA.asUnsigned(), UInt32(GL_UNSIGNED_BYTE), spriteData)
+ glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_NEAREST)
+ glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGBA, GLsizei(width), GLsizei(height), 0, GLenum(GL_RGBA), UInt32(GL_UNSIGNED_BYTE), spriteData)
free(spriteData)
return texName
}
func cleanupVideoTextures() {
- if (videoTexture) {
- CFRelease(videoTexture)
+ if ((videoTexture) != nil) {
videoTexture = nil
}
- CVOpenGLESTextureCacheFlush(coreVideoTextureCache, 0)
+ CVOpenGLESTextureCacheFlush(coreVideoTextureCache!, 0)
}
func getTextureFromSampleBuffer(sampleBuffer: CMSampleBuffer!) -> GLuint {
cleanupVideoTextures()
- var unmanagedImageBuffer: Unmanaged = CMSampleBufferGetImageBuffer(sampleBuffer)
- var imageBuffer = unmanagedImageBuffer.takeUnretainedValue()
- var opaqueImageBuffer = unmanagedImageBuffer.toOpaque()
-
- var cameraFrame: CVPixelBuffer = Unmanaged.fromOpaque(opaqueImageBuffer).takeUnretainedValue()
- textureWidth = CVPixelBufferGetWidth(cameraFrame)
- textureHeight = CVPixelBufferGetHeight(cameraFrame)
-
- CVPixelBufferLockBaseAddress(cameraFrame, 0)
+ let imageBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
+ let textureWidth = CVPixelBufferGetWidth(imageBuffer)
+ let textureHeight = CVPixelBufferGetHeight(imageBuffer)
- var err: CVReturn = CVOpenGLESTextureCacheCreateTextureFromImage(
+ CVPixelBufferLockBaseAddress(imageBuffer, [])
+ CVOpenGLESTextureCacheCreateTextureFromImage(
kCFAllocatorDefault,
- coreVideoTextureCache,
+ coreVideoTextureCache!,
imageBuffer,
nil,
- GL_TEXTURE_2D.asUnsigned(),
+ GLenum(GL_TEXTURE_2D),
GL_RGBA,
- GLsizei(textureWidth!),
- GLsizei(textureHeight!),
- GL_BGRA.asUnsigned(),
+ GLsizei(textureWidth),
+ GLsizei(textureHeight),
+ GLenum(GL_BGRA),
UInt32(GL_UNSIGNED_BYTE),
0,
- &unmanagedVideoTexture
+ &videoTexture
)
-
- videoTexture = unmanagedVideoTexture!.takeUnretainedValue()
-
+
var textureID: GLuint = GLuint()
- textureID = CVOpenGLESTextureGetName(videoTexture);
- glBindTexture(GL_TEXTURE_2D.asUnsigned(), textureID);
+ textureID = CVOpenGLESTextureGetName(videoTexture!);
+ glBindTexture(GLenum(GL_TEXTURE_2D), textureID);
- glTexParameteri(GL_TEXTURE_2D.asUnsigned(), GL_TEXTURE_MIN_FILTER.asUnsigned(), GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D.asUnsigned(), GL_TEXTURE_MAG_FILTER.asUnsigned(), GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D.asUnsigned(), GL_TEXTURE_WRAP_S.asUnsigned(), GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D.asUnsigned(), GL_TEXTURE_WRAP_T.asUnsigned(), GL_CLAMP_TO_EDGE);
+ glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR);
+ glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR);
+ glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_CLAMP_TO_EDGE);
+ glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_CLAMP_TO_EDGE);
- CVPixelBufferUnlockBaseAddress(cameraFrame, 0)
+ CVPixelBufferUnlockBaseAddress(imageBuffer, [])
return textureID
}
func updateUsingSampleBuffer(sampleBuffer: CMSampleBuffer!) {
- dispatch_async(dispatch_get_main_queue(), {
- self.videoTextureID = self.getTextureFromSampleBuffer(sampleBuffer)
- });
+ DispatchQueue.main.async {
+ self.videoTextureID = self.getTextureFromSampleBuffer(sampleBuffer: sampleBuffer)
+ }
}
func shouldShowShader(show: Bool) {
showShader = show ? 1.0 : 0.0
}
- func render(displayLink: CADisplayLink) {
+ @objc func render(displayLink: CADisplayLink) {
- if textureWidth && textureHeight {
+ if (textureWidth != nil) && (textureHeight != nil) {
var ratio = CGFloat(frame.size.height) / CGFloat(textureHeight!)
glViewport(0, 0, GLint(CGFloat(textureWidth!) * ratio), GLint(CGFloat(textureHeight!) * ratio))
}
else {
- glViewport(0, 0, GLint(frame.size.width), GLint(frame.size.height))
+ //glViewport(0, 0, GLint(frame.size.width), GLint(frame.size.height))
+ glViewport(0, 35, 480, 445) // iPhone 7 full screen without bottom bar
}
- let positionSlotFirstComponent = ConstUnsafePointer(0)
- glVertexAttribPointer(positionSlot, 3 as GLint, GL_FLOAT.asUnsigned(), GLboolean.convertFromIntegerLiteral(UInt8(GL_FALSE)), Int32(sizeof(Vertex)), positionSlotFirstComponent)
+ glVertexAttribPointer(positionSlot, 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout.size), nil)
- let texCoordFirstComponent = ConstUnsafePointer(sizeof(Float) * 3)
- glVertexAttribPointer(texCoordSlot, 2, GL_FLOAT.asUnsigned(), GLboolean.convertFromIntegerLiteral(UInt8(GL_FALSE)), Int32(sizeof(Vertex)), texCoordFirstComponent)
+ let ptr = UnsafeRawPointer(bitPattern: MemoryLayout.size * 3)
+ glVertexAttribPointer(texCoordSlot, 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout.size), ptr)
glActiveTexture(UInt32(GL_TEXTURE0))
- if videoTextureID {
- glBindTexture(GL_TEXTURE_2D.asUnsigned(), videoTextureID!)
- glUniform1i(textureUniform.asSigned(), 0)
+ if (videoTextureID != nil) {
+ glBindTexture(GLenum(GL_TEXTURE_2D), videoTextureID!)
+ glUniform1i(GLint(textureUniform), 0)
}
- // Incriment and pass time to shader. This is experimental, be sure to fully test any use of this variable.
- time += Float(displayLink.duration)
- glUniform1f(timeUniform.asSigned(), time)
-
- glUniform1f(showShaderBoolUniform.asSigned(), showShader)
+ glUniform1f(GLint(showShaderBoolUniform), showShader)
- let vertextBufferOffset = ConstUnsafePointer(0)
- glDrawElements(GL_TRIANGLES.asUnsigned(), Int32(GLfloat(sizeofValue(Indices)) / GLfloat(sizeofValue(Indices.0))), GL_UNSIGNED_BYTE.asUnsigned(), vertextBufferOffset)
+ glDrawElements(GLenum(GL_TRIANGLES), GLsizei(MemoryLayout.size(ofValue: Indices) / MemoryLayout.size), GLenum(GL_UNSIGNED_BYTE), nil)
context.presentRenderbuffer(Int(GL_RENDERBUFFER))
}
-}
\ No newline at end of file
+}
diff --git a/iOSSwiftOpenGLCamera/SimpleFragment.glsl b/iOSSwiftOpenGLCamera/SimpleFragment.glsl
index c8d0d14..834941e 100644
--- a/iOSSwiftOpenGLCamera/SimpleFragment.glsl
+++ b/iOSSwiftOpenGLCamera/SimpleFragment.glsl
@@ -1,19 +1,14 @@
precision mediump float;
uniform sampler2D Texture;
-uniform float time;
uniform float showShader;
varying vec2 CameraTextureCoord;
void main() {
if (showShader > 0.5) {
- vec2 offset = 0.5 * vec2( cos(0.0), sin(0.0));
- vec4 cr = texture2D(Texture, CameraTextureCoord + offset);
- vec4 cga = texture2D(Texture, CameraTextureCoord);
- vec4 cb = texture2D(Texture, CameraTextureCoord - offset);
- gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);
- }
- else {
+ vec4 pix = texture2D(Texture, CameraTextureCoord);
+ gl_FragColor = vec4(pix.g, pix.g, pix.g, pix.a);
+ } else {
gl_FragColor = texture2D(Texture, CameraTextureCoord);
}
-}
\ No newline at end of file
+}