【问题标题】:Creating an OpenGL View without Interface Builder在没有 Interface Builder 的情况下创建 OpenGL 视图
【发布时间】:2012-06-19 12:38:30
【问题描述】:

所以我试图创建一个 openGL 视图(在我的窗口中)。我正在制作一个 Cocoa 应用程序。 我设法通过 Interface Builder 创建了一个,但出于教育目的,我想继续制作一个没有它的。只是在纸上。

这就是我告诉你我正在努力解决的问题。 所以到目前为止,我基本上已经尝试过的是: 我创建了一个继承自 NSOpenGLView 的新类“MyOpenGLView.h/m”。 我没有添加任何私有变量或方法,只是类名。我唯一做的就是覆盖 initWithFrame: (在其中添加一个 self = [super initWithFrame:pixelFormat:] 。) 我在网上读到它,你必须先用类似的东西实例化它,然后才能使用它)。这是代码:

- (id) initWithFrame:(NSRect)frameRect
{
 NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc]
                                    initWithAttributes:(NSOpenGLPixelFormatAttribute[])
                                    {
                                    NSOpenGLPFAWindow,
                                    NSOpenGLPFADoubleBuffer,
                                    NSOpenGLPFADepthSize, 32,
                                    nil
                                    }];
 self = [super initWithFrame:frameRect pixelFormat:pixelFormat];
 [[self openGLContext] makeCurrentContext];
}

所以我有另一个名为“MyViewController.h/m”的类来处理我的视图? 我有我的 MyOpenGLView *myView。 在 .m 文件中,我使用如下内容:

myView = [[MyOpenGLView alloc] initWithFrame:CGRectMake(0,0,100.0,100.0)];
if (!myView) { NSLog(@"ERROR"); }

当然,我得到了错误。

我的窗口应用程序中没有移植 openGL 视图。我猜想它与被调用方法的层次结构有关,但又一次……我不确定。你能帮帮我吗?

【问题讨论】:

    标签: objective-c macos cocoa opengl nsopenglview


    【解决方案1】:

    我让这个工作的方式是在我看来我没有实现init 方法。然后在我的控制器或应用程序委托中。

    @implementation AppDelegate
    
    @synthesize window = _window;
    @synthesize view = _view;
    
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
        NSRect mainDisplayRect = [[NSScreen mainScreen] frame]; // I'm going to make a full screen view.
    
        NSOpenGLPixelFormatAttribute attr[] = {
            NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, // Needed if using opengl 3.2 you can comment this line out to use the old version.
            NSOpenGLPFAColorSize,     24,
            NSOpenGLPFAAlphaSize,     8,
            NSOpenGLPFAAccelerated,
            NSOpenGLPFADoubleBuffer,
            0
        };
    
        NSOpenGLPixelFormat *pix = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
        self.view = [[OpenGLViewCoreProfile alloc] initWithFrame:mainDisplayRect pixelFormat:pix];
    
        // Below shows how to make the view fullscreen. But you could just add to the contact view of any window.
        self.window = [[NSWindow alloc] initWithContentRect:mainDisplayRect
                                                  styleMask:NSBorderlessWindowMask 
                                                    backing:NSBackingStoreBuffered 
                                                      defer:YES];
    
        self.window.opaque = YES;
        self.window.hidesOnDeactivate = YES;
        self.window.level = NSMainMenuWindowLevel + 1; // Show window above main menu.
        self.window.contentView = self.view;
        [self.window makeKeyAndOrderFront:self]; // Display window.
    }
    
    @end
    

    可以在您的-prepareOpenGl 方法中拨打-makeCurrentContext。我在下面写的所有内容都不是必需的,但出于性能原因很好。我已经开始使用CVDisplayLink 将帧绘制与屏幕刷新率同步,所以我的 openGLview 看起来像

    // This is the callback function for the display link.
    static CVReturn OpenGLViewCoreProfileCallBack(CVDisplayLinkRef displayLink,
                                                  const CVTimeStamp* now, 
                                                  const CVTimeStamp* outputTime, 
                                                  CVOptionFlags flagsIn, 
                              CVOptionFlags *flagsOut, 
                                                  void *displayLinkContext) {
        @autoreleasepool {
            OpenGLViewCoreProfile *view = (__bridge OpenGLViewCoreProfile*)displayLinkContext;
            [view.openGLContext makeCurrentContext];
            CGLLockContext(view.openGLContext.CGLContextObj); // This is needed because this isn't running on the main thread.
            [view drawRect:view.bounds]; // Draw the scene. This doesn't need to be in the drawRect method.
            CGLUnlockContext(view.openGLContext.CGLContextObj);
            CGLFlushDrawable(view.openGLContext.CGLContextObj); // This does glFlush() for you.
    
            return kCVReturnSuccess;
        }
    }
    
    - (void)reshape {
        [super reshape];
        CGLLockContext(self.openGLContext.CGLContextObj);
    
        ... // standard opengl reshape stuff goes here.
    
        CGLUnlockContext(self.openGLContext.CGLContextObj);
    }
    
    - (void)prepareOpenGL {
        [super prepareOpenGL];
    
        [self.openGLContext makeCurrentContext];
        GLint swapInt = 1;
        [self.openGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
    
        CGLLockContext(self.openGLContext.CGLContextObj);
    
        ... // all opengl prep goes here
    
        CGLUnlockContext(self.openGLContext.CGLContextObj);
    
        // Below creates the display link and tell it what function to call when it needs to draw a frame.
        CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
        CVDisplayLinkSetOutputCallback(self.displayLink, &OpenGLViewCoreProfileCallBack, (__bridge void *)self);
        CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(self.displayLink, 
                                                          self.openGLContext.CGLContextObj, 
                                                          self.pixelFormat.CGLPixelFormatObj);
        CVDisplayLinkStart(self.displayLink);
    }
    

    【讨论】:

    • self.view = [[OpenGLViewCoreProfile alloc] initWithFrame:mainDisplayRect pixelFormat:pix]; - 你不是在这里初始化视图吗?
    • 是的。但是我还没有编写自己的initWithFrame:pixelFormat: 方法。我依赖从 NSOpenGLView 继承的方法。
    【解决方案2】:

    虽然上面的答案提供了有关 OpenGL 的更多信息,但您遇到特定问题的原因是您的 initWithFrame 方法需要返回 self

    没有那个 initWithFrame 将总是返回 Nil。 (您还应该调用 super 的 initWithFrame 并接受其他 OpenGL 建议)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-11
      • 1970-01-01
      • 2015-01-24
      • 2011-12-27
      相关资源
      最近更新 更多