【问题标题】:Apple Metal without Interface Builder没有界面生成器的 Apple Metal
【发布时间】:2016-12-24 23:43:52
【问题描述】:

我正在为此绞尽脑汁。我一直在尝试复制 Apple 提供的初始 metal 项目,但根本不使用 interface builder。我可以创建一个窗口,但它是空白的,没有渲染任何内容,我不知道为什么。

main.m

#import <Cocoa/Cocoa.h>
#import "AppDelegate.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSApplication* app = [NSApplication sharedApplication];
        AppDelegate* appDelegate = [[AppDelegate alloc] init];

        [app setDelegate:appDelegate];

        [app run];
    }

    return EXIT_SUCCESS;
}

AppDelegate.h

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate> {
    NSWindow *window;
}

@end

AppDelegate.m

#import <Metal/Metal.h>

#import "AppDelegate.h"

#import "GameViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (id)init {
    if (self = [super init]) {
        NSScreen* mainScreen = [NSScreen mainScreen];

        NSRect frame = NSMakeRect(0, 0, mainScreen.frame.size.width / 2, mainScreen.frame.size.height / 2);

        NSUInteger styleMask =
            NSWindowStyleMaskTitled |
            NSWindowStyleMaskResizable |
            NSWindowStyleMaskClosable |
            NSWindowStyleMaskMiniaturizable;

        NSBackingStoreType backing = NSBackingStoreBuffered;


        window = [[NSWindow alloc] initWithContentRect:frame styleMask:styleMask backing:backing defer:YES];
        [window center];


        GameViewController* gvc = [[GameViewController alloc] init];

        MTKView* metalView = [[MTKView alloc] initWithFrame:frame device:MTLCreateSystemDefaultDevice()];

        [metalView setClearColor:MTLClearColorMake(0, 0, 0, 1)];
        [metalView setColorPixelFormat:MTLPixelFormatBGRA8Unorm];
        [metalView setDepthStencilPixelFormat:MTLPixelFormatDepth32Float];
        [metalView setDelegate:gvc];

        [gvc setView:metalView];

        [window setContentView:metalView];
        //[window setContentViewController: gvc];

    }
    return self;
}

- (void)applicationWillFinishLaunching:(NSNotification *)notification {
    [window makeKeyAndOrderFront:self];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
}

- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
}

- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
    return YES;
}

@end

其他文件; GameViewController.hGameViewController.mShaders.metalSharedStructures.h;与 XCode 8.2.1 (8C1002) 在您创建使用 Metal 和 Objective-c 的游戏项目时自动生成的相同。

您会注意到[window setContentViewController: gvc]; 行已被注释掉。当取消注释时,我在GameViewController.m 的渲染函数dispatch_semaphore_wait(_inflight_semaphore, DISPATCH_TIME_FOREVER); 的第一行得到一个EXEC_BAD_ACCESS

很明显,我遗漏了一些东西,但我整天都在谷歌上搜索,但我似乎无法弄清楚。非常感谢任何帮助。

【问题讨论】:

    标签: objective-c xcode macos metal programmatically


    【解决方案1】:

    问题在于,当 NSViewController (例如 GameViewController)未从 NIB 加载时,它不会调用 -viewDidLoad 方法。 GameViewController 在该方法中做了重要的工作。

    您可以将视图的创建移动到 -loadView 的覆盖 GameViewController 中。创建视图并将其分配给self.view。你不需要设置它的委托。现有的GameViewController 代码已经这样做了。设置视图的属性应移至-_setupView,现有代码已经在其中执行此类操作。

    不要在-[AppDelegate init] 中创建视图。显然,您也不能在那里设置视图控制器的视图。只需将视图控制器设置为窗口的内容视图控制器(取消注释该行),其余部分将自动处理。当窗口请求内容视图控制器的view 属性时,它将调用您对-loadView 的覆盖以及现有的-viewDidLoad 等。

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 2016-02-17
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      相关资源
      最近更新 更多