Skip to content

Commit cf3c9d1

Browse files
committed
Implement rendering on macOS.
1 parent 8306f69 commit cf3c9d1

File tree

12 files changed

+255
-122
lines changed

12 files changed

+255
-122
lines changed

objc/04-DrawingIn3D/DrawingIn3D-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: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
//
2-
// ViewController.h
2+
// MBEMetalViewMac.h
33
// DrawingIn3D-Mac
44
//
55
// Created by Brent Gulanowski on 2018-06-18.
66
// Copyright © 2018 Metal by Example. All rights reserved.
77
//
88

9-
#import <Cocoa/Cocoa.h>
9+
@import Cocoa;
1010

11-
@interface ViewController : NSViewController
11+
#import "MBEMetalView.h"
1212

13+
@interface MBEMetalViewMac : MBEMetalView
1314

1415
@end
15-
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/04-DrawingIn3D/DrawingIn3D-Mac/ViewController.m

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

objc/04-DrawingIn3D/DrawingIn3D.xcodeproj/project.pbxproj

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,16 @@
1818
83E2D7B61BD598810006DDD8 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7AD1BD598810006DDD8 /* Shaders.metal */; };
1919
83E2D7B81BD598810006DDD8 /* MBEMathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7B11BD598810006DDD8 /* MBEMathUtilities.m */; };
2020
845182E520D8214900BF473E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 845182E420D8214900BF473E /* AppDelegate.m */; };
21-
845182E820D8214900BF473E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 845182E720D8214900BF473E /* ViewController.m */; };
2221
845182EA20D8214A00BF473E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 845182E920D8214A00BF473E /* Assets.xcassets */; };
2322
845182ED20D8214A00BF473E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 845182EB20D8214A00BF473E /* Main.storyboard */; };
2423
845182F020D8214A00BF473E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 845182EF20D8214A00BF473E /* main.m */; };
24+
845182F720D821B300BF473E /* MBEMetalViewMac.m in Sources */ = {isa = PBXBuildFile; fileRef = 845182F620D821B300BF473E /* MBEMetalViewMac.m */; };
25+
845182F820D821DD00BF473E /* MBEMetalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7A71BD598810006DDD8 /* MBEMetalView.m */; };
26+
845182FB20D8222100BF473E /* MBEMetalViewIOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 845182FA20D8222100BF473E /* MBEMetalViewIOS.m */; };
27+
8451830020D8278F00BF473E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7961BD597A30006DDD8 /* ViewController.m */; };
28+
8451830120D827C800BF473E /* MBEMathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7B11BD598810006DDD8 /* MBEMathUtilities.m */; };
29+
8451830220D827C800BF473E /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7AC1BD598810006DDD8 /* MBERenderer.m */; };
30+
8451830320D827DC00BF473E /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7AD1BD598810006DDD8 /* Shaders.metal */; };
2531
/* End PBXBuildFile section */
2632

2733
/* Begin PBXFileReference section */
@@ -45,13 +51,15 @@
4551
845182E120D8214900BF473E /* Drawing in 3D.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Drawing in 3D.app"; sourceTree = BUILT_PRODUCTS_DIR; };
4652
845182E320D8214900BF473E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
4753
845182E420D8214900BF473E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
48-
845182E620D8214900BF473E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
49-
845182E720D8214900BF473E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
5054
845182E920D8214A00BF473E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
5155
845182EC20D8214A00BF473E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
5256
845182EE20D8214A00BF473E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
5357
845182EF20D8214A00BF473E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
5458
845182F120D8214A00BF473E /* DrawingIn3D_Mac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DrawingIn3D_Mac.entitlements; sourceTree = "<group>"; };
59+
845182F520D821B300BF473E /* MBEMetalViewMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewMac.h; sourceTree = "<group>"; };
60+
845182F620D821B300BF473E /* MBEMetalViewMac.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewMac.m; sourceTree = "<group>"; };
61+
845182F920D8222100BF473E /* MBEMetalViewIOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewIOS.h; sourceTree = "<group>"; };
62+
845182FA20D8222100BF473E /* MBEMetalViewIOS.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewIOS.m; sourceTree = "<group>"; };
5563
/* End PBXFileReference section */
5664

