GCameraFboRender
package com.example.glivepush.camera;
import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import com.example.glivepush.R;
import com.example.glivepush.egl.GShaderUtil;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
public class GCameraFboRender {
private Context context;
/*******************************************添加水印贴图-start***********************************/
private Bitmap bitmap;
private int bitmapTextureId;
private float[] vertexData = {
-1f, -1f,
1f, -1f,
-1f, 1f,
1f, 1f,
0f, 0f,
0f, 0f,
0f, 0f,
0f, 0f
};
/*******************************************添加水印贴图-end***********************************/
private FloatBuffer vertexBuffer;
private float[] fragmentData = {
0f, 1f,
1f, 1f,
0f, 0f,
1f, 0f
};
private FloatBuffer fragmentBuffer;
private int program;
private int vPosition;
private int fPosition;
private int textureid;
private int sampler;
private int vboId;
public GCameraFboRender(Context context) {
this.context = context;
/*******************************************添加水印贴图-start*******************************/
bitmap = GShaderUtil.createTextImage("视频直播推流:godv", 50, "#ff0000",
"#00000000", 0);
float r = 1.0f * bitmap.getWidth() / bitmap.getHeight();
float w = r * 0.1f;
vertexData[8] = 0.8f - w;
vertexData[9] = -0.8f;
vertexData[10] = 0.8f;
vertexData[11] = -0.8f;
vertexData[12] = 0.8f - w;
vertexData[13] = -0.7f;
vertexData[14] = 0.8f;
vertexData[15] = -0.7f;
/*******************************************添加水印贴图-end**********************************/
vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(vertexData);
vertexBuffer.position(0);
fragmentBuffer = ByteBuffer.allocateDirect(fragmentData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(fragmentData);
fragmentBuffer.position(0);
}
public void onCreate() {
/*******************************************添加水印贴图-start*******************************/
//开启argb透明
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
/*******************************************添加水印贴图-end*******************************/
String vertexSource = GShaderUtil.getRawResource(context, R.raw.vertex_shader_screen);
String fragmentSource = GShaderUtil.getRawResource(context, R.raw.fragment_shader_screen);
program = GShaderUtil.createProgram(vertexSource, fragmentSource);
vPosition = GLES20.glGetAttribLocation(program, "v_Position");
fPosition = GLES20.glGetAttribLocation(program, "f_Position");
sampler = GLES20.glGetUniformLocation(program, "sTexture");
int[] vbos = new int[1];
GLES20.glGenBuffers(1, vbos, 0);
vboId = vbos[0];
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexData.length * 4 + fragmentData.length * 4, null, GLES20.GL_STATIC_DRAW);
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, vertexData.length * 4, vertexBuffer);
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, vertexData.length * 4, fragmentData.length * 4, fragmentBuffer);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
/*******************************************添加水印贴图-start*******************************/
bitmapTextureId = GShaderUtil.loadBitmapTexture(bitmap);
/*******************************************添加水印贴图-end*******************************/
}
public void onChange(int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
public void onDraw(int textureId) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glClearColor(1f, 0f, 0f, 1f);
GLES20.glUseProgram(program);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
//fbo
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glEnableVertexAttribArray(vPosition);
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8,
0);
GLES20.glEnableVertexAttribArray(fPosition);
GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8,
vertexData.length * 4);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
/*******************************************添加水印贴图-start*******************************/
//bitmap
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, bitmapTextureId);
GLES20.glEnableVertexAttribArray(vPosition);
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8,
32);
GLES20.glEnableVertexAttribArray(fPosition);
GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8,
vertexData.length * 4);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
/*******************************************添加水印贴图-end*******************************/
//解绑
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
}
GShaderUtil
package com.example.glivepush.egl;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.opengl.GLES20;
import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
public class GShaderUtil {
public static String getRawResource(Context context, int rawId)
{
InputStream inputStream = context.getResources().openRawResource(rawId);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer sb = new StringBuffer();
String line;
try
{
while((line = reader.readLine()) != null)
{
sb.append(line).append("\n");
}
reader.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return sb.toString();
}
private static int loadShader(int shaderType, String source)
{
int shader = GLES20.glCreateShader(shaderType);
if(shader != 0)
{
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
int[] compile = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compile, 0);
if(compile[0] != GLES20.GL_TRUE)
{
Log.d("ywl5320", "shader compile error");
GLES20.glDeleteShader(shader);
shader = 0;
}
return shader;
}
else
{
return 0;
}
}
public static int createProgram(String vertexSource, String fragmentSoruce)
{
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSoruce);
if(vertexShader != 0 && fragmentShader != 0)
{
int program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
return program;
}
return 0;
}
/*******************************************添加水印贴图-start***********************************/
//文字生成图片的工具类
public static Bitmap createTextImage(String text, int textSize, String textColor, String bgColor,
int padding) {
Paint paint = new Paint();
paint.setColor(Color.parseColor(textColor));
paint.setTextSize(textSize);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
float width = paint.measureText(text, 0, text.length());
float top = paint.getFontMetrics().top;
float bottom = paint.getFontMetrics().bottom;
Bitmap bm = Bitmap.createBitmap((int) (width + padding * 2), (int) ((bottom - top) + padding * 2),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bm);
canvas.drawColor(Color.parseColor(bgColor));
canvas.drawText(text, padding, - top + padding, paint);
return bm;
}
//根据bitmap返回纹理
public static int loadBitmapTexture(Bitmap bitmap) {
int[] textureIds = new int[1];
GLES20.glGenTextures(1, textureIds, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureIds[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
ByteBuffer bitmapBuffer = ByteBuffer.allocate(bitmap.getHeight() * bitmap.getWidth() * 4);
bitmap.copyPixelsToBuffer(bitmapBuffer);
bitmapBuffer.flip();
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(),
bitmap.getHeight(), 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, bitmapBuffer);
return textureIds[0];
}
/*******************************************添加水印贴图-end***********************************/
}
GEncodecRender
package com.example.glivepush.encodec;
import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import com.example.glivepush.R;
import com.example.glivepush.egl.GEGLSurfaceView;
import com.example.glivepush.egl.GShaderUtil;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
public class GEncodecRender implements GEGLSurfaceView.GGLRender {
private Context context;
/****************从fbo中摘取******************添加水印贴图-start*******************************/
private Bitmap bitmap;
private int bitmapTextureId;
private float[] vertexData = {
-1f, -1f,
1f, -1f,
-1f, 1f,
1f, 1f,
0f, 0f,
0f, 0f,
0f, 0f,
0f, 0f
};
/*******************************************添加水印贴图-end***********************************/
private FloatBuffer vertexBuffer;
private float[] fragmentData = {
0f, 1f,
1f, 1f,
0f, 0f,
1f, 0f
};
private FloatBuffer fragmentBuffer;
private int program;
private int vPosition;
private int fPosition;
private int textureid;
private int vboId;
public GEncodecRender(Context context, int textureid) {
this.context = context;
this.textureid = textureid;
/****************从fbo中摘取******************添加水印贴图-start*******************************/
bitmap = GShaderUtil.createTextImage("视频直播推流:godv", 50, "#ff0000",
"#00000000", 0);
float r = 1.0f * bitmap.getWidth() / bitmap.getHeight();
float w = r * 0.1f;
vertexData[8] = 0.8f - w;
vertexData[9] = -0.8f;
vertexData[10] = 0.8f;
vertexData[11] = -0.8f;
vertexData[12] = 0.8f - w;
vertexData[13] = -0.7f;
vertexData[14] = 0.8f;
vertexData[15] = -0.7f;
/*******************************************添加水印贴图-end**********************************/
vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(vertexData);
vertexBuffer.position(0);
fragmentBuffer = ByteBuffer.allocateDirect(fragmentData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(fragmentData);
fragmentBuffer.position(0);
}
@Override
public void onSurfaceCreated() {
/****************从fbo中摘取******************添加水印贴图-start*******************************/
//开启argb透明
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
/*******************************************添加水印贴图-end*******************************/
String vertexSource = GShaderUtil.getRawResource(context, R.raw.vertex_shader_screen);
String fragmentSource = GShaderUtil.getRawResource(context, R.raw.fragment_shader_screen);
program = GShaderUtil.createProgram(vertexSource, fragmentSource);
vPosition = GLES20.glGetAttribLocation(program, "v_Position");
fPosition = GLES20.glGetAttribLocation(program, "f_Position");
int[] vbos = new int[1];
GLES20.glGenBuffers(1, vbos, 0);
vboId = vbos[0];
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexData.length * 4 + fragmentData.length * 4, null, GLES20.GL_STATIC_DRAW);
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, vertexData.length * 4, vertexBuffer);
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, vertexData.length * 4, fragmentData.length * 4, fragmentBuffer);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
/****************从fbo中摘取******************添加水印贴图-start*******************************/
bitmapTextureId = GShaderUtil.loadBitmapTexture(bitmap);
/*******************************************添加水印贴图-end*******************************/
}
@Override
public void onSurfaceChanged(int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame() {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glClearColor(1f, 0f, 0f, 1f);
GLES20.glUseProgram(program);
//先设置vbo再绑定纹理
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureid);
GLES20.glEnableVertexAttribArray(vPosition);
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8,
0);
GLES20.glEnableVertexAttribArray(fPosition);
GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8,
vertexData.length * 4);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
/****************从fbo中摘取******************添加水印贴图-start*******************************/
//bitmap
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, bitmapTextureId);
GLES20.glEnableVertexAttribArray(vPosition);
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8,
32);
GLES20.glEnableVertexAttribArray(fPosition);
GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8,
vertexData.length * 4);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
/*******************************************添加水印贴图-end*******************************/
//解绑
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
}