2012-08-25 21 views
11

Androidエミュレータのテクスチャ破損に問題があります(ほとんどのアンドロイドデバイスで正常に動作します)。Android OpenGLテクスチャ破損

Android 4.1 reference rendering

上の写真は、それが必要としてすべてが見え、アンドロイド4.1ジェリービーンを実行しているエミュレータによって生成された基準レンダリングです。

Android 1.6

第二の画像は、アンドロイド1.6を実行しているエミュレータに捕捉されます。無効ツールバーボタンの一部の破損に注意し

Android 1.6

第三の画像が同じエミュレータに捕捉される(それらは色1F、1F、1F、0.5Fでレンダリングされます)。違いは、スコアは右上隅に表示されることです。スコアはビットマップフォントで、テクスチャはアルファマスクです。スコアの後にレンダリングされたものはすべて、テクスチャが失われます。前のスクリーンショットには、同じ方法でレンダリングされたビットマップフォントも含まれていました(しかし、異なるテクスチャを使用しています)。

サムスンのデバイスの1つにも同様の問題がありました(モデルは覚えていません)。フロアテクスチャがレンダリングされると、その後にレンダリングされるすべてのテクスどちらか一方がテクスチャをバインドしていないときはテクスチャをバインドしていましたが、それを使って三角形を描いていないときはc)もう一度pngアセットを作り直してみてください。

OpenGLの設定:

gl.glDisable(GL10.GL_LIGHTING); 
gl.glDisable(GL10.GL_CULL_FACE); 
gl.glDisable(GL10.GL_DEPTH_TEST); 
gl.glDisable(GL10.GL_DITHER); 
gl.glDepthMask(false); 
gl.glEnable(GL10.GL_TEXTURE_2D); 
gl.glBlendFunc(GL10.GL_ONE,GL10.GL_ONE_MINUS_SRC_ALPHA); 
gl.glShadeModel(GL10.GL_FLAT); 
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE); 

テクスチャがロードされている方法:

public void doGLLoading(Engine renderer) { 
     GL10 gl=renderer.getGl(); 
     int[] ids=new int[1]; 
     gl.glGenTextures(1, ids,0); 
     id=ids[0]; 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, id); 
     Log.d("SpriteDraw", String.format("Texture %s has format %s",getPath(),bitmap.getConfig().toString())); 
     buildMipmap(gl, bitmap); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER, minFilter); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER, magFilter); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S, textureWrapS); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T, textureWrapT); 
    } 
private void buildMipmap(GL10 gl, Bitmap bitmap) { 
    int level = 0; 
    int height = bitmap.getHeight(); 
    int width = bitmap.getWidth(); 

    while (height >= 1 || width >= 1) { 
     // First of all, generate the texture from our bitmap and set it to 
     // the according level 
        //TextureUtils.texImage2D(gl, GL10.GL_TEXTURE_2D, level, -1, bitmap, -1, 0); 
     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bitmap, 0); 
     if (height == 1 || width == 1) { 
      break; 
     } 
     // Increase the mipmap level 
     level++; 
     height /= 2; 
     width /= 2; 
     Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, 
       true); 

     // Clean up 
     bitmap.recycle(); 
     bitmap = bitmap2; 
    } 
} 

注:フォントがgl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);GL10.glDrawArraysを使用してレンダリングされます。この破損は1.6エミュレータだけでなく、アンドロイド2.xシリーズにも影響しますが、アルファマスクはまだ間違ってレンダリングされています。すべてのアセットは、2つのビットマップの累乗として正しくロードされます。

+0

テクスチャのディメンションは2のべき乗ですか? superPngやPngを使用していますか?通常のPNGファイルではアルファをマスクとして正しく予約していません。 superPngはそれを予約することができます。 Photoshop用のプラグインがsuperPngとしてエクスポートされています – Behnam

+0

はい、それらはすべてPower of Twoです(記事の最後に記載されています)。ビットマップはグレースケールビットマップとして格納され、アンドロイドによってARGB_8888としてロードされ、自分のコードでアルファマスクに変換されます。 – rkapl

答えて

2
  1. 私は(それ何?)、32ビットテクスチャではなく、グレースケールを使用していない「alphamasks」
  2. あなたのテクスチャのサイズを確認し、それが最大サイズ(glGetInteger(GL_MAX_TEXTURE_SIZE)を超えないようにしてください示唆している。また、あなたのSHURE作りますテクスチャは2の累乗です。それ以前に言いましたが、スケーラブルアセット(drawable_x_dpiフォルダ)にある場合は、アンドロイドでスケーリングされます。スケーリングを避けるには、「生の」フォルダに入れてください。
  3. テスト、ミップマップを含むすべてのフィルタリングを無効にしようとする - GL_TEXTURE_WRAP_S、GL_TEXTURE_WRAP_TをGL_NEARESTに設定する
+0

アルファマスクは、アルファチャンネルのみを持つテクスチャです。彼らはうまくいくはずです。すべてのテクスチャは実際には2つのビットマップの累乗としてロードされます(リソースIDではなく 'InputStream'を使ってロードされるため、スケーリングされません)。フィルタリングに関しては、あなたは 'GL_TEXTURE_MIN_FILTER'を意味すると思います。 'GL_NEAREST'に設定しても問題は解決されません。 – rkapl

+0

はい、私はGL_TEXTURE_MIN_FILTERを意味しました。 次は、正常に動作するテクスチャにグリッチするテクスチャファイルを置き換えることです。テクスチャの読み込みや使用方法に問題があるかどうかを知ることができます。 – Dave