Skip to content

Commit 749920a

Browse files
committed
Extend MetalView and Renderer to support macOS.
Reuse code from ch 04 mac support work.
1 parent fdfb2a5 commit 749920a

File tree

13 files changed

+260
-118
lines changed

13 files changed

+260
-118
lines changed

objc/05-Lighting/Lighting-Mac/Base.lproj/Main.storyboard

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
33
<dependencies>
4-
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11134"/>
4+
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
5+
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
56
</dependencies>
67
<scenes>
78
<!--Application-->
@@ -673,7 +674,7 @@
673674
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
674675
</connections>
675676
</application>
676-
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModuleProvider=""/>
677+
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
677678
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
678679
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
679680
</objects>
@@ -688,7 +689,7 @@
688689
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
689690
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
690691
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
691-
<connections>
692+
<connections>
692693
<outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
693694
</connections>
694695
</window>
@@ -703,8 +704,8 @@
703704
<!--View Controller-->
704705
<scene sceneID="hIz-AP-VOD">
705706
<objects>
706-
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
707-
<view key="view" wantsLayer="YES" id="m2S-Jp-Qdl">
707+
<viewController id="XfG-lQ-9wD" customClass="ViewController" sceneMemberID="viewController">
708+
<view key="view" wantsLayer="YES" id="m2S-Jp-Qdl" customClass="MBEMetalViewMac">
708709
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
709710
<autoresizingMask key="autoresizingMask"/>
710711
</view>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// MBEMetalViewMac.h
3+
// DrawingIn3D-Mac
4+
//
5+
// Created by Brent Gulanowski on 2018-06-18.
6+
// Copyright © 2018 Metal by Example. All rights reserved.
7+
//
8+
9+
@import Cocoa;
10+
11+
#import "MBEMetalView.h"
12+
13+
@interface MBEMetalViewMac : MBEMetalView
14+
15+
@end
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//
2+
// MBEMetalViewMac.m
3+
// DrawingIn3D-Mac
4+
//
5+
// Created by Brent Gulanowski on 2018-06-18.
6+
// Copyright © 2018 Metal by Example. All rights reserved.
7+
//
8+
9+
#import "MBEMetalViewMac.h"
10+
11+
@interface MBEMetalViewMac()
12+
@property (nonatomic) CVDisplayLinkRef displayLink;
13+
@property (nonatomic, strong) CAMetalLayer *metalLayer;
14+
@end
15+
16+
static NSTimeInterval C3DTimeIntervalFromTimeStamp(const CVTimeStamp *timeStamp) {
17+
return 1.0 / (timeStamp->rateScalar * (double)timeStamp->videoTimeScale / (double)timeStamp->videoRefreshPeriod);
18+
}
19+
20+
static CVReturn C3DViewDisplayLink(CVDisplayLinkRef displayLink,
21+
const CVTimeStamp *inNow,
22+
const CVTimeStamp *inOutputTime,
23+
CVOptionFlags flagsIn,
24+
CVOptionFlags *flagsOut,
25+
void *view) {
26+
@autoreleasepool {
27+
[(__bridge MBEMetalView *)view renderWithDuration:C3DTimeIntervalFromTimeStamp(inOutputTime)];
28+
}
29+
30+
return kCVReturnSuccess;
31+
}
32+
33+
@implementation MBEMetalViewMac
34+
35+
@synthesize metalLayer=_metalLayer;
36+
37+
- (CALayer *)makeBackingLayer
38+
{
39+
CAMetalLayer *layer = [[CAMetalLayer alloc] init];
40+
_metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
41+
_metalLayer = layer;
42+
return layer;
43+
}
44+
45+
- (CGSize)drawableSize {
46+
return self.bounds.size;
47+
}
48+
49+
- (void)viewDidMoveToSuperview
50+
{
51+
[super viewDidMoveToSuperview];
52+
53+
if (self.metalLayer.device == nil) {
54+
self.metalLayer.device = MTLCreateSystemDefaultDevice();
55+
}
56+
if (self.depthTexture == nil) {
57+
[self makeDepthTexture];
58+
}
59+
60+
if (self.superview) {
61+
CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
62+
CVDisplayLinkSetOutputCallback(_displayLink, C3DViewDisplayLink, (__bridge void *)(self));
63+
CVDisplayLinkStart(_displayLink);
64+
}
65+
else {
66+
CVDisplayLinkStop(_displayLink);
67+
CVDisplayLinkRelease(_displayLink);
68+
_displayLink = NULL;
69+
}
70+
}
71+
72+
@end