5765
/* Begin PBXFrameworksBuildPhase section */
@@ -95,20 +103,22 @@
95103
children = (
96104
83E2D7921BD597A30006DDD8 /* AppDelegate.h */,
97105
83E2D7931BD597A30006DDD8 /* AppDelegate.m */,
98-
83E2D7951BD597A30006DDD8 /* ViewController.h */,
99-
83E2D7961BD597A30006DDD8 /* ViewController.m */,
106+
83E2D79B1BD597A30006DDD8 /* Assets.xcassets */,
107+
83E2D7A01BD597A30006DDD8 /* Info.plist */,
108+
83E2D79D1BD597A30006DDD8 /* LaunchScreen.storyboard */,
109+
83E2D7981BD597A30006DDD8 /* Main.storyboard */,
100110
83E2D7B01BD598810006DDD8 /* MBEMathUtilities.h */,
101111
83E2D7B11BD598810006DDD8 /* MBEMathUtilities.m */,
102112
83E2D7A61BD598810006DDD8 /* MBEMetalView.h */,
103113
83E2D7A71BD598810006DDD8 /* MBEMetalView.m */,
114+
845182F920D8222100BF473E /* MBEMetalViewIOS.h */,
115+
845182FA20D8222100BF473E /* MBEMetalViewIOS.m */,
104116
83E2D7AB1BD598810006DDD8 /* MBERenderer.h */,
105117
83E2D7AC1BD598810006DDD8 /* MBERenderer.m */,
106118
83E2D7AD1BD598810006DDD8 /* Shaders.metal */,
107-
83E2D7981BD597A30006DDD8 /* Main.storyboard */,
108-
83E2D79B1BD597A30006DDD8 /* Assets.xcassets */,
109-
83E2D79D1BD597A30006DDD8 /* LaunchScreen.storyboard */,
110-
83E2D7A01BD597A30006DDD8 /* Info.plist */,
111119
83E2D78F1BD597A30006DDD8 /* Supporting Files */,
120+
83E2D7951BD597A30006DDD8 /* ViewController.h */,
121+
83E2D7961BD597A30006DDD8 /* ViewController.m */,
112122
);
113123
path = DrawingIn3D;
114124
sourceTree = "<group>";
@@ -126,13 +136,13 @@
126136
children = (
127137
845182E320D8214900BF473E /* AppDelegate.h */,
128138
845182E420D8214900BF473E /* AppDelegate.m */,
129-
845182E620D8214900BF473E /* ViewController.h */,
130-
845182E720D8214900BF473E /* ViewController.m */,
131139
845182E920D8214A00BF473E /* Assets.xcassets */,
132-
845182EB20D8214A00BF473E /* Main.storyboard */,
140+
845182F120D8214A00BF473E /* DrawingIn3D_Mac.entitlements */,
133141
845182EE20D8214A00BF473E /* Info.plist */,
134142
845182EF20D8214A00BF473E /* main.m */,
135-
845182F120D8214A00BF473E /* DrawingIn3D_Mac.entitlements */,
143+
845182EB20D8214A00BF473E /* Main.storyboard */,
144+
845182F520D821B300BF473E /* MBEMetalViewMac.h */,
145+
845182F620D821B300BF473E /* MBEMetalViewMac.m */,
136146
);
137147
path = "DrawingIn3D-Mac";
138148
sourceTree = "<group>";
@@ -239,6 +249,7 @@
239249
buildActionMask = 2147483647;
240250
files = (
241251
83E2D7971BD597A30006DDD8 /* ViewController.m in Sources */,
252+
845182FB20D8222100BF473E /* MBEMetalViewIOS.m in Sources */,
242253
83E2D7B61BD598810006DDD8 /* Shaders.metal in Sources */,
243254
83E2D7941BD597A30006DDD8 /* AppDelegate.m in Sources */,
244255
83E2D7B51BD598810006DDD8 /* MBERenderer.m in Sources */,
@@ -252,9 +263,14 @@
252263
isa = PBXSourcesBuildPhase;
253264
buildActionMask = 2147483647;
254265
files = (
255-
845182E820D8214900BF473E /* ViewController.m in Sources */,
266+
8451830320D827DC00BF473E /* Shaders.metal in Sources */,
267+
8451830020D8278F00BF473E /* ViewController.m in Sources */,
268+
8451830120D827C800BF473E /* MBEMathUtilities.m in Sources */,
256269
845182F020D8214A00BF473E /* main.m in Sources */,
257270
845182E520D8214900BF473E /* AppDelegate.m in Sources */,
271+
8451830220D827C800BF473E /* MBERenderer.m in Sources */,
272+
845182F820D821DD00BF473E /* MBEMetalView.m in Sources */,
273+
845182F720D821B300BF473E /* MBEMetalViewMac.m in Sources */,
258274
);
259275
runOnlyForDeploymentPostprocessing = 0;
260276
};

objc/04-DrawingIn3D/DrawingIn3D/Base.lproj/Main.storyboard

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +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="8191" systemVersion="15B38b" 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>
4-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
7+
<deployment identifier="iOS"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
9+
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
510
</dependencies>
611
<scenes>
712
<!--View Controller-->
@@ -12,11 +17,10 @@
1217
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
1318
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
1419
</layoutGuides>
15-
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC" customClass="MBEMetalView">
16-
<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"/>
1722
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
18-
<animations/>
19-
<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"/>
2024
</view>
2125
</viewController>
2226
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>

objc/04-DrawingIn3D/DrawingIn3D/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)