package com.af.experiments.FxCameraApp.renderer;
import android.graphics.Bitmap;
import com.af.experiments.FxCameraApp.Utils.OpenGlUtils;
import java.nio.IntBuffer;
import static android.opengl.GLES20.*;
public class GLES20FramebufferObject {
private int mWidth;
private int mHeight;
private int mFramebufferName;
private int mRenderbufferName;
private int mTexName;
public int getWidth() {
return mWidth;
}
public int getHeight() {
return mHeight;
}
public int getTexName() {
return mTexName;
}
public void setup(final int width, final int height) {
final int[] args = new int[1];
glGetIntegerv(GL_MAX_TEXTURE_SIZE, args, 0);
if (width > args[0] || height > args[0]) {
throw new IllegalArgumentException("GL_MAX_TEXTURE_SIZE " + args[0]);
}
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, args, 0);
if (width > args[0] || height > args[0]) {
throw new IllegalArgumentException("GL_MAX_RENDERBUFFER_SIZE " + args[0]);
}
glGetIntegerv(GL_FRAMEBUFFER_BINDING, args, 0);
final int saveFramebuffer = args[0];
glGetIntegerv(GL_RENDERBUFFER_BINDING, args, 0);
final int saveRenderbuffer = args[0];
glGetIntegerv(GL_TEXTURE_BINDING_2D, args, 0);
final int saveTexName = args[0];
release();
try {
mWidth = width;
mHeight = height;
glGenFramebuffers(args.length, args, 0);
mFramebufferName = args[0];
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);
glGenRenderbuffers(args.length, args, 0);
mRenderbufferName = args[0];
glBindRenderbuffer(GL_RENDERBUFFER, mRenderbufferName);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mRenderbufferName);
glGenTextures(args.length, args, 0);
mTexName = args[0];
glBindTexture(GL_TEXTURE_2D, mTexName);
OpenGlUtils.setupSampler(GL_TEXTURE_2D, GL_LINEAR, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexName, 0);
final int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
throw new RuntimeException("Failed to initialize framebuffer object " + status);
}
} catch (final RuntimeException e) {
release();
throw e;
}
glBindFramebuffer(GL_FRAMEBUFFER, saveFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, saveRenderbuffer);
glBindTexture(GL_TEXTURE_2D, saveTexName);
}
public void release() {
final int[] args = new int[1];
args[0] = mTexName;
glDeleteTextures(args.length, args, 0);
mTexName = 0;
args[0] = mRenderbufferName;
glDeleteRenderbuffers(args.length, args, 0);
mRenderbufferName = 0;
args[0] = mFramebufferName;
glDeleteFramebuffers(args.length, args, 0);
mFramebufferName = 0;
}
public void enable() {
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);
}
public Bitmap getBitmap() {
return getBitmap(0, false);
}
public Bitmap getBitmap(final int orientation) {
return getBitmap(orientation, false);
}
public Bitmap getBitmap(final int orientation, final boolean mirror) {
final int[] pixels = new int[mWidth * mHeight];
final IntBuffer buffer = IntBuffer.wrap(pixels);
buffer.position(0);
enable();
glReadPixels(0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return OpenGlUtils.createBitmap(pixels, mWidth, mHeight, Bitmap.Config.ARGB_8888, orientation, mirror);
}
}