objc/05-Lighting/Lighting-Mac/ViewController.m

Lines changed: 0 additions & 27 deletions
This file was deleted.

objc/05-Lighting/Lighting.xcodeproj/project.pbxproj

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,21 @@
2323
839E18BD1BE31EC300944528 /* teapot.obj in Resources */ = {isa = PBXBuildFile; fileRef = 839E18BC1BE31EC300944528 /* teapot.obj */; };
2424
839E18C01BE3224E00944528 /* MBEMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18BF1BE3224E00944528 /* MBEMesh.m */; };
2525
8451830C20D8346200BF473E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451830B20D8346200BF473E /* AppDelegate.m */; };
26-
8451830F20D8346200BF473E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451830E20D8346200BF473E /* ViewController.m */; };
2726
8451831120D8346200BF473E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8451831020D8346200BF473E /* Assets.xcassets */; };
2827
8451831420D8346200BF473E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8451831220D8346200BF473E /* Main.storyboard */; };
2928
8451831720D8346200BF473E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451831620D8346200BF473E /* main.m */; };
29+
8451831E20D835D400BF473E /* MBEMetalViewIOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451831D20D835D400BF473E /* MBEMetalViewIOS.m */; };
30+
8451832120D835EB00BF473E /* MBEMetalViewMac.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451832020D835EB00BF473E /* MBEMetalViewMac.m */; };
31+
8451832220D84E2A00BF473E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18971BE31CDA00944528 /* ViewController.m */; };
32+
8451832320D84E5800BF473E /* MBEMathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18A81BE31D6100944528 /* MBEMathUtilities.m */; };
33+
8451832420D84E5800BF473E /* MBEOBJGroup.mm in Sources */ = {isa = PBXBuildFile; fileRef = 839E18B31BE31DE300944528 /* MBEOBJGroup.mm */; };
34+
8451832520D84E5800BF473E /* MBEOBJModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 839E18B71BE31DE300944528 /* MBEOBJModel.mm */; };
35+
8451832620D84E5C00BF473E /* MBEMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18BF1BE3224E00944528 /* MBEMesh.m */; };
36+
8451832720D84E5C00BF473E /* MBEOBJMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18B51BE31DE300944528 /* MBEOBJMesh.m */; };
37+
8451832820D84E6000BF473E /* MBEMetalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18AA1BE31D6100944528 /* MBEMetalView.m */; };
38+
8451832920D84E7C00BF473E /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18AC1BE31D6100944528 /* MBERenderer.m */; };
39+
8451832A20D84EA300BF473E /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 839E18B01BE31D8A00944528 /* Shaders.metal */; };
40+
8451832B20D84EA300BF473E /* teapot.obj in Resources */ = {isa = PBXBuildFile; fileRef = 839E18BC1BE31EC300944528 /* teapot.obj */; };
3041
/* End PBXBuildFile section */
3142

