将OpenGL上下文添加到Cocoa窗口

时间:2014-12-27 12:47:10

标签: opengl swift glkit openglcontext

我试图将一个OpenGL上下文添加到NSWindow,但由于某种原因它无法正常工作。 它在我运行应用程序时正确创建并显示NSWindow,但我无法对OpenGL上下文做任何事情,所以我认为上下文没有正确添加到NSWindow。

到目前为止,这是我的代码:

import Foundation
import AppKit
import GLKit

let application = NSApplication.sharedApplication()

application.setActivationPolicy(NSApplicationActivationPolicy.Regular)

let window = NSWindow(contentRect: NSMakeRect(0, 0, 640, 480), styleMask: NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask, backing: .Buffered, defer: false)

window.center()
window.title = "Programmatically Created Window"

window.makeKeyAndOrderFront(window)

class WindowDelegate: NSObject, NSWindowDelegate {
    func windowWillClose(notification: NSNotification) {
        NSApplication.sharedApplication().terminate(0)
    }
}

let windowDelegate = WindowDelegate()
window.delegate = windowDelegate

class AppDelegate: NSObject, NSApplicationDelegate {
    var window: NSWindow

    init(window: NSWindow) {
        self.window = window
    }

    func applicationDidFinishLaunching(notification: NSNotification) {
        let glContext = NSOpenGLView()

        self.window.contentView.addSubview(glContext)

//      let glAttributes: [NSOpenGLPixelFormatAttribute] = [
//          UInt32(NSOpenGLPFAAccelerated),
//          UInt32(NSOpenGLPFADoubleBuffer),
//          UInt32(NSOpenGLPFAColorSize), UInt32(48),
//          UInt32(NSOpenGLPFAAlphaSize), UInt32(16),
//          UInt32(NSOpenGLPFAMultisample),
//          UInt32(NSOpenGLPFASampleBuffers), UInt32(1),
//          UInt32(NSOpenGLPFASamples), UInt32(4),
//          UInt32(NSOpenGLPFAMinimumPolicy),
//          UInt32(0)
//      ]
//      
//      let pixelFormat = NSOpenGLPixelFormat(attributes: glAttributes)
//      let glContext = NSOpenGLContext(format: pixelFormat, shareContext: nil)

//      self.window.contentView.addSubview(glContext!.view)

//      glContext!.view = self.window.contentView as NSView
    }
}

let applicationDelegate = AppDelegate(window: window)

application.delegate = applicationDelegate
application.activateIgnoringOtherApps(true)
application.run()

glClearColor(0, 0, 0, 0)

1 个答案:

答案 0 :(得分:0)

只是为了说明我的评论,这里有一些代码。这个OpenGLView由IB初始化,所以有一个awakeFromNib方法,但你会得到这个想法:

#import "WispView.h"
#import "AppController.h"

@implementation WispView

// *************************** Init **************************************

- (id)initWithFrame:(NSRect)frameRect
{
    self = [super initWithFrame:frameRect];

    return self;
}

// *********************** Awake From Nib *********************************

- (void)awakeFromNib;
{
    // *********** Invoke OpenGL 4.1 and GLSL 4.1
    // ********* Default is OpenGL 2.1 and GLSL 1.2

    NSOpenGLPixelFormatAttribute attributes [] =
    {
        NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
        NSOpenGLPFADoubleBuffer,    // double buffered
        NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)32, // 32 bit depth buffer
        NSOpenGLPFAAccelerated,
        (NSOpenGLPixelFormatAttribute)nil
    };

    NSOpenGLPixelFormat * pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
    [self setPixelFormat:pf];

    tempFractalIsDisplayed = NO;
    workingFractalIsDisplayed = NO;
    gridIsDisplayed = NO;
    attractorIsDisplayed = NO;

    return;
}

// ******************** Init OpenGL Stuff Here **********************************

- (void) prepareOpenGL
{
    [[self openGLContext] makeCurrentContext];

    // *********** Log the Current OpenGL and GLSL Versions

    NSLog(@"OpenGL version = %s", glGetString(GL_VERSION));
    NSLog(@"GLSL version = %s", glGetString(GL_SHADING_LANGUAGE_VERSION));

    //********************* General OpenGL Stuff

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // ** Set Background Clear Color

    glEnable(GL_DEPTH_TEST); // Hide hidden surfaces
    glDepthFunc(GL_LEQUAL);
    glClearDepth(1.0);

    glEnable(GL_TEXTURE_2D);

    glFrontFace(GL_CCW);

    return;
}

// *************************** Draw Rect **********************************

- (void)drawRect:(NSRect)dirtyRect
{
    [[self openGLContext] makeCurrentContext];

    // ******************************************** Clear the Drawable

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if(tempFractalIsDisplayed)
    {
        [appController->flameFractals runTheFlameShadersWithColoringData:&appDelegate->tempColoringData];
    }

    if(workingFractalIsDisplayed)
    {
        [appController->flameFractals runTheFlameShadersWithColoringData:&appDelegate->workingColoringData];
    }

    if(gridIsDisplayed)
    {
        [appController->flameFractals runTheGridShaders];
    }

    if(attractorIsDisplayed)
    {
        [appController->flameFractals runTheFlameShadersWithColoringData:&appController->lyapunov->attractorColoringData];
    }

    [[self openGLContext] flushBuffer];

    return;
}

您不需要在NSOpenGLClass内完成所有绘图。其他类也可以使用它的上下文绘制,但是你确实需要在drawRect方法中至少使用某种绘图更新代码,因为在调整大小期间会调用此方法。

在这个drawRect方法中,图像实际上是在其他类中绘制的。此代码仅在调整大小或转换为全屏时由系统调用。