В 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, я не могу найти ошибку

0 ответов

Другие вопросы по тегам