GlSurfaceViewRenderer: Capture graph output texture
Captures the original graph output texture, not what has been copied to the screen. This will be important for zooming to prevent top/bottom letterboxes, and it preserves the original quality, so that high resolution images can be used. PiperOrigin-RevId: 570604422
This commit is contained in:
parent
da8fcb6bb2
commit
9bb042cc86
|
@ -21,6 +21,7 @@ import android.graphics.Bitmap;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
import android.opengl.GLES11Ext;
|
import android.opengl.GLES11Ext;
|
||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
|
import android.opengl.GLES31;
|
||||||
import android.opengl.GLSurfaceView;
|
import android.opengl.GLSurfaceView;
|
||||||
import android.opengl.Matrix;
|
import android.opengl.Matrix;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -204,11 +205,36 @@ public class GlSurfaceViewRenderer implements GLSurfaceView.Renderer {
|
||||||
// Capture Bitmap if requested.
|
// Capture Bitmap if requested.
|
||||||
BitmapCaptureListener bitmapCaptureListener = this.bitmapCaptureListener;
|
BitmapCaptureListener bitmapCaptureListener = this.bitmapCaptureListener;
|
||||||
if (captureNextFrameBitmap.getAndSet(false) && bitmapCaptureListener != null) {
|
if (captureNextFrameBitmap.getAndSet(false) && bitmapCaptureListener != null) {
|
||||||
int bitmapSize = surfaceWidth * surfaceHeight;
|
// Find the name of the bound texture.
|
||||||
|
int[] texName = new int[1];
|
||||||
|
if (surfaceTexture != null) {
|
||||||
|
GLES20.glGetIntegerv(GLES11Ext.GL_TEXTURE_BINDING_EXTERNAL_OES, texName, 0);
|
||||||
|
} else {
|
||||||
|
texName[0] = frame.getTextureName();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find texture size and create byte buffer large enough to hold an RGBA image.
|
||||||
|
int[] texDims = new int[2];
|
||||||
|
GLES31.glGetTexLevelParameteriv(textureTarget, 0, GLES31.GL_TEXTURE_WIDTH, texDims, 0);
|
||||||
|
GLES31.glGetTexLevelParameteriv(textureTarget, 0, GLES31.GL_TEXTURE_HEIGHT, texDims, 1);
|
||||||
|
int texWidth = texDims[0];
|
||||||
|
int texHeight = texDims[1];
|
||||||
|
int bitmapSize = texWidth * texHeight;
|
||||||
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmapSize * 4);
|
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmapSize * 4);
|
||||||
byteBuffer.order(ByteOrder.nativeOrder());
|
byteBuffer.order(ByteOrder.nativeOrder());
|
||||||
|
|
||||||
|
// Read pixels from texture.
|
||||||
|
int[] fbo = new int[1];
|
||||||
|
GLES20.glGenFramebuffers(1, fbo, 0);
|
||||||
|
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);
|
||||||
|
GLES20.glFramebufferTexture2D(
|
||||||
|
GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, texName[0], 0);
|
||||||
GLES20.glReadPixels(
|
GLES20.glReadPixels(
|
||||||
0, 0, surfaceWidth, surfaceHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuffer);
|
0, 0, texWidth, texHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuffer);
|
||||||
|
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
|
||||||
|
GLES20.glDeleteFramebuffers(1, fbo, 0);
|
||||||
|
ShaderUtil.checkGlError("capture frame");
|
||||||
|
|
||||||
int[] pixelBuffer = new int[bitmapSize];
|
int[] pixelBuffer = new int[bitmapSize];
|
||||||
byteBuffer.asIntBuffer().get(pixelBuffer);
|
byteBuffer.asIntBuffer().get(pixelBuffer);
|
||||||
for (int i = 0; i < bitmapSize; i++) {
|
for (int i = 0; i < bitmapSize; i++) {
|
||||||
|
@ -218,10 +244,17 @@ public class GlSurfaceViewRenderer implements GLSurfaceView.Renderer {
|
||||||
| ((pixelBuffer[i] & 0x000000ff) << 16)
|
| ((pixelBuffer[i] & 0x000000ff) << 16)
|
||||||
| ((pixelBuffer[i] & 0x00ff0000) >> 16);
|
| ((pixelBuffer[i] & 0x00ff0000) >> 16);
|
||||||
}
|
}
|
||||||
Bitmap bitmap = Bitmap.createBitmap(surfaceWidth, surfaceHeight, Bitmap.Config.ARGB_8888);
|
|
||||||
|
// Send bitmap.
|
||||||
|
Bitmap bitmap = Bitmap.createBitmap(texWidth, texHeight, Bitmap.Config.ARGB_8888);
|
||||||
bitmap.setPixels(
|
bitmap.setPixels(
|
||||||
pixelBuffer, /* offset= */bitmapSize - surfaceWidth, /* stride= */-surfaceWidth,
|
pixelBuffer,
|
||||||
/* x= */0, /* y= */0, surfaceWidth, surfaceHeight);
|
/* offset= */ bitmapSize - texWidth,
|
||||||
|
/* stride= */ -texWidth,
|
||||||
|
/* x= */ 0,
|
||||||
|
/* y= */ 0,
|
||||||
|
texWidth,
|
||||||
|
texHeight);
|
||||||
bitmapCaptureListener.onBitmapCaptured(bitmap);
|
bitmapCaptureListener.onBitmapCaptured(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user