【问题标题】:Adding an OpenGL Context to Cocoa Window将 OpenGL 上下文添加到 Cocoa 窗口
【发布时间】:2014-12-27 12:47:10
【问题描述】:

我正在尝试将 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)

【问题讨论】:

  • 我没有看到您创建 NSOpenGLView 的任何地方。在某个地方,您应该有一个子类 NSOpenGLView 的类,您可以在其中进行初始化(-(id)initWithFrame:(NSRect)frameRect)和准备(-(void)prepareOpenGL)。 NSOpenGLView 也有一个 initWithFrame:pixelFormat:initializer。应该将 OpenGLView 添加为子视图。

标签: opengl swift glkit openglcontext


【解决方案1】:

为了说明我的评论,这里有一些代码。这个 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方法中,图像实际上是在其他类中绘制的。此代码仅在调整大小或切换到全屏期间被系统调用。

【讨论】:

    猜你喜欢
    • 2011-04-19
    • 1970-01-01
    • 2020-05-16
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多