iPod / iPhone OpenGL ES UIView мигает при обновлении - PullRequest
0 голосов
/ 10 марта 2010

У меня есть простое приложение для iPhone, которое использует OpenGL ES (v1) для рисования линий, основанных на прикосновениях пользователя. В XCode Simulator код работает отлично. Однако, когда я устанавливаю приложение на iPod или iPhone, представление OpenGL ES «мигает» при рисовании линии. Если я отключу рисование линий, вспышка исчезнет. Под «вспышкой» я подразумеваю, что фоновое изображение (которое является текстурой OpenGL) на мгновение исчезает, а затем снова появляется. Похоже, что вся сцена полностью стерта и перерисована.

Код, который обрабатывает рисование линий, следующий:

renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end
{
    static GLfloat*       vertexBuffer = NULL;
    static NSUInteger vertexMax = 64;
    NSUInteger            vertexCount = 0,
    count,
    i;

    //Allocate vertex array buffer
    if(vertexBuffer == NULL)
        vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat));

    //Add points to the buffer so there are drawing points every X pixels
    count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / kBrushPixelStep), 1);
    for(i = 0; i < count; ++i) {
        if(vertexCount == vertexMax) {
            vertexMax = 2 * vertexMax;
            vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));
        }

        vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count);
        vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count);
        vertexCount += 1;
    }

    //Render the vertex array
    glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
    glDrawArrays(GL_POINTS, 0, vertexCount);

    //Display the buffer
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

(Эта функция основана на функции с тем же именем из примера приложения GLPaint.) По жизни я не могу понять, почему это заставляет экран мигать. Линия нарисована правильно (как в симуляторе, так и в iPod). Но вспышка делает его непригодным для использования.

У кого-нибудь есть идеи, как предотвратить «вспышку»?

Ответы [ 3 ]

1 голос
/ 11 марта 2010

После долгих испытаний я нашел решение этой проблемы, хотя я не уверен, что это лучшая практика.

Решением было изменение kEAGLDrawablePropertyRetainedBacking с НЕТ на ДА. Это прекратило мигать. В частности, код для настройки представления OpenGL теперь выглядит следующим образом:

CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer;
eaglLayer.opaque = YES;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithBool:YES], 
                                kEAGLDrawablePropertyRetainedBacking, 
                                kEAGLColorFormatRGB565, kEAGLDrawablePropertyColorFormat, nil];

Опять же, я не уверен, лучше ли использовать стратегию RetainedBacking, но она перестала мигать. Согласно http://developer.apple.com/iphone/library/documentation/iPhone/Reference/EAGLDrawable_Ref/EAGLDrawable/EAGLDrawable.html#jumpTo_6 следует установить RetainedBacking в YES только при определенных обстоятельствах.

Установка значения YES рекомендуется только в том случае, если необходимо, чтобы содержимое оставалось неизменным, поскольку его использование может привести как к снижению производительности, так и к дополнительному использованию памяти.

Непонятно, как влияет производительность или память, но это одно изменение полностью остановило все "мигание", которое я видел.

0 голосов
/ 13 марта 2010

Возможно ли, что вы вызываете glRenderBuffer () и отправляете сообщение presentRenderBuffer в свой EAGLContext без каких-либо обновлений OpenGL, то есть без новых glDrawElements или glDrawArrays. Возможно, вы отправляете сообщение presentRenderBuffer в другой точке вашего кода? Если вы сделаете это без kEAGLDrawablePropertyRetainedBacking, установленным в YES, то вы можете получить раздражающее мерцание.

Посмотрите kEAGLDrawablePropertyRetainedBacking на свойстве drawableProperties вашего CAEAGLLayer. Это свойство определяет поведение отрисовываемой поверхности после отображения ее содержимого. Если для этого свойства установлено значение NO, содержимое не сохраняется и поэтому не гарантируется, что оно останется неизменным после отображения. Если вы установите его в YES, то содержимое будет сохранено и останется неизменным после отображения.

Я полагаю, что установка kEAGLDrawablePropertyRetainedBacking в YES замаскирует проблему, но не устранит ее.

0 голосов
/ 10 марта 2010

Однажды у меня была точно такая же проблема. У меня было окно UIWindow, в которое я поместил OpenGLES UIView. Процесс рисования был приятным, пока я не попытался добавить подпредставление (UIImageView) в представлении OpenGLES. Экран мигал. Я смог решить проблему, добавив UIImageView в качестве подпредставления UIWindow вместо этого. Кажется, рендеринг OpenGLES не любит подпредставления ...

Так что в вашем представлении OpenGLES, если у вас есть что-то вроде:

[self addSubView: ...]

Вы можете заменить его, например, на:

[self.superview addSubView: ...]

Не могу увидеть в вашем коде, если у вас есть подобные вещи, но я надеюсь, что это немного поможет ...:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...