Пиксельные буферы основного видео как GL_TEXTURE_2D

Итак, я настроил CVPixelBuffer и успешно привязал их к OpenGL FBO на iOS. Но теперь попытка сделать то же самое на OSX меня зацепила.

Текстуры из CVOpenGLTextureCacheCreateTextureFromImage возвращаются как цели GL_TEXTURE_RECTANGLE вместо целей GL_TEXTURE_2D.

Я нашел ключ kCVOpenGLBufferTarget, но похоже, что он должен использоваться с CVOpenGLBufferCreate, а не с CVPixelBufferCreate.

Возможно ли вообще получить целевые текстуры GL_TEXTURE_2D на OSX с помощью CVPixelBufferCreate, и если да, то как?

FWIW список настроек CV PBO:

NSDictionary *bufferAttributes = @{ (__bridge NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA), (__bridge NSString *)kCVPixelBufferWidthKey : @(size.width), (__bridge NSString *)kCVPixelBufferHeightKey : @(size.height), (__bridge NSString *)kCVPixelBufferIOSurfacePropertiesKey : @{ } };

if (pool)
{
    error = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pool, &renderTarget);
}
else
{
    error = CVPixelBufferCreate(kCFAllocatorDefault, (NSUInteger)size.width, (NSUInteger)size.height, kCVPixelFormatType_32BGRA, (__bridge CFDictionaryRef)bufferAttributes, &renderTarget);
}

ZAssert(!error, @"Couldn't create pixel buffer");

error = CVOpenGLTextureCacheCreate(kCFAllocatorDefault, NULL, [[NSOpenGLContext context] CGLContextObj], [[NSOpenGLContext format] CGLPixelFormatObj], NULL, &textureCache);
ZAssert(!error, @"Could not create texture cache.");

error = CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, renderTarget, NULL, &renderTexture);
ZAssert(!error, @"Couldn't create a texture from cache.");

GLuint reference = CVOpenGLTextureGetName(renderTexture);
GLenum target = CVOpenGLTextureGetTarget(renderTexture);

ОБНОВЛЕНИЕ: мне удалось успешно использовать полученные текстуры GL_TEXTURE_RECTANGLE. Однако это вызовет много проблем с шейдерами для совместимости между iOS и OSX. И в любом случае я предпочел бы продолжать использовать нормализованные координаты текстуры.

Если таким образом невозможно получить текстуры GL_TEXTURE_2D непосредственно из CVPixelBuffer, возможно ли создать CVOpenGLBuffer и подключить к нему CVPixelBuffer для получения данных пикселей?


person v01d    schedule 18.12.2012    source источник
comment
Вы используете основной профиль?   -  person Justin Meiners    schedule 21.12.2012
comment
Учитывая, что я не знал, что это такое, пока ты не упомянул об этом... наверное, нет.   -  person v01d    schedule 23.12.2012
comment
Хорошо, я не использовал профиль ядра 3.2. Даже сейчас Core Video по-прежнему использует GL_TEXTURE_RECTANGLE в качестве цели.   -  person v01d    schedule 23.12.2012
comment
Я должен отметить, что #import ‹CoreVideo/CoreVideo.h› вызывает предупреждение компилятора о включении gl.h и gl3.h. Это говорит о том, что CoreVideo не использует для меня профиль ядра 3.2.   -  person v01d    schedule 23.12.2012
comment
Я думаю, что если вы используете основной профиль, то он будет использовать GL_TEXTURE_2D, по крайней мере, это то, что он делает на iOS. Предполагается, что 3.2 совместим с es 2.0, который поддерживает прямоугольные текстуры в TEXTURE_2D.   -  person Justin Meiners    schedule 24.12.2012
comment
Да, определенно перешел на ядро ​​​​3.2, мне пришлось изменить много вещей, чтобы быть совместимым с ним. Возможно, в настройках моего резюме отсутствует какой-то флаг? Я знаю, что могу сделать цель GL_TEXTURE_2D по умолчанию при использовании CVOpenGLBuffers, но это бесполезно, так как мне нужны данные пикселей.   -  person v01d    schedule 24.12.2012
comment
Кстати, iOS не поддерживает ES1.0 в качестве контекста для Core Video, и ES1.0 вообще не поддерживает прямоугольные текстуры. ES2.0 и GL_TEXTURE_2D — единственный вариант (кроме GL_RENDERBUFFER, конечно). Чем больше я исследую, тем больше я нахожу его недокументированным, и более вероятно, что Core Video на OSX был создан до того, как NPOT/прямоугольный GL_TEXTURE_2D стал нормой, и, вероятно, он не обновлялся. Я вижу только ссылки на людей, предполагающих то же самое; ничего наоборот.   -  person v01d    schedule 24.12.2012


Ответы (2)


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

iOS использует OpenGL ES (первоначально 2.0, затем 3.0). OS X использует обычный старый (не ES) OpenGL с выбором профиля Core (только 3.0+) или профиля совместимости (до 3.2).

Разница здесь в том, что OpenGL (не ES) был разработан очень давно, когда было много ограничений на размеры текстур. Когда карты сняли эти ограничения, были добавлены расширения, в том числе GL_TEXTURE_RECTANGLE. Теперь для любого графического процессора нет ничего страшного в поддержке текстуры любого размера, но по причинам совместимости API они не могут исправить OpenGL. Поскольку OpenGL ES технически представляет собой параллельный, но отдельный API, который был разработан гораздо позже, они смогли исправить проблему с самого начала (т. е. им не пришлось беспокоиться о поломке старых вещей). Таким образом, для OpenGL ES они никогда не определяли GL_TEXTURE_RECTANGLE, они просто определяли, что GL_TEXTURE_2D не имеет ограничений по размеру.

Краткий ответ: OS X использует OpenGL для настольных ПК, который по соображениям устаревшей совместимости по-прежнему обрабатывает прямоугольные текстуры отдельно, в то время как iOS использует OpenGL ES, который не накладывает ограничений на размер GL_TEXTURE_2D и поэтому вообще никогда не предлагал GL_TEXTURE_RECTANGLE. Таким образом, в OS X CoreVideo создает объекты GL_TEXTURE_RECTANGLE, потому что GL_TEXTURE_2D будет тратить много памяти, а в iOS он создает объекты GL_TEXTURE_2D, потому что GL_TEXTURE_RECTANGLE не существует и в этом нет необходимости.

Это досадная несовместимость между OpenGL и OpenGL ES, но это то, что есть, и с этим ничего не поделаешь, кроме кода. Или теперь вы можете (и, вероятно, должны рассмотреть) перейти к металлу.

person bmac6502    schedule 07.03.2017

Поскольку это, похоже, осталось подвешенным, и я недавно имел дело с этим: нет, GL_TEXTURE_RECTANGLE, похоже, единственный вариант использования. Чтобы получить GL_TEXTURE_2D, вам нужно выполнить рендеринг в текстуру.

person Community    schedule 28.09.2015
comment
Мета-комментарий: я с самого начала пометил это как вики сообщества, поскольку все это было сказано или подразумевалось в комментариях три года назад, но было бы неплохо формализовать это как ответ. - person Tommy; 28.09.2015