所以我试图创建一个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”的类来处理我的View? 我有我的MyOpenGLView * myView。 在.m文件中,我使用以下内容:
myView = [[MyOpenGLView alloc] initWithFrame:CGRectMake(0,0,100.0,100.0)];
if (!myView) { NSLog(@"ERROR"); }
当然,我得到错误。
我的窗口应用程序中没有移植的openGL视图。我猜它有关于被调用的方法的层次结构,但后来再次..我不确定。你可以帮我吗?
答案 0 :(得分: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
可以在-makeCurrentContext
方法中拨打电话-prepareOpenGl
。我在下面写的所有内容都没有必要,但出于性能原因很好。我已经开始使用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);
}
答案 1 :(得分:2)
虽然上面的答案提供了有关OpenGL的更多信息,但您遇到的具体问题的原因是您的 initWithFrame方法需要返回自我。
如果没有,initWithFrame将始终返回Nil。 (您还应该调用super的initWithFrame并采用其他OpenGL建议。)