在AR云渲染服务中,有时候需要把生成的纹理保存到图片来进行调试。
那就想办法看看存成图片,很多人说用glGetTexImage这个函数可以直接读取纹理的数据,但是我们用到了opengl es 32版本,不支持这个函数,想了办法,把纹理绑定到framebuffer,然后用glReadPixels读取出来,然后在保存图片。
具体实现如下:
private void saveRgb2Bitmap(Buffer buf, String filename, int width, int height) {
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(filename));
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bmp.copyPixelsFromBuffer(buf);
bmp.compress(Bitmap.CompressFormat.PNG, 90, bos);
bmp.recycle();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void saveTextureToImage(int textureID, int width, int height, String fileName) {
int[] frameBuffer = new int[1];
GLES32.glGenFramebuffers(1, frameBuffer, 0);
GLES32.glBindFramebuffer(GLES32.GL_FRAMEBUFFER, frameBuffer[0]);
GLES32.glFramebufferTexture2D(GLES32.GL_FRAMEBUFFER, GLES32.GL_COLOR_ATTACHMENT0, GLES32.GL_TEXTURE_2D, textureID, 0);
GLES32.glDrawBuffers(1, new int[]{GLES32.GL_COLOR_ATTACHMENT0}, 0);
if (GLES32.glCheckFramebufferStatus(GLES32.GL_FRAMEBUFFER) != GLES32.GL_FRAMEBUFFER_COMPLETE) {
Log.e(TAG, "framebuffer not complete");
return;
}
ByteBuffer rgbaBuf = ByteBuffer.allocateDirect(width * height * 4);
rgbaBuf.position(0);
GLES32.glReadPixels(0, 0, width, height, GLES32.GL_RGBA, GLES32.GL_UNSIGNED_BYTE, rgbaBuf);
saveRgb2Bitmap(rgbaBuf, fileName, width, height);
GLES32.glDeleteFramebuffers(1, IntBuffer.wrap(frameBuffer));
GLES32.glBindFramebuffer(GLES32.GL_FRAMEBUFFER, 0);
ShaderUtil.checkGlError(TAG, "glCsInit end.");
}
在其他地方调用就可以了。
String destDir = mContext.getExternalFilesDir(null).getAbsolutePath();
String fileName = destDir + "/" + System.nanoTime() + ".png";
saveTextureToImage(mCsImageIDs[1], width / 2, height, fileName);
glReadPixels函数是一个非常耗时的操作,我们只能当做调试来用。
参考文献:
https://blog.piasy.com/2016/06/14/Open-gl-es-android-2-part-2/index.html
https://stackoverflow.com/questions/53993820/opengl-es-2-0-android-c-glgetteximage-alternative