1

私は OpenGL についてほとんど知らないので、優しくしてください。

アプリは (リソースから) ビットマップを読み込み、サイズを変更し、OpenGL テクスチャで使用する必要があります。動作する実装がありますが、Wildfire S にバンディングの問題がありました。そのため、実装を変更し、バンディングの問題を修正しました (ARGB_8888 に切り替えることで) が、Galaxy Nexus と Nexus One の機能が壊れました。

次の 3 つのビジュアル プレゼンテーションが表示されます。

  1. ビットマップ (滑らかな 24 ビット グラデーション) は、バンディングなしで正しく表示されます。

  2. グラデーションが表示されますが、明らかなバンディングがあります

  3. テクスチャがフラット ホワイトとして表示され、ビットマップが表示されない (または logcat の問題)

ビットマップをロードする方法の 2 つのバージョンと、それぞれの結果に関するメモを次に示します。

    // White on Galaxy Nexus. White on Nexus One. Renders correct image (no banding) on Wildfire S
    private Bitmap getBitmap1() {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        options.outWidth = getTextureSize();
        options.outHeight = getTextureSize();
        final Bitmap bmp;
        bmp = BitmapFactory.decodeResource(getResources(), bitmapResourceId, options);
        return bmp;
    }

    // Renders correctly (no banding) on Galaxy Nexus. Renders on Nexus One and Wildfire S but with obvious banding.
    private Bitmap getBitmap2() {
        int textureSize = getTextureSize();
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        options.outWidth = getTextureSize();
        options.outHeight = getTextureSize();
        final Bitmap bmp;
        bmp = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), bitmapResourceId, options), textureSize, textureSize, true);
        return bmp;
    }

getTextureSize() は 1024 を返します。

すべてのデバイスでバンディングなしでビットマップを表示し、どのデバイスも大きな白いボックスを表示しない単一のメソッドを構築するにはどうすればよいですか?

4

3 に答える 3

1

OpenGL.orgは、そのエラーについて次のように述べています。

GL_INVALID_VALUE, 0x0501: 値パラメーターがその関数のレベル値ではない場合に指定されます。これはローカルの問題に対してのみ与えられます。仕様が特定の状況で値を許可し、他のパラメーターまたは状態がそれらの状況を指示する場合、代わりに GL_INVALID_OPERATION が結果になります。

ステップ 1 は、問題の原因となっている正確な opengl 呼び出しを見つけることです。どの行がそのエラーをスローしているかを確認するには、試行錯誤を行う必要があります。プログラム フローを次のように設定すると、次のようになります。

glSomeCallA()
glGetError() //returns 0
glSomeCallB()
glGetError() //returns 0
glSomeCallC()  
glGetError() //returns 0x501

glSomeCallC次に、それがエラーの原因となった操作であることがわかります。その特定の呼び出しの man ページを見ると、特定のエラーが発生する可能性のあるすべてのものが列挙されています。

あなたの場合、私は肯定的ではありませんが、時間を節約するために glTexImage 呼び出しの後にエラーが発生すると推測します。

glTexImageの man ページを見ると、下部に無効な値のエラーを引き起こす可能性のあるすべてのものがリストされています。私の推測では、テクスチャが GL_MAX_TEXTURE_SIZE よりも大きいと思います。これをチェックすることで確認できますglGetIntegerv(GL_MAX_TEXTURE_SIZE);

于 2012-04-25T20:03:41.257 に答える
1

getBitmap1

outHeight と outWidth は、inJustDecodeBounds と組み合わせて使用​​されます。それらを使用して、スケーリングされたビットマップをロードすることはできません。白いテクスチャが表示されているのは、ビットマップが 2 のべき乗でないためです。

getBitmap2

後で再利用できるように、decodeResource によって返されたビットマップへの参照を保持する必要があります。options.inScaled = false;ビットマップのスケーリングされていないバージョンをロードするためにも使用 します。また、元のビットマップにアルファ チャネル ( Source )が含まれていない場合、 createScaledBitmap はビットマップの深さを RGB_565 に変更する可能性があることに注意してください。

質問: 元のビットマップ リソースは正方形ですか? そうでない場合、スケーリング コードによってアスペクト比が変更され、アーティファクトが発生する可能性があります。

編集:ビットマップをスケーリングしてビット深度を維持するにはどうすればよいですか? 最も簡単な解決策は、アルファ チャネルを含むビットマップを createScaledBitmap に渡すことです。次のように自分自身をスケーリングすることもできます。

                    Bitmap newBitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888);
                    Canvas canvas = new Canvas(newBitmap);
                    final int width = src.getWidth();
                    final int height = src.getHeight();
                    final float sx = 1024  / (float)width;
                    final float sy = 1024 / (float)height;
                    Matrix m = new Matrix();
                    m.setScale(sx, sy);
                    canvas.drawBitmap(src,m,null );
                    src.recycle();

別の編集:これに対処する方法については、この質問を参照してください。

于 2012-04-25T20:05:21.547 に答える
1

カラー バンディングが解決しました

カラー バンディングを 2 段階で解決しました

1) * BitmapFactory を使用してリソースをデコードする場合、ARGB_8888 を使用する代わりに、カラー バンディングを示す RGB565 でリソースをデコードするため、デコード オプションを ARGB_8888 に設定するために BitmapFactory.Options を使用しました。

2番目の問題は、ビットマップをスケーリングするたびに再びバンドができたことでした

2)これは難しい部分であり、多くの検索が必要で、最終的に機能しました*ビットマップをスケーリングするためのBitmap.createScaledBitmapメソッドも、スケーリング後に画像をRGB565形式に縮小しました。バンド画像を取得しました(これを解決するための古い方法は、少なくとも1つpng の透明なピクセルですが、jpg や bmp のような他の形式は機能しませんでした)そこで、CreateScaledBitmap メソッドを作成して、結果のスケール ビットマップで元のビットマップ構成を使用してビットマップをスケーリングしました (実際には、logicnet.dk による投稿からメソッドをコピーし、 Javaで翻訳)

    BitmapFactory.Options myOptions = new BitmapFactory.Options();
    myOptions.inDither = true;
    myOptions.inScaled = false;
    myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//important
    //myOptions.inDither = false;
    myOptions.inPurgeable = true;
    Bitmap tempImage =  
    BitmapFactory.decodeResource(getResources(),R.drawable.defaultart, myOptions);//important

    //this is important part new scale method created by someone else
    tempImage = CreateScaledBitmap(tempImage,300,300,false);

    ImageView v = (ImageView)findViewById(R.id.imageView1);
    v.setImageBitmap(tempImage);

// 関数

public static Bitmap CreateScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
{
    Matrix m = new Matrix();
    m.setScale(dstWidth  / (float)src.getWidth(), dstHeight / (float)src.getHeight());
    Bitmap result = Bitmap.createBitmap(dstWidth, dstHeight, src.getConfig());
    Canvas canvas = new Canvas(result);
    //using (var canvas = new Canvas(result))
    {
        Paint paint = new Paint();
        paint.setFilterBitmap(filter);
        canvas.drawBitmap(src, m, paint);
    }
    return result;

}

私が間違っている場合は修正してください。それがあなたのために働いたかどうかもコメントしてください。

私はそれを解決してとてもうれしいです、それがあなたのために働くことを願っています.

于 2012-04-26T18:03:00.217 に答える