3

OpenGL サーフェスを作成しましたが、すべて正常に動作しますが、次の方法を使用してテキストを描画しようとすると:

public void loadFPSTexture(GL10 gl){

    Bitmap bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.RGB_565);
    bitmap.eraseColor(Color.BLACK);
    Canvas canvas = new Canvas(bitmap);

    Paint textPaint = new Paint();
    textPaint.setTextSize(35);
    textPaint.setFakeBoldText(true);
    textPaint.setAntiAlias(true);
    textPaint.setARGB(255, 255, 255, 255);
    canvas.drawText("FPS "+reportedFramerate, 10,35, textPaint);
    gl.glGenTextures(1, texturesFPS, 0);

    gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesFPS[0]);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

    bitmap.recycle();
}

次に、 onDraw 関数で次のように使用します。

gl.glPushMatrix();
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesFPS[0]);
gl.glTranslatef(-surfaceSize.x/1.5f, surfaceSize.y/1.5f, 0.0f);
gl.glScalef(10, 10, 1.0f);
gl.glColor4f(1.0f, 1.0f, 1.0f, saturation_head); 
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureFPSBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,GL10.GL_UNSIGNED_SHORT, indexBuffer);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glPopMatrix();

奇妙なクラッシュが発生し、この時点以降、サーフェスを描画できません。Logcat は、次の一定のストリームを示します。

E/Adreno200-EGL( 2578): eglLockWindowSurface: failed to map the memory for fd=32 offs=1536000
E/SurfaceFlinger( 2578): GL error 0x0505
E/Adreno200-EGL( 2578): eglLockWindowSurface: failed to map the memory for fd=32 offs=1536000
E/Adreno200-EGL( 2578): egliSwapWindowSurface: oglSwapBuffer failed
E/SurfaceFlinger( 2578): eglSwapBuffers: EGL error 0x3003 (EGL_BAD_ALLOC)

なぜこれが起こっているのかわかりませんか?どんな助けでも大歓迎です!

4

3 に答える 3

5

問題は、テクスチャを削除せずに繰り返し生成していたことです。生成前に 1 行追加するだけで、メモリ リークを防ぐことができます (テクスチャが既に生成されているかどうかを確認する必要はないようです)。

 gl.glDeleteTextures(1, texturesFPS, 1);
 gl.glGenTextures(1, texturesFPS, 1);

そのような単純な :)

于 2011-02-28T16:05:57.203 に答える
3

を呼び出すたびに新しいテクスチャを作成しているように見えますがloadFPSTexture()、解放することはありません。しばらくすると、これによりメモリが不足EGL_BAD_ALLOCし、ログに記録される可能性があります。

bitmapcanvasおよびtexturesFPS変数を一度だけ作成し、それらをloadFPSTexture() 関数で再利用することをお勧めします。その場合、新しいビットマップ データを既存のテクスチャにアップロードするには、おそらくGLUtils.texSubImage2D()の代わりに を使用する必要があります。GLUtils.texImage2D()

于 2011-01-22T15:39:29.153 に答える
0

私はまだコメントへのアクセス権を持っていません (頻繁に他の「ヘルプ」サイト、SO に立ち上がったばかりです) が、svdree のメモをエコー (および賛成) し、詳細を追加したかった - GLES を始めた他の人は確かに同様のヒットになるため問題。

ビットマップ、キャンバス、テクスチャ (およびペイント!) は、最初に gles リソースを設定する場所で一度作成する必要があります。アプリのリソースをクリーンアップするときに、それらを削除する必要があります。ビットマップ/テクスチャのサイズを変更しない限り、再作成は不必要にメモリ (CPU と GPU) をスラッシングします。

テクスチャの最初の作成では、GLUtils.texImage2D 関数を使用してテクスチャを準備します (ビットマップをそのままアップロードでき、データは気にしません)。これにより、ドライバーによってテクスチャが確実に割り当てられ、適切な幅/高さのバッファーが後で更新できるようになります。

fps のレンダリングは次のようになります。

s_bitmap.eraseColor(Color.BLACK);
s_canvas.drawText("FPS "+reportedFramerate, 10, 35, s_textPaint);
gl.glBindTexture(GL10.GL_TEXTURE_2D, s_texturesFPS[0]);
GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, s_bitmap);

... 以上です。桁違いに高速で、明らかにはるかにクリーンです。:-)

たとえば、fps が描画されているビットマップの四角形のみを消去/塗りつぶし、gl.glTexSubImage2D を直接使用して、テキストがレンダリングされる行のみをアップロードします (クリアとアップロードを節約し、変更されていない余分な 220 行のデータがあるとします...)。

それが役立つことを願っています!

于 2011-08-24T17:14:23.313 に答える