Сопоставьте UIView с лицом для дисплея Retina iPhone 5

У меня есть UIView, который я хотел бы сопоставить с лицом моей формы. Все это работает, но я хотел бы, чтобы это работало с графикой сетчатки на iPhone 5. Я установил свойство contentScale моего слоя openGL на 2.0, но, тем не менее, результат немного размыт. Так что размер правильный, просто кажется, что я использовал графику без сетчатки для изображения на дисплее сетчатки. Так что «единственное», что мне нужно сделать, это сказать iPhone, что это должно быть вдвое больше пикселей. Я попробовал решение, предложенное DarthMike, но, к сожалению, безрезультатно.

Здесь я инициализирую и добавляю его в свое представление:

    MyOpenGLView *view = [[MyOpenGLView alloc] initWithFrame:CGRectMake(0, dY, 230,230) context:context];
    view.contentScaleFactor = 2.0;
    view.layer.contentsScale = 2.0;
    view.delegate = view;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat16;
    [view setupGL];
    [self.view addSubview:view];

Здесь я отображаю представление в контексте и добавляю его как текстуру

    MyViewToBeTheTexture *textureView = [[MyViewToBeTheTexture alloc]initWithFrame:CGRectMake(0, 0, 230, 230)];

    self.effect.texture2d0.enabled = true;

    // make space for an RGBA image of the view
    GLubyte *pixelBuffer = (GLubyte *)malloc(
                                             4 *
                                             textureView.bounds.size.width *
                                             textureView.bounds.size.height);

    // create a suitable CoreGraphics context
    CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context =
    CGBitmapContextCreate(pixelBuffer,
                          textureView.bounds.size.width, textureView.bounds.size.height,
                          8, 4*textureView.bounds.size.width,
                          colourSpace,
                          kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colourSpace);

    // draw the view to the buffer
    [textureView.layer renderInContext:context];

    // upload to OpenGL
    glTexImage2D(GL_TEXTURE_2D, 0,
                 GL_RGBA,
                 textureView.bounds.size.width, textureView.bounds.size.height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer);



    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);



    glGenBuffers(1, &texArray);
    glBindBuffer(GL_ARRAY_BUFFER, texArray);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0,0);
    glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoords), TexCoords, GL_STATIC_DRAW);

person the_critic    schedule 04.01.2013    source источник
comment
Что не работает? Лучшее описание того, что показывает проблема, поможет людям ответить на ваш вопрос.   -  person DarthMike    schedule 04.01.2013
comment
Прости, @DartMike. Я просто хотел добавить немного информации. Изображение кажется очень размытым, и любой UILabel, который я добавляю в представление, также размыт...   -  person the_critic    schedule 04.01.2013
comment
Это работает и на сетчатке iPhone 4? (не размыто) Потому что масштаб содержимого должен быть таким же для iPhone 5, так как экран имеет больше пикселей только в y.   -  person DarthMike    schedule 04.01.2013
comment
Это выглядит почти так же на iPhone 4 (ретина).   -  person the_critic    schedule 04.01.2013
comment
@DarthMike Странно то, что когда я устанавливаю для параметра GL_TEXTURE_WRAP_S и/или GL_TEXTURE_WRAP_T значение GL_REPEAT, он вообще ничего не показывает.   -  person the_critic    schedule 04.01.2013
comment
Может ли это быть так же просто, как попробовать разные параметры размера в Имитированных метриках Инспектора атрибутов в xib? т. е. полноэкранный режим Retina 4 и полноэкранный режим Retina 3.5.   -  person avenger    schedule 31.01.2013


Ответы (2)


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

При работе с разрешением retina нужно загружать совсем другую текстуру, т.к. экран имеет двойное разрешение для одних и тех же координат. Вот почему вы видите размытую текстуру (увеличенную в 2 раза). Вы должны создать буферы с двойным размером x и y для сетчатки, прочитав [UIScreen mainScreen].scale. Я даю вам предварительный код, может не работать, так как я не мог его проверить:

MyView *view = [[MyView alloc]initWithFrame:CGRectMake(0, 0, 320, 80)];

self.effect.texture2d0.enabled = true;

//Pixel to coord scale
GLFloat coordToPixScale = [UIScreen mainScreen].scale;

// make space for an RGBA image of the view
GLubyte *pixelBuffer = (GLubyte *)malloc(
                                         4 *
                                         view.bounds.size.width * coordToPixScale *
                                         view.bounds.size.height * coordToPixScale);

// create a suitable CoreGraphics context
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =
CGBitmapContextCreate(pixelBuffer,
                      view.bounds.size.width*coordToPixScale, view.bounds.size.height*coordToPixScale,
                      8, 4*view.bounds.size.width *coordToPixScale,
                      colourSpace,
                      kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colourSpace);

// draw the view to the buffer
[view.layer renderInContext:context];

// upload to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0,
             GL_RGBA,
             view.bounds.size.width * coordToPixScale, view.bounds.size.height * coordToPixScale, 0,
             GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer);

BOOL repeatX = NO;
BOOL repeatY = NO;

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeatX ? GL_REPEAT
                       : GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeatY ? GL_REPEAT
                       : GL_CLAMP_TO_EDGE);



glGenBuffers(1, &texArray);
glBindBuffer(GL_ARRAY_BUFFER, texArray);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0,0);
glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoords), TexCoords, GL_STATIC_DRAW);
person DarthMike    schedule 04.01.2013
comment
Мое единственное предположение заключается в том, что contentScale в слое должно быть 1.0. - person DarthMike; 04.01.2013
comment
теперь он выглядит в два раза ужаснее, чем раньше... поэтому я думаю, что ваш ответ помогает с точки зрения того, как он выглядит (почти идеально), но он вдвое меньше... Однако contentScale должен оставаться 2.0, потому что, когда я его устанавливаю на 1.0 это выглядит просто ужасно - person the_critic; 04.01.2013

РЕШЕНИЕ НАЙДЕНО!

Пожалуйста, взгляните на этот вопрос:

текстуры OpenGL ES 2.0 для дисплея сетчатки?

person the_critic    schedule 04.03.2013