如何在OpelGL ES,Android中的相机预览上方叠加对象?

时间:2018-08-15 09:32:06

标签: android android-camera opengl-es-2.0

我是Android和Stack Overflow的新手。

当前,我正在实现AR android应用程序。 我已经有一个正在运行的项目,演示了一些3D对象。 现在,我要做的就是将摄像机预览置于这些渲染对象的后面。

我从github找到了一个可工作的相机预览android示例代码- https://github.com/shimoda-tomoaki/CameraTestProject

我已经成功地将该项目合并到我的项目中。 但是,我无法将摄像机预览“推回”并把我的3D对象放到最前面,将它们叠加到预览中。

在示例代码中,我看到了一个硬编码的顶点坐标数组,

private static final float VERTECES[] = {
        -1.0f, 1.0f, 0.0f,
        -1.0f, -1.0f, 0.0f,
        1.0f, 1.0f, 0.0f,
        1.0f, -1.0f, 0.0f
};

现在,我假设相机预览在此正方形上渲染。 但是,当我将MVP矩阵引入代码和顶点着色器时,尝试操纵该正方形的位置时,相机预览变为空白。

正如我之前的研究,GLSurfaceView的背景不能透明。 我从这里和其他站点尝试了几个样本,但没有一个起作用。 似乎无法为相机创建新视图并将GLSurfaceView放在其上方。 因此,我对背景的解决方法是添加一个带纹理的方形对象,将其背景图像放到其上,然后推回去,同时使其保持在屏幕上。

Matrix.translateM(ModelMatrix_background, 0, 0.0f, 0.0f, -110.0f);

但是,如果我尝试操纵MVP矩阵并将其应用于摄像机预览的正方形对象(只要MVP矩阵不是所有的标识矩阵),摄像机预览就会变成空白。

是否可以对相机预览执行相同的操作?

这是我的代码:

顶点着色器

uniform mat4 u_MVPMatrix;

attribute vec4 a_Position;
attribute vec2 a_TexCoordinate;

varying vec3 v_Position; 
varying vec2 v_TexCoordinate;

void main() {

    v_TexCoordinate = a_TexCoordinate;
    gl_Position = u_MVPMatrix * a_Position;

} 

片段着色器

#extension GL_OES_EGL_image_external : require

precision mediump float;
varying vec2 v_TexCoordinate;
uniform samplerExternalOES u_texture;

void main() 
{
    gl_FragColor = texture2D(u_texture, v_TexCoordinate);
}

渲染器

@Override
public void onDrawFrame()
{
    ...
    drawCameraPreviewBackground();
    ...
}

private void drawCameraPreviewBackground()
{
    GLES20.glClearColor(0.5f, 0.5f, 1.0f, 1.0f);
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

    mCameraMgr.updateTexture();

    GLES20.glUseProgram(mShaderProgramHandle_cameraPreview);

    final int MVMatrixHandle_cameraPreview = GLES20.glGetUniformLocation(mShaderProgramHandle_cameraPreview, "u_MVMatrix");
    final int MVPMatrixHandle_cameraPreview = GLES20.glGetUniformLocation(mShaderProgramHandle_cameraPreview, "u_MVPMatrix");
    final int positionHandle_cameraPreview = GLES20.glGetAttribLocation(mShaderProgramHandle_cameraPreview, "a_Position");
    final int texCoordHandle_cameraPreview = GLES20.glGetAttribLocation(mShaderProgramHandle_cameraPreview, "a_TexCoordinate");
    final int textureHandle_cameraPreview = GLES20.glGetUniformLocation(mShaderProgramHandle_cameraPreview, "u_texture");
    final int textureTransformMatrixHandle_cameraPreview = GLES20.glGetUniformLocation(mShaderProgramHandle_cameraPreview, "u_textureTransformMatrix");

    float[] ModelMatrix_cameraPreview = new float[16];
    float[] ViewMatrix_cameraPreview = new float[16];
    float[] ProjectionMatrix_cameraPreview = new float[16];
    float[] MVMatrix_cameraPreview = new float[16];
    float[] MVPMatrix_cameraPreview = new float[16];

    // Get a copy of global matrices
    System.arraycopy(mViewMatrix, 0, ViewMatrix_cameraPreview, 0, 16);
    System.arraycopy(mProjectionMatrix, 0, ProjectionMatrix_cameraPreview, 0, 16);

    Matrix.setIdentityM(ModelMatrix_cameraPreview, 0);

    // Translate the background to its position
    Matrix.translateM(ModelMatrix_cameraPreview, 0, 0.0f, 0.0f, -110.0f);

    Matrix.multiplyMM(MVMatrix_cameraPreview, 0, ViewMatrix_cameraPreview, 0, ModelMatrix_cameraPreview, 0);
    GLES20.glUniformMatrix4fv(MVMatrixHandle_cameraPreview, 1, false, MVMatrix_cameraPreview, 0);

    Matrix.multiplyMM(MVPMatrix_cameraPreview, 0, ProjectionMatrix_cameraPreview, 0, MVMatrix_cameraPreview, 0);
    GLES20.glUniformMatrix4fv(MVPMatrixHandle_cameraPreview, 1, false, MVPMatrix_cameraPreview, 0);

    // Prepare the object coordinate data
    GLES20.glVertexAttribPointer(positionHandle_cameraPreview, 3,
            GLES20.GL_FLOAT, false,
            0, mBgCameraPreview.getVertexBuffer());
    GLES20.glEnableVertexAttribArray(positionHandle_cameraPreview);

    // Prepare the object texture data
    GLES20.glVertexAttribPointer(texCoordHandle_cameraPreview, 2,
            GLES20.GL_FLOAT, false,
            0, mBgCameraPreview.getTexCoordBuffer());
    GLES20.glEnableVertexAttribArray(texCoordHandle_cameraPreview);

    GLES20.glUniform1i(textureHandle_cameraPreview, 0);
    mRendererHelper.checkGLError("glUniform1i");

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureHandle_CameraPreview);
    mRendererHelper.checkGLError("glBindTexture");

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

    glDisableVertexAttribArray(positionHandle_cameraPreview);
    glDisableVertexAttribArray(texCoordHandle_cameraPreview);
}

0 个答案:

没有答案