рендеринг UIImage с размером> 1024 с OpenGL ES 2.0 на iPhone - PullRequest
1 голос
/ 09 ноября 2011

Я снимаю UIImage с полным разрешением на iPhone 4 (1936X2592)
тогда я масштабирую его до квадрата размером 1936x1936.

Теперь мне нужно загрузить это изображение в текстуру и позволить OpenGL визуализировать его с помощью некоторого GLSL.

проблема в том, что OpenGL поддерживает только 2 размера текстур и только до 1024.

так как мне это решить?

Спасибо.

РЕДАКТИРОВАТЬ: мой вопрос не имеет значения, я нацелена на 3GS и выше, и он поддерживает размер изображения 2048x2048. моя проблема в другом вопросе: Кадр камеры в UIImage для рендеринга OpenGL дает нечетное изображение

Ответы [ 3 ]

3 голосов
/ 09 ноября 2011

Начиная с 3GS, OpenGL поддерживает текстуры размером до 2048x2048. 4S и iPad2 поддерживают 4096x4096.

Однако, если это не так, то ваши параметры вращаются вокруг упаковки пикселей вместе со сжатием с потерями или с использованием нескольких текстур, которые вы можете исправить (за плату) в GLSL или с помощью геометрии.

Самым очевидным вариантом является загрузка в виде четырех плиток. Ваш выходной размер 1936 в каждом направлении позволяет вам загружать текстуры с некоторым перекрытием, чтобы вы могли получить бесшовное соединение даже с линейной фильтрацией текстур. Предположим, что вам нужно только разделить по горизонтали, вы можете убедиться, что две нижние строки одной текстуры совпадают с двумя верхними строками другой, и поместить геометрическое соединение между этими двумя строками.

Другие варианты не только менее очевидны, но и менее полезны. С точки зрения упаковки с потерями, вы можете перевести свою текстуру из пространства RGB в пространство YUV, и в 32 битах, представляющих каждую выборку RGBA, хранятся четыре 5-битных Y-выборки, одна 6-битная U-выборка и одна 6-битная V-выборка. Затем вы распаковываете и рекомбинируете в шейдере. Однако вы получите снижение качества изображения и значительное снижение производительности.

1 голос
/ 09 ноября 2011

Учитывая, что iPhone 4 имеет только экран 960x640, почему бы просто не уменьшить его до 1024x1024?Таким образом, вы не тратите впустую память без нужды.

Если это не удастся, разделите ее на 4 текстуры.

Редактировать: На самом деле вам не нужно уничтожать исходное изображение, когда вы рисуете еще 4.

Что касается разбиения изображения на 4 отдельных изображения, это довольно просто.Для рендеринга верхнего левого 1024x1024 в UIImage вы можете сделать следующее.

subImageArea = CGRectMake( 0, 0, 1024, 1024 );
CGImage* pCGSubImage = CGImageCreateWithImageInRect( [pUILargeImage CGImage], subImageArea );
UIImage* pUISubImage = [UIImage initWithCGImage: pCGSubImage];
0 голосов
/ 09 ноября 2011

Из того, что я прочитал в ваших предыдущих ответах, вы можете жить с размером текстуры 2048x2048.

У меня была похожая проблема при создании снимков экрана, размер экрана 960x640 -> 1024x1024 Размер текстуры, я просто делаю это:

void *buffer = malloc( x * y * 4 );

glReadPixels(0,0,x,y,GL_RGBA,GL_UNSIGNED_BYTE,buffer);
glEnable(GL_TEXTURE_2D);

glGenTextures(1, &screenShotTexture);
glBindTexture(GL_TEXTURE_2D, screenShotTexture);

glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
free(buffer);

Конечно, я уверен, что x и y - это POT.Мне также пришлось поработать с картой текстур, например:

static const float screenTexCoordsR[] = {
0.0, 0.0,
0.0, 0.9375,
0.625, 0.0,
0.625, 0.9375
};

Ваши были бы не такими бесполезными, вместо 0,9375 и 0,625 у вас было бы 0,9453 или что-то еще.

...