在没有Interface Builder的情况下创建一个OpenGL视图

问题描述:

所以即时尝试创建一个openGL视图(在我的窗口中)。我正在制作一个可可应用程序。 我设法通过界面生成器创建一个,但为了教育目的,我想继续,没有它。只是在纸上。在没有Interface Builder的情况下创建一个OpenGL视图

这里是要告诉你我正在努力的一点。 所以基本上做了什么 - 到目前为止尝试的是这样的: 我创建了一个从NSOpenGLView继承的新类“MyOpenGLView.h/m”。 我没有添加私人变数或方法,只是类名。我做的唯一的事情就是覆盖initWithFrame:(在它内部添加一个self = [super initWithFrame:pixelFormat:]。) 我在Web上阅读了它,必须先使用类似这样的东西实例化它,然后才能使用它)。这里是代码:

- (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视图。我会猜测它关于方法被调用的层次结构,但之后再次..我不知道。你可以帮助我吗?

他们的方式我已经得到这个工作是我没有实现我认为的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); 
} 
+0

self.view = [[OpenGLViewCoreProfile alloc] initWithFrame:mainDisplayRect pixelFormat:pix]; - 你不是在这里启动视图吗? – Bisder 2012-01-25 09:23:50

+0

是的。但是我没有写我自己的'initWithFrame:pixelFormat:'方法。我依靠从NSOpenGLView继承的方法。 – user1139069 2012-01-26 01:35:11

虽然上述问题的答案提供了有关OpenGL的详细信息,您遇到的具体问题的原因是开始那你initWithFrame方法需要返回自我

没有这个initWithFrame将始终返回零。 (你也应该调用super的initWithFrame并采取其他的OpenGL建议)。