Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Black texture with OpenGL when image is too big

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.

like image 789
Odrakir Avatar asked Dec 06 '25 17:12

Odrakir


1 Answers

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?

like image 69
Brad Larson Avatar answered Dec 08 '25 06:12

Brad Larson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!