3243
/* Begin PBXFileReference section */
@@ -60,13 +71,15 @@
6071
8451830820D8346200BF473E /* Lighting.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Lighting.app; sourceTree = BUILT_PRODUCTS_DIR; };
6172
8451830A20D8346200BF473E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
6273
8451830B20D8346200BF473E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
63-
8451830D20D8346200BF473E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
64-
8451830E20D8346200BF473E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
6574
8451831020D8346200BF473E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
6675
8451831320D8346200BF473E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
6776
8451831520D8346200BF473E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6877
8451831620D8346200BF473E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
6978
8451831820D8346200BF473E /* Lighting_Mac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Lighting_Mac.entitlements; sourceTree = "<group>"; };
79+
8451831C20D835D400BF473E /* MBEMetalViewIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewIOS.h; sourceTree = "<group>"; };
80+
8451831D20D835D400BF473E /* MBEMetalViewIOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewIOS.m; sourceTree = "<group>"; };
81+
8451831F20D835EB00BF473E /* MBEMetalViewMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewMac.h; sourceTree = "<group>"; };
82+
8451832020D835EB00BF473E /* MBEMetalViewMac.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewMac.m; sourceTree = "<group>"; };
7083
/* End PBXFileReference section */
7184

7285
/* Begin PBXFrameworksBuildPhase section */
@@ -144,11 +157,13 @@
144157
839E18C21BE3252800944528 /* User Interface */ = {
145158
isa = PBXGroup;
146159
children = (
147-
839E18C51BE3256C00944528 /* Storyboards */,
148160
839E18931BE31CDA00944528 /* AppDelegate.h */,
149161
839E18941BE31CDA00944528 /* AppDelegate.m */,
150162
839E18A91BE31D6100944528 /* MBEMetalView.h */,
151163
839E18AA1BE31D6100944528 /* MBEMetalView.m */,
164+
8451831C20D835D400BF473E /* MBEMetalViewIOS.h */,
165+
8451831D20D835D400BF473E /* MBEMetalViewIOS.m */,
166+
839E18C51BE3256C00944528 /* Storyboards */,
152167
839E18961BE31CDA00944528 /* ViewController.h */,
153168
839E18971BE31CDA00944528 /* ViewController.m */,
154169
);
@@ -199,13 +214,13 @@
199214
children = (
200215
8451830A20D8346200BF473E /* AppDelegate.h */,
201216
8451830B20D8346200BF473E /* AppDelegate.m */,
202-
8451830D20D8346200BF473E /* ViewController.h */,
203-
8451830E20D8346200BF473E /* ViewController.m */,
204217
8451831020D8346200BF473E /* Assets.xcassets */,
205-
8451831220D8346200BF473E /* Main.storyboard */,
206218
8451831520D8346200BF473E /* Info.plist */,
207-
8451831620D8346200BF473E /* main.m */,
208219
8451831820D8346200BF473E /* Lighting_Mac.entitlements */,
220+
8451831620D8346200BF473E /* main.m */,
221+
8451831220D8346200BF473E /* Main.storyboard */,
222+
8451831F20D835EB00BF473E /* MBEMetalViewMac.h */,
223+
8451832020D835EB00BF473E /* MBEMetalViewMac.m */,
209224
);
210225
path = "Lighting-Mac";
211226
sourceTree = "<group>";
@@ -302,6 +317,7 @@
302317
files = (
303318
8451831120D8346200BF473E /* Assets.xcassets in Resources */,
304319
8451831420D8346200BF473E /* Main.storyboard in Resources */,
320+
8451832B20D84EA300BF473E /* teapot.obj in Resources */,
305321
);
306322
runOnlyForDeploymentPostprocessing = 0;
307323
};
@@ -317,6 +333,7 @@
317333
839E18B81BE31DE300944528 /* MBEOBJGroup.mm in Sources */,
318334
839E18AF1BE31D6100944528 /* MBERenderer.m in Sources */,
319335
839E18BA1BE31DE300944528 /* MBEOBJModel.mm in Sources */,
336+
8451831E20D835D400BF473E /* MBEMetalViewIOS.m in Sources */,
320337
839E18951BE31CDA00944528 /* AppDelegate.m in Sources */,
321338
839E18921BE31CDA00944528 /* main.m in Sources */,
322339
839E18AE1BE31D6100944528 /* MBEMetalView.m in Sources */,
@@ -330,9 +347,18 @@
330347
isa = PBXSourcesBuildPhase;
331348
buildActionMask = 2147483647;
332349
files = (
333-
8451830F20D8346200BF473E /* ViewController.m in Sources */,
350+
8451832A20D84EA300BF473E /* Shaders.metal in Sources */,
351+
8451832920D84E7C00BF473E /* MBERenderer.m in Sources */,
334352
8451831720D8346200BF473E /* main.m in Sources */,
335353
8451830C20D8346200BF473E /* AppDelegate.m in Sources */,
354+
8451832420D84E5800BF473E /* MBEOBJGroup.mm in Sources */,
355+
8451832820D84E6000BF473E /* MBEMetalView.m in Sources */,
356+
8451832320D84E5800BF473E /* MBEMathUtilities.m in Sources */,
357+
8451832520D84E5800BF473E /* MBEOBJModel.mm in Sources */,
358+
8451832620D84E5C00BF473E /* MBEMesh.m in Sources */,
359+
8451832220D84E2A00BF473E /* ViewController.m in Sources */,
360+
8451832120D835EB00BF473E /* MBEMetalViewMac.m in Sources */,
361+
8451832720D84E5C00BF473E /* MBEOBJMesh.m in Sources */,
336362
);
337363
runOnlyForDeploymentPostprocessing = 0;
338364
};

