ig2*_*g2r 5 opengl macos cocoa core-animation
试图使用CARenderer将Core Animation图层树渲染到OpenGL上下文中,我已经呆了几个小时。OpenGL上下文当前由Interface Builder中设置的NSOpenGLView子类提供,默认设置为。
这是我在示例中设置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];
Run Code Online (Sandbox Code Playgroud)
如果我将它们添加到常规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();
}
Run Code Online (Sandbox Code Playgroud)
我验证了在创建图层后是否重新绘制了视图,并且视图本身似乎可以正常工作-我发出的OpenGL命令可以正确显示。CARenderer确实可以运行(实际上,如果在运行此代码时l1已经附加到另一个上下文,它将忠实地抱怨)。从来没有可见的输出。
我尝试过的其他方法:将CARenderer代码包装在CATransaction中,摆弄Interface Builder中的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];
}
Run Code Online (Sandbox Code Playgroud)
注意CATransaction图层/渲染器创建代码周围的块。没有这个,图层将根本不显示(这是我最初的问题),或者仅在稍有延迟之后才渲染,即,经过一段时间后重新绘制视图时。至于为什么必须这样做,我仍不确定,如果有人能对此有所启发,我会感到非常高兴。
显然,此解决方案可能仍然存在某种错误,但是考虑到缺少示例代码,我决定暂时将其留在此处CARenderer。
编辑:正如我后来发现的那样,上述解决方案的一个相当非显而易见的错误是将0.0其传递给beginFrameAtTime方法调用;相反,这应该是中的值CACurrentMediaTime。这将消除对CATransaction块的需求,并在此过程中纠正其他一些错误。就像对任何可能偶然发现此答案的人的提醒。
| 归档时间: |
|
| 查看次数: |
1216 次 |
| 最近记录: |