我已经创建了一个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)
我不确定为什么会这样?任何帮助将不胜感激!
答案 0 :(得分:5)
麻烦的是我反复生成纹理而没有删除它们。只需在生成之前添加一行就足以防止内存泄漏(似乎无需检查是否已生成纹理):
gl.glDeleteTextures(1, texturesFPS, 1);
gl.glGenTextures(1, texturesFPS, 1);
简单如下:)
答案 1 :(得分:3)
看起来每次调用loadFPSTexture()
时都会创建一个新纹理,并且永远不会释放它。一段时间后,这会导致内存不足,这可以解释日志中的EGL_BAD_ALLOC
。
最好只创建一次bitmap
,canvas
和texturesFPS
个变量,然后在loadFPSTexture
()函数中重复使用它们。在这种情况下,您应该使用GLUtils.texSubImage2D()
代替GLUtils.texImage2D()
,将新的位图数据上传到现有纹理。
答案 2 :(得分:0)
我还没有评论访问权限(频繁的其他'帮助'网站,只是起床了),但想回应(和upvoted)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个额外的数据行没有改变......)。
希望有所帮助!