创建没有Interface Builder的OpenGL视图 [英] Creating an OpenGL View without Interface Builder
问题描述
所以我想创建一个openGL视图(在我的窗口)。我做一个Cocoa应用程序。
我设法通过Interface Builder创建一个,但是为了教育的目的,我想继续做一个没有它。只要在论文上。
So im trying to create an openGL view (in my window). Im making a Cocoa app. Ive managed to create one through Interface Builder, but for educational purposes i want to go on and make one without it. Just on papers.
这里是点子,告诉你在努力。
所以基本上做的事情是这样的:
我创建了一个新类MyOpenGLView.h / m继承自NSOpenGLView。
我没有添加私人变量或方法,它只是类名。我做的唯一的事情,是覆盖initWithFrame :(在它里面添加一个self = [super initWithFrame:pixelFormat:]。)
我在Web上读到它,你必须实例化这样的第一次之前可以使用它)。这里是代码:
And here is the point im telling you im struggling with it. So what ive basically done-tried so far is this: I ve created a new class "MyOpenGLView.h/m" inheriting from NSOpenGLView. I ve added no private vars or methods to it just the class name. The only thing i did, was override initWithFrame: (adding a self = [super initWithFrame:pixelFormat:] inside it.) I read about it on the Web that you have to instantiate it with something like this first before you can use it). here is the code:
- (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文件中我使用这样的:
So i have another class named by "MyViewController.h/m" which handles my View? and there i have my MyOpenGLView *myView. In the .m file i go with something like this:
myView = [[MyOpenGLView alloc] initWithFrame:CGRectMake(0,0,100.0,100.0)];
if (!myView) { NSLog(@"ERROR"); }
当然,我得到错误。
在我的窗口应用程序中没有移植任何openGL视图。我会猜测它关于方法被调用的层次结构,但然后再次..我不知道。你能帮助我吗?
There is no openGL view ported in my window application. I would guess its something about the hierarchy on methods being called but then again.. im not sure. Can you aid me with it?
推荐答案
他们的方式我得到这个工作是我不实现 init
方法。然后在我的控制器或应用程式委托中。
They way I have gotten this to work is I don't implement an init
method in my view. Then in my controller or app delegate I have.
@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
方法中使用c $ c> -makeCurrentContext 。所有我下面写的是没有必要的,但很好的性能原因。我已经开始使用 CVDisplayLink
与屏幕刷新率同步框架图,所以我的openGLview看起来像
Can can make call -makeCurrentContext
in your -prepareOpenGl
method. All that I have written below is not necessary but nice for performance reasons. I have started using the CVDisplayLink
to sync frame drawing with the screen refresh rate so my openGLview looks like
// 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);
}
这篇关于创建没有Interface Builder的OpenGL视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!