├── .gitignore
├── HelloMetal
├── HelloMetal
│ ├── photo_night.jpg
│ ├── VideoMetalView.m
│ ├── VideoMetalView.h
│ ├── AppDelegate.h
│ ├── main.m
│ ├── ViewController.h
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ ├── AppDelegate.m
│ └── ViewController.m
└── HelloMetal.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── volvet.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ ├── xcuserdata
│ └── volvet.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── HelloMetal.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ └── project.pbxproj
├── MetalImage
├── MetalImage
│ ├── Assets.xcassets
│ │ ├── mandrill.imageset
│ │ │ ├── mandrill.png
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── AppDelegate.h
│ ├── main.m
│ ├── MainBoundleTextureProvider.h
│ ├── GaussianBlurFilter.h
│ ├── SaturationAdjustmentFilter.h
│ ├── UIImage+TextureUtility.h
│ ├── IPContext.h
│ ├── ViewController.h
│ ├── IPContext.m
│ ├── ImageFilter.h
│ ├── SaturationAdjustmentFilter.m
│ ├── Info.plist
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Shaders.metal
│ ├── AppDelegate.m
│ ├── MainBoundleTextureProvider.m
│ ├── UIImage+TextureUtility.m
│ ├── GaussianBlurFilter.m
│ ├── ImageFilter.m
│ └── ViewController.m
└── MetalImage.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── volvetzhang.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ └── volvetzhang.xcuserdatad
│ └── xcschemes
│ ├── xcschememanagement.plist
│ └── MetalImage.xcscheme
├── Draw2d
├── Draw2d.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── volvetzhang.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── volvetzhang.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── Draw2d.xcscheme
└── Draw2d
│ ├── ViewController.h
│ ├── AppDelegate.h
│ ├── MetalView.h
│ ├── main.m
│ ├── Shaders.metal
│ ├── ViewController.m
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.storyboard
│ ├── AppDelegate.m
│ └── MetalView.m
├── Draw3d
├── Draw3d.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── volvetzhang.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── volvetzhang.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── Draw3d.xcscheme
└── Draw3d
│ ├── ViewController.h
│ ├── AppDelegate.h
│ ├── MetalRender.h
│ ├── main.m
│ ├── MathUtility.h
│ ├── Shader.metal
│ ├── ViewController.m
│ ├── MetalView.h
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.storyboard
│ ├── AppDelegate.m
│ ├── MathUtility.m
│ ├── MetalView.m
│ └── MetalRender.m
├── Teapot
├── Teapot.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── volvetzhang.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── volvetzhang.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── Teapot.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
└── Teapot
│ ├── ViewController.h
│ ├── MetalViewRender.h
│ ├── AppDelegate.h
│ ├── main.m
│ ├── OBJGroup.h
│ ├── OBJModel.h
│ ├── OBJMesh.h
│ ├── typedef.h
│ ├── OBJGroup.m
│ ├── MathUtility.h
│ ├── OBJMesh.m
│ ├── ViewController.m
│ ├── UIMetalView.h
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.storyboard
│ ├── AppDelegate.m
│ ├── shader.metal
│ ├── MathUtility.m
│ ├── UIMetalView.m
│ ├── MetalViewRender.m
│ └── OBJModel.mm
├── ClearTheScreen
├── ClearTheScreen.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ ├── volvet.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ │ └── volvetzhang.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ ├── volvet.xcuserdatad
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── ClearTheScreen.xcscheme
│ │ └── volvetzhang.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── ClearTheScreen.xcscheme
└── ClearTheScreen
│ ├── ViewController.h
│ ├── MetalView.h
│ ├── AppDelegate.h
│ ├── main.m
│ ├── ViewController.m
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.storyboard
│ ├── MetalView.m
│ └── AppDelegate.m
├── README.md
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/photo_night.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volvet/metalDemo/HEAD/HelloMetal/HelloMetal/photo_night.jpg
--------------------------------------------------------------------------------
/MetalImage/MetalImage/Assets.xcassets/mandrill.imageset/mandrill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volvet/metalDemo/HEAD/MetalImage/MetalImage/Assets.xcassets/mandrill.imageset/mandrill.png
--------------------------------------------------------------------------------
/Draw2d/Draw2d.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Teapot/Teapot.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d.xcodeproj/project.xcworkspace/xcuserdata/volvetzhang.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volvet/metalDemo/HEAD/Draw2d/Draw2d.xcodeproj/project.xcworkspace/xcuserdata/volvetzhang.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Draw3d/Draw3d.xcodeproj/project.xcworkspace/xcuserdata/volvetzhang.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volvet/metalDemo/HEAD/Draw3d/Draw3d.xcodeproj/project.xcworkspace/xcuserdata/volvetzhang.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Teapot/Teapot.xcodeproj/project.xcworkspace/xcuserdata/volvetzhang.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volvet/metalDemo/HEAD/Teapot/Teapot.xcodeproj/project.xcworkspace/xcuserdata/volvetzhang.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal.xcodeproj/project.xcworkspace/xcuserdata/volvet.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volvet/metalDemo/HEAD/HelloMetal/HelloMetal.xcodeproj/project.xcworkspace/xcuserdata/volvet.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/MetalImage/MetalImage.xcodeproj/project.xcworkspace/xcuserdata/volvetzhang.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volvet/metalDemo/HEAD/MetalImage/MetalImage.xcodeproj/project.xcworkspace/xcuserdata/volvetzhang.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen.xcodeproj/project.xcworkspace/xcuserdata/volvet.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volvet/metalDemo/HEAD/ClearTheScreen/ClearTheScreen.xcodeproj/project.xcworkspace/xcuserdata/volvet.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen.xcodeproj/project.xcworkspace/xcuserdata/volvetzhang.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volvet/metalDemo/HEAD/ClearTheScreen/ClearTheScreen.xcodeproj/project.xcworkspace/xcuserdata/volvetzhang.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/VideoMetalView.m:
--------------------------------------------------------------------------------
1 | //
2 | // VideoMetalView.m
3 | // HelloMetal
4 | //
5 | // Created by Volvet Zhang on 16/3/5.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import "VideoMetalView.h"
10 |
11 | @implementation VideoMetalView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // Draw2d
4 | //
5 | // Created by Volvet Zhang on 16/3/18.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/19.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Teapot/Teapot/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/VideoMetalView.h:
--------------------------------------------------------------------------------
1 | //
2 | // VideoMetalView.h
3 | // HelloMetal
4 | //
5 | // Created by Volvet Zhang on 16/3/5.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface VideoMetalView : MTKView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // ClearTheScreen
4 | //
5 | // Created by Volvet Zhang on 16/3/13.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Teapot/Teapot/MetalViewRender.h:
--------------------------------------------------------------------------------
1 | //
2 | // MentalViewRender.h
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/4/2.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "UIMetalView.h"
11 |
12 |
13 | @interface MetalViewRender : NSObject
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen/MetalView.h:
--------------------------------------------------------------------------------
1 | //
2 | // MetalView.h
3 | // ClearTheScreen
4 | //
5 | // Created by Volvet Zhang on 16/3/13.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 |
13 | @interface MetalView : UIView
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // Draw2d
4 | //
5 | // Created by Volvet Zhang on 16/3/18.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/MetalView.h:
--------------------------------------------------------------------------------
1 | //
2 | // MetalView.h
3 | // Draw2d
4 | //
5 | // Created by Volvet Zhang on 16/3/18.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 | @import Metal;
11 | @import QuartzCore;
12 |
13 | @interface MetalView : UIView
14 |
15 | @property (nonatomic, readonly) CAMetalLayer *mMetalLayer;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/19.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/Teapot/Teapot/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/4/23.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // HelloMetal
4 | //
5 | // Created by Volvet Zhang on 16/3/5.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/MetalRender.h:
--------------------------------------------------------------------------------
1 | //
2 | // MetalRender.h
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/20.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #ifndef MetalRender_h
10 | #define MetalRender_h
11 |
12 | #import "MetalView.h"
13 |
14 | @interface MetalRender : NSObject
15 |
16 | @end
17 |
18 |
19 | #endif /* MetalRender_h */
20 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // ClearTheScreen
4 | //
5 | // Created by Volvet Zhang on 16/3/13.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # metalDemo
2 | Video process demo base on metal
3 |
4 | #### ClearTheScreen
5 | Clear the view screen by MTL clear color
6 |
7 | #### Draw2d
8 | Draw triangle
9 |
10 | #### Draw3d
11 | Draw cube
12 |
13 | #### Teapot
14 | Draw teapot
15 |
16 | #### MetalImage
17 | Gaussion Blur Filter and Saturation Adjustment Filter by Metal
18 |
19 | ### Reference
20 | https://github.com/metal-by-example
21 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Draw2d
4 | //
5 | // Created by Volvet Zhang on 16/3/18.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/19.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Teapot/Teapot/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/4/23.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // HelloMetal
4 | //
5 | // Created by Volvet Zhang on 16/3/5.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // ClearTheScreen
4 | //
5 | // Created by Volvet Zhang on 16/3/13.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/Assets.xcassets/mandrill.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "mandrill.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Teapot/Teapot/OBJGroup.h:
--------------------------------------------------------------------------------
1 | //
2 | // OBJGroup.h
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface OBJGroup : NSObject
12 |
13 | - (instancetype) initWithName :(NSString*) name;
14 |
15 | @property (copy) NSString * name;
16 | @property (copy) NSData * vertexData;
17 | @property (copy) NSData * indexData;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // HelloMetal
4 | //
5 | // Created by Volvet Zhang on 16/3/5.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @import AVFoundation;
12 | @import Metal;
13 | @import MetalKit;
14 | @import MetalPerformanceShaders;
15 |
16 | @interface ViewController : UIViewController
17 |
18 |
19 | @end
20 |
21 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/MainBoundleTextureProvider.h:
--------------------------------------------------------------------------------
1 | //
2 | // MainBoundleTextureProvider.h
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/5/2.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ImageFilter.h"
11 |
12 | @interface MainBoundleTextureProvider : NSObject
13 |
14 | + (instancetype) textureProviderWithImageNamed :(NSString*)imageName context:(IPContext*)context;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/GaussianBlurFilter.h:
--------------------------------------------------------------------------------
1 | //
2 | // GaussianBlurFilter.h
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/5/1.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "ImageFilter.h"
10 |
11 | @interface GaussianBlurFilter : ImageFilter
12 |
13 | @property (nonatomic, assign) float radius;
14 | @property (nonatomic, assign) float sigma;
15 |
16 | + (instancetype) filterWithRadius :(float)radius :(IPContext*) context;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/SaturationAdjustmentFilter.h:
--------------------------------------------------------------------------------
1 | //
2 | // SaturationAdjustmentFilter.h
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/5/1.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "ImageFilter.h"
10 |
11 | @interface SaturationAdjustmentFilter : ImageFilter
12 |
13 | @property (nonatomic, assign) float saturationFactor;
14 |
15 | + (instancetype) filterWithSaturationFactor : (float)saturation context:(IPContext*)context;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/UIImage+TextureUtility.h:
--------------------------------------------------------------------------------
1 | //
2 | // TextureUtility.h
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/5/1.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #ifndef TextureUtility_h
10 | #define TextureUtility_h
11 |
12 | @import UIKit;
13 |
14 | @protocol MTLTexture;
15 |
16 | @interface UIImage (TextureUtility)
17 |
18 | + (UIImage*) imageWithMTLTexture: (id) texture;
19 |
20 | @end
21 |
22 |
23 | #endif /* TextureUtility_h */
24 |
--------------------------------------------------------------------------------
/Teapot/Teapot/OBJModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // OBJModel.h
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class OBJGroup;
12 |
13 | @interface OBJModel : NSObject
14 |
15 | - (instancetype) initWithContentsOfURL :(NSURL*)fileUrl generateNormals:(BOOL)generateNormals;
16 |
17 | @property (nonatomic, readonly) NSArray * groups;
18 |
19 | - (OBJGroup*) groupForName :(NSString*)groupName;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/IPContext.h:
--------------------------------------------------------------------------------
1 | //
2 | // IPContext.h
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/4/23.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 |
13 | @interface IPContext : NSObject
14 |
15 | @property (nonatomic, strong) id device;
16 | @property (nonatomic, strong) id library;
17 | @property (nonatomic, strong) id commandQuene;
18 |
19 |
20 | + (instancetype) newContext;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/Shaders.metal:
--------------------------------------------------------------------------------
1 | //
2 | // Shaders.metal
3 | // Draw2d
4 | //
5 | // Created by Volvet Zhang on 16/3/19.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 |
12 | struct Vertex
13 | {
14 | float4 position[[position]];
15 | float4 color;
16 | };
17 |
18 |
19 | vertex Vertex vertex_main(device Vertex * vertices [[buffer(0)]], uint vid [[vertex_id]])
20 | {
21 | return vertices[vid];
22 | }
23 |
24 | fragment float4 fragment_main(Vertex inVertex [[stage_in]])
25 | {
26 | return inVertex.color;
27 | }
28 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // Draw2d
4 | //
5 | // Created by Volvet Zhang on 16/3/18.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | @interface ViewController ()
12 |
13 | @end
14 |
15 | @implementation ViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | // Do any additional setup after loading the view, typically from a nib.
20 | }
21 |
22 | - (void)didReceiveMemoryWarning {
23 | [super didReceiveMemoryWarning];
24 | // Dispose of any resources that can be recreated.
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/4/23.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 | @property (weak, nonatomic) IBOutlet UIImageView *imageView;
14 |
15 | @property (weak, nonatomic) IBOutlet UISlider *blurRadiusSlider;
16 |
17 | @property (weak, nonatomic) IBOutlet UISlider *saturationSlider;
18 |
19 | - (IBAction)blurRadiusDidChange:(id)sender;
20 |
21 |
22 | - (IBAction)saturationDidChange:(id)sender;
23 |
24 | @end
25 |
26 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Draw2d.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | D3AE2DB91C9C330900C8AC82
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Draw3d.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | D3908F2B1C9D6B3700076D59
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Teapot/Teapot.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Teapot.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | D38854781CA7A3EB00916E0A
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // ClearTheScreen
4 | //
5 | // Created by Volvet Zhang on 16/3/13.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | @interface ViewController ()
12 |
13 | @end
14 |
15 | @implementation ViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | // Do any additional setup after loading the view, typically from a nib.
20 | }
21 |
22 | - (void)didReceiveMemoryWarning {
23 | [super didReceiveMemoryWarning];
24 | // Dispose of any resources that can be recreated.
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/Teapot/Teapot/OBJMesh.h:
--------------------------------------------------------------------------------
1 | //
2 | // OBJMesh.h
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #ifndef OBJMesh_h
10 | #define OBJMesh_h
11 |
12 | @import Metal;
13 | @import UIKit;
14 |
15 | @class OBJGroup;
16 |
17 | @interface Mesh : NSObject
18 |
19 | @property (nonatomic, readonly) id vertexBuffer;
20 | @property (nonatomic, readonly) id indexBuffer;
21 |
22 | @end
23 |
24 | @interface OBJMesh : Mesh
25 |
26 | - (instancetype) initWithGroup :(OBJGroup*) group device:(id)device;
27 |
28 | @end
29 |
30 | #endif /* OBJMesh_h */
31 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal.xcodeproj/xcuserdata/volvet.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | HelloMetal.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 1483CCC31C8A9622003E8891
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | MetalImage.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | D3AB0F5D1CCB5A2D00090731
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen.xcodeproj/xcuserdata/volvet.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ClearTheScreen.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 14A170AB1C9515D6000B8D14
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ClearTheScreen.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 14A170AB1C9515D6000B8D14
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/IPContext.m:
--------------------------------------------------------------------------------
1 | //
2 | // IPContext.m
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/4/23.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "IPContext.h"
10 |
11 | @implementation IPContext
12 |
13 | + (instancetype) newContext {
14 | return [[self alloc] initWithDevice:nil];
15 | }
16 |
17 | - (instancetype) initWithDevice : (id) device {
18 | if( self = [super init] ){
19 | _device = device ? device : MTLCreateSystemDefaultDevice();
20 | _library = [_device newDefaultLibrary];
21 | _commandQuene = [_device newCommandQueue];
22 | }
23 | return self;
24 | }
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/Teapot/Teapot/typedef.h:
--------------------------------------------------------------------------------
1 | //
2 | // typedef.h
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #ifndef typedef_h
10 | #define typedef_h
11 |
12 |
13 | #include
14 | #include
15 |
16 | #define VertexIndexType MTLIndexTypeUInt16
17 | typedef uint16_t VertexIndex;
18 |
19 | typedef struct __attribute((packed)) {
20 | vector_float4 position;
21 | vector_float4 normal;
22 | } Vertex;
23 |
24 | typedef struct __attribute((packed)) {
25 | matrix_float4x4 modelViewProjectionMatrix;
26 | matrix_float4x4 modelViewMatrix;
27 | matrix_float3x3 normalMatrix;
28 | } Uniforms;
29 |
30 |
31 |
32 | #endif /* typedef_h */
33 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/MathUtility.h:
--------------------------------------------------------------------------------
1 | //
2 | // MathUtility.h
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/19.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #ifndef MathUtility_h
10 | #define MathUtility_h
11 |
12 |
13 | @import simd;
14 |
15 | // build a translation matrix
16 | matrix_float4x4 matrix_float4x4_translation(vector_float3 t);
17 |
18 | // build a scale matrix
19 | matrix_float4x4 matrix_float4x4_uniform_scale(float scale);
20 |
21 | // build a rotation matrix
22 | matrix_float4x4 matrix_float4x4_rotation(vector_float3 axis, float angle);
23 |
24 | // build a symmetric perspective matrix
25 | matrix_float4x4 matrix_float4x4_perspective(float aspect, float fovy, float near, float far);
26 |
27 |
28 | #endif /* MathUtility_h */
29 |
--------------------------------------------------------------------------------
/Teapot/Teapot/OBJGroup.m:
--------------------------------------------------------------------------------
1 | //
2 | // OBJGroup.m
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "typedef.h"
10 | #import "OBJGroup.h"
11 |
12 |
13 | @implementation OBJGroup
14 |
15 | - (instancetype) initWithName:(NSString *)name {
16 | if( self = [super init] ){
17 | _name = [name copy];
18 | }
19 | return self;
20 | }
21 |
22 | - (NSString *) description {
23 | size_t vertCount = _vertexData.length / sizeof(Vertex);
24 | size_t indexCount = _indexData.length / sizeof(VertexIndex);
25 |
26 | return [NSString stringWithFormat:@"
10 | using namespace metal;
11 |
12 | struct Vertex {
13 | float4 position[[position]];
14 | float4 color;
15 | };
16 |
17 | struct Uniforms {
18 | float4x4 modelViewProjectionMatrix;
19 | };
20 |
21 | vertex Vertex vertex_main(device Vertex * vertices[[buffer(0)]], constant Uniforms * uniforms[[buffer(1)]],
22 | uint vid[[vertex_id]])
23 | {
24 | Vertex vertexOut;
25 |
26 | vertexOut.position = uniforms->modelViewProjectionMatrix * vertices[vid].position;
27 | vertexOut.color = vertices[vid].color;
28 |
29 | return vertexOut;
30 | }
31 |
32 |
33 | fragment half4 fragment_main(Vertex vertexIn[[stage_in]])
34 | {
35 | return half4(vertexIn.color);
36 | }
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/19.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "MetalRender.h"
11 |
12 | @interface ViewController ()
13 |
14 | @property (nonatomic, strong) MetalRender * mRender;
15 |
16 | @end
17 |
18 | @implementation ViewController
19 |
20 | - (MetalView*) metalView {
21 | return (MetalView*)self.view;
22 | }
23 |
24 | - (void)viewDidLoad {
25 | [super viewDidLoad];
26 | // Do any additional setup after loading the view, typically from a nib.
27 |
28 | self.mRender = [[MetalRender alloc] init];
29 | self.metalView.mDelegate = self.mRender;
30 | }
31 |
32 | - (void)didReceiveMemoryWarning {
33 | [super didReceiveMemoryWarning];
34 | // Dispose of any resources that can be recreated.
35 | }
36 |
37 | - (BOOL) prefersStatusBarHidden {
38 | return YES;
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Teapot/Teapot/OBJMesh.m:
--------------------------------------------------------------------------------
1 | //
2 | // OBJMesh.m
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 |
10 | #import "OBJMesh.h"
11 | #import "OBJGroup.h"
12 |
13 |
14 | @implementation Mesh
15 |
16 | @end
17 |
18 |
19 | @implementation OBJMesh
20 |
21 | @synthesize vertexBuffer;
22 | @synthesize indexBuffer;
23 |
24 | - (instancetype) initWithGroup:(OBJGroup *)group device:(id)device {
25 | if( self = [super init] ){
26 | vertexBuffer = [device newBufferWithBytes:[group.vertexData bytes] length:[group.vertexData length] options:MTLResourceCPUCacheModeDefaultCache];
27 |
28 | [vertexBuffer setLabel:group.name];
29 |
30 | indexBuffer = [device newBufferWithBytes:[group.indexData bytes] length:[group.indexData length] options:MTLResourceCPUCacheModeDefaultCache];
31 |
32 | [indexBuffer setLabel:group.name];
33 | }
34 |
35 | return self;
36 | }
37 |
38 | @end
--------------------------------------------------------------------------------
/Draw3d/Draw3d/MetalView.h:
--------------------------------------------------------------------------------
1 | //
2 | // MetalView.h
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/20.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 | @import Metal;
11 | @import QuartzCore;
12 |
13 |
14 | @protocol MetalViewDelegate;
15 |
16 |
17 | @interface MetalView : UIView
18 |
19 | @property (nonatomic, weak) id mDelegate;
20 |
21 | @property (nonatomic) NSInteger mPreferredFramePerSecond;
22 |
23 | @property (nonatomic) MTLPixelFormat pixelFormat;
24 |
25 | @property (nonatomic, assign) MTLClearColor mClearColor;
26 |
27 | @property (nonatomic, readonly) NSTimeInterval mFrameDuration;
28 |
29 | @property (nonatomic, readonly) id mCurrentDrawable;
30 |
31 | @property (nonatomic) MTLRenderPassDescriptor * currentRenderPassDescriptor;
32 |
33 | - (CAMetalLayer*) metalLayer;
34 |
35 | @end
36 |
37 |
38 | @protocol MetalViewDelegate
39 |
40 | - (void) drawInView:(MetalView*)view;
41 |
42 | @end
--------------------------------------------------------------------------------
/Teapot/Teapot/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ViewController.h"
11 | #import "UIMetalView.h"
12 | #import "MetalViewRender.h"
13 |
14 |
15 | @interface ViewController ()
16 |
17 | @property (nonatomic, strong) MetalViewRender * metalViewRender;
18 |
19 | @end
20 |
21 | @implementation ViewController
22 |
23 | - (UIMetalView*) uiMetalView {
24 | return (UIMetalView*) self.view;
25 | }
26 |
27 | - (void)viewDidLoad {
28 | [super viewDidLoad];
29 | // Do any additional setup after loading the view, typically from a nib.
30 | _metalViewRender = [[MetalViewRender alloc] init];
31 | self.uiMetalView.delegate = _metalViewRender;
32 | }
33 |
34 | - (BOOL) prefersStatusBarHidden {
35 | return YES;
36 | }
37 |
38 | - (void)didReceiveMemoryWarning {
39 | [super didReceiveMemoryWarning];
40 | // Dispose of any resources that can be recreated.
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/Teapot/Teapot/UIMetalView.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIMetalView.h
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/4/2.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 |
13 | @protocol UIMetalViewDelegate;
14 |
15 |
16 | @interface UIMetalView : UIView
17 |
18 | @property (nonatomic, weak) id delegate;
19 |
20 | @property (nonatomic, readonly) CAMetalLayer * metalLayer;
21 |
22 | @property (nonatomic) NSInteger preferredFramesPerSecond;
23 |
24 | @property (nonatomic) MTLPixelFormat colorPixelFormat;
25 |
26 | @property (nonatomic, assign) MTLClearColor clearColor;
27 |
28 | @property (nonatomic, readonly) NSTimeInterval frameDuration;
29 |
30 | @property (nonatomic, readonly) id currentDrawable;
31 |
32 | @property (nonatomic, readonly) MTLRenderPassDescriptor * currentRenderPassDescriptor;
33 |
34 | @end
35 |
36 | @protocol UIMetalViewDelegate
37 |
38 | - (void) drawInView :(UIMetalView *) view;
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 volvet
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/ImageFilter.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImageFilter.h
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/4/24.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 |
13 | #import "IPContext.h"
14 |
15 |
16 |
17 | @protocol TextureProvider
18 |
19 | @property (nonatomic, readonly) id texture;
20 |
21 | @end
22 |
23 | @protocol TextureConsumer
24 |
25 | @property (nonatomic, strong) id provider;
26 |
27 | @end
28 |
29 |
30 | @interface ImageFilter : NSObject
31 |
32 | @property (nonatomic, strong) IPContext * context;
33 | @property (nonatomic, strong) id uniformBuffer;
34 | @property (nonatomic, strong) id pipeline;
35 | @property (nonatomic, strong) id internalTexture;
36 | @property (nonatomic, assign, getter=isDirty) BOOL dirty;
37 |
38 | - (instancetype) initWithFunctionName :(NSString*) functionName context:(IPContext*) context;
39 | - (void) configureArgumentTableWithCommandEncoder :(id) commandEncoder;
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/Teapot/Teapot/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/Draw3d/Draw3d/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/MetalImage/MetalImage/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/MetalImage/MetalImage/SaturationAdjustmentFilter.m:
--------------------------------------------------------------------------------
1 | //
2 | // SaturationAdjustmentFilter.m
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/5/1.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "SaturationAdjustmentFilter.h"
10 |
11 | struct AdjustSaturationUniforms
12 | {
13 | float saturationFactor;
14 | };
15 |
16 | @implementation SaturationAdjustmentFilter
17 |
18 | + (instancetype) filterWithSaturationFactor:(float)saturation context:(IPContext *)context {
19 | return [[self alloc] initWithSaturationFactor : saturation context:context];
20 | }
21 |
22 | - (instancetype) initWithSaturationFactor : (float)saturation context:(IPContext*)context {
23 | if( self = [super initWithFunctionName:@"adjust_saturation" context:context] ){
24 | _saturationFactor = saturation;
25 | }
26 | return self;
27 | }
28 |
29 | - (void) setSaturationFactor:(float)saturationFactor {
30 | self.dirty = YES;
31 |
32 | _saturationFactor = saturationFactor;
33 | }
34 |
35 | - (void) configureArgumentTableWithCommandEncoder:(id)commandEncoder {
36 | struct AdjustSaturationUniforms uniforms;
37 |
38 | uniforms.saturationFactor = _saturationFactor;
39 |
40 | if( !self.uniformBuffer ) {
41 | self.uniformBuffer = [self.context.device newBufferWithLength:sizeof(uniforms) options:MTLResourceOptionCPUCacheModeDefault];
42 | }
43 |
44 | memcpy( [self.uniformBuffer contents], &uniforms, sizeof(uniforms) );
45 | [commandEncoder setBuffer:self.uniformBuffer offset:0 atIndex:0];
46 |
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal.xcodeproj/xcuserdata/volvet.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
24 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Teapot/Teapot/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Teapot/Teapot/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Teapot/Teapot/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/Shaders.metal:
--------------------------------------------------------------------------------
1 | //
2 | // Shaders.metal
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/5/2.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 |
12 |
13 | struct AdjustStaturationUniforms
14 | {
15 | float saturationFactor;
16 | };
17 |
18 | kernel void adjust_saturation(texture2d inTexture[[texture(0)]],
19 | texture2d outTexture[[texture(1)]],
20 | constant AdjustStaturationUniforms & uniforms[[buffer(0)]],
21 | uint2 gid[[thread_position_in_grid]])
22 | {
23 | float4 inColor = inTexture.read(gid);
24 | float value = dot(inColor.rgb, float3(0.299, 0.587, 0.014));
25 | float4 grayColor(value, value, value, 1.0);
26 |
27 | float4 outColor = mix(grayColor, inColor, uniforms.saturationFactor);
28 | outTexture.write(outColor, gid);
29 | }
30 |
31 |
32 | kernel void gaussian_blur_2d(texture2d inTexture[[texture(0)]],
33 | texture2d outTexture[[texture(1)]],
34 | texture2d weights[[texture(2)]],
35 | uint2 gid[[thread_position_in_grid]])
36 | {
37 | int size = weights.get_width();
38 | int radius = size / 2;
39 | float4 accumColor(0, 0, 0, 0);
40 |
41 | for( int j=0;j mDevice;
15 | @property (nonatomic, strong) id mCommandQueue;
16 |
17 | @end
18 |
19 | @implementation MetalView
20 |
21 | + (id) layerClass {
22 | return [CAMetalLayer class];
23 | }
24 |
25 |
26 | -(instancetype)initWithCoder:(NSCoder *)aDecoder {
27 | if( self = [super initWithCoder:aDecoder] ){
28 | self.mDevice = MTLCreateSystemDefaultDevice();
29 | self.mCommandQueue = [self.mDevice newCommandQueue];
30 |
31 | self.metalLayer.device = self.mDevice;
32 | self.metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
33 | }
34 |
35 | return self;
36 | }
37 |
38 | -(CAMetalLayer*) metalLayer {
39 | return (CAMetalLayer*) self.layer;
40 | }
41 |
42 | -(void)didMoveToWindow {
43 | [self redraw];
44 | }
45 |
46 | -(void)redraw {
47 | id drawable = [self.metalLayer nextDrawable];
48 | id texture = drawable.texture;
49 |
50 | MTLRenderPassDescriptor *passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
51 | passDescriptor.colorAttachments[0].texture = texture;
52 | passDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
53 | passDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
54 | passDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1, 0, 1, 1);
55 |
56 |
57 | id commandBuffer = [self.mCommandQueue commandBuffer];
58 | id commandEncoder = [commandBuffer renderCommandEncoderWithDescriptor:passDescriptor];
59 |
60 | [commandEncoder endEncoding];
61 | [commandBuffer presentDrawable:drawable];
62 | [commandBuffer commit];
63 | }
64 |
65 |
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // Draw2d
4 | //
5 | // Created by Volvet Zhang on 16/3/18.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/19.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Teapot/Teapot/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/4/23.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // HelloMetal
4 | //
5 | // Created by Volvet Zhang on 16/3/5.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // ClearTheScreen
4 | //
5 | // Created by Volvet Zhang on 16/3/13.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Teapot/Teapot.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
18 |
19 |
20 |
22 |
34 |
35 |
36 |
38 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/MainBoundleTextureProvider.m:
--------------------------------------------------------------------------------
1 | //
2 | // MainBoundleTextureProvider.m
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/5/2.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | @import Metal;
10 | @import UIKit;
11 |
12 | #import "MainBoundleTextureProvider.h"
13 |
14 |
15 | @interface MainBoundleTextureProvider()
16 |
17 | @property (nonatomic, strong) id texture;
18 |
19 | @end
20 |
21 | @implementation MainBoundleTextureProvider
22 |
23 | + (instancetype) textureProviderWithImageNamed:(NSString *)imageName context:(IPContext *)context {
24 | return [[self alloc] initWithImageNamed:imageName context:context];
25 | }
26 |
27 |
28 | - (instancetype) initWithImageNamed :(NSString*)imageName context:(IPContext*)context {
29 | if( self = [super init] ){
30 | UIImage * image = [UIImage imageNamed:imageName];
31 | _texture = [self textureForImage:image context:context];
32 | }
33 |
34 | return self;
35 | }
36 |
37 | - (id) textureForImage :(UIImage*)image context:(IPContext*)context {
38 | CGImageRef imageRef = [image CGImage];
39 |
40 | NSUInteger width = CGImageGetWidth(imageRef);
41 | NSUInteger height = CGImageGetHeight(imageRef);
42 | CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
43 | uint8_t * rawData = (uint8_t*)malloc(width * height * 4);
44 | const NSUInteger bytesPerPixel = 4;
45 | const NSUInteger bytesPerRow = bytesPerPixel * width;
46 | const NSUInteger bitsPerComponent = 8;
47 | CGContextRef bitmapContext = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorspace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrder32Big);
48 | CGColorSpaceRelease(colorspace);
49 |
50 | CGContextTranslateCTM(bitmapContext, 0, height);
51 | CGContextScaleCTM(bitmapContext, 1, -1);
52 |
53 | CGContextDrawImage(bitmapContext, CGRectMake(0, 0, width, height), imageRef);
54 | CGContextRelease(bitmapContext);
55 |
56 | MTLTextureDescriptor * descriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm width:width height:height mipmapped:NO];
57 |
58 | id texture = [context.device newTextureWithDescriptor:descriptor];
59 | MTLRegion region = MTLRegionMake2D(0, 0, width, height);
60 | [texture replaceRegion:region mipmapLevel:0 withBytes:rawData bytesPerRow:bytesPerRow];
61 |
62 | free(rawData);
63 | return texture;
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/UIImage+TextureUtility.m:
--------------------------------------------------------------------------------
1 | //
2 | // TextureUtility.m
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/5/1.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "UIImage+TextureUtility.h"
12 |
13 |
14 | static void ReleaseDataCallback(void * inof, const void * data, size_t size)
15 | {
16 | free((void*)data);
17 | }
18 |
19 | @implementation UIImage(TextureUtility)
20 |
21 | + (UIImage*) imageWithMTLTexture :(id)texture {
22 | NSAssert([texture pixelFormat] == MTLPixelFormatRGBA8Unorm, @"Unexpected pixel format");
23 |
24 | CGSize imageSize = CGSizeMake([texture width], [texture height]);
25 | size_t imageByteCount = imageSize.width * imageSize.height * 4;
26 |
27 | void * imageBytes = malloc(imageByteCount);
28 | NSUInteger bytesPerRow = imageSize.width * 4;
29 | MTLRegion region = MTLRegionMake2D(0, 0, imageSize.width, imageSize.height);
30 | [texture getBytes :imageBytes bytesPerRow:bytesPerRow fromRegion:region mipmapLevel:0];
31 |
32 | CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,
33 | imageBytes,
34 | imageByteCount,
35 | ReleaseDataCallback);
36 | const int bitsPerComponent = 8;
37 | const int bitsPerPixel = 32;
38 | CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
39 | CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
40 | CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
41 | CGImageRef imageRef = CGImageCreate(imageSize.width,
42 | imageSize.height,
43 | bitsPerComponent,
44 | bitsPerPixel,
45 | bytesPerRow,
46 | colorspace,
47 | bitmapInfo,
48 | provider,
49 | NULL,
50 | false,
51 | renderingIntent);
52 | UIImage * img = [UIImage imageWithCGImage:imageRef scale:0.0 orientation:UIImageOrientationDownMirrored];
53 | CFRelease(provider);
54 | CFRelease(colorspace);
55 | CFRelease(imageRef);
56 |
57 | return img;
58 | }
59 |
60 | @end
--------------------------------------------------------------------------------
/Draw3d/Draw3d/MathUtility.m:
--------------------------------------------------------------------------------
1 | //
2 | // MathUtility.m
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/19.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "MathUtility.h"
10 |
11 |
12 | // build a translation matrix
13 | matrix_float4x4 matrix_float4x4_translation(vector_float3 t)
14 | {
15 | vector_float4 X = { 1, 0, 0, 0 };
16 | vector_float4 Y = { 0, 1, 0, 0 };
17 | vector_float4 Z = { 0, 0, 1, 0 };
18 | vector_float4 W = { t.x, t.y, t.z, 1 };
19 |
20 | matrix_float4x4 mat = { X, Y, Z, W };
21 |
22 | return mat;
23 | }
24 |
25 | // build a scale matrix
26 | matrix_float4x4 matrix_float4x4_uniform_scale(float scale)
27 | {
28 | vector_float4 X = { scale, 0, 0, 0 };
29 | vector_float4 Y = { 0, scale, 0, 0 };
30 | vector_float4 Z = { 0, 0, scale, 0 };
31 | vector_float4 W = { 0, 0, 0, 1 };
32 |
33 | matrix_float4x4 mat = { X, Y, Z, W };
34 |
35 | return mat;
36 | }
37 |
38 | // build a rotation matrix
39 | matrix_float4x4 matrix_float4x4_rotation(vector_float3 axis, float angle)
40 | {
41 | float c = cos(angle);
42 | float s = sin(angle);
43 |
44 | vector_float4 X;
45 | X.x = axis.x * axis.x + (1 - axis.x * axis.x) * c;
46 | X.y = axis.x * axis.y * (1 - c) - axis.z * s;
47 | X.z = axis.x * axis.z * (1 - c) + axis.y * s;
48 | X.w = 0.0;
49 |
50 | vector_float4 Y;
51 | Y.x = axis.x * axis.y * (1 - c) + axis.z * s;
52 | Y.y = axis.y * axis.y + (1 - axis.y * axis.y) * c;
53 | Y.z = axis.y * axis.z * (1 - c) - axis.x * s;
54 | Y.w = 0.0;
55 |
56 | vector_float4 Z;
57 | Z.x = axis.x * axis.z * (1 - c) - axis.y * s;
58 | Z.y = axis.y * axis.z * (1 - c) + axis.x * s;
59 | Z.z = axis.z * axis.z + (1 - axis.z * axis.z) * c;
60 | Z.w = 0.0;
61 |
62 | vector_float4 W;
63 | W.x = 0.0;
64 | W.y = 0.0;
65 | W.z = 0.0;
66 | W.w = 1.0;
67 |
68 | matrix_float4x4 mat = { X, Y, Z, W };
69 |
70 | return mat;
71 | }
72 |
73 | // build a symmetric perspective matrix
74 | matrix_float4x4 matrix_float4x4_perspective(float aspect, float fovy, float near, float far)
75 | {
76 | float yScale = 1 / tan(fovy * 0.5);
77 | float xScale = yScale / aspect;
78 | float zRange = far - near;
79 | float zScale = -(far + near) / zRange;
80 | float wzScale = -2 * far * near / zRange;
81 |
82 | vector_float4 P = { xScale, 0, 0, 0 };
83 | vector_float4 Q = { 0, yScale, 0, 0 };
84 | vector_float4 R = { 0, 0, zScale, -1 };
85 | vector_float4 S = { 0, 0, wzScale, 0 };
86 |
87 | matrix_float4x4 mat = { P, Q, R, S };
88 |
89 | return mat;
90 | }
--------------------------------------------------------------------------------
/Teapot/Teapot/shader.metal:
--------------------------------------------------------------------------------
1 | //
2 | // shader.metal
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/4/2.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #include
10 | #include
11 |
12 | using namespace metal;
13 |
14 | struct Light
15 | {
16 | float3 direction;
17 | float3 ambientColor;
18 | float3 diffuseColor;
19 | float3 specularColor;
20 | };
21 |
22 | constant Light light = {
23 | .direction = { 0.13, 0.72, 0.68 },
24 | .ambientColor = { 0.05, 0.05, 0.05 },
25 | .diffuseColor = { 0.9, 0.9, 0.9 },
26 | .specularColor = { 1, 1, 1 }
27 | };
28 |
29 | struct Material
30 | {
31 | float3 ambientColor;
32 | float3 diffuseColor;
33 | float3 specularColor;
34 | float specularPower;
35 | };
36 |
37 | constant Material material = {
38 | .ambientColor = { 0.9, 0.1, 0 },
39 | .diffuseColor = { 0.9, 0.1, 0 },
40 | .specularColor = { 1, 1, 1 },
41 | .specularPower = 100
42 | };
43 |
44 | struct Uniforms
45 | {
46 | float4x4 modelViewProjectionMatrix;
47 | float4x4 modelViewMatrix;
48 | float3x3 normalMatrix;
49 | };
50 |
51 | struct Vertex
52 | {
53 | float4 position;
54 | float4 normal;
55 | };
56 |
57 | struct ProjectedVertex
58 | {
59 | float4 position [[position]];
60 | float3 eye;
61 | float3 normal;
62 | };
63 |
64 | vertex ProjectedVertex vertex_main(device Vertex *vertices [[buffer(0)]],
65 | constant Uniforms &uniforms [[buffer(1)]],
66 | uint vid [[vertex_id]])
67 | {
68 | ProjectedVertex outVert;
69 | outVert.position = uniforms.modelViewProjectionMatrix * vertices[vid].position;
70 | outVert.eye = -(uniforms.modelViewMatrix * vertices[vid].position).xyz;
71 | outVert.normal = uniforms.normalMatrix * vertices[vid].normal.xyz;
72 |
73 | return outVert;
74 | }
75 |
76 | fragment float4 fragment_main(ProjectedVertex vert [[stage_in]],
77 | constant Uniforms &uniforms [[buffer(0)]])
78 | {
79 | float3 ambientTerm = light.ambientColor * material.ambientColor;
80 |
81 | float3 normal = normalize(vert.normal);
82 | float diffuseIntensity = saturate(dot(normal, light.direction));
83 | float3 diffuseTerm = light.diffuseColor * material.diffuseColor * diffuseIntensity;
84 |
85 | float3 specularTerm(0);
86 | if (diffuseIntensity > 0)
87 | {
88 | float3 eyeDirection = normalize(vert.eye);
89 | float3 halfway = normalize(light.direction + eyeDirection);
90 | float specularFactor = pow(saturate(dot(normal, halfway)), material.specularPower);
91 | specularTerm = light.specularColor * material.specularColor * specularFactor;
92 | }
93 |
94 | return float4(ambientTerm + diffuseTerm + specularTerm, 1);
95 | }
96 |
97 |
98 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/GaussianBlurFilter.m:
--------------------------------------------------------------------------------
1 | //
2 | // GaussianBlurFilter.m
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/5/1.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "Metal/Metal.h"
10 | #import "GaussianBlurFilter.h"
11 |
12 | @interface GaussianBlurFilter()
13 |
14 | @property (nonatomic, strong) id blurWeightTexture;
15 |
16 | @end
17 |
18 | @implementation GaussianBlurFilter
19 |
20 |
21 | + (instancetype) filterWithRadius:(float)radius :(IPContext *)context {
22 | return [[self alloc] initWithRadius :radius context:context];
23 | }
24 |
25 | - (instancetype) initWithRadius :(float)radius context:(IPContext*)context {
26 | if( self = [super initWithFunctionName:@"gaussian_blur_2d" context:context] ){
27 | _radius = radius;
28 | _sigma = 0.5f;
29 | }
30 | return self;
31 | }
32 |
33 | - (void) generateBlurWeightTexture {
34 | NSAssert(_radius > 0.0f, @"Blur radius must > 0");
35 |
36 | const float radius = _radius;
37 | const float sigma = _sigma;
38 | const int size = (round(radius) * 2 + 1);
39 | float delta = 0;
40 | float expScale = 0;
41 |
42 | if( radius > 0.0f ){
43 | delta = (radius * 2)/(size - 1);
44 | expScale = -1 / (2 * sigma * sigma);
45 | }
46 |
47 | float * weights = malloc(sizeof(float) * size * size);
48 | float weightSum = 0;
49 | float y = - radius;
50 | for( int j=0;j)commandEncoder {
86 | if( !_blurWeightTexture ) {
87 | [self generateBlurWeightTexture];
88 | }
89 | [commandEncoder setTexture:_blurWeightTexture atIndex:2];
90 | }
91 |
92 | @end
93 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/ImageFilter.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageFilter.m
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/4/24.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "ImageFilter.h"
10 |
11 | @interface ImageFilter()
12 |
13 | @property (nonatomic, strong) id kernalFunction;
14 | @property (nonatomic, strong) id texture;
15 |
16 | @end
17 |
18 | @implementation ImageFilter
19 |
20 | @synthesize dirty = _dirty;
21 | @synthesize provider = _provider;
22 |
23 | - (instancetype) initWithFunctionName:(NSString *)functionName context:(IPContext *)context {
24 | if( self = [super init] ){
25 | NSError * error = nil;
26 | _context = context;
27 | _kernalFunction = [_context.library newFunctionWithName:functionName];
28 | _pipeline = [_context.device newComputePipelineStateWithFunction:_kernalFunction error:&error];
29 |
30 | if( !_pipeline ){
31 | NSLog(@"Error occured when building compute pipeline for function %@", functionName);
32 | return nil;
33 | }
34 | }
35 |
36 | return self;
37 | }
38 |
39 | - (void) configureArgumentTableWithCommandEncoder:(id)commandEncoder {
40 |
41 | }
42 |
43 | - (void) applyFilter {
44 | id inputTexture = self.provider.texture;
45 |
46 | if( (!_internalTexture) || ([_internalTexture width] != [inputTexture width]) ||
47 | ([_internalTexture height] != [_internalTexture height]) ) {
48 | MTLTextureDescriptor * textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:[inputTexture pixelFormat] width:[inputTexture width] height:[inputTexture height] mipmapped:NO];
49 | _internalTexture = [_context.device newTextureWithDescriptor:textureDescriptor];
50 | }
51 |
52 | MTLSize threadgroupCounts = MTLSizeMake(8, 8, 1);
53 | MTLSize threadgroups = MTLSizeMake([inputTexture width]/threadgroupCounts.width,
54 | [inputTexture height]/threadgroupCounts.height,
55 | 1);
56 |
57 | id commandBuffer = [_context.commandQuene commandBuffer];
58 | id commandEncoder = [commandBuffer computeCommandEncoder];
59 | [commandEncoder setComputePipelineState: _pipeline];
60 | [commandEncoder setTexture:inputTexture atIndex:0];
61 | [commandEncoder setTexture:_internalTexture atIndex:1];
62 | [self configureArgumentTableWithCommandEncoder:commandEncoder];
63 | [commandEncoder dispatchThreadgroups:threadgroups threadsPerThreadgroup:threadgroupCounts];
64 | [commandEncoder endEncoding];
65 |
66 | [commandBuffer commit];
67 | [commandBuffer waitUntilCompleted];
68 | }
69 |
70 | - (id) texture {
71 | if( _dirty ) {
72 | [self applyFilter];
73 | _dirty = NO;
74 | }
75 | return self.internalTexture;
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // MetalImage
4 | //
5 | // Created by Volvet Zhang on 16/4/23.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "IPContext.h"
11 | #import "ImageFilter.h"
12 | #import "GaussianBlurFilter.h"
13 | #import "SaturationAdjustmentFilter.h"
14 | #import "UIImage+TextureUtility.h"
15 | #import "MainBoundleTextureProvider.h"
16 |
17 | @interface ViewController ()
18 |
19 | @property (nonatomic, strong) IPContext * context;
20 | @property (nonatomic, strong) id imageProvider;
21 | @property (nonatomic, strong) SaturationAdjustmentFilter * saturationFilter;
22 | @property (nonatomic, strong) GaussianBlurFilter * gaussionBlurFilter;
23 |
24 | @property (nonatomic, strong) dispatch_queue_t renderingQueue;
25 | @property (atomic, assign) uint64_t jobIndex;
26 |
27 |
28 | @end
29 |
30 | @implementation ViewController
31 |
32 | - (void)viewDidLoad {
33 | [super viewDidLoad];
34 | // Do any additional setup after loading the view, typically from a nib.
35 |
36 | _renderingQueue = dispatch_queue_create("Rendering", DISPATCH_QUEUE_SERIAL);
37 | [self buildFilterGraph];
38 | //[self updateImage];
39 | }
40 |
41 | - (void)didReceiveMemoryWarning {
42 | [super didReceiveMemoryWarning];
43 | // Dispose of any resources that can be recreated.
44 | }
45 |
46 | - (void)buildFilterGraph {
47 | _context = [IPContext newContext];
48 | _imageProvider = [MainBoundleTextureProvider textureProviderWithImageNamed:@"mandrill" context:_context];
49 | _saturationFilter = [SaturationAdjustmentFilter filterWithSaturationFactor:self.saturationSlider.value context:_context];
50 | _saturationFilter.provider = _imageProvider;
51 | _gaussionBlurFilter = [GaussianBlurFilter filterWithRadius:self.blurRadiusSlider.value :_context];
52 | _gaussionBlurFilter.provider = _saturationFilter;
53 | [self updateImage];
54 | }
55 |
56 | - (void)updateImage {
57 | ++ _jobIndex;
58 |
59 | uint64_t currentJobIndex = _jobIndex;
60 | float blurRadius = _blurRadiusSlider.value;
61 | float saturation = _saturationSlider.value;
62 |
63 | NSLog(@"blurRadius = %f, saturation = %f", blurRadius, saturation);
64 |
65 | dispatch_async(_renderingQueue, ^{
66 | if( currentJobIndex != _jobIndex ) return;
67 | _gaussionBlurFilter.radius = blurRadius;
68 | _saturationFilter.saturationFactor = saturation;
69 |
70 | id texture = _gaussionBlurFilter.texture;
71 | UIImage * image = [UIImage imageWithMTLTexture:texture];
72 |
73 | dispatch_async(dispatch_get_main_queue(), ^{
74 | _imageView.image = image;
75 | });
76 | });
77 | }
78 |
79 | - (IBAction)blurRadiusDidChange:(id)sender {
80 | [self updateImage];
81 | }
82 |
83 | - (IBAction)saturationDidChange:(id)sender {
84 | [self updateImage];
85 | }
86 | @end
87 |
--------------------------------------------------------------------------------
/Teapot/Teapot/MathUtility.m:
--------------------------------------------------------------------------------
1 | //
2 | // MathUtility.m
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/19.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "MathUtility.h"
10 |
11 |
12 | // build a translation matrix
13 | matrix_float4x4 matrix_float4x4_translation(vector_float3 t)
14 | {
15 | vector_float4 X = { 1, 0, 0, 0 };
16 | vector_float4 Y = { 0, 1, 0, 0 };
17 | vector_float4 Z = { 0, 0, 1, 0 };
18 | vector_float4 W = { t.x, t.y, t.z, 1 };
19 |
20 | matrix_float4x4 mat = { X, Y, Z, W };
21 |
22 | return mat;
23 | }
24 |
25 | // build a scale matrix
26 | matrix_float4x4 matrix_float4x4_uniform_scale(float scale)
27 | {
28 | vector_float4 X = { scale, 0, 0, 0 };
29 | vector_float4 Y = { 0, scale, 0, 0 };
30 | vector_float4 Z = { 0, 0, scale, 0 };
31 | vector_float4 W = { 0, 0, 0, 1 };
32 |
33 | matrix_float4x4 mat = { X, Y, Z, W };
34 |
35 | return mat;
36 | }
37 |
38 | // build a rotation matrix
39 | matrix_float4x4 matrix_float4x4_rotation(vector_float3 axis, float angle)
40 | {
41 | float c = cos(angle);
42 | float s = sin(angle);
43 |
44 | vector_float4 X;
45 | X.x = axis.x * axis.x + (1 - axis.x * axis.x) * c;
46 | X.y = axis.x * axis.y * (1 - c) - axis.z * s;
47 | X.z = axis.x * axis.z * (1 - c) + axis.y * s;
48 | X.w = 0.0;
49 |
50 | vector_float4 Y;
51 | Y.x = axis.x * axis.y * (1 - c) + axis.z * s;
52 | Y.y = axis.y * axis.y + (1 - axis.y * axis.y) * c;
53 | Y.z = axis.y * axis.z * (1 - c) - axis.x * s;
54 | Y.w = 0.0;
55 |
56 | vector_float4 Z;
57 | Z.x = axis.x * axis.z * (1 - c) - axis.y * s;
58 | Z.y = axis.y * axis.z * (1 - c) + axis.x * s;
59 | Z.z = axis.z * axis.z + (1 - axis.z * axis.z) * c;
60 | Z.w = 0.0;
61 |
62 | vector_float4 W;
63 | W.x = 0.0;
64 | W.y = 0.0;
65 | W.z = 0.0;
66 | W.w = 1.0;
67 |
68 | matrix_float4x4 mat = { X, Y, Z, W };
69 |
70 | return mat;
71 | }
72 |
73 | // build a symmetric perspective matrix
74 | matrix_float4x4 matrix_float4x4_perspective(float aspect, float fovy, float near, float far)
75 | {
76 | float yScale = 1 / tan(fovy * 0.5);
77 | float xScale = yScale / aspect;
78 | float zRange = far - near;
79 | float zScale = -(far + near) / zRange;
80 | float wzScale = -2 * far * near / zRange;
81 |
82 | vector_float4 P = { xScale, 0, 0, 0 };
83 | vector_float4 Q = { 0, yScale, 0, 0 };
84 | vector_float4 R = { 0, 0, zScale, -1 };
85 | vector_float4 S = { 0, 0, wzScale, 0 };
86 |
87 | matrix_float4x4 mat = { P, Q, R, S };
88 |
89 | return mat;
90 | }
91 |
92 | matrix_float3x3 matrix_float4x4_extract_linear(matrix_float4x4 matrix)
93 | {
94 | vector_float3 X = matrix.columns[0].xyz;
95 | vector_float3 Y = matrix.columns[1].xyz;
96 | vector_float3 Z = matrix.columns[2].xyz;
97 |
98 | matrix_float3x3 extracted_matrix = { X, Y, Z };
99 |
100 | return extracted_matrix;
101 | }
102 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcschemes/Draw2d.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcschemes/Draw3d.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Teapot/Teapot.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcschemes/Teapot.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal.xcodeproj/xcuserdata/volvet.xcuserdatad/xcschemes/HelloMetal.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcschemes/MetalImage.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen.xcodeproj/xcuserdata/volvet.xcuserdatad/xcschemes/ClearTheScreen.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ClearTheScreen/ClearTheScreen.xcodeproj/xcuserdata/volvetzhang.xcuserdatad/xcschemes/ClearTheScreen.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/MetalImage/MetalImage/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Teapot/Teapot/UIMetalView.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIMetalView.m
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/4/2.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "UIMetalView.h"
10 |
11 | @interface UIMetalView()
12 |
13 | @property (nonatomic, strong) id depthTexture;
14 |
15 | @property (nonatomic) id currentDrawable;
16 |
17 | @property (nonatomic) NSTimeInterval frameDuration;
18 |
19 | @property (nonatomic, strong) CADisplayLink * displayLink;
20 |
21 | @end
22 |
23 |
24 | @implementation UIMetalView
25 |
26 |
27 | + (Class) layerClass {
28 | return [CAMetalLayer class];
29 | }
30 |
31 | - (CAMetalLayer*) metalLayer {
32 | return (CAMetalLayer*)self.layer;
33 | }
34 |
35 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
36 | if( self = [super initWithCoder:aDecoder] ){
37 | [self commonInit];
38 | }
39 |
40 | return self;
41 | }
42 |
43 | - (instancetype) initWithFrame:(CGRect)frame {
44 | if( self = [super initWithFrame:frame] ){
45 | [self commonInit];
46 | }
47 |
48 | return self;
49 | }
50 |
51 | - (void) commonInit {
52 | self.preferredFramesPerSecond = 60;
53 | self.clearColor = MTLClearColorMake(1, 1, 1, 1);
54 | self.metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
55 | self.metalLayer.device = MTLCreateSystemDefaultDevice();
56 | }
57 |
58 | - (void) setColorPixelFormat:(MTLPixelFormat)colorPixelFormat {
59 | self.metalLayer.pixelFormat = colorPixelFormat;
60 | }
61 |
62 | - (MTLPixelFormat) colorPixelFormat {
63 | return self.metalLayer.pixelFormat;
64 | }
65 |
66 | - (void) makeDepthTexture {
67 | CGSize drawableSize = self.metalLayer.drawableSize;
68 |
69 | if( ([self.depthTexture width] != drawableSize.width) ||
70 | ([self.depthTexture height] != drawableSize.height) ) {
71 | MTLTextureDescriptor * descriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatDepth32Float width:drawableSize.width height:drawableSize.height mipmapped:NO];
72 | self.depthTexture = [self.metalLayer.device newTextureWithDescriptor:descriptor];
73 | }
74 | }
75 |
76 | - (void) setFrame :(CGRect)frame {
77 | [super setFrame :frame];
78 |
79 | CGFloat scale = [UIScreen mainScreen].scale;
80 |
81 | if( self.window ){
82 | scale = self.window.screen.scale;
83 | }
84 |
85 | CGSize drawableSize = self.bounds.size;
86 |
87 | drawableSize.width *= scale;
88 | drawableSize.height *= scale;
89 |
90 | self.metalLayer.drawableSize = drawableSize;
91 |
92 | [self makeDepthTexture];
93 | }
94 |
95 | - (void) displayLinkDidFire :(CADisplayLink*) displayLink {
96 | self.currentDrawable = [self.metalLayer nextDrawable];
97 | self.frameDuration = displayLink.duration;
98 |
99 | @autoreleasepool {
100 | if( [self.delegate respondsToSelector:@selector(drawInView:)] ){
101 | [self.delegate drawInView:self];
102 | }
103 | }
104 | }
105 |
106 | - (void) didMoveToWindow {
107 | const NSTimeInterval idealFrameDuration = (1.0/60);
108 | const NSTimeInterval targetFrameDuration = (1.0/self.preferredFramesPerSecond);
109 | const NSInteger frameInterval = round(targetFrameDuration/idealFrameDuration);
110 |
111 | if( self.window ){
112 | [self.displayLink invalidate];
113 | self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
114 | self.displayLink.frameInterval = frameInterval;
115 | [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
116 | } else {
117 | [self.displayLink invalidate];
118 | self.displayLink = nil;
119 | }
120 | }
121 |
122 | - (MTLRenderPassDescriptor*) currentRenderPassDescriptor {
123 | MTLRenderPassDescriptor * descriptor = [MTLRenderPassDescriptor new];
124 |
125 | descriptor.colorAttachments[0].texture = [self.currentDrawable texture];
126 | descriptor.colorAttachments[0].clearColor = self.clearColor;
127 | descriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
128 | descriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
129 |
130 | descriptor.depthAttachment.texture = self.depthTexture;
131 | descriptor.depthAttachment.clearDepth = 1.0;
132 | descriptor.depthAttachment.loadAction = MTLLoadActionClear;
133 | descriptor.depthAttachment.storeAction = MTLStoreActionDontCare;
134 |
135 | return descriptor;
136 | }
137 |
138 |
139 | @end
140 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/MetalView.m:
--------------------------------------------------------------------------------
1 | //
2 | // MetalView.m
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/20.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "MetalView.h"
10 |
11 |
12 | @interface MetalView()
13 |
14 | @property (strong) id mCurrentDrawable;
15 | @property (assign) NSTimeInterval mFrameDuration;
16 | @property (strong) id mDepthTexture;
17 | @property (strong) CADisplayLink *mDisplayLink;
18 |
19 | @end
20 |
21 |
22 | @implementation MetalView
23 |
24 | + (Class) layerClass {
25 | return [CAMetalLayer class];
26 | }
27 |
28 | - (CAMetalLayer*) metalLayer {
29 | return (CAMetalLayer*)self.layer;
30 | }
31 |
32 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
33 | if( self = [super initWithCoder:aDecoder] ){
34 | [self mtlInit];
35 | }
36 |
37 | return self;
38 | }
39 |
40 | - (instancetype) initWithFrame:(CGRect)frame {
41 | if( self = [super initWithFrame:frame] ){
42 | [self mtlInit];
43 | }
44 |
45 | return self;
46 | }
47 |
48 | - (void) dealloc {
49 | [self.mDisplayLink invalidate];
50 | }
51 |
52 | - (void) mtlInit {
53 | self.metalLayer.device = MTLCreateSystemDefaultDevice();
54 | self.metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
55 | self.mClearColor = MTLClearColorMake(1.0, 1.0, 1.0, 1.0);
56 | self.mPreferredFramePerSecond = 60;
57 | }
58 |
59 | - (void) setFrame:(CGRect)frame {
60 | [super setFrame:frame];
61 |
62 | CGFloat scale = [UIScreen mainScreen].scale;
63 |
64 | if( self.window ){
65 | scale = self.window.screen.scale;
66 | }
67 |
68 | CGSize drawableSize = self.bounds.size;
69 | drawableSize.width *= scale;
70 | drawableSize.height *= scale;
71 |
72 | self.metalLayer.drawableSize = drawableSize;
73 | [self makeDepthTexture];
74 | }
75 |
76 | - (void) makeDepthTexture {
77 | CGSize drawableSize = self.metalLayer.drawableSize;
78 |
79 | if( ([self.mDepthTexture width] != drawableSize.width) ||
80 | ([self.mDepthTexture height] != drawableSize.height) ) {
81 | MTLTextureDescriptor * textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatDepth32Float width:drawableSize.width height:drawableSize.height mipmapped:NO];
82 | self.mDepthTexture = [self.metalLayer.device newTextureWithDescriptor:textureDescriptor];
83 | }
84 |
85 | return;
86 | }
87 |
88 | - (void) setPixelFormat: (MTLPixelFormat) pixelFormat {
89 | self.metalLayer.pixelFormat = pixelFormat;
90 | }
91 |
92 | - (MTLPixelFormat) pixelFormat {
93 | return self.metalLayer.pixelFormat;
94 | }
95 |
96 | - (void) didMoveToWindow {
97 | [super didMoveToWindow];
98 |
99 | const NSTimeInterval idealFrameDuration = 1.0 / 60.0;
100 | const NSTimeInterval targetFrameDuration = (1.0 / self.mPreferredFramePerSecond);
101 | const NSInteger frameInterval = round(targetFrameDuration / idealFrameDuration);
102 |
103 | if( self.window ){
104 | [self.mDisplayLink invalidate];
105 | self.mDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
106 | self.mDisplayLink.frameInterval = frameInterval;
107 | [self.mDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
108 | } else {
109 | [self.mDisplayLink invalidate];
110 | self.mDisplayLink = nil;
111 | }
112 | }
113 |
114 | - (void) displayLinkDidFire: (CADisplayLink*) displayLink {
115 | @autoreleasepool {
116 | self.mCurrentDrawable = self.metalLayer.nextDrawable;
117 | self.mFrameDuration = self.mDisplayLink.duration;
118 |
119 | if( [self.mDelegate respondsToSelector:@selector(drawInView:)] ) {
120 | [self.mDelegate drawInView:self];
121 | }
122 | }
123 | }
124 |
125 | - (MTLRenderPassDescriptor *) currentRenderPassDescriptor {
126 | MTLRenderPassDescriptor * passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
127 |
128 | passDescriptor.colorAttachments[0].texture = [self.mCurrentDrawable texture];
129 | passDescriptor.colorAttachments[0].clearColor = self.mClearColor;
130 | passDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
131 | passDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
132 |
133 | passDescriptor.depthAttachment.texture = self.mDepthTexture;
134 | passDescriptor.depthAttachment.clearDepth = 1.0;
135 | passDescriptor.depthAttachment.loadAction = MTLLoadActionClear;
136 | passDescriptor.depthAttachment.storeAction = MTLStoreActionDontCare;
137 |
138 | return passDescriptor;
139 | }
140 |
141 | @end
142 |
--------------------------------------------------------------------------------
/Draw2d/Draw2d/MetalView.m:
--------------------------------------------------------------------------------
1 | //
2 | // MetalView.m
3 | // Draw2d
4 | //
5 | // Created by Volvet Zhang on 16/3/18.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | #import "MetalView.h"
10 |
11 | @import simd;
12 |
13 | typedef struct {
14 | vector_float4 position;
15 | vector_float4 color;
16 | } MetalVertex;
17 |
18 | @interface MetalView()
19 |
20 | @property (nonatomic, strong) CADisplayLink * mDisplayLink;
21 | @property (nonatomic, strong) id mDevice;
22 | @property (nonatomic, strong) id mPipeline;
23 | @property (nonatomic, strong) id mCommandQueue;
24 | @property (nonatomic, strong) id mVertexBuffer;
25 |
26 | @end
27 |
28 | @implementation MetalView
29 |
30 | + (Class) layerClass {
31 | return [CAMetalLayer class];
32 | }
33 |
34 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
35 | if( self = [super initWithCoder:aDecoder] ){
36 | [self mtlDeviceInit];
37 | [self mtlVertexBufferInit];
38 | [self mtlPipelineInit];
39 | }
40 |
41 | return self;
42 | }
43 |
44 | - (void) dealloc {
45 | [self.mDisplayLink invalidate];
46 | }
47 |
48 | - (CAMetalLayer*) metalLayer {
49 | return (CAMetalLayer*)self.layer;
50 | }
51 |
52 | - (void) mtlDeviceInit {
53 | self.mDevice = MTLCreateSystemDefaultDevice();
54 | self.metalLayer.device = self.mDevice;
55 | self.metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
56 | }
57 |
58 | - (void) mtlVertexBufferInit {
59 | static const MetalVertex vertices[] = {
60 | { .position = { 0.0f, 0.8f, 0.0f, 1.0f }, .color = { 1.0f, 0.0f, 0.0f, 1.0f } },
61 | { .position = { -0.8, -0.8f, 0.0f, 1.0f }, .color = { 0.0f, 1.0f, 0.0f, 1.0f } },
62 | { .position = { 0.8f, -0.8f, 0.0f, 1.0f }, .color = { 0.0f, 0.0f, 1.0f, 1.0f } }
63 | };
64 |
65 | self.mVertexBuffer = [self.mDevice newBufferWithBytes:vertices length:sizeof(vertices) options:MTLResourceCPUCacheModeDefaultCache];
66 | }
67 |
68 | - (void) mtlPipelineInit {
69 | id library = [self.mDevice newDefaultLibrary];
70 | id vertexFunc = [library newFunctionWithName:@"vertex_main"];
71 | id fragmentFunc = [library newFunctionWithName:@"fragment_main"];
72 |
73 | MTLRenderPipelineDescriptor * pipelineDescriptor = [MTLRenderPipelineDescriptor new];
74 | pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
75 | pipelineDescriptor.vertexFunction = vertexFunc;
76 | pipelineDescriptor.fragmentFunction = fragmentFunc;
77 |
78 | NSError * error = nil;
79 | self.mPipeline = [self.mDevice newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error];
80 |
81 | if( self.mPipeline == nil ){
82 | NSLog(@"mtlPipelineInit: fail to create pipeline");
83 | }
84 |
85 | self.mCommandQueue = [self.mDevice newCommandQueue];
86 | }
87 |
88 | - (void)didMoveToSuperview {
89 | [super didMoveToSuperview];
90 |
91 | if( self.subviews ){
92 | self.mDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
93 | [self.mDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
94 | } else {
95 | [self.mDisplayLink invalidate];
96 | self.mDisplayLink = nil;
97 | }
98 | }
99 |
100 | - (void)displayLinkDidFire:(CADisplayLink*)displayLink {
101 | @autoreleasepool {
102 | [self redraw];
103 | }
104 | }
105 |
106 | - (void) redraw {
107 | id drawable = [self.metalLayer nextDrawable];
108 | id texture = drawable.texture;
109 |
110 | if( drawable ) {
111 | MTLRenderPassDescriptor * passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
112 | passDescriptor.colorAttachments[0].texture = texture;
113 | passDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.3, 0.3, 0.3, 1.0);
114 | passDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
115 | passDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
116 |
117 | id commandBuffer = [self.mCommandQueue commandBuffer];
118 | id commandEncoder = [commandBuffer renderCommandEncoderWithDescriptor:passDescriptor];
119 | [commandEncoder setRenderPipelineState:self.mPipeline];
120 | [commandEncoder setVertexBuffer:self.mVertexBuffer offset:0 atIndex:0];
121 | [commandEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];
122 | [commandEncoder endEncoding];
123 |
124 | [commandBuffer presentDrawable:drawable];
125 | [commandBuffer commit];
126 | }
127 | }
128 |
129 |
130 |
131 | @end
132 |
--------------------------------------------------------------------------------
/HelloMetal/HelloMetal/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // HelloMetal
4 | //
5 | // Created by Volvet Zhang on 16/3/5.
6 | // Copyright © 2016年 Volvet Zhang. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "VideoMetalView.h"
11 |
12 | @interface ViewController () {
13 | //AVCaptureSession *mCaptureSession;
14 | }
15 |
16 | @property(nonatomic, strong) VideoMetalView * mMetalView;
17 |
18 | @property(nonatomic, strong) id mMetalCommandQueue;
19 |
20 | @property(nonatomic, strong) id mSourceTexture;
21 |
22 | @end
23 |
24 |
25 |
26 | @implementation ViewController
27 |
28 |
29 | - (void)viewDidLoad {
30 | [super viewDidLoad];
31 | // Do any additional setup after loading the view, typically from a nib.
32 |
33 | self.mMetalView = (VideoMetalView*) self.view;
34 | self.mMetalView.device = MTLCreateSystemDefaultDevice();
35 |
36 | if( !MPSSupportsMTLDevice(self.mMetalView.device) ){
37 | NSLog(@"This device can't support Metal Performance Shaders!");
38 | return;
39 | }
40 |
41 | [self setupView];
42 |
43 | [self setupMetal];
44 |
45 | [self loadAssets];
46 |
47 | //[self startCapture];
48 | }
49 |
50 | - (void)viewWillDisappear:(BOOL)animated {
51 | [super viewWillDisappear :animated];
52 | //[self stopCapture];
53 | }
54 |
55 | - (void)didReceiveMemoryWarning {
56 | [super didReceiveMemoryWarning];
57 | // Dispose of any resources that can be recreated.
58 | }
59 |
60 | - (void)setupView {
61 | self.mMetalView.delegate = self;
62 | self.mMetalView.depthStencilPixelFormat = MTLPixelFormatDepth32Float_Stencil8;
63 | self.mMetalView.colorPixelFormat = MTLPixelFormatBGRA8Unorm;
64 | self.mMetalView.framebufferOnly = FALSE;
65 | }
66 |
67 | - (void)setupMetal {
68 | self.mMetalCommandQueue = [self.mMetalView.device newCommandQueue];
69 | }
70 |
71 | - (void)loadAssets {
72 | MTKTextureLoader * loader = [[MTKTextureLoader alloc] initWithDevice:self.mMetalView.device];
73 | NSBundle * mainBundle = [NSBundle mainBundle];
74 |
75 | NSURL *url = [mainBundle URLForResource:@"photo_night" withExtension:@"jpg"];
76 |
77 | self.mSourceTexture = [loader newTextureWithContentsOfURL:url options:nil error:nil];
78 | }
79 |
80 | - (void)render {
81 | // Create a new command buffer for each renderpass to the current drawable.
82 | id commandBuffer = [self.mMetalCommandQueue commandBuffer];
83 |
84 | // Initialize MetalPerformanceShaders gaussianBlur with Sigma = 10.0f.
85 | MPSImageGaussianBlur *gaussianblur = [[MPSImageGaussianBlur alloc] initWithDevice:self.mMetalView.device sigma:1.0f];
86 |
87 | // Run MetalPerformanceShader gaussianblur
88 | [gaussianblur encodeToCommandBuffer:commandBuffer
89 | sourceTexture:self.mSourceTexture
90 | destinationTexture:self.mMetalView.currentDrawable.texture];
91 |
92 | // Schedule a present using the current drawable.
93 | [commandBuffer presentDrawable:self.mMetalView.currentDrawable];
94 |
95 | // Finalize command buffer.
96 | [commandBuffer commit];
97 | [commandBuffer waitUntilCompleted];
98 | }
99 |
100 | /*
101 | - (void) startCapture {
102 | mCaptureSession = [[AVCaptureSession alloc] init];
103 |
104 | [mCaptureSession beginConfiguration];
105 | [mCaptureSession setSessionPreset:AVCaptureSessionPresetHigh];
106 |
107 | // Get the a video device with preference to the front facing camera
108 | AVCaptureDevice* videoDevice = nil;
109 | NSArray* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
110 | for (AVCaptureDevice* device in devices)
111 | {
112 | if ([device position] == AVCaptureDevicePositionFront)
113 | {
114 | videoDevice = device;
115 | }
116 | }
117 |
118 | if(videoDevice == nil)
119 | {
120 | videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
121 | }
122 |
123 | if(videoDevice == nil)
124 | {
125 | NSLog(@">> ERROR: Couldnt create a AVCaptureDevice");
126 | assert(0);
127 | }
128 |
129 | NSError *error;
130 |
131 | // Device input
132 | AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
133 |
134 | if (error)
135 | {
136 | NSLog(@">> ERROR: Couldnt create AVCaptureDeviceInput");
137 | assert(0);
138 | }
139 |
140 | [mCaptureSession addInput:deviceInput];
141 |
142 | // Create the output for the capture session.
143 | AVCaptureVideoDataOutput * dataOutput = [[AVCaptureVideoDataOutput alloc] init];
144 | [dataOutput setAlwaysDiscardsLateVideoFrames:YES];
145 |
146 | // Set the color space.
147 | [dataOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
148 | forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
149 |
150 | // Set dispatch to be on the main thread to create the texture in memory and allow Metal to use it for rendering
151 | [dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
152 |
153 | [mCaptureSession addOutput:dataOutput];
154 | [mCaptureSession commitConfiguration];
155 |
156 | // this will trigger capture on its own queue
157 | [mCaptureSession startRunning];
158 |
159 | }
160 |
161 | - (void) stopCapture {
162 | [mCaptureSession stopRunning];
163 | }
164 |
165 | - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
166 | //NSLog(@"captureOutput");
167 | }*/
168 |
169 | - (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
170 |
171 | }
172 |
173 | - (void)drawInMTKView:(nonnull MTKView *)view {
174 | @autoreleasepool {
175 | [self render];
176 | }
177 | }
178 |
179 | @end
180 |
--------------------------------------------------------------------------------
/Teapot/Teapot/MetalViewRender.m:
--------------------------------------------------------------------------------
1 | //
2 | // MentalViewRender.m
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/4/2.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 | @import Metal;
10 | @import simd;
11 | @import QuartzCore;
12 |
13 | #import "typedef.h"
14 | #import "MetalViewRender.h"
15 | #import "MathUtility.h"
16 | #import "OBJMesh.h"
17 | #import "OBJModel.h"
18 |
19 | static const NSInteger InFlightBufferCount = 3;
20 |
21 | @interface MetalViewRender()
22 |
23 | @property (nonatomic, strong) Mesh *mesh;
24 | @property (nonatomic, strong) id device;
25 | @property (nonatomic, strong) id uniformBuffer;
26 | @property (nonatomic, strong) id commandQueue;
27 | @property (nonatomic, strong) id renderPipelineState;
28 | @property (nonatomic, strong) id depthStencilState;
29 | @property (nonatomic, strong) dispatch_semaphore_t displaySemaphore;
30 | @property (nonatomic, assign) NSInteger bufferIndex;
31 | @property (nonatomic, assign) float rotationX, rotationY, rotionZ, time;
32 |
33 | @end
34 |
35 | @implementation MetalViewRender
36 |
37 | - (instancetype) init {
38 | if( self = [super init] ){
39 | _device = MTLCreateSystemDefaultDevice();
40 | _displaySemaphore = dispatch_semaphore_create(InFlightBufferCount);
41 | [self makePipeline];
42 | [self makeResource];
43 | }
44 |
45 | return self;
46 | }
47 |
48 | - (void) makePipeline {
49 | _commandQueue = [_device newCommandQueue];
50 | id library = [_device newDefaultLibrary];
51 |
52 |
53 | MTLRenderPipelineDescriptor * descriptor = [MTLRenderPipelineDescriptor new];
54 | descriptor.vertexFunction = [library newFunctionWithName:@"vertex_main"];
55 | descriptor.fragmentFunction = [library newFunctionWithName:@"fragment_main"];
56 | descriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
57 | descriptor.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float;
58 |
59 | MTLDepthStencilDescriptor * depthStencilDescriptor = [MTLDepthStencilDescriptor new];
60 | depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionLess;
61 | depthStencilDescriptor.depthWriteEnabled = YES;
62 | _depthStencilState = [_device newDepthStencilStateWithDescriptor:depthStencilDescriptor];
63 |
64 | NSError * error = nil;
65 | _renderPipelineState = [_device newRenderPipelineStateWithDescriptor:descriptor error:&error];
66 |
67 | if( !_renderPipelineState ){
68 | NSLog(@"Fail to create pipeline");
69 | }
70 | }
71 |
72 | - (void) makeResource {
73 | NSURL * modelURL = [[NSBundle mainBundle] URLForResource:@"teapot" withExtension:@"obj"];
74 | OBJModel * model = [[OBJModel alloc] initWithContentsOfURL:modelURL generateNormals:YES];
75 | OBJGroup * group = [model groupForName:@"teapot"];
76 |
77 | _mesh = [[OBJMesh alloc] initWithGroup:group device:_device];
78 |
79 | _uniformBuffer = [_device newBufferWithLength:sizeof(Uniforms) * InFlightBufferCount options:MTLResourceCPUCacheModeDefaultCache];
80 | }
81 |
82 | - (void) updateUniformsForView :(UIMetalView*)view duration:(NSTimeInterval)duration {
83 | _time += duration;
84 | _rotationX += duration * (M_PI/2);
85 | _rotationY += duration * (M_PI/3);
86 | float scaleFactor = 1;
87 | static const vector_float3 xAxis = { 1, 0, 0 };
88 | static const vector_float3 yAxis = { 0, 1, 0 };
89 | const matrix_float4x4 xRot = matrix_float4x4_rotation(xAxis, _rotationX);
90 | const matrix_float4x4 yRot = matrix_float4x4_rotation(yAxis, _rotationY);
91 | const matrix_float4x4 scale = matrix_float4x4_uniform_scale(scaleFactor);
92 | const matrix_float4x4 modelMatrix = matrix_multiply(matrix_multiply(xRot, yRot), scale);
93 |
94 | const vector_float3 cameraTranslation = { 0, 0, -1.5 };
95 | const matrix_float4x4 viewMatrix = matrix_float4x4_translation(cameraTranslation);
96 |
97 | const CGSize drawableSize = view.metalLayer.drawableSize;
98 | const float aspect = drawableSize.width / drawableSize.height;
99 | const float fov = 2 * M_PI / 5;
100 | const float near = 0.1;
101 | const float far = 100;
102 | const matrix_float4x4 projectionMatrix = matrix_float4x4_perspective(aspect, fov, near, far);
103 |
104 | Uniforms uniforms;
105 | uniforms.modelViewMatrix = matrix_multiply(viewMatrix, modelMatrix);
106 | uniforms.modelViewProjectionMatrix = matrix_multiply(projectionMatrix, uniforms.modelViewMatrix);
107 | uniforms.normalMatrix = matrix_float4x4_extract_linear(uniforms.modelViewMatrix);
108 |
109 | const NSUInteger uniformBufferOffset = sizeof(Uniforms) * _bufferIndex;
110 | memcpy([_uniformBuffer contents] + uniformBufferOffset, &uniforms, sizeof(uniforms));
111 | }
112 |
113 | - (void) drawInView:(UIMetalView *)view {
114 | dispatch_semaphore_wait(_displaySemaphore, DISPATCH_TIME_FOREVER);
115 |
116 | view.clearColor = MTLClearColorMake(0.95, 0.95, 0.95, 1);
117 | [self updateUniformsForView:view duration:view.frameDuration];
118 |
119 | id commandBuffer = [_commandQueue commandBuffer];
120 | MTLRenderPassDescriptor * renderPassDescriptor = [view currentRenderPassDescriptor];
121 | id renderCommandEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
122 |
123 | [renderCommandEncoder setRenderPipelineState:_renderPipelineState];
124 | [renderCommandEncoder setDepthStencilState:_depthStencilState];
125 | [renderCommandEncoder setFrontFacingWinding:MTLWindingCounterClockwise];
126 | [renderCommandEncoder setCullMode:MTLCullModeBack];
127 |
128 | const NSUInteger uniformBufferOffset = sizeof(Uniforms) * _bufferIndex;
129 | [renderCommandEncoder setVertexBuffer:_mesh.vertexBuffer offset:0 atIndex:0];
130 | [renderCommandEncoder setVertexBuffer:self.uniformBuffer offset:uniformBufferOffset atIndex:1];
131 |
132 | [renderCommandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle indexCount:[_mesh.indexBuffer length]/sizeof(VertexIndex) indexType:VertexIndexType indexBuffer:_mesh.indexBuffer indexBufferOffset:0];
133 | [renderCommandEncoder endEncoding];
134 |
135 | [commandBuffer presentDrawable:view.currentDrawable];
136 |
137 | [commandBuffer addCompletedHandler:^(id commandBuffer) {
138 | self.bufferIndex = (self.bufferIndex + 1) % InFlightBufferCount;
139 | dispatch_semaphore_signal(_displaySemaphore);
140 | }];
141 |
142 | [commandBuffer commit];
143 | }
144 |
145 | @end
146 |
--------------------------------------------------------------------------------
/Draw3d/Draw3d/MetalRender.m:
--------------------------------------------------------------------------------
1 | //
2 | // MetalRender.m
3 | // Draw3d
4 | //
5 | // Created by Volvet Zhang on 16/3/20.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 |
10 | @import QuartzCore;
11 | @import Metal;
12 | @import simd;
13 |
14 | #import "MetalRender.h"
15 | #import "MathUtility.h"
16 |
17 | const static NSInteger InFlightBufferCount = 3;
18 |
19 | typedef uint16_t VerticeIndex;
20 |
21 | typedef struct
22 | {
23 | vector_float4 position;
24 | vector_float4 color;
25 | } Vertex;
26 |
27 | typedef struct
28 | {
29 | matrix_float4x4 modelViewProjectionMatrix;
30 | } Uniforms;
31 |
32 | @interface MetalRender()
33 |
34 | @property (strong) id mDevice;
35 | @property (strong) id mVertexBuffer;
36 | @property (strong) id mIndexBuffer;
37 | @property (strong) id mUniformBuffer;
38 | @property (strong) id mCommandQueue;
39 | @property (strong) id mPipeline;
40 | @property (strong) id mDepthStencilState;
41 | @property (strong) dispatch_semaphore_t mDisplaySemaphore;
42 | @property (assign) NSInteger mBufferIndex;
43 | @property (assign) float mRotateX, mRotateY, mTime;
44 |
45 | @end
46 |
47 | @implementation MetalRender
48 |
49 |
50 | - (instancetype) init {
51 | if( self = [super init] ){
52 | _mDevice = MTLCreateSystemDefaultDevice();
53 | _mDisplaySemaphore = dispatch_semaphore_create(InFlightBufferCount);
54 | _mTime = 0.0;
55 |
56 | [self mtlPipelineInit];
57 | [self mtlBufferInit];
58 | }
59 |
60 | return self;
61 | }
62 |
63 | - (void) mtlPipelineInit {
64 | _mCommandQueue = [_mDevice newCommandQueue];
65 |
66 | id library = [_mDevice newDefaultLibrary];
67 |
68 | MTLRenderPipelineDescriptor * pipeDescriptor = [MTLRenderPipelineDescriptor new];
69 |
70 | pipeDescriptor.vertexFunction = [library newFunctionWithName:@"vertex_main"];
71 | pipeDescriptor.fragmentFunction = [library newFunctionWithName:@"fragment_main"];
72 | pipeDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
73 | pipeDescriptor.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float;
74 | NSError * error = nil;
75 | _mPipeline = [_mDevice newRenderPipelineStateWithDescriptor:pipeDescriptor error:&error];
76 |
77 | MTLDepthStencilDescriptor * depthStencilDescriptor = [MTLDepthStencilDescriptor new];
78 | depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionLess;
79 | depthStencilDescriptor.depthWriteEnabled = YES;
80 | _mDepthStencilState = [_mDevice newDepthStencilStateWithDescriptor:depthStencilDescriptor];
81 |
82 | if( !_mPipeline ){
83 | NSLog(@"mtlPipelineInit: fail to create render pipeline, error: %@", error);
84 | }
85 | }
86 |
87 | - (void) mtlBufferInit {
88 | static const Vertex vertices[] =
89 | {
90 | { .position = { -1, 1, 1, 1 }, .color = { 0, 1, 1, 1 } },
91 | { .position = { -1, -1, 1, 1 }, .color = { 0, 0, 1, 1 } },
92 | { .position = { 1, -1, 1, 1 }, .color = { 1, 0, 1, 1 } },
93 | { .position = { 1, 1, 1, 1 }, .color = { 1, 1, 1, 1 } },
94 | { .position = { -1, 1, -1, 1 }, .color = { 0, 1, 0, 1 } },
95 | { .position = { -1, -1, -1, 1 }, .color = { 0, 0, 0, 1 } },
96 | { .position = { 1, -1, -1, 1 }, .color = { 1, 0, 0, 1 } },
97 | { .position = { 1, 1, -1, 1 }, .color = { 1, 1, 0, 1 } }
98 | };
99 |
100 | static const VerticeIndex indices[] =
101 | {
102 | 3, 2, 6, 6, 7, 3,
103 | 4, 5, 1, 1, 0, 4,
104 | 4, 0, 3, 3, 7, 4,
105 | 1, 5, 6, 6, 2, 1,
106 | 0, 1, 2, 2, 3, 0,
107 | 7, 6, 5, 5, 4, 7
108 | };
109 |
110 | _mVertexBuffer = [_mDevice newBufferWithBytes:vertices
111 | length:sizeof(vertices)
112 | options:MTLResourceOptionCPUCacheModeDefault];
113 | [_mVertexBuffer setLabel:@"Vertices"];
114 |
115 | _mIndexBuffer = [_mDevice newBufferWithBytes:indices
116 | length:sizeof(indices)
117 | options:MTLResourceOptionCPUCacheModeDefault];
118 | [_mIndexBuffer setLabel:@"Indices"];
119 |
120 | _mUniformBuffer = [_mDevice newBufferWithLength:sizeof(Uniforms) * InFlightBufferCount
121 | options:MTLResourceOptionCPUCacheModeDefault];
122 | [_mUniformBuffer setLabel:@"Uniforms"];
123 | }
124 |
125 | - (void)updateUniformsForView:(MetalView *)view duration:(NSTimeInterval)duration
126 | {
127 | _mTime += duration;
128 | _mRotateX += duration * (M_PI / 4);
129 | _mRotateY += duration * (M_PI / 5);
130 | float scaleFactor = sinf(0.5 * _mTime) * 0.25 + 1;
131 | const vector_float3 xAxis = { 1, 0, 0 };
132 | const vector_float3 yAxis = { 0, 1, 0 };
133 | const matrix_float4x4 xRot = matrix_float4x4_rotation(xAxis, _mRotateX);
134 | const matrix_float4x4 yRot = matrix_float4x4_rotation(yAxis, _mRotateY);
135 | const matrix_float4x4 scale = matrix_float4x4_uniform_scale(scaleFactor);
136 | const matrix_float4x4 modelMatrix = matrix_multiply(matrix_multiply(xRot, yRot), scale);
137 |
138 | const vector_float3 cameraTranslation = { 0, 0, -5 };
139 | const matrix_float4x4 viewMatrix = matrix_float4x4_translation(cameraTranslation);
140 |
141 | const CGSize drawableSize = view.metalLayer.drawableSize;
142 | const float aspect = drawableSize.width / drawableSize.height;
143 | const float fov = (2 * M_PI) / 5;
144 | const float near = 1;
145 | const float far = 100;
146 | const matrix_float4x4 projectionMatrix = matrix_float4x4_perspective(aspect, fov, near, far);
147 |
148 | Uniforms uniforms;
149 | uniforms.modelViewProjectionMatrix = matrix_multiply(projectionMatrix, matrix_multiply(viewMatrix, modelMatrix));
150 |
151 | const NSUInteger uniformBufferOffset = sizeof(Uniforms) * _mBufferIndex;
152 | memcpy([_mUniformBuffer contents] + uniformBufferOffset, &uniforms, sizeof(uniforms));
153 | }
154 |
155 | - (void)drawInView:(MetalView *)view
156 | {
157 | dispatch_semaphore_wait(_mDisplaySemaphore, DISPATCH_TIME_FOREVER);
158 |
159 | view.mClearColor = MTLClearColorMake(0.3, 0.3, 0.3, 1);
160 |
161 | [self updateUniformsForView:view duration:view.mFrameDuration];
162 |
163 | id commandBuffer = [_mCommandQueue commandBuffer];
164 |
165 | MTLRenderPassDescriptor *passDescriptor = [view currentRenderPassDescriptor];
166 |
167 | id renderPass = [commandBuffer renderCommandEncoderWithDescriptor:passDescriptor];
168 | [renderPass setRenderPipelineState:_mPipeline];
169 | [renderPass setDepthStencilState:_mDepthStencilState];
170 | [renderPass setFrontFacingWinding:MTLWindingCounterClockwise];
171 | [renderPass setCullMode:MTLCullModeBack];
172 |
173 | const NSUInteger uniformBufferOffset = sizeof(Uniforms) * _mBufferIndex;
174 |
175 | [renderPass setVertexBuffer:_mVertexBuffer offset:0 atIndex:0];
176 | [renderPass setVertexBuffer:_mUniformBuffer offset:uniformBufferOffset atIndex:1];
177 |
178 | [renderPass drawIndexedPrimitives:MTLPrimitiveTypeTriangle
179 | indexCount:[_mIndexBuffer length] / sizeof(VerticeIndex)
180 | indexType:MTLIndexTypeUInt16
181 | indexBuffer:_mIndexBuffer
182 | indexBufferOffset:0];
183 |
184 | [renderPass endEncoding];
185 |
186 | [commandBuffer presentDrawable:view.mCurrentDrawable];
187 |
188 | [commandBuffer addCompletedHandler:^(id commandBuffer) {
189 | _mBufferIndex = (_mBufferIndex + 1) % InFlightBufferCount;
190 | dispatch_semaphore_signal(_mDisplaySemaphore);
191 | }];
192 |
193 | [commandBuffer commit];
194 | }
195 |
196 |
197 | @end
--------------------------------------------------------------------------------
/Teapot/Teapot/OBJModel.mm:
--------------------------------------------------------------------------------
1 | //
2 | // OBJModel.m
3 | // Teapot
4 | //
5 | // Created by Volvet Zhang on 16/3/27.
6 | // Copyright © 2016年 volvet. All rights reserved.
7 | //
8 |
9 |
10 |
11 | #include