【发布时间】:2014-02-19 07:02:28
【问题描述】:
我有一个上下文消失的问题。我有一个简单的 NSOpenGLView 子类。我在 initWithFrame 中定义了像素格式,然后验证我有一个有效的上下文。我在 awakeFromNib 中做了一些额外的 gl 设置,并验证我仍然有一个有效的上下文。我使用 DisplayLink 进行主渲染。在显示链接回调中,[self openGLContext] 返回 nil。在调试器中,我可以看到 _openGLContext 实例变量仍然有效 - 但访问器返回 nil。我错过了什么?
-----编辑:包含代码------------
MyGLView.h
@interface MyGLView : NSOpenGLView
- (void)displayLinkDraw;
@end
MyGLView.m
- (id)initWithFrame:(NSRect)frameRect
{
NSOpenGLPixelFormat *windowedPixelFormat;
NSOpenGLPixelFormatAttribute attribs[] = {
NSOpenGLPFAWindow,
NSOpenGLPFAColorSize, 32,
NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFASingleRenderer,
0 };
windowedPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
self = [super initWithFrame:frameRect pixelFormat:windowedPixelFormat];
// set synch to VBL to eliminate tearing
GLint vblSynch = 1;
[[self openGLContext] setValues:&vblSynch forParameter:NSOpenGLCPSwapInterval];
NSOpenGLContext* context = self.openGLContext;
// *** self.openGLContext returns valid context here. ***
return self;
}
- (void)awakeFromNib
{
NSOpenGLContext* context = self.openGLContext;
// *** self.openGLContext returns valid context here. ***
[self.openGLContext makeCurrentContext];
glDisable(GL_DEPTH_TEST);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(ATTRIB_TEXCOORD);
glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
glGenFramebuffers(1, &_frameBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferID);
glGenRenderbuffers(1, &_colorBufferID);
glBindRenderbuffer(GL_RENDERBUFFER, _colorBufferID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, self.frame.size.width, self.frame.size.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorBufferID);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
- (void)displayLinkDraw
{
NSOpenGLContext* context = self.openGLContext;
// *** self.openGLContext returns nil here??? ***
[context makeCurrentContext];
CGLLockContext([context CGLContextObj]);
glClearColor(0.9f, 0.9f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// ...
[context flushBuffer];
CGLUnlockContext([context CGLContextObj]);
}
MyViewController.m
static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext)
{
MyViewController* self = (__bridge MyViewController *)displayLinkContext;
MyGLView* glView = self->_myGLView;
[glView displayLinkDraw];
return kCVReturnSuccess;
}
【问题讨论】:
-
请阅读“如何提问”部分并发布您的代码。
-
它发现了一些链接,听起来像是 NSOpenGLView 上下文是线程特定的。由于 DisplayLink 肯定在不同的线程上,因此共享上下文是否可以解决这个问题?还是应该在第一个 DisplayLink 回调中进行初始化?