0

テクスチャを 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 では残念ながらパフォーマンスの向上は見られませんでした。 ここに画像の説明を入力

4

2 に答える 2

1

このような場合は、 devilのような画像ライブラリを使用するのがおそらく最善でしょう。

しかし、libpbg から取得した画像データを変換したい場合は、以下のコードと同様のことを行うことができます。

これを行うときは、速度とサイズを交換することに注意してください。

struct Color {
unsigned char r:4;
unsigned char g:4;
unsigned char b:4;
unsigned char a:4;
};

float factor = 16 / 255;

Color colors[imgWidth*imgHeight];

for(int i = 0; i < imgWidth*imgHeight; ++i)
{
    colors[i].r = image[i*4]*factor;
    colors[i].g = image[i*4+1]*factor;
    colors[i].b = image[i*4+2]*factor;
    colors[i].a = image[i*4+3]*factor;
}
于 2013-05-15T08:26:27.263 に答える
1

でもどうやらこれだけでは足りないようです

変更したトークンは、OpenGL に渡された配列内のデータの形式を伝えます。そのため、これも調整する必要があります。ただし、特定の形式に強制しなかったため、OpenGL は必要な任意の内部形式に変換できます。これが、内部形式パラメーターの目的です (外部データ型とは独立して機能します)。したがって、内部的に 16 ビットの解像度が必要な場合は、内部フォーマット パラメータを に変更する必要がありますGL_RGBA4。データは、1 ピクセルあたり 8 ビットの形式のままである場合があります。だからあなたの場合

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RGBA4,
    width, height, 0, GL_RGBA,
    …, (GLvoid*) image);

type パラメーターは、データのレイアウトと一致する必要があります。元のピクセルあたり 8 ビットの場合は、GL_UNSIGNED_BYTE です。ただし、ushorts ニブルに事前にパッケージ化された RGBA の場合、GL_UNSIGNED_SHORT_4_4_4_4

于 2013-05-15T05:56:33.400 に答える