gpt4 book ai didi

cocoa - NSOpenGLView 和 CVDisplayLink,无默认帧缓冲区

转载 作者:行者123 更新时间:2023-12-03 17:12:17 46 4
gpt4 key购买 nike

我有一个 NSOpenGLView 和 OpenGL 代码,可与在主循环中运行的 NSTimer 一起使用(调用 setNeedsDisplay 和 drawRect)。我想使用 CVDisplayLink,这样我就可以获得更好的帧速率,而不会过度驱动计时器。我从苹果的 OSXGLEssentials 示例中复制了大部分代码。显示链接启动并且回调运行,但屏幕上实际上没有绘制任何内容。 glGetError 返回 GL_INVALID_FRAMEBUFFER_OPERATION。

glCheckFramebufferStatus 对于 GL_FRAMEBUFFER、GL_DRAW_FRAMEBUFFER 和 GL_READ_FRAMEBUFFER 返回 GL_FRAMEBUFFER_UNDEFINED。

文档中的信息:

GL_FRAMEBUFFER_UNDEFINED is returned if target is the default framebuffer, but the default framebuffer does not exist.

以下是相关代码:

- (void)awakeFromNib {

NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, // Core Profile !
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFAAllowOfflineRenderers,
0
};

NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:format shareContext: nil];
// [context setView: self];
[self setPixelFormat: format];
[self setOpenGLContext: context];

}


- (void)prepareOpenGL {

[super prepareOpenGL];

NSOpenGLContext* context = [self openGLContext];
[context makeCurrentContext];

// Synchronize buffer swaps with vertical refresh rate
GLint swapInt = 1;
[context setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];

MyDisplay_setup();
MyDisplay_initScene(_bounds.size.width, _bounds.size.height);

CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
CVDisplayLinkSetOutputCallback(displayLink, &displayLinkCallback, (__bridge void *)self);
CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [context CGLContextObj], cglPixelFormat);
CVDisplayLinkStart(displayLink);

}


static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime,
CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) {

@autoreleasepool {
[(__bridge MyView*)displayLinkContext redraw];
}
return kCVReturnSuccess;

}


- (void)redraw {

NSOpenGLContext* context = [self openGLContext];
[context makeCurrentContext];
CGLLockContext([context CGLContextObj]);
MyDisplay_drawScene();
CGLFlushDrawable([context CGLContextObj]);
CGLUnlockContext([context CGLContextObj]);

}

最佳答案

这是一个老问题,但这个问题仍然存在,所以这是我的答案。作为引用,我根本不使用 Xcode,我在 Vim 中编写代码并使用 Clang 进行编译,所以这是默认行为,与 IB 无关。我仅使用 NSOpenGLView、NSOpenGLContext 和 CGDisplayLink 进行渲染。我有一台运行 macOS Sierra 的 MacBook Pro(视网膜屏,15 英寸,2014 年中)。

在调试时,我发现 NSOpenGLContext 的 view 属性在启动显示链接后的前几帧返回 nil。如果您在未附加 View 时进行任何渲染(glClear 除外),这足以破坏上下文,并导致相同的 GL_FRAMEBUFFER_UNDEFINED 错误。

我发现解决这个问题的最简单方法是在创建后将 NSOpenGLView 分配给它的 NSOpenGLContext,如下所示:

NSOpenGLView *view = ...;

view.openglContext.view = view;

我很困惑,显然,即使 NSOpenGLContext 是由 NSOpenGLView 创建的,也有必要这样做,但事实就是如此。

关于cocoa - NSOpenGLView 和 CVDisplayLink,无默认帧缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20083027/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com