7

I used the code in this link to map textures of human faces. This code uses GLKIT to render the images. Code works fine in simulator but the same code if I run in device its not working. The below are the screen shots of the images where it works in device and not in my ipad.

Code I used to Load Texture:

- (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));
}

Image of simulator:

Output in simulator

The same code in device gives the following output:

Output in Device

Is There something i`m missing?

Dattatray Deokar
  • 1,923
  • 2
  • 21
  • 31
2vision2
  • 4,933
  • 16
  • 83
  • 164

3 Answers3

3
  1. Use Apple's built-in 1-line method to load -- don't write your own (broken) implementation!

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


  1. Or, if you must do it yourself, you have two suspicious parts:

    2.1. Get rid of this line:

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    2.2. This line uses an out-of-scope number, which isn't great:

    glGenTextures(1, &_texture);


  1. If for some reason you cannot use Apple's code (e.g. you want to load raw data from in-memory image), here's a copy/paste of working code:

    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);
    
Adam
  • 32,900
  • 16
  • 126
  • 153
  • Are you sure about your fix @Adam? I wrote the original texture loading code and have replaced it with your suggestion in another application, but the result is even worse. I'm no OpenGL expert, so my implementation may still be wrong, but this code isn't working either. Good call on the out-of-scope number though. – Ricardo RendonCepeda Apr 02 '13 at 15:20
  • Here's a [screenshot](http://i.imgur.com/pSVWEGr.png) of my results using both methods (different application, iPhone Simulator w/ retina display). – Ricardo RendonCepeda Apr 02 '13 at 15:36
  • @RicardoRendonCepeda which bit? My PRIMARY SUGGESTION is to use Apple's code, because it works! Always! – Adam Apr 03 '13 at 15:51
  • The copy/paste code at the bottom is for the cases where you generate the data live in-memory (which Apple only partially supports) and is much higher performance than Apple's code. In that case you need to understand your data format and fit the format I'ce got there (RGBA) or change the info you're giving to OpenGL -- but if you're using a custom non-standard image data format I assume you know what you're doing and know how to deal with that :)... – Adam Apr 03 '13 at 15:53
  • Nope, i'm using standard RGBA too. To be fair, I haven't given this project proper attention in a while and was happy with it's initial purpose (furthermore, no iPad = no thorough testing). I started using OpenGL ES 2.0 before GLKit, so I also need to look at GLKTextureLoader in more detail. – Ricardo RendonCepeda Apr 03 '13 at 18:08
  • My source for image data in-memory is: create a bitmap graphics context, and use the Apple method to get the raw bytes as an NSData. What you get is W * H * (bytes per pixel) bytes - no header, no footer, etc. The code above assumes this (this is the most standard raw representation of image data :)). Apple's system requires a JPG or PNG header (this is NOT documented, but I had it from Apple engineers via a tech-support request) – Adam Apr 04 '13 at 09:02
2

Looking at the screenshots ... I wonder if the problem is that you're going from iPhone to iPad?

i.e. retina to non-retina?

Looks to me like your image loading might be ignoring the Retina scale, so that the texture map is "2x too big" on the iPad.

Using Apple's method (my other answer) should fix that automatically, but if not: you could try making two copies of the image, one at current size (named "image@2x.png") and one at half size (resize in photoshop / preview.app / etc) (named "image.png")

Adam
  • 32,900
  • 16
  • 126
  • 153
  • Thanks for your reply. The problem is between simulator and the device. I imulator it works and in device it doesnt :( – 2vision2 Apr 02 '13 at 12:28
  • What happens if you use a RETINA simualator versus a NON RETINA simulator? (use the Hardware menu to switch) – Adam Apr 02 '13 at 13:59
2

I finally caved in and switched to GLKTextureLoader. As Adam mentions, it's pretty sturdy.

Here's an implementation which might work for you:

- (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);
}

I'll change it for the mtl2opengl project on GitHub soon...

Ricardo RendonCepeda
  • 3,271
  • 4
  • 23
  • 30