CAOpenGLLayer обрезал изображение - PullRequest
4 голосов
/ 05 июня 2011

Я борюсь с 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 голосов
/ 18 октября 2012

Я проверил ваш код и искал документацию.Вам просто нужно добавить вызов к [caLayer setNeedsDisplay] где-то.

Я заставил ваш код работать, просто добавив [self setNeedsDisplay]; внутри drawInCGLContext:pixelFormat:forLayerTime:displayTime:, но я уверен, что есть лучшее место для этого (может быть, запуститьцикл или другой метод синхронизации).

Без setNeedsDisplay результат весьма непредсказуем: кажется, что OpenGL рисует правильно, glViewport правильно отображает область рендеринга, но CALayer сохраняет содержимоеобласть та же самая и копирует часть обновленных данных OpenGL в нее, даже если bounds, frame и contentRect имеют правильные значения.Переключение на kCAGravityResize (в попытке заставить область содержимого заполнить слой) привело к еще более странным результатам с частичным масштабированием содержимого.Я предполагаю, что это является частью реализации CAOpenGLLayer , разделяющей на независимые процедуры процесс рисования OpenGL и процесс Core Animation.

...