Рисование OpenGL испортилось, когда я изменил размер CAEAGLLayer - PullRequest
2 голосов
/ 31 августа 2011

Я пытаюсь реализовать базовый OpenGL в своем приложении, и при этом я использовал пример GLPaint, включенный в SDK, в качестве отправной точки. Мой код работает нормально сам по себе, но как только я перенесу все в свое приложение, тот же код завершится ошибкой.

В зависимости от того, что я пытаюсь сделать, проблема в том, что (1) примитивы кажутся сплющенными при первом рисовании, а затем всплывают в верхнюю часть экрана при рисовании последующих примитивов, или (2) примитивы вообще не появляются .

Я сузил его до того факта, что мое приложение требует изменения размера CAEAGLLayer. Он находится в UIScrollView и может быть перемещен и изменен в любое время (сжатие, перетаскивание и т. Д.). Как и в примере с GLPaint, я удаляю буфер кадра и воссоздаю его каждый раз, когда размер представления изменяется (через layoutSubviews), но это не т работа. (Так как пример GLPaint никогда не изменяет размеры, я подозреваю, что эта часть кода примера никогда не работала, так как в этом никогда не было необходимости.)

Только если я установлю CAEAGLLayer на постоянный размер 1024 x 768, код будет работать как положено:

self.layer.frame = CGRectMake(0, 0, 1024, 768);

Как только я изменю эту строку на:

self.layer.frame = self.bounds;

проблемы возвращаются. Остальная часть моего метода layoutSubviews выглядит так:

[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];

if (needsClearView) {
    [self clearView];
    needsClearView = NO;
}

Методы destroyFramebuffer и createFramebuffer практически не отличаются от примера GLPaint. Единственный другой код, который ссылается на размер представления, это строки в initWithCoder:

glOrthof(0, self.bounds.size.width, 0, self.bounds.size.height, -1, 1);
glViewport(0, 0, self.bounds.size.width, self.bounds.size.height);

Я пытался изменить значения здесь и переместить эти строки в другое место, но ничего из того, что я пробовал, не сработало. У кого-нибудь есть предложения для меня?

Ответы [ 3 ]

4 голосов
/ 10 января 2012

У меня была та же самая проблема на днях, и я понял это. Вам нужно вызвать glOrthof и glViewport с новым размером, прежде чем воссоздать буфер кадра. Я сделал это в layoutSubviews вызове:

-(void)layoutSubviews
{
    [EAGLContext setCurrentContext:context];

    glMatrixMode(GL_PROJECTION);
    CGRect frame = self.bounds;
    CGFloat scaleFactor = self.contentScaleFactor;
    glLoadIdentity();
    glOrthof(0, frame.size.width * scaleFactor, 0, frame.size.height * scaleFactor, -1, 1);
    glViewport(0, 0, frame.size.width * scaleFactor, frame.size.height * scaleFactor);
    glMatrixMode(GL_MODELVIEW);    

    [self destroyFramebuffer];
    [self createFramebuffer];

    // Clear the framebuffer the first time it is allocated
    if (needsErase) {
        [self erase];
        needsErase = NO;
    }
}

Убедитесь, что вы сначала позвонили glLoadIdentity, так как glOrthof умножается на текущую матрицу.

1 голос
/ 16 декабря 2013

У меня была такая же проблема при использовании PaintingView в VC и изменении его фрейма.Решил это, применяя CGAffineTransform к представлению перед изменением кадра.

т.е.:

paintingView.transform = CGAffineTransformMakeScale(0.5, 0.5);
paintingView.frame = CGRectMake(paintingView.frame.origin.x, paintingView.frame.origin.y, paintingView.frame.size.width/2, paintingView.frame.size.height/2);
1 голос
/ 02 сентября 2011

Я обнаружил, что CAEAGLLayer не счастлив, если его bounds.width кратно 8.

...