安卓-openGl-贴纸


##安卓- OpenGLDemo

OpenGL-普通贴纸

应用场景:照相机或视频播放

效果:

1692345789077280


对应shader

uniform mat4 uMVPMatrix;        // 变换矩阵
attribute vec4 aPosition;       // 图像顶点坐标
attribute vec2 aTextureCoord;   // 图像纹理坐标

varying vec2 textureCoordinate; // 图像纹理坐标

void main() {
    gl_Position = uMVPMatrix * aPosition;
    textureCoordinate = aTextureCoord.xy;
}

precision mediump float;
varying vec2 textureCoordinate;
uniform sampler2D inputTexture;

void main() {
    gl_FragColor = texture2D(inputTexture, textureCoordinate);
}

普通贴纸对关键点,对应图片加载成纹理id,对应背景(可以照相机纹理、视频纹理)进行融合(这个不是单独把纹理渲染背景在可以,这样边缘会很生硬)

//透明的需要开启混合模式
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendEquation(GLES20.GL_FUNC_ADD);
GLES20.glBlendFuncSeparate(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA, GLES20.GL_ONE, GLES20.GL_ONE);

代码实现

/**
 * 贴纸
 */
public class StickerRender extends GLOperatorBase {

    //顶点旋转
    private int textureId=GlUtil.NO_TEXTURE;
    private float[] matrix = new float[16];
    //坐标原点对应屏幕左下角
    private final float[] vertexData = {
            0f, 0f,//左上角坐标
            500f, 0f,//右上角坐标
            0f, 500f, //左下角坐标
            500f, 500f,//右下角坐标
    };

    private final float[] textureData = {
            0f, 0f,
            1f, 0f,
            0f, 1f,
            1f, 1f
    };
    private FloatBuffer vertexBuffer;
    private FloatBuffer textureBuffer;
    float[] value={0f,0f,250,250};//x,y,w,h
    //顶点矩阵手柄
    private int mMVPMatrixHandle;

    public StickerRender(Context context) {
        super(context,R.raw.vertex_sticker_normal, R.raw.fragment_sticker_normal);

        textureBuffer = GlUtil.createFloatBuffer( TextureRotationUtils.getRotation(Rotation.NORMAL,false,false));
    }
    public void setPiont(PointEntity entity){

        float x = entity.x*mFrameWidth-value[2]/2;
        float y = entity.y*mFrameHeight-value[3]/2;
        float right =x + value[2];
        float bottom =y + value[3];
        vertexData[0]=x;
        vertexData[1]=y;

        vertexData[2]=right;
        vertexData[3]=y;

        vertexData[4]=x;
        vertexData[5]=bottom;

        vertexData[6]=right;
        vertexData[7]=bottom;
        vertexBuffer.clear();
        vertexBuffer = GlUtil.createFloatBuffer(vertexData);
        value[0]=entity.x;
        value[1]=entity.y;

    }

    public void onSurfaceCreated() {
        super.onSurfaceCreated();
        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "uMVPMatrix");
        //图片变化纹理id
        if (textureId==GlUtil.NO_TEXTURE){
            Bitmap bitmap= BitmapUtils.getImageFromAssetsFile(context,"a.png");
            textureId =  GlUtil.createImageTexture(bitmap);
            bitmap.recycle();
        }
    }

    @Override
    public void onImageChanged(int width, int height) {

        //换算顶点坐标位置
        {
            float x = value[0] * width;
            float y =value[1] * height;
            float right =x + value[2];
            float bottom =y + value[3];
            vertexData[0]=x;
            vertexData[1]=y;

            vertexData[2]=right;
            vertexData[3]=y;

            vertexData[4]=x;
            vertexData[5]=bottom;

            vertexData[6]=right;
            vertexData[7]=bottom;

        }
        vertexBuffer = GlUtil.createFloatBuffer(vertexData);
        super.onImageChanged(width, height);
    }

    public void onDrawFrame() {
        //透明的需要开启混合模式
        GLES20.glEnable(GLES20.GL_BLEND);
        GLES20.glBlendEquation(GLES20.GL_FUNC_ADD);
        GLES20.glBlendFuncSeparate(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA, GLES20.GL_ONE, GLES20.GL_ONE);

        GLES20.glUseProgram(mProgramHandle);

        Matrix.setIdentityM(matrix, 0);
        /**
         * 正交投影来换算vertexBuffer使用真实的宽高
         */
        //matrix = makeOrthoFrustum(0, mFrameWidth, mFrameHeight,0 , 1, -1);


//        float[] orthoMtx = new float[16];
//        float[] rotateMtx = new float[16];
//

        Matrix.orthoM(matrix, 0, 0, mFrameWidth, mFrameHeight,0 , -1, 1);
//        Matrix.setRotateM(rotateMtx, 0, 180, 0.0f, 0.0f, 1.0f);
//
//
//       Matrix.multiplyMM(matrix, 0, rotateMtx, 0, orthoMtx, 0);



        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, matrix,0);

        //传递顶点坐标到shader
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glVertexAttribPointer(mPositionHandle, 2, GLES20.GL_FLOAT, false,
                8, vertexBuffer);

        //传递纹理坐标到shader
        GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
        GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false,
                8, textureBuffer);

        // 绑定纹理
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
        GLES20.glUniform1i(mInputTextureHandle, 0);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

        // 解绑
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisableVertexAttribArray(mTextureCoordinateHandle);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
        GLES20.glUseProgram(0);
        GLES20.glDisable(GLES20.GL_BLEND);

    }



}

完整代码下载地址

https://download.csdn.net/download/u012836015/88229210

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

baoyu45585

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值