在OpenGLA的RGBA4444 RGBA5551中创建和加载.png [英] Creating and loading .pngs in RGBA4444 RGBA5551 for openGL

查看:90
本文介绍了在OpenGLA的RGBA4444 RGBA5551中创建和加载.png的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个openGL游戏,到目前为止,我一直在使用RGBA8888格式的.png作为纹理表,但是它们占用的内存过多,并且我的应用程序经常崩溃.我在Apple网站上读到,这种格式仅在需要太多质量时才使用,建议使用RGBA4444和RGBA5551(我已经将纹理转换为PVR,但是大多数Sprite表的质量损失都太大了).

I'm creating an openGL game and so far I have been using .pngs in the RGBA8888 format as texture sheets, but those are too memory hungry, and my app crashes frequently. I read in Apple's site that such format such be used just when too much quality is needed, and recommends to use RGBA4444 and RGBA5551 instead ( I already converted my textures to PVR but the quality loss is too great in most of the sprite sheets).

我只需要在我的纹理加载器类中的glTexImage2D调用中使用GL_UNSIGNED_SHORT_5_5_5_1或GL_UNSIGNED_SHORT_4_4_4_4来加载我的纹理,但是我需要将我的纹理表转换为RGBA4444和RGBA5551,并且我一无所知这个.

I only need to use GL_UNSIGNED_SHORT_5_5_5_1 or GL_UNSIGNED_SHORT_4_4_4_4 in my glTexImage2D call inside my texture loader class in order to load my textures, but I need to convert my texture sheets to RGBA4444 and RGBA5551, and I'm clueless about how could I achieve this.

推荐答案

是认真的吗?有一些库可以进行这种转换.但是坦率地说,这有点混乱.有一些库使用asm或专用的SSE命令来加速它,这很快,但是用C/C ++滚动您自己的格式转换器很容易. 您的基本过程将是:

Seriously? There are libraries to do this kind of conversion. But frankly, this is a bit of bit twiddling. There are libraries that use asm, or specialized SSE commands to accellerate this which will be fast, but its pretty easy to roll your own format converter in C/C++. Your basic process would be:

  • 提供RGBA8888编码值的缓冲区
  • 创建一个足以容纳RGBA4444或RGBA5551值的缓冲区.在这种情况下,它很简单-只有一半大小.
  • 环回源缓冲区,解压缩每个组件,然后重新打包为目标格式,然后将其写入目标缓冲区.

  • Given a buffer of RGBA8888 encoded values
  • Create a buffer big enough to hold the RGBA4444 or RGBA5551 values. In this case, its simple - half the size.
  • Loop over the source buffer, unpacking each component, and repacking into the destination format, and write it into the destination buffer.

void* rgba8888_to_rgba4444(
  void* src, // IN, pointer to source buffer
  int cb)    // IN size of source buffer, in bytes
{
  // this code assumes that a long is 4 bytes and short is 2.
  //on some compilers this isnt true
  int i;
  // compute the actual number of pixel elements in the buffer.
  int cpel = cb/4;
  unsigned long* psrc = (unsigned long*)src;
  // create the RGBA4444 buffer
  unsigned short* pdst = (unsigned short*)malloc(cpel*2);
  // convert every pixel
  for(i=0;i<cpel; i++)
  {
    // read a source pixel
    unsigned pel = psrc[i];
    // unpack the source data as 8 bit values
    unsigned r = p & 0xff;
    unsigned g = (pel >> 8) & 0xff;
    unsigned b = (pel >> 16) & 0xff; 
    unsigned a = (pel >> 24) & 0xff;
    //convert to 4 bit vales
    r >>= 4;
    g >>= 4;
    b >>= 4;
    a >>= 4;
    // and store
    pdst[i] = r | g << 4  | b << 8 | a << 12;
  }
  return pdst;
} 

我做的实际转换循环非常浪费,可以通过一次提取,转换和重新打包组件,从而获得了更快的代码.我这样做是为了使转换明确且易于更改.另外,我不确定我是否以正确的方式获得了组件订单.因此它可能是b,r,g,a,但它不会以相同的顺序重新打包到dest缓冲区中,因此不会影响函数的结果.

The actual conversion loop I did very wastefully, the components can be extracted, converted and repacked in a single pass, making for far faster code. I did it this way to make the conversion explicit, and easy to change. Also, im not sure that I got the component order the right way around. So it might be b, r, g, a, but it shouldn't effect the result of the function as it repackes in the same order into the dest buffer.

这篇关于在OpenGLA的RGBA4444 RGBA5551中创建和加载.png的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