objc/05-Lighting/Lighting/Base.lproj/Main.storyboard

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9059" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
3+
<device id="retina4_7" orientation="portrait">
4+
<adaptation id="fullscreen"/>
5+
</device>
36
<dependencies>
47
<deployment identifier="iOS"/>
5-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9049"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
9+
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
610
</dependencies>
711
<scenes>
812
<!--View Controller-->
@@ -13,11 +17,10 @@
1317
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
1418
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
1519
</layoutGuides>
16-
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC" customClass="MBEMetalView">
17-
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
20+
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC" customClass="MBEMetalViewIOS">
21+
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
1822
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
19-
<animations/>
20-
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
23+
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
2124
</view>
2225
</viewController>
2326
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>

objc/05-Lighting/Lighting/MBEMesh.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import UIKit;
1+
@import Foundation;
22
@import Metal;
33

44
@interface MBEMesh : NSObject

objc/05-Lighting/Lighting/MBEMetalView.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1+
#import <TargetConditionals.h>
2+
3+
#if TARGET_OS_IPHONE
14
@import UIKit;
5+
#define NSUIView UIView;
6+
#else
7+
@import AppKit;
8+
#define NSUIView NSView;
9+
#endif
210
@import Metal;
311
@import QuartzCore.CAMetalLayer;
412

513
@protocol MBEMetalViewDelegate;
614

7-
@interface MBEMetalView : UIView
15+
@interface MBEMetalView : NSUIView
816

917
/// The delegate of this view, responsible for drawing
1018
@property (nonatomic, weak) id<MBEMetalViewDelegate> delegate;
@@ -36,6 +44,19 @@
3644
/// size as its depth attachment's texture
3745
@property (nonatomic, readonly) MTLRenderPassDescriptor *currentRenderPassDescriptor;
3846

47+
// Subclass override points
48+
@property (nonatomic, readonly) CGSize drawableSize;
49+
50+
- (void)makeDepthTexture;
51+
- (void)renderWithDuration:(NSTimeInterval)duration;
52+
53+
@end
54+
55+
// For subclasses
56+
@interface MBEMetalView ()
57+
@property (assign) NSTimeInterval frameDuration;
58+
@property (strong) id<CAMetalDrawable> currentDrawable;
59+
@property (strong) id<MTLTexture> depthTexture;
3960
@end
4061

4162
@protocol MBEMetalViewDelegate <NSObject>

0 commit comments

Comments
 (0)