3

In my app (Tres) I'm loading an image from the image picker and putting it on a texture. It all worked fine in all my tests, but now that it's online people with iPads with retina display are complaining images come out black.

I'm looking at GL_MAX_TEXTURE_SIZE to make sure the image is not bigger than that.

Here I setup the texture:

texture_aspect = image.size.width / image.size.height;
CGFloat side = image.size.width;

if(side>GL_MAX_TEXTURE_SIZE)
    side = GL_MAX_TEXTURE_SIZE;
UIImage *newImage = [ImageUtils imageWithImage:image scaledToSize:CGSizeMake(side, side)];

image_height = 600.0f;
image_width = image_height * texture_aspect;
if(image_width>600.0f) {
    image_width = 900.0f;
    image_height = image_width / texture_aspect;
}

NSError* error;
GLKTextureInfo * texture = [GLKTextureLoader textureWithCGImage:newImage.CGImage options:nil error:&error];
if (error) {
    NSLog(@"Error loading texture from image: %@",error);
}

And this is how I draw the image:

- (void) dibujaFoto {
    self.effect.texture2d0.enabled = GL_TRUE;
    [self.effect prepareToDraw];
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

    GLfloat squareVertices[] = {
        -image_width/2, -image_height/2,
        image_width/2,-image_height/2,
        -image_width/2, image_height/2,
        image_width/2,image_height/2,
    };

    const GLfloat squareTextureCoords[] = {
        0.0, 1.0,
        1.0, 1.0,
        0.0, 0.0,
        1.0, 0.0,
    };

    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, squareVertices);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0, squareTextureCoords);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDisableVertexAttribArray(GLKVertexAttribPosition);
    glDisableVertexAttribArray(GLKVertexAttribTexCoord0);
    self.effect.texture2d0.enabled = GL_FALSE;
}

It doesn't matter how big the image is, it always works on my 2nd generation iPad, but it seems retina displays are having problems with this code.

Odrakir
  • 4,254
  • 1
  • 20
  • 52

1 Answers1

6

For one thing, you're not actually reading the maximum texture size. GL_MAX_TEXTURE_SIZE doesn't represent the maximum texture size on a device, it's an OpenGL ES constant used when reading the maximum texture size.

To read the actual maximum texture size, you need to use something like the following:

static GLint maxTextureSize = 0;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);

You need to run this after you've set up and made current your EAGLContext, of course.

Older devices (pre-iPhone 4S) all had a maximum texture size of 2048x2048. A5 and above devices (4S and newer) have a maximum 4096x4096 texture size.

Something else is going wrong here, though, because the GL_MAX_TEXTURE_SIZE constant on my SDK translates to 3379 in decimal, which should be well within the 4096x4096 maximum texture size on the Retina iPads (but too large for the original model of iPad). I don't see why this would fail on those and not the older devices. Is it possible that your ImageUtils class is applying the device scale factor in an incorrect manner?

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • Great answer. It is possible I'm doing something wrong when scaling. I'll check that and get back with more info. By the way, it's a honor getting a answer from you. The little I know of OpenGL and iOS programming I learned it from your videos. – Odrakir May 28 '13 at 18:27
  • Getting the correct max texture size apparently fixed the problem. Don't ask me why. I'll buy an iPad retina soon and try to find out. – Odrakir May 29 '13 at 05:54
  • 1
    @Odrakir - Having one of those around (particularly the 3rd gen iPad, without the extra processing horsepower of the 4th) is really valuable for exposing fill-rate bottlenecks that other devices don't see. Also, I've found that there are some quirks around the undocumented rounding behavior of low-precision types in shaders that behaved differently on the iPad 3 and 4 vs. older devices. – Brad Larson May 29 '13 at 14:53
  • My bad. I finally got to try it my self and it did had to do with ImageUtils. Silly me, I was using UIGraphicsBeginImageContextWithOptions and scaling the image to 2.0 for retina devices... some legacy code, I guess. – Odrakir Jun 04 '13 at 11:14
  • Weird thing is, the image I got back did have the correct size. – Odrakir Jun 04 '13 at 11:15