Texture mapping in GLKit is not working only in de

2020-06-17 04:26发布

问题:

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:

The same code in device gives the following output:

Is There something i`m missing?

回答1:

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...



回答2:

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


回答3:

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")