package com.af.experiments.FxCameraApp.renderer;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.util.Log;
import com.af.experiments.FxCameraApp.Utils.Fps;
import com.af.experiments.FxCameraApp.Utils.OpenGlUtils;
import com.af.experiments.FxCameraApp.shaders.GlShader;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import java.util.LinkedList;
import java.util.Queue;
import static android.opengl.GLES20.*;
public abstract class GlFrameBufferObjectRenderer implements GLSurfaceView.Renderer {
private GLES20FramebufferObject mFramebufferObject;
private GlShader mShader;
private final Queue<Runnable> mRunOnDraw;
private Fps mFps;
protected GlFrameBufferObjectRenderer() {
mRunOnDraw = new LinkedList<Runnable>();
}
public void setFps(final Fps fps) {
if (mFps != null) {
mFps.stop();
mFps = null;
}
mFps = fps;
}
public Bitmap getBitmap() {
return mFramebufferObject.getBitmap();
}
public Bitmap getBitmap(final int orientation) {
return mFramebufferObject.getBitmap(orientation);
}
public Bitmap getBitmap(final int orientation, final boolean mirror) {
return mFramebufferObject.getBitmap(orientation, mirror);
}
@Override
public final void onSurfaceCreated(final GL10 gl, final EGLConfig config) {
mFramebufferObject = new GLES20FramebufferObject();
mShader = new GlShader();
mShader.setup();
onSurfaceCreated(config);
if (mFps != null) {
mFps.start();
}
}
@Override
public final void onSurfaceChanged(final GL10 gl, final int width, final int height) {
mFramebufferObject.setup(width, height);
mShader.setFrameSize(width, height);
onSurfaceChanged(width, height);
}
@Override
public final void onDrawFrame(final GL10 gl) {
synchronized (mRunOnDraw) {
while (!mRunOnDraw.isEmpty()) {
mRunOnDraw.poll().run();
}
}
mFramebufferObject.enable();
glViewport(0, 0, mFramebufferObject.getWidth(), mFramebufferObject.getHeight());
onDrawFrame(mFramebufferObject);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, mFramebufferObject.getWidth(), mFramebufferObject.getHeight());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mShader.draw(mFramebufferObject.getTexName(), null);
if (mFps != null) {
mFps.countup();
}
}
@Override
protected void finalize() throws Throwable {
try {
if (mFps != null) {
mFps.stop();
mFps = null;
}
} finally {
super.finalize();
}
}
public abstract void onSurfaceCreated(EGLConfig config);
public abstract void onSurfaceChanged(int width, int height);
public abstract void onDrawFrame(GLES20FramebufferObject fbo);
protected void runOnDraw(final Runnable runnable) {
synchronized (mRunOnDraw) {
mRunOnDraw.add(runnable);
}
}
private int mGLTextureId = OpenGlUtils.NO_TEXTURE;
public void setImageBitmap(final Bitmap bitmap, boolean b) {
runOnDraw(new Runnable() {
@Override
public void run() {
mGLTextureId = OpenGlUtils.loadTexture(bitmap, mGLTextureId, false);
if (bitmap != null) {
bitmap.recycle();
}
}
});
}
public void deleteImage() {
runOnDraw(new Runnable() {
@Override
public void run() {
try {
GLES20.glDeleteTextures(1, new int[]{mGLTextureId}, 0);
mGLTextureId = -1;
}catch (Exception e){
Log.d("DEBUG", "", e);
}
}
});
}
}