CAOpenGLLayer已剪切图像

时间:2011-06-05 04:34:54

标签: objective-c cocoa mobile calayer

我正在与CAOpenGLLayer斗争。

我的问题是,当我调整小于初始大小的窗口时,内部图像被剪裁(顶部或右侧部分消失)。我试图调整glViewport()或glOrtho(),但它不起作用。请给我建议。

#import <Cocoa/Cocoa.h>
#import "MyOpenGLLayer.h"

@interface CALayerTestAppDelegate : NSObject <NSApplicationDelegate> {
    NSWindow *window;
}
@property (assign) IBOutlet NSWindow *window;
@end

@implementation CALayerTestAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    [[window contentView] setWantsLayer:YES];
    CALayer *contentLayer = [[window contentView] layer];
    MyOpenGLLayer *layer = [MyOpenGLLayer layer];
    [contentLayer addSublayer:layer];

    layer.contentsGravity = kCAGravityCenter;
    layer.bounds = contentLayer.bounds;
    layer.frame = contentLayer.frame;
    layer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
    layer.asynchronous = YES;
}
@end

使用以下CAOpenGLLayer子类:

@interface MyOpenGLLayer : CAOpenGLLayer 
@end

@implementation MyOpenGLLayer
- (void)drawInCGLContext:(CGLContextObj)glContext 
         pixelFormat:(CGLPixelFormatObj)pixelFormat 
        forLayerTime:(CFTimeInterval)timeInterval 
         displayTime:(const CVTimeStamp *)timeStamp {
NSRect bounds = NSRectFromCGRect([self bounds]);
GLfloat minX, minY, maxX, maxY;        
minX = NSMinX(bounds);
minY = NSMinY(bounds);
maxX = NSMaxX(bounds);
maxY = NSMaxY(bounds);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glViewport(minX, minY, maxX, maxY);
glOrtho(minX, maxX, minY, maxY, -1.0, 1.0);

glClearColor(0.0, 0.5, 0.5, 1.0);         
glClear(GL_COLOR_BUFFER_BIT);

const size_t unit = 40;
for (int x = 0; x<[self bounds].size.width; x+=unit) 
    for (int y = 0; y<[self bounds].size.height; y+=unit)
        if ((x + y)/unit & 1) 
            glRectd(x, y, x+unit, y+unit);
glFlush();

[super drawInCGLContext:glContext pixelFormat:pixelFormat 
           forLayerTime:timeInterval displayTime:timeStamp];
}
@end

1 个答案:

答案 0 :(得分:0)

我已经测试了您的代码并搜索了文档。您只需要在某处添加对[caLayer setNeedsDisplay]的调用。

我让你的代码工作只是在[self setNeedsDisplay];内添加drawInCGLContext:pixelFormat:forLayerTime:displayTime:,但我确信有一个更好的地方(可能是一个运行循环或其他计时方法)。

没有setNeedsDisplay结果是非常不可预测的:似乎OpenGL正确绘制, glViewport 正确映射渲染区域,但CALayer保持内容区域相同并复制部分内容其中更新了OpenGL数据,即使boundsframecontentRect具有正确的值。切换到kCAGravityResize(试图强制内容区域填充图层)产生了甚至更奇怪的结果,内容被部分缩放。我想这是 CAOpenGLLayer 的实现的一部分,将OpenGL绘图过程和Core Animation的过程划分为独立的过程。