Android Рисование текста с помощью opengl es вылетает через несколько минут - PullRequest
3 голосов
/ 22 января 2011

Я создал поверхность 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)

Я не уверен, почему это происходит?любая помощь будет высоко ценится!

Ответы [ 3 ]

5 голосов
/ 28 февраля 2011

Проблема в том, что я неоднократно генерировал текстуры, даже не удаляя их.Простого добавления одной строки перед генерацией достаточно для предотвращения утечки памяти (кажется, нет необходимости проверять, что текстура уже создана):

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

Просто так:)

3 голосов
/ 22 января 2011

Похоже, вы создаете новую текстуру каждый раз, когда вызываете loadFPSTexture(), и никогда не отпускаете ее.Через некоторое время это приведет к нехватке памяти, что может объяснить EGL_BAD_ALLOC в ваших журналах.

Было бы лучше создать переменные bitmap, canvas и texturesFPS простои повторно использовать их в функции loadFPSTexture ().В этом случае вам, вероятно, следует использовать GLUtils.texSubImage2D() вместо GLUtils.texImage2D() для загрузки новых растровых данных в существующую текстуру.

0 голосов
/ 24 августа 2011

У меня пока нет доступа к комментариям (часто другие «справочные» сайты, просто встаю на 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 дополнительных строк данных, которые не меняются ...).

Надеюсь, это поможет!

...