В OpenGLES ES Android изображение камеры будет искажаться при повороте телефона
Я сейчас изучаю OpenGLES. В моем проекте я хочу добавить фильтры для предварительного просмотра камеры. У меня это работает. Но теперь у меня есть проблема, когда я поворачиваю камеру, изображение будет искажено. образ
Вот мой основной код. Код GLSL
uniform mat4 uTexMatrix;
attribute vec4 aPosition;
attribute vec4 aTextureCoord;
varying vec2 vTextureCoord;
void main(){
gl_Position = vec4(aPosition.xy, 0.0, 1.0);
vTextureCoord = (uTexMatrix * aTextureCoord).xy;
}
#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 vTextureCoord;
uniform samplerExternalOES sTexture;
void main(){
vec4 vCameraColor = texture2D(sTexture, vTextureCoord);
float fGrayColor = (0.3*vCameraColor.r + 0.59*vCameraColor.g + 0.11*vCameraColor.b);
gl_FragColor = vec4(fGrayColor, fGrayColor, fGrayColor, 1.0);
}
В камере рендеринга
public class BeautyGLRender implements GLSurfaceView.Renderer {
private SurfaceTexture mSurfaceTexture;
private int mOESTextureId = -1;
private CameraHelper mCamera;
private BeautyGLSurfaceView mSurfaceView;
boolean bIsPreviewStarted;
private float[] transformMatrix = new float[16];
private float[] mOrientationM = new float[16];
private int[] mFBOIds = new int[1];
private FloatBuffer positionBuffer;
private FloatBuffer texCoordBuffer;
private Context mContext;
private int mShaderProgram;
public static final int PER_FLOAT_SIZE = Float.SIZE / 8;
public static final float[] position = new float[]{
-1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, 1.0f,
1.0f, -1.0f,
};
public static final float[] textureCord = new float[]{
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f,
};
public void init(Context context, CameraHelper helper, BeautyGLSurfaceView surfaceView) {
mCamera = helper;
mContext = context;
mSurfaceView = surfaceView;
positionBuffer = ByteBuffer.allocateDirect(PER_FLOAT_SIZE * position.length).order(ByteOrder.nativeOrder()).asFloatBuffer();
positionBuffer.put(position).position(0);
texCoordBuffer = ByteBuffer.allocateDirect(PER_FLOAT_SIZE * textureCord.length).order(ByteOrder.nativeOrder()).asFloatBuffer();
texCoordBuffer.put(textureCord).position(0);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
int[] tex = new int[1];
mShaderProgram = Utils.createProgram(Utils.readShaderFromResource(mContext, R.raw.vertex_shader),
Utils.readShaderFromResource(mContext, R.raw.fragment_shader));
GLES20.glGenTextures(1, tex, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, tex[0]);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
mOESTextureId = tex[0];
GLES20.glGenFramebuffers(1, mFBOIds, 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFBOIds[0]);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
if (mSurfaceTexture != null) {
mSurfaceTexture.updateTexImage();
mSurfaceTexture.getTransformMatrix(transformMatrix);
}
if (!bIsPreviewStarted) {
bIsPreviewStarted = start();
bIsPreviewStarted = true;
return;
}
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
int muTexMatrixLoc = GLES20.glGetUniformLocation(mShaderProgram, "uTexMatrix");
GLES20.glUniformMatrix4fv(muTexMatrixLoc, 1, false, transformMatrix, 0);
int muOrientaMatrixLoc = GLES20.glGetUniformLocation(mShaderProgram, "uOrientationM");
GLES20.glUniformMatrix4fv(muOrientaMatrixLoc, 1, false, mOrientationM, 0);
int msTexture = GLES20.glGetUniformLocation(mShaderProgram, "sTexture");
GLES20.glActiveTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mOESTextureId);
GLES20.glUniform1i(msTexture, 0);
int maPositinLoc = GLES20.glGetAttribLocation(mShaderProgram, "aPosition");
int maTextureCoord = GLES20.glGetAttribLocation(mShaderProgram, "aTextureCoord");
if(positionBuffer != null) {
positionBuffer.position(0);
GLES20.glEnableVertexAttribArray(maPositinLoc);
GLES20.glVertexAttribPointer(maPositinLoc, 2, GLES20.GL_FLOAT, false, 0, positionBuffer);
}
if(texCoordBuffer != null) {
texCoordBuffer.position(0);
GLES20.glEnableVertexAttribArray(maTextureCoord);
GLES20.glVertexAttribPointer(maTextureCoord, 2, GLES20.GL_FLOAT, false, 0, texCoordBuffer);
}
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLES20.glDisableVertexAttribArray(maPositinLoc);
GLES20.glDisableVertexAttribArray(maTextureCoord);
}
public boolean start() {
mSurfaceTexture = new SurfaceTexture(mOESTextureId);
mSurfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
mSurfaceView.requestRender();
Log.d("-----", "onFrameAvailable " + surfaceTexture.toString());
}
});
mCamera.setPreviewTexture(mSurfaceTexture);
mCamera.startPreview();
return true;
}
}
Я думаю, что-то не так в функции onDrawFrame. И я прочитал некоторый код в Git, как Shadercam, я не могу найти ошибку