以下是我在示例中设置CALayers的方法:
l1 = [[CALayer layer] retain]; // l1 is an instance variable l1.bounds = CGRectMake(0,100,100); l1.backgroundColor = CGColorCreateGenericRGB(1,1,1); CALayer* l2 = [CALayer layer]; l2.bounds = CGRectMake(0,20,20); l2.backgroundColor = CGColorCreateGenericRGB(1,1); l2.position = CGPointMake(50,50); [l1 addSublayer:l2];
这是我的NSOpenGLView子类的绘图代码:
- (void) drawRect:(NSRect)dirtyRect { NSRect frame = [self frame]; // set up context according to CARenderer.h instructions glViewport(0,frame.size.width,frame.size.height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,frame.size.height,-1,1); glClearColor(0,0); glClear(GL_COLOR_BUFFER_BIT); if (l1) { CARenderer* renderer = [CARenderer rendererWithCGLContext:[[self openGLContext] CGLContextObj] options:nil]; renderer.layer = l1; renderer.bounds = NSRectToCGRect(frame); [renderer beginFrameAtTime:0.0 timeStamp:NULL]; [renderer addUpdateRect:renderer.bounds]; [renderer render]; [renderer endFrame]; } glFlush(); }
我确认在创建图层后重新绘制了视图,并且视图本身似乎工作正常 – 我正确发布的OpenGL命令. CARenderer确实活跃了(实际上,如果在此代码运行时l1已经附加到另一个上下文,它将尽职尽责地抱怨).从来没有可见的输出.
我尝试过的其他事情:将CARenderer代码包装在CATransaction中,摆弄Interface Builder中的NSOpenGLView设置选项,将整个事件渲染到手动创建的OpenGL上下文屏幕并将其保存到图像文件中……所有这些都是相同的效果:原生OpenGL命令显示正常,CARenderer没有显示任何内容.
我怀疑我的OpenGL上下文的设置方式有问题,或者我甚至可能以某种方式在我的视口之外渲染……可能是一些非常愚蠢的细节.不幸的是,CARenderer在网络上的文档和示例代码都有些稀疏,虽然我对Core Animation很有经验,但我的OpenGL知识显然有限.
所以现在,我非常难过,完全没有想法,所以任何指针都非常感谢!
干杯
解决方法
- (void) drawRect:(NSRect)dirtyRect { NSRect viewBounds = [self bounds]; // set up context according to CARenderer.h instructions glViewport(0,viewBounds.size.width,viewBounds.size.height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,viewBounds.size.height,0); glClear(GL_COLOR_BUFFER_BIT); [renderer beginFrameAtTime:0.0 timeStamp:NULL]; [renderer addUpdateRect:renderer.bounds]; [renderer render]; [renderer endFrame]; glFlush(); } - (void) prepareOpenGL { renderer = [[CARenderer rendererWithCGLContext:[[self openGLContext] CGLContextObj] options:nil] retain]; [CATransaction begin]; CALayer* l = [CALayer layer]; l.bounds = CGRectMake(0,100); l.backgroundColor = CGColorCreateGenericRGB(1,1); renderer.layer = l; renderer.bounds = l.bounds; [CATransaction commit]; }
请注意图层/渲染器创建代码周围的CATransaction块.如果没有这个,该层将根本不显示(就像我最初的问题一样),或者仅在稍微延迟之后呈现,即,在经过一段时间后重新绘制视图时.至于为什么这是必要的,我仍然不确定,如果有人能在这一点上启发我,我会非常高兴.
显然这个解决方案可能仍然有点错误,但我决定暂时将其留在这里考虑缺少CARenderer的示例代码.
编辑:正如我后来发现的,上面解决方案的一个非常明显的错误是将0.0传递给beginFrameAtTime方法调用;相反,这应该是来自CACurrentMediaTime的值.这将消除对CATransaction块的需求,同时纠正一些其他错误.对于任何可能偶然发现这个答案的人来说都是一个单挑.