views:

149

answers:

2

I'm a noob in openGL and trying to learn as much as possible. I'm using this method to load my openGL textures, loading every .png as RGBA4444. I'm doing anything incorrect ?

- (void)loadTexture:(NSString*)nombre {

    CGImageRef textureImage     =[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:nombre ofType:nil]].CGImage; 
    if (textureImage == nil) {
        NSLog(@"Failed to load texture image");
        return;
    }

    textureWidth = NextPowerOfTwo(CGImageGetWidth(textureImage));   
    textureHeight = NextPowerOfTwo(CGImageGetHeight(textureImage));

    imageSizeX= CGImageGetWidth(textureImage);
    imageSizeY= CGImageGetHeight(textureImage);

    GLubyte *textureData = (GLubyte *)calloc(1,textureWidth * textureHeight * 4); // Por 4 pues cada pixel necesita 4 bytes, RGBA

    CGContextRef textureContext = CGBitmapContextCreate(textureData, textureWidth,textureHeight,8, textureWidth * 4,CGImageGetColorSpace(textureImage),kCGImageAlphaPremultipliedLast );
    CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)textureWidth, (float)textureHeight), textureImage);

    //Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA"
    void *tempData = malloc(textureWidth * textureHeight * 2);
    unsigned int* inPixel32 = (unsigned int*)textureData;
    unsigned short* outPixel16 = (unsigned short*)tempData;
    for(int i = 0; i < textureWidth * textureHeight ; ++i, ++inPixel32)
        *outPixel16++ = 
        ((((*inPixel32 >> 0) & 0xFF) >> 4) << 12) | // R
        ((((*inPixel32 >> 8) & 0xFF) >> 4) << 8) | // G
        ((((*inPixel32 >> 16) & 0xFF) >> 4) << 4) | // B
        ((((*inPixel32 >> 24) & 0xFF) >> 4) << 0); // A


    free(textureData);
    textureData = tempData;

    CGContextRelease(textureContext);

    glGenTextures(1, &textures[0]);

    glBindTexture(GL_TEXTURE_2D, textures[0]);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 , textureData);

    free(textureData);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   
}

And this is my dealloc method:

- (void)dealloc {
     glDeleteTextures(1,textures);
    [super dealloc];
}
A: 

I'm not quite sure about the API related issues, but at least it seems that you're changing the colour component ordering when repacking (RGBA->ABGR), and the bitwise expression could be expressed better:

for(int i = 0; i < textureWidth * textureHeight; i++)
        outPixel16[i] = (inPixel32[i] >> 4  & 0xF) |
                        (inPixel32[i] >> 12 & 0xF) |
                        (inPixel32[i] >> 20 & 0xF) |
                        (inPixel32[i] >> 28 & 0xF);

BTW, where does textures come from? Is it a global?

fortran
It's not global, it's just a variable where I save the texture id.GLuint textures[1];
José Joel.
I cannot see it's declaration in the local scope... Maybe I'm missing something.
fortran
I'm sorry, It's a member of a Texture class. That load method serves to load my texture when I construct an object of the class.
José Joel.
A: 

Why do you ask? Does it not look right on the screen?

Apart from the endian ickiness in *outPixel16++ = blah; my first reaction
was surprise that the iPhone supported GL_UNSIGNED_SHORT_4_4_4_4.

Whenever using GL, make sure your context is active, using
[EAGLContext setCurrentContext:context];

Rhythmic Fistman