在没有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);
}
虽然上述问题的答案提供了有关OpenGL的详细信息,您遇到的具体问题的原因是开始那你initWithFrame方法需要返回自我。
没有这个initWithFrame将始终返回零。 (你也应该调用super的initWithFrame并采取其他的OpenGL建议)。
self.view = [[OpenGLViewCoreProfile alloc] initWithFrame:mainDisplayRect pixelFormat:pix]; - 你不是在这里启动视图吗? – Bisder 2012-01-25 09:23:50
是的。但是我没有写我自己的'initWithFrame:pixelFormat:'方法。我依靠从NSOpenGLView继承的方法。 – user1139069 2012-01-26 01:35:11