テクスチャを OpenGL にロードする方法があります。
bool AndroidGraphicsManager::setTexture(
UINT& id, UCHAR* image, UINT width, UINT height,
bool wrapURepeat, bool wrapVRepeat, bool useMipmaps)
{
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA,
width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, (GLvoid*) image);
int minFilter = GL_LINEAR;
if (useMipmaps) {
glGenerateMipmap(GL_TEXTURE_2D);
minFilter = GL_NEAREST_MIPMAP_NEAREST;
}
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
int wrap_u = wrapURepeat ?
GL_REPEAT : GL_CLAMP_TO_EDGE;
int wrap_v = wrapVRepeat ?
GL_REPEAT : GL_CLAMP_TO_EDGE;
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_WRAP_S, wrap_u);
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_WRAP_T, wrap_v);
glBindTexture(GL_TEXTURE_2D, 0);
return !checkGLError("Loading texture.");
}
これはうまくいきます。libpng を使用してテクスチャを読み込みます。これにより、符号なし文字の配列が得られます。次に、この配列を上で指定したメソッドに渡します。写真は 32 ビットなので、UCHAR 配列では各 UCHAR に単一の色成分が含まれ、4 つの UCHAR が 1 つのピクセルを構成すると仮定します。16 ビット テクスチャを使用してみました。GL_UNSIGNED_BYTE を GL_UNSIGNED_SHORT_4_4_4_4 に変更しました。しかし、どうやらこれだけでは不十分な ようです。16 ビット テクスチャを適切に表示できるようにするには、他に何を変更すればよいでしょうか?
[編集] @DatenWolfが提案したように、このコードを使用してみました:
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA4,
width, height, 0, GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4, (GLvoid*) image);
Linux バージョンのエンジンで使用しましたが、結果は以前の Android スクリーンショットとまったく同じでした。では、libpng と、それが私の UCHAR 配列を生成する方法に問題があると想定しても安全でしょうか?
[EDIT2]ようやく 32bit テクスチャを 16bit に圧縮できました。必要だったのは、32 ビット テクスチャ データの単純な反復と、32 ビットを 16 ビットに圧縮するためのいくつかのビットシフト操作だけでした。
void* rgba8888ToRgba4444(void* in, int size) {
int pixelCount = size / 4;
ULONG* input = static_cast<ULONG*>(in);
USHORT* output = new USHORT[pixelCount];
for (int i = 0; i < pixelCount; i++) {
ULONG pixel = input[i];
// Unpack the source data as 8 bit values
UINT r = pixel & 0xff;
UINT g = (pixel >> 8) & 0xff;
UINT b = (pixel >> 16) & 0xff;
UINT a = (pixel >> 24) & 0xff;
// Convert to 4 bit vales
r >>= 4; g >>= 4; b >>= 4; a >>= 4;
output[i] = r << 12 | g << 8 | b << 4 | a;
}
return static_cast<void*>(output);
}
モバイル デバイスではパフォーマンスが向上すると考えていましたが、Galaxy SIII では残念ながらパフォーマンスの向上は見られませんでした。