OpenGL ES на IOS тэкстуры загрузкі - як я атрымліваю ад RGBA8888 .png файл у RGB565 тэкстуры?

таму я працую з кучай 2048x2048 спрайт лістоў, якія запаўняюць памяць даволі хутка. Як, я выкарыстоўваю наступны метад (праз Ray Wenderlich), каб загрузіць тэкстуру:

- (GLuint)setupTexture:(NSString *)fileName 
{    
    CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage;
    if (!spriteImage) 
    {
        NSLog(@"Failed to load image %@", fileName);
        exit(1);
    }
    size_t width = CGImageGetWidth(spriteImage);
    size_t height = CGImageGetHeight(spriteImage);
    GLubyte * spriteData = (GLubyte *) calloc(width*height*4, sizeof(GLubyte));
    CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8,     width*4,CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);    
    CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
    CGContextRelease(spriteContext);
    GLuint texName;
    glGenTextures(1, &texName);
    glBindTexture(GL_TEXTURE_2D, texName);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
    GLenum err = glGetError();
    if (err != GL_NO_ERROR)
        NSLog(@"Error uploading texture. glError: 0x%04X", err);    
    free(spriteData);        
    return texName;    
}

так што маё пытанне, як я адкідаць альфа інфармацыю з CGImage, затым «дэкадуе" малюнкі на меншую колькасць біт на піксель, і, нарэшце, сказаць OpenGL пра гэта?

4

3 адказы

Я выкарыстоўваю гэты код, каб пераўтварыць дадзеныя, напісаныя CGContextDrawImage у RGB565. Ён выкарыстоўвае аптымізаваны код NEON для апрацоўкі 8 пікселяў адначасова на прыладах з падтрымкай NEON (кожная прылада IOS, які працуе ARMv7 код мае такі чып). Элемент дадзеныя паказальнік, які вы бачыце там жа, як ваш spriteData паказальнік, я быў занадта лянівы, каб перайменаваць яго.

void *temp = malloc(width * height * 2);
uint32_t *inPixel32  = (uint32_t *)data;
uint16_t *outPixel16 = (uint16_t *)temp;
uint32_t pixelCount = width * height;

#ifdef __ARM_NEON__
for(uint32_t i=0; i> 0)  & 0xFF) >> 3);
    uint32_t g = (((*inPixel32 >> 8)  & 0xFF) >> 2);
    uint32_t b = (((*inPixel32 >> 16) & 0xFF) >> 3);

    *outPixel16++ = (r << 11) | (g << 5) | (b << 0);               
}
#endif

free(data);
data = temp;
7
дададзена
цудоўны! прыйшлося змяніць лінію glTexImage2D да наступных параметрах: glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, шырыня, вышыня, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, spriteData);
дададзена аўтар Jakob, крыніца
Вялікі адказ, вы не бачыце шмат кода NEON там. Каб быць больш апаратна-агностыку, вы глядзелі на рэалізацыю гэтага з дапамогай Паскорыць рамкі?
дададзена аўтар Brad Larson, крыніца
@BradLarson Так, гэта была мая першая спроба, але для мяне аснова паскарэння выкарыстоўвае яшчэ больш загадкавыя імёны, і я паняцця не меў, што шукаць. Я таксама хацеў прызначацца iOS 3.0 і, такім чынам, я вырашыў выкарыстаць NEON «непасрэдна», так як ён будзе таксама працаваць на iOS 3.x.
дададзена аўтар JustSid, крыніца
<Код> uint8x8_t тып вызначаны ў arm_neon.h
дададзена аўтар brigadir, крыніца

Замест таго, каб проста змена каляровага, я мог бы прапанаваць выкарыстоўваць PVRTC сціснутых тэкстур тут. Гэта павінна выкарыстоўваць значна менш памяці на GPU, чым нават версію RGB565, таму што гэтыя тэкстуры застаюцца сціснутымі, а не пашыраецца ў несціснутых растравых малюнкаў.

У "PVRTextureLoader sample application, іI reused some of that code to load PVRTC textures in a textured cube sample application I slapped together. You can look at the "Encode Images" build phase in the PVRTextureLoader for how to script the conversion of PNG textures into PVRTC ones at compile time.

3
дададзена
Ваш адказ прапанаваў мне паглядзець на прыкладзе PVRTexturLoader зноў. Я спрабаваў прымусіць яго працаваць з маімі тэкстурамі ноччу і не ўдалося, але я атрымаў гэта працуе. Вялізныя след памяці паляпшэння! Дзякуючы г-н Ларсан
дададзена аўтар Jakob, крыніца

Паглядзіце на параметр internalFormat. Можа быць, вы маглі б паказаць GL_R3_G3_B2 выкарыстоўваць толькі 8 біт на піксель ці GL_RGB5 можа быць карысным. Ёсць некалькі варыянтаў, якія могуць быць карысныя.

См тэкстуры Унутраныя фарматы для атрымання дадатковай інфармацыі.

0
дададзена