implemented shader while taking picture and video

pull/527/head
Suneet Agrawal 6 years ago
parent 7706c5ea3c
commit 8bad1ce5a7
  1. 2
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  2. 41
      cameraview/src/main/java/com/otaliastudios/cameraview/internal/egl/EglViewport.java
  3. 7
      cameraview/src/main/java/com/otaliastudios/cameraview/picture/SnapshotGlPictureRecorder.java
  4. 9
      cameraview/src/main/java/com/otaliastudios/cameraview/preview/GlCameraPreview.java
  5. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/preview/RendererFrameCallback.java
  6. 8
      cameraview/src/main/java/com/otaliastudios/cameraview/shadereffects/effects/NoEffect.java
  7. 12
      cameraview/src/main/java/com/otaliastudios/cameraview/video/SnapshotVideoRecorder.java

@ -590,7 +590,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
Log.d("Suneet Agrawal", "onTouchEvent " + event.getAction());
//BlackAndWhiteEffect effect = new BlackAndWhiteEffect();
changeEffect(ShaderEffectFactory.ShaderEffects.BRIGHTNESS_EFFECT);
changeEffect(ShaderEffectFactory.ShaderEffects.SEPIA_EFFECT);
}
return true;

@ -17,28 +17,6 @@ public class EglViewport extends EglElement {
private final static CameraLogger LOG = CameraLogger.create(EglViewport.class.getSimpleName());
// Simple vertex shader.
private static final String SIMPLE_VERTEX_SHADER =
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uTexMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = (uTexMatrix * aTextureCoord).xy;\n" +
"}\n";
// Simple fragment shader for use with external 2D textures
private static final String SIMPLE_FRAGMENT_SHADER =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform samplerExternalOES sTexture;\n" +
"void main() {\n" +
" gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
"}\n";
// Stuff from Drawable2d.FULL_RECTANGLE
// A full square, extending from -1 to +1 in both dimensions.
// When the model/view/projection matrix is identity, this will exactly cover the viewport.
@ -76,15 +54,14 @@ public class EglViewport extends EglElement {
// private int muTexOffsetLoc; // Used for filtering
// private int muColorAdjustLoc; // Used for filtering
private String mVertexShader = SIMPLE_VERTEX_SHADER;
private String mFragmentShader = SIMPLE_FRAGMENT_SHADER;
private BaseShaderEffect mShaderEffect;
private boolean mIsShaderChanged = false;
public EglViewport() {
mTextureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES;
//init the default shader effect
mShaderEffect = new NoEffect();
initProgram();
}
@ -105,20 +82,6 @@ public class EglViewport extends EglElement {
checkLocation(muMVPMatrixLocation, mShaderEffect.getMVPMatrixVariableName());
muTexMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, mShaderEffect.getTextureMatrixVariableName());
checkLocation(muTexMatrixLocation, mShaderEffect.getTextureMatrixVariableName());
/*mProgramHandle = createProgram(mVertexShader, mFragmentShader);
maPositionLocation = GLES20.glGetAttribLocation(mProgramHandle, "aPosition");
checkLocation(maPositionLocation, "aPosition");
maTextureCoordLocation = GLES20.glGetAttribLocation(mProgramHandle, "aTextureCoord");
checkLocation(maTextureCoordLocation, "aTextureCoord");
muMVPMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, "uMVPMatrix");
checkLocation(muMVPMatrixLocation, "uMVPMatrix");
muTexMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, "uTexMatrix");
checkLocation(muTexMatrixLocation, "uTexMatrix");*/
// Stuff from Drawable2d.FULL_RECTANGLE
}
public void release(boolean doEglCleanup) {

@ -27,6 +27,7 @@ import com.otaliastudios.cameraview.internal.utils.WorkerHandler;
import com.otaliastudios.cameraview.preview.GlCameraPreview;
import com.otaliastudios.cameraview.preview.RendererFrameCallback;
import com.otaliastudios.cameraview.preview.RendererThread;
import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect;
import com.otaliastudios.cameraview.size.AspectRatio;
import com.otaliastudios.cameraview.size.Size;
@ -99,7 +100,7 @@ public class SnapshotGlPictureRecorder extends PictureRecorder {
@RendererThread
@Override
public void onRendererFrame(@NonNull SurfaceTexture surfaceTexture, final float scaleX, final float scaleY) {
public void onRendererFrame(@NonNull SurfaceTexture surfaceTexture, final float scaleX, final float scaleY, BaseShaderEffect shaderEffect) {
mPreview.removeRendererFrameCallback(this);
// This kinda work but has drawbacks:
@ -121,6 +122,10 @@ public class SnapshotGlPictureRecorder extends PictureRecorder {
// and draw the last frame again there.
final EGLContext eglContext = EGL14.eglGetCurrentContext();
final EglCore core = new EglCore(eglContext, EglCore.FLAG_RECORDABLE);
//set the current shader before taking the snapshot
mViewport.changeShaderEffect(shaderEffect);
// final EGLSurface oldSurface = EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW);
// final EGLDisplay oldDisplay = EGL14.eglGetCurrentDisplay();
WorkerHandler.execute(new Runnable() {

@ -16,6 +16,7 @@ import com.otaliastudios.cameraview.R;
import com.otaliastudios.cameraview.internal.egl.EglViewport;
import com.otaliastudios.cameraview.internal.utils.Op;
import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect;
import com.otaliastudios.cameraview.shadereffects.effects.NoEffect;
import com.otaliastudios.cameraview.size.AspectRatio;
import java.util.Collections;
@ -69,6 +70,8 @@ public class GlCameraPreview extends CameraPreview<GLSurfaceView, SurfaceTexture
@VisibleForTesting float mCropScaleY = 1F;
private View mRootView;
private BaseShaderEffect mCurrectShaderEffect;
public GlCameraPreview(@NonNull Context context, @NonNull ViewGroup parent) {
super(context, parent);
}
@ -162,6 +165,9 @@ public class GlCameraPreview extends CameraPreview<GLSurfaceView, SurfaceTexture
getView().requestRender(); // requestRender is thread-safe.
}
});
//init the default shader effect
mCurrectShaderEffect = new NoEffect();
}
@RendererThread
@ -210,7 +216,7 @@ public class GlCameraPreview extends CameraPreview<GLSurfaceView, SurfaceTexture
synchronized (mRendererFrameCallbacks) {
// Need to synchronize when iterating the Collections.synchronizedSet
for (RendererFrameCallback callback : mRendererFrameCallbacks) {
callback.onRendererFrame(mInputSurfaceTexture, mCropScaleX, mCropScaleY);
callback.onRendererFrame(mInputSurfaceTexture, mCropScaleX, mCropScaleY, mCurrectShaderEffect);
}
}
}
@ -311,6 +317,7 @@ public class GlCameraPreview extends CameraPreview<GLSurfaceView, SurfaceTexture
}
public void setShaderEffect(BaseShaderEffect shaderEffect){
mCurrectShaderEffect = shaderEffect;
mOutputViewport.changeShaderEffect(shaderEffect);
}
}

@ -4,6 +4,8 @@ import android.graphics.SurfaceTexture;
import androidx.annotation.NonNull;
import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect;
/**
* Callback for renderer frames.
*/
@ -28,5 +30,5 @@ public interface RendererFrameCallback {
* @param scaleY the scaleY (in REF_VIEW) value
*/
@RendererThread
void onRendererFrame(@NonNull SurfaceTexture surfaceTexture, float scaleX, float scaleY);
void onRendererFrame(@NonNull SurfaceTexture surfaceTexture, float scaleX, float scaleY, BaseShaderEffect shaderEffect);
}

@ -15,17 +15,17 @@ public class NoEffect extends BaseShaderEffect {
@Override
public String getFragmentShader() {
String shader = "#extension GL_OES_EGL_image_external : require\n"
/*String shader = "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "varying vec2 vTextureCoord;\n"
+ "uniform samplerExternalOES sTexture;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(sTexture, vTextureCoord);\n"
+ "}\n";
+ "}\n";*/
//This fragment shader is copied from black and white,
//this is for testing purpose and need to be removed once testing is done.
/*String shader = "#extension GL_OES_EGL_image_external : require\n"
String shader = "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "varying vec2 vTextureCoord;\n"
+ "uniform samplerExternalOES sTexture;\n" + "void main() {\n"
@ -34,7 +34,7 @@ public class NoEffect extends BaseShaderEffect {
+ " float colorG = (color.r + color.g + color.b) / 3.0;\n"
+ " float colorB = (color.r + color.g + color.b) / 3.0;\n"
+ " gl_FragColor = vec4(colorR, colorG, colorB, color.a);\n"
+ "}\n";*/
+ "}\n";
return shader;

@ -17,6 +17,7 @@ import com.otaliastudios.cameraview.internal.egl.EglViewport;
import com.otaliastudios.cameraview.preview.GlCameraPreview;
import com.otaliastudios.cameraview.preview.RendererFrameCallback;
import com.otaliastudios.cameraview.preview.RendererThread;
import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect;
import com.otaliastudios.cameraview.size.Size;
import com.otaliastudios.cameraview.video.encoding.AudioConfig;
import com.otaliastudios.cameraview.video.encoding.AudioMediaEncoder;
@ -66,6 +67,8 @@ public class SnapshotVideoRecorder extends VideoRecorder implements RendererFram
private boolean mHasOverlay;
private int mOverlayRotation;
private EglViewport mViewport;
public SnapshotVideoRecorder(@NonNull CameraEngine engine,
@NonNull GlCameraPreview preview,
@Nullable Overlay overlay,
@ -93,8 +96,8 @@ public class SnapshotVideoRecorder extends VideoRecorder implements RendererFram
public void onRendererTextureCreated(int textureId) {
mTextureId = textureId;
if (mHasOverlay) {
EglViewport temp = new EglViewport();
mOverlayTextureId = temp.createTexture();
mViewport = new EglViewport();
mOverlayTextureId = mViewport.createTexture();
mOverlaySurfaceTexture = new SurfaceTexture(mOverlayTextureId);
mOverlaySurfaceTexture.setDefaultBufferSize(mResult.size.getWidth(), mResult.size.getHeight());
mOverlaySurface = new Surface(mOverlaySurfaceTexture);
@ -103,10 +106,13 @@ public class SnapshotVideoRecorder extends VideoRecorder implements RendererFram
@RendererThread
@Override
public void onRendererFrame(@NonNull SurfaceTexture surfaceTexture, float scaleX, float scaleY) {
public void onRendererFrame(@NonNull SurfaceTexture surfaceTexture, float scaleX, float scaleY, BaseShaderEffect shaderEffect) {
if (mCurrentState == STATE_NOT_RECORDING && mDesiredState == STATE_RECORDING) {
LOG.i("Starting the encoder engine.");
//set current shader effect
mViewport.changeShaderEffect(shaderEffect);
// Set default options
if (mResult.videoFrameRate <= 0) mResult.videoFrameRate = DEFAULT_VIDEO_FRAMERATE;
if (mResult.videoBitRate <= 0) mResult.videoBitRate = estimateVideoBitRate(mResult.size, mResult.videoFrameRate);

Loading…
Cancel
Save