Отображение текстур в GLKit не работает только на устройствах

Я использовал код в этой ссылке для сопоставления текстур человеческих лиц. Этот код использует GLKIT для рендеринга изображений. Код отлично работает в симуляторе, но тот же код, если я запускаю его на устройстве, не работает. Ниже приведены снимки экрана с изображениями, где он работает на устройстве, а не на моем iPad.

Код, который я использовал для загрузки текстуры:

- (void)loadTexture:(UIImage *)textureImage
{
    glGenTextures(1, &_texture);
    glBindTexture(GL_TEXTURE_2D, _texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    CGImageRef cgImage = textureImage.CGImage;
    float imageWidth = CGImageGetWidth(cgImage);
    float imageHeight = CGImageGetHeight(cgImage);
    CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(cgImage));

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA,  
    GL_UNSIGNED_BYTE, CFDataGetBytePtr(data));
}

Изображение симулятора:

Вывод в симуляторе

Тот же код в устройстве дает следующий результат:

Вывод в устройстве

Есть что-то, что я упускаю?


person 2vision2    schedule 13.03.2013    source источник
comment
Может кто ответит на мой вопрос!!   -  person 2vision2    schedule 20.03.2013
comment
проверьте: stackoverflow.com/a/7952288/2128327   -  person Khaled.K    schedule 26.03.2013


Ответы (3)


В конце концов я сдался и переключился на GLKTextureLoader. Как упоминает Адам, он довольно прочный.

Вот реализация, которая может сработать для вас:

- (void)loadTexture:(NSString *)fileName
{
    NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES],
                             GLKTextureLoaderOriginBottomLeft,
                             nil];

    NSError* error;
    NSString* path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
    GLKTextureInfo* texture = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
    if(texture == nil)
    {
        NSLog(@"Error loading file: %@", [error localizedDescription]);
    }

    glBindTexture(GL_TEXTURE_2D, texture.name);
}

Я скоро изменю его для проекта mtl2opengl на GitHub...

person Ricardo RendonCepeda    schedule 16.04.2013
comment
Спасибо за ваш ответ Рикардо. Я попробую и скоро вернусь к вам. Большое спасибо.\ - person 2vision2; 17.04.2013

  1. Используйте встроенный однострочный метод Apple для загрузки — не пишите свою собственную (сломанную) реализацию!

    https://developer.apple.com/library/mac/#documentation/GLkit/Reference/GLKTextureLoader_ClassRef/Reference/Reference.html#//apple_ref/occ/clm/GLKTextureLoader/textureWithContentsOfFile:options:error :


  1. Или, если вы должны сделать это самостоятельно, у вас есть две подозрительные части:

    2.1. Избавьтесь от этой строки:

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    2.2. В этой строке используется номер вне области видимости, что не очень хорошо:

    glGenTextures(1, &_texture);


  1. Если по какой-то причине вы не можете использовать код Apple (например, вы хотите загрузить необработанные данные из изображения в памяти), вот копия/вставка рабочего кода:

    NSData* imageData = ... // fill this yourself
    CGSize* imageSize = ... // fill this yourself
    
    GLuint integerForOpenGLToFill;
    glGenTextures(1, &integerForOpenGLToFill);
    
    glBindTexture( GL_TEXTURE_2D, integerForOpenGLToFill);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    unsigned char* pixelData = (unsigned char*) malloc( [imageData length] * sizeof(unsigned char) );
    [imageData getBytes:pixelData];
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width, imageSize.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
    
person Adam    schedule 01.04.2013
comment
Вы уверены в своем исправлении @Adam? Я написал исходный код загрузки текстур и заменил его вашим предложением в другом приложении, но результат еще хуже. Я не эксперт по OpenGL, поэтому моя реализация может быть неправильной, но этот код тоже не работает. Хороший звонок по номеру вне зоны действия, хотя. - person Ricardo RendonCepeda; 02.04.2013
comment
Вот скриншот моих результатов с использованием обоих методов (другое приложение, iPhone Simulator с дисплеем Retina) . - person Ricardo RendonCepeda; 02.04.2013
comment
@RicardoRendonCepeda какой бит? Мое ОСНОВНОЕ ПРЕДЛОЖЕНИЕ — использовать код Apple, потому что он работает! Всегда! - person Adam; 03.04.2013
comment
Код копирования/вставки внизу предназначен для случаев, когда вы генерируете данные в реальном времени в памяти (что Apple поддерживает лишь частично) и обеспечивает гораздо более высокую производительность, чем код Apple. В этом случае вам нужно понять свой формат данных и соответствовать формату, который у меня есть (RGBA), или изменить информацию, которую вы даете OpenGL, но если вы используете собственный нестандартный формат данных изображения, я предполагаю Вы знаете, что делаете, и знаете, как с этим бороться :)... - person Adam; 03.04.2013
comment
Нет, я тоже использую стандартный RGBA. Честно говоря, я давно не уделял этому проекту должного внимания и был доволен его первоначальной целью (к тому же, нет iPad = нет тщательного тестирования). Я начал использовать OpenGL ES 2.0 до GLKit, поэтому мне также нужно более подробно изучить GLKTextureLoader. - person Ricardo RendonCepeda; 03.04.2013
comment
Мой источник данных изображения в памяти: создайте контекст растровой графики и используйте метод Apple для получения необработанных байтов в виде NSData. Вы получаете W * H * (байт на пиксель) байтов - без заголовка, без нижнего колонтитула и т. д. Код выше предполагает это (это наиболее стандартное необработанное представление данных изображения :)). Для системы Apple требуется заголовок JPG или PNG (это НЕ задокументировано, но я получил его от инженеров Apple по запросу в техподдержку) - person Adam; 04.04.2013

Глядя на скрины... Интересно, проблема в том, что ты переходишь с айфона на айпад?

т.е. сетчатка к не-сетчатке?

Мне кажется, что ваша загрузка изображения может быть игнорирует масштаб Retina, поэтому карта текстуры на iPad «в 2 раза больше».

Использование метода Apple (мой другой ответ) должно исправить это автоматически, но если нет: вы можете попробовать сделать две копии изображения, одну с текущим размером (с именем «[email protected]») и одну с половинным размером (изменить размер в фотошопе). /preview.app/etc) (с именем "image.png")

person Adam    schedule 02.04.2013
comment
Спасибо за ответ. Проблема между симулятором и устройством. У меня в эмуляторе работает, а в девайсе нет :( - person 2vision2; 02.04.2013
comment
Что произойдет, если вы используете симулятор RETINA вместо симулятора НЕ RETINA? (используйте меню «Оборудование» для переключения) - person Adam; 02.04.2013