-
Notifications
You must be signed in to change notification settings - Fork 1
/
MBEViewController.m
356 lines (256 loc) · 11.2 KB
/
MBEViewController.m
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
//
// MBEViewController.m
// TextRendering
//
// Created by Warren Moore on 2/6/15.
// Copyright (c) 2015 Metal By Example. All rights reserved.
//
#import "MBEViewController.h"
#import "MBEMetalView.h"
#import "MBERenderer.h"
@interface MBEViewController () //<UIGestureRecognizerDelegate>
@property (nonatomic, strong) MBERenderer *renderer;
//@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic) CVDisplayLinkRef displayLink;
//@property (nonatomic) MTLCommandBuffer commandQueue;
@end
@implementation MBEViewController
// Vars
MBEMetalView *_view;
//Renderer *_renderer;
// Init
//NSFont *font;
- (MBEMetalView *)metalView
{
return (MBEMetalView *)self.view;
}
- (void)viewDidLoad {
[super viewDidLoad];
_view = (MBEMetalView *)self.view;
_view.device = MTLCreateSystemDefaultDevice();
if(!_view.device)
{
NSLog(@"Metal is not supported on this device");
self.view = [[NSView alloc] initWithFrame:self.view.frame];
return;
}
self.renderer = [[MBERenderer alloc] initWithMetalKitView:_view];
[_renderer mtkView:_view drawableSizeWillChange:_view.bounds.size];
_view.delegate = _renderer;
// Init
_font = [NSFont fontWithName:@"American Typewriter" size:72];
//self.renderer = [[MBERenderer alloc] initWithLayer:self.metalView.metalLayer];
// TODO: port this to macOS: displayLinkDidFire -> redraw -> renderer.draw
//self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
//[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
// CGDirectDisplayID displayID = CGMainDisplayID();
// CVReturn error = kCVReturnSuccess;
// error = CVDisplayLinkCreateWithCGDisplay(displayID, _displayLink);
// if (error)
// {
// NSLog(@"DisplayLink created with error:%d", error);
// _displayLink = NULL;
// }
// CVDisplayLinkSetOutputCallback(_displayLink, renderCallback, (__bridge void *)self);
// CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
// CVDisplayLinkSetOutputCallback(_displayLink, &MyDisplayLinkCallback, (__bridge void * _Nullable)(self));
// CVDisplayLinkStart(_displayLink);
// We moeten nu MetalView koppelen aan de Renderer maar het originele project was voor iOS en
// gebruikte de oude CAMetalLayer methode (ipv MTKView). De renderer daar heeft:
//
// - (instancetype)initWithLayer:(CAMetalLayer *)layer;
// - (void)draw;
//
// Hoe kunnen we draw nu aanduiden als de gameloop methode? CADisplayLink werkt niet op macOS.
// Vraag is of we op die manier de boel kunnen koppelen of toch moeten ombouwen naar de MTKView methode
// met een delegate.
// Zo wordt het gedaan met MTKView:
// //////////////
// _view = (MBEMetalView *)self.view;
//
// _view.device = MTLCreateSystemDefaultDevice();
//
// if(!_view.device)
// {
// NSLog(@"Metal is not supported on this device");
// self.view = [[NSView alloc] initWithFrame:self.view.frame];
// return;
// }
//
// //_renderer = [[MBERenderer alloc] initWithMetalKitView:_view];
// NOTE: Need <MTKViewDelegate> in MBERenderer
//self.renderer = [[MBERenderer alloc] initWithMetalKitView:_view];
//
// //[_renderer mtkView:_view drawableSizeWillChange:_view.bounds.size];
//
// //_view.delegate = _renderer;
// ////////////////
// //UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
// action:@selector(panGestureWasRecognized:)];
// //panGestureRecognizer.delegate = self;
// //[self.view addGestureRecognizer:panGestureRecognizer];
//
// //UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self
// action:@selector(pinchGestureWasRecognized:)];
// //pinchGestureRecognizer.delegate = self;
// //[self.view addGestureRecognizer:pinchGestureRecognizer];
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
////////
- (void)displayLinkDidFire:(id)sender
{
[self redraw];
}
- (void)redraw
{
//[self.renderer draw];
}
///////////////
// We can use this to get a font panel that has the font correctly selected the first time it shows
// TODO: colors work, but not font change
// DONE
// TODO: get this in ViewController
// DONE: must connect menu item with ViewController's first responder and then select showFonts2
// TODO: use a variable
// DONE
- (IBAction)showFonts2:(id)sender {
NSFontManager * fontManager = [NSFontManager sharedFontManager];
[fontManager setTarget:self];
//[fontManager setSelectedFont:[NSFont fontWithName:@"American Typewriter" size:72.0] isMultiple:NO];
[fontManager setSelectedFont:_font isMultiple:NO];
[fontManager orderFrontFontPanel:self];
}
- (void)changeFont:(id)sender { // deprecated but works
// blah
// NSAlert *alert = [[NSAlert alloc] init];
// [alert setMessageText:@"Hi there."];
// [alert runModal];
// See: https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/FontHandling/FontHandling.html
NSFont *oldFont = [self font];
NSFont *newFont = [sender convertFont:oldFont];
[self setFont:newFont];
// NSString *str = [NSString stringWithFormat:@"Font: %@\nSize: %f", newFont.fontName, newFont.pointSize];
//
// NSAlert *alert = [[NSAlert alloc] init];
// [alert setMessageText:str];
// [alert runModal];
// rebuild font atlas
[_renderer buildFontAtlas:newFont.fontName];
[_renderer buildTextMesh:@"MyText" size:newFont.pointSize];
[_renderer buildUniformBuffer];
// TEST:
// We get here only for the first time user picks a color from the Font Panel's T button color picker but do
// not get the color this way.
//NSColor *newColor = [sender color];
//_renderer.mbeTextColor = simd_make_float4( newColor.redComponent, newColor.greenComponent, newColor.blueComponent, newColor.alphaComponent );
// NOTE: the font panel has three color pickers:
// cogwheel -> color for text (works)
// T for text (does not work)
// / for background (works)
// how can we access when user picks the T button?
// See: NSFontPanelTextColorEffectModeMask and NSFontPanelModeMaskDocumentColorEffect
return;
}
// YESS: Works!!
// But where is it in the fucking docs??? Do we really have to get this from an obscure old stackoverflow post?
// Should be in the docs loud and clear. With examples.
// FUCK: now background no longer works probably because this is overriding changeDocumentBackgroundColor
// DONE: set background here too.
// NOTE: clicking background button does not work the first time. Need to reclick twice. Why?
// It is because the first click changeFont and then setColor are called. Why? Bug???
// Why is this called when we only click the button? This API sucks big time.
- (void)setColor:(NSColor *)col forAttribute:(NSString *)attr {
if ([attr isEqualToString:@"NSDocumentBackgroundColor"]) {
//self.airportTableView.backgroundColor = col;
_renderer.mbeClearColor = MTLClearColorMake( col.redComponent, col.greenComponent, col.blueComponent, col.alphaComponent );
} else if ([attr isEqualToString:@"NSColor"]) {
//_fontColor = col;
//[self.airportTableView reloadData];
_renderer.mbeTextColor = simd_make_float4( col.redComponent, col.greenComponent, col.blueComponent, col.alphaComponent );
}
}
// Deprecated? May be but Font->Show Colors menu, and Cogwheel->Color need it. Crappy docs again.
- (void)changeColor:(id)sender {
// HELL: This works from Font->Show Colors menu, also from Cogwheel->Color but not From T Button Colorpicker.
// Also when picking from T button then Cogwheel no longer works.
// This API is such a major pain.
// TODO: make text color changes also work from the Font Panel T button color picker
NSColor *newColor = [sender color];
_renderer.mbeTextColor = simd_make_float4( newColor.redComponent, newColor.greenComponent, newColor.blueComponent, newColor.alphaComponent );
}
// This is now no longer called
-(void)changeDocumentBackgroundColor:(id)sender {
//[self setBackgroundColor:[sender color]];
NSColor *newColor = [sender color];
_renderer.mbeClearColor = MTLClearColorMake( newColor.redComponent, newColor.greenComponent, newColor.blueComponent, newColor.alphaComponent );
}
// See: https://cocoadev.github.io/NSFontPanel/
// Allow the font panel to set the underline, strikethrough and shadow attributes.
// Why is this not in the docs??? Cocoa sucks.
-(void)changeAttributes:(id)sender {
//NSDictionary *oldAttributes = [self fontAttributes];
//NSDictionary *newAttributes = [sender convertAttributes: oldAttributes];
//[self setFontAttributes:newAttributes]; return;
}
////////
// See: https://stackoverflow.com/questions/37794646/the-right-way-to-make-a-continuously-redrawn-metal-nsview
////////
//static CVReturn renderCallback(CVDisplayLinkRef displayLink,
// const CVTimeStamp *inNow,
// const CVTimeStamp *inOutputTime,
// CVOptionFlags flagsIn,
// CVOptionFlags *flagsOut,
// void *displayLinkContext)
//{
// return [(__bridge SPVideoView *)displayLinkContext renderTime:inOutputTime];
//}
//static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
//{
//
// [(__bridge MBEMetalView *)displayLinkContext setNeedsDisplay:YES];
// return kCVReturnSuccess;
//}
//- (BOOL) wantsLayer {
// return YES;
//}
//
//- (BOOL) wantsUpdateLayer {
// return YES;
//}
//
//- (void) displayLayer:(CALayer *)layer {
// //id<MTLCommandBuffer> cmdBuffer = [_commandQueue commandBuffer];
// //id<CAMetalDrawable> drawable = [((CAMetalLayer *) layer) nextDrawable];
//
// //[cmdBuffer enqueue];
// //[cmdBuffer presentDrawable:drawable];
//
// // rendering
// [self redraw];
//
// //[cmdBuffer commit];
//}
//- (void)panGestureWasRecognized:(UIPanGestureRecognizer *)sender
//{
// CGPoint translation = self.renderer.textTranslation;
// CGPoint deltaTranslation = [sender translationInView:self.view];
// self.renderer.textTranslation = CGPointMake(translation.x + deltaTranslation.x, translation.y + deltaTranslation.y);
// [sender setTranslation:CGPointZero inView:self.view];
//}
//
//- (void)pinchGestureWasRecognized:(UIPinchGestureRecognizer *)sender
//{
// CGFloat targetScale = self.renderer.textScale * sender.scale;
// targetScale = fmax(0.5, fmin(targetScale, 5)); // RG: 15 bepaalt max zoom
// self.renderer.textScale = targetScale;
// sender.scale = 1;
//}
//
//- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
//{
// return YES;
//}
@end