2011-12-19 110 views
4

所以即時嘗試創建一個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視圖。我會猜測它關於方法被調用的層次結構,但之後再次..我不知道。你可以幫助我嗎?

回答

7

他們的方式我已經得到這個工作是我沒有實現我認爲的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

2

雖然上述問題的答案提供了有關OpenGL的詳細信息,您遇到的具體問題的原因是開始那你initWithFrame方法需要返回自我

沒有這個initWithFrame將始終返回零。 (你也應該調用super的initWithFrame並採取其他的OpenGL建議)。

相關問題