EAGLView для UIImage вопрос времени - PullRequest
1 голос
/ 13 августа 2011

У меня есть EAGLView, который я хочу преобразовать в UIImage.Я могу сделать это с помощью решения, размещенного здесь:

Как получить UIImage из EAGLView?

Однако я могу сделать это, только если прошло немного временимежду созданием EAGLView и UIImage.

Этот код, который создает EAGLView, а затем UIImageView сразу после этого, не работает:

EAGLView *EAGLphoto = [[EAGLView alloc] initWithImage:photo.workAreaImage];

[theWorkArea.photoArea1 addSubview:EAGLphoto];

//I put a glfinish() here but it didn't help

UIImageView *photoView = [[UIImageView alloc] initWithImage:[self glToUIImage]];
//glToUIImage is taken from the link above

[theWorkArea.photoArea2 addSubview:photoView];

Я предполагаю,UIImageView пытается создать созданную версию до завершения создания EAGLView.Я попытался поместить glfinish () между ними, но ничего не получилось.Когда я запускаю код, EAGLView отображается нормально, но UIImageView отображается как черный.

Однако эта измененная версия приведенного выше кода работает:

EAGLView *EAGLphoto = [[EAGLView alloc] initWithImage:photo.workAreaImage];

[theWorkArea.photoArea1 addSubview:EAGLphoto];

[self performSelector:@selector(getUIImage) withObject:nil afterDelay:0.1];

- (void)getUIImage {

    UIImageView *photoView = [[UIImageView alloc] initWithImage:[self glToUIImage]];
    //glToUIImage is taken from the link above

    [theWorkArea.photoArea2 addSubview:photoView];

}

Использую ли я glfinish () неправильно?Есть ли лучший способ, чем мой хак?

1 Ответ

0 голосов
/ 14 августа 2011

Обычно, когда вы вносите видимые изменения в объекты UIKit вместо немедленного обновления, они просто помечают себя для внесения этих изменений в будущем, а затем выполняют весь набор изменений в виде пакета в следующий раз, когда вы отказываетесь от основного потока (возвращаясь кrunloop).Это не ошибка или сбой в реализации, на самом деле это обычно то, чего вы неявно ожидаете, потому что вы можете написать такой код:

view.frame = someNewFrame;
view.someOtherProperty = someOtherValue;

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

Иногда вы сталкиваетесь с ситуацией, как у вас здесь, когда факт, что изменения, которые вы уже запросили, не пришелв действие еще выставлено.frame и someOtherProperty вернут свои новые значения в приведенном выше примере, так что вам все равно, вступили ли изменения в силу немедленно или нет, но на основании ваших наблюдений о performSelector:withObject:afterDelay: кажется вероятным, что вы наткнулись наситуация, когда изменение не претендует на немедленное действие.

EAGLView трудно диагностировать, потому что на самом деле это не функция UIKit.Это CAEAGLLayer, на котором он построен, но EAGLView - это просто имя, которое Apple приняла для пользовательского подкласса UIView, построенного на CAEAGLLayer в различных примерах проектов.Они не были единообразны в отношении интерфейса или реализации EAGLView в своих примерах, но, вероятно, я бы сказал, что, вероятно, он создает объект буфера фрейма OpenGL (то есть то, что OpenGL использует для хранения чисел, связанных спикселей, что позволяет glReadPixels работать), только когда его просят выложить, и он не выкладывается, пока UIKit не попросит его это сделать.И это не до тех пор, пока вы не зашли в runloop.

Этот диагноз можно подтвердить, проверив код EAGLView, который у вас есть.Если есть несколько вызовов таких вещей, как glGenFramebuffers, которые срабатывают в результате layoutSubviews, drawRect или какого-либо другого метода, который не вызывается напрямую соответствующим init, тогда это подтверждается.

Предполагая, что этот диагноз верен, вы можете адаптировать EAGLView, но я думаю, что, вероятно, лучшее решение - просто придерживаться performSelector:withObject:afterDelay:0.Это не условие гонки, так что решение не является ни малейшим ошибочным или ненадежным, это всего лишь несколько окольный способ сказать "пусть UIKit догнать все эти инструкции, учитывая, что я знаю, что позволит EAGLViewвойти в осмысленное состояние, а затем продолжить с моими вещами ".

...