CARenderer从不产生输出
我一直坚持了几个小时,试图使用CARenderer将Core Animation图层树渲染到OpenGL上下文中。 OpenGL上下文当前由Interface Builder中设置的NSOpenGLView子类提供,并且具有默认设置。CARenderer从不产生输出
以下是我在我的例子建立CALayers:
l1 = [[CALayer layer] retain]; // l1 is an instance variable
l1.bounds = CGRectMake(0, 0, 100, 100);
l1.backgroundColor = CGColorCreateGenericRGB(1, 1, 0, 1);
CALayer* l2 = [CALayer layer];
l2.bounds = CGRectMake(0, 0, 20, 20);
l2.backgroundColor = CGColorCreateGenericRGB(1, 0, 0, 1);
l2.position = CGPointMake(50, 50);
[l1 addSublayer:l2];
如果我添加这些有规律的NSView,他们出现就好了。
下面是从我NSOpenGLView子类中的绘图代码:
- (void) drawRect:(NSRect)dirtyRect
{
NSRect frame = [self frame];
// set up context according to CARenderer.h instructions
glViewport(0, 0, frame.size.width, frame.size.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, frame.size.width, 0, frame.size.height, -1, 1);
glClearColor(0, 0, 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已经连接到另一个上下文,它将会尽职尽责)。没有可见的输出。
我试过的其他东西:在CATransaction中包装CARenderer代码,摆弄界面生成器中的NSOpenGLView设置选项,将整个事件渲染为手动创建的OpenGL上下文,并将其保存到图像文件中...所有相同的效果:原生OpenGL命令显示正常,CARenderer不显示任何内容。
我怀疑我的OpenGL上下文设置的方式有问题,或者我甚至可能以某种方式在我的视口之外渲染......可能是一些非常愚蠢的小细节。不幸的是,Web上CARenderer的文档和示例代码都有些稀疏,虽然我对Core Animation有相当的经验,但我的OpenGL知识却是有限的。
所以现在,我很难过,完全没有想法,所以任何指针都非常感谢!
干杯
哦哇。所以如果有人有兴趣,我同时得到了这个“大多数工作”。下面是相关的代码:
- (void) drawRect:(NSRect)dirtyRect
{
NSRect viewBounds = [self bounds];
// set up context according to CARenderer.h instructions
glViewport(0, 0, viewBounds.size.width, viewBounds.size.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, viewBounds.size.width, 0, viewBounds.size.height, -1, 1);
glClearColor(0, 0, 0, 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, 0, 100, 100);
l.backgroundColor = CGColorCreateGenericRGB(1, 1, 0, 1);
renderer.layer = l;
renderer.bounds = l.bounds;
[CATransaction commit];
}
注意周围的层/渲染器生成的代码CATransaction
块。如果没有这个,那么图层根本就不会显示(就像我最初的问题),或者只是在稍微延迟之后才呈现,即经过一段时间后重新绘制视图。至于为什么这是必要的我还不确定,如果有人能够在这一点上给我启发,我会非常高兴。
很明显,这个解决方案可能仍然存在问题,但我决定在这里暂时考虑缺乏CARenderer
的示例代码。
编辑:正如我后来发现的,一个非常明显的错误与上述解决方案是0.0
传递给beginFrameAtTime
方法调用;相反,这应该是CACurrentMediaTime
的值。这将消除对CATransaction
块的需求,同时纠正一些其他错误。就像任何人可能偶然发现这个答案一样。
感谢您发布此信息。在prepareOpenGL方法之后,似乎有助于让CALayer拥有一个非零表示层,而不会实际显示(我试图使用CAKeyFrameanimation来冒险计算沿着CGPath的点) – 2015-08-05 04:26:09