views:

238

answers:

2

How much memory will consume a texture loaded with this method ?

With this method, will a 1024x1024 texture consume 4MB anyway ? ( regardless of loading it as RGBA4444 ) ?

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


// Dimensiones de nuestra imagen
imageSizeX= CGImageGetWidth(textureImage);
imageSizeY= CGImageGetHeight(textureImage);

textureWidth = NextPowerOfTwo(imageSizeX);  
textureHeight = NextPowerOfTwo(imageSizeY);


GLubyte *textureData = (GLubyte *)calloc(1,textureWidth * textureHeight * 4);

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 data to RGBA4444******************/   
//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;

// Ya no necesitamos el bitmap, lo liberamos
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);


//glEnable(GL_BLEND);

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

}

+1  A: 

In OpenGL, there is no way to find out how much video-memory a texture uses.

Also there is no single answer to the question to start with. Such details depend on graphic card, driver version, platform..

Nils Pipenbrinck
+2  A: 

The GL ES 1.1.12 specification (pdf) has this to say on the subject:

The GL stores the resulting texture with internal component resolutions of its own choosing. The allocation of internal component resolution may vary based on any TexImage2D parameter (except target), but the allocation must not be a function of any other state and cannot be changed once established.

However, according to the iphone dev center, RGBA4444 is natively supported. So I would expect it to consume 2MB with your code snippet. Do you have reasons to doubt it's using 2MB ?

Bahbar
I have doubts: Does the texture has mipmaps? Does the graphic chip needs alignment of the texture-scanlines (or blocks) in memory? If so, which alignment and how many bytes are wasted?
Nils Pipenbrinck
@Nils Pipenbrinck: Well, yes, the implementation may have some overhead. I may have read too much into the question, but it sounded like the author was wondering if the implementation would expand to RGBA8888. That, from the documentation, is not the case. As for mipmaps, well, it clearly loads only one level, and picks LINEAR filtering. I would be shocked if an embedded system would require the full mip-chain allocation when not in use. BTW, textures are generally tiled, not stored in scanlines. And... 1024 happens to fit most alignment reqs.
Bahbar
I know about an embedded graphic chip that can only start a texture or mipmap-level at an 8k boundary.. That blows up the memory requirements a lot.
Nils Pipenbrinck
@Nils Pipenbrinck: not 2MB, though. I'm curious now, which chip ?
Bahbar