文章目录
##安卓- 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