Activity
package com.example.opengldemo;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class GTextureActivity extends AppCompatActivity {
private GGLTextureView gglTextureView;
private LinearLayout lyContent;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_texture);
gglTextureView = findViewById(R.id.g_gl_surface_view);
lyContent = findViewById(R.id.g_ly_content);
/**************************多Surface渲染同一纹理-START*************************************/
gglTextureView.getGglTextureRender().setOnRenderCreateListener(new GGLTextureRender.OnRenderCreateListener() {
@Override
public void onCreate(final int textureId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if(lyContent.getChildCount() > 0){
lyContent.removeAllViews();
}
GMutiSurfaceView gMutiSurfaceView = new GMutiSurfaceView(GTextureActivity.this);
gMutiSurfaceView.setTextureId(textureId);
gMutiSurfaceView.setSurfaceAndEglContext(null,gglTextureView.getEglContext());
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
layoutParams.width = 200;
layoutParams.height = 300;
gMutiSurfaceView.setLayoutParams(layoutParams);
lyContent.addView(gMutiSurfaceView);
}
});
}
});
/**************************多Surface渲染同一纹理-END***************************************/
}
}
GGLTextureRender
package com.example.opengldemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import android.util.Log;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
public class GGLTextureRender implements MyGLSurfaceView.MyGLRender {
private Context context;
//顶点坐标
private final float[] vertexData = {
-1f, -1f,
1f, -1f,
-1f, 1f,
1f, 1f
};
//纹理坐标
private final float[] fragmentData = {
//fbo坐标
// 0f, 0f,
// 1f, 0f,
// 0f, 1f,
// 1f, 1f
0f, 1f,
1f, 1f,
0f, 0f,
1f, 0f
};
private FloatBuffer vertexBuffer;
private FloatBuffer fragmentBuffer;
public GGLTextureRender(Context context) {
this.context = context;
fboRender = new FboRender(context);
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);
}
private int program;
private int vPosition;
private int fPosition;
private int textureid;
private int sampler;
private int vboId;
private int fboId;
private int imgTextureId;
private FboRender fboRender;
private int umatrix;
private float[] matrix = new float[16];
private int width;
private int height;
@Override
public void onSufaceCreated() {
fboRender.onCreate();
//更换shader
String vertexSource = GShaderUtil.getRawResource(context, R.raw.vertex_shader_m);
String fragmentSource = GShaderUtil.getRawResource(context, R.raw.fragment_shader);
program = GShaderUtil.createProgram(vertexSource, fragmentSource);
if (program > 0) {
//顶点坐标
vPosition = GLES20.glGetAttribLocation(program, "v_Position");
//纹理坐标
fPosition = GLES20.glGetAttribLocation(program, "f_Position");
sampler = GLES20.glGetUniformLocation(program,"sTexture");
//获取矩阵
umatrix = GLES20.glGetUniformLocation(program,"u_Matrix");
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);
int [] fbos = new int[1];
GLES20.glGenBuffers(1, fbos, 0);
fboId = fbos[0];
//绑定
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER,fboId);
//生成离屏渲染纹理
int[] textureIds = new int[1];
GLES20.glGenTextures(1, textureIds, 0);
textureid = textureIds[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureid);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glUniform1i(sampler, 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);
//设置FBO分配内存大小
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 900, 1600, 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
//把纹理绑定到FBO
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D, textureid, 0);
//检查FBO绑定是否成功
if(GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER) != GLES20.GL_FRAMEBUFFER_COMPLETE){
Log.e("godv", "fbo error");
}else {
Log.e("godv", "fbo success");
}
//解绑纹理
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
//解绑
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
imgTextureId = loadTexture(R.drawable.androids);
/**************************多Surface渲染同一纹理-START*********************************/
if(onRenderCreateListener != null){
onRenderCreateListener.onCreate(textureid);
}
/**************************多Surface渲染同一纹理-END***********************************/
}
}
@Override
public void onSufaceChanged(int width, int height) {
this.width = width;
this.height = height;
width = 900;
height = 1600;
if (width > height){
Matrix.orthoM(matrix, 0, -width / ((height / 702f * 526f)),
width / ((height / 702f * 526f)), -1f, 1f, -1f, 1f);
}else {
Matrix.orthoM(matrix, 0, -1, 1, - height / ((width / 526f * 702f)),
height / ((width / 526f * 702f)), -1f, 1f);
}
Matrix.rotateM(matrix, 0, 180, 1, 0, 0);
// Matrix.rotateM(matrix, 0, 30, 0, 0, 1);
}
@Override
public void onDrawFrame() {
//900 * 1600
GLES20.glViewport(0,0,900,1600);
fboRender.onChange(width, height);
//绑定FBO 离屏渲染 =0关掉
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboId);
//清屏
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//使用颜色清屏
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
//使用program
GLES20.glUseProgram(program);
//使用
GLES20.glUniformMatrix4fv(umatrix, 1, false, matrix, 0);
//绑定FBO纹理id
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, imgTextureId);
//绑定VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
//使用顶点坐标
GLES20.glEnableVertexAttribArray(vPosition);
//传0 从VBO中取值
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8, 0);
GLES20.glEnableVertexAttribArray(fPosition);
//VBO
GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8,
vertexData.length * 4);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
//解绑
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
//解绑VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glViewport(0,0,width,height);
//解绑FBO
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
fboRender.onDraw(textureid);
}
/*
返回图片数据的纹理
*/
private int loadTexture(int src){
//创建纹理
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);
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),src);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
//解绑
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
return textureIds[0];
}
/**************************多Surface渲染同一纹理-START*****************************************/
private OnRenderCreateListener onRenderCreateListener;
public void setOnRenderCreateListener(OnRenderCreateListener onRenderCreateListener) {
this.onRenderCreateListener = onRenderCreateListener;
}
public interface OnRenderCreateListener{
void onCreate(int textureId);
}
/**************************多Surface渲染同一纹理-END*******************************************/
}
GGLTextureView
package com.example.opengldemo;
import android.content.Context;
import android.util.AttributeSet;
public class GGLTextureView extends MyGLSurfaceView {
private GGLTextureRender gglTextureRender;
public GGLTextureView(Context context) {
this(context,null);
}
public GGLTextureView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public GGLTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//执行
/**************************多Surface渲染同一纹理-START*************************************/
gglTextureRender = new GGLTextureRender(context);
setMyGLRender(gglTextureRender);
/**************************多Surface渲染同一纹理-END***************************************/
}
/**************************多Surface渲染同一纹理-START*****************************************/
public GGLTextureRender getGglTextureRender() {
return gglTextureRender;
}
/**************************多Surface渲染同一纹理-END*******************************************/
}
GMutiSurfaceView
package com.example.opengldemo;
import android.content.Context;
import android.util.AttributeSet;
public class GMutiSurfaceView extends MyGLSurfaceView {
private GMutiRender gMutiRender;
public GMutiSurfaceView(Context context) {
this(context,null);
}
public GMutiSurfaceView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public GMutiSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
gMutiRender = new GMutiRender(context);
setMyGLRender(gMutiRender);
}
public void setTextureId(int textureId){
if(gMutiRender != null){
gMutiRender.setTextureId(textureId);
}
}
}
GMutiRender
package com.example.opengldemo;
import android.content.Context;
import android.opengl.GLES20;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
public class GMutiRender implements MyGLSurfaceView.MyGLRender {
private Context context;
//顶点坐标
private final float[] vertexData = {
-1f, -1f,
1f, -1f,
-1f, 1f,
1f, 1f
};
//纹理坐标
private final float[] fragmentData = {
//fbo坐标
// 0f, 0f,
// 1f, 0f,
// 0f, 1f,
// 1f, 1f
0f, 1f,
1f, 1f,
0f, 0f,
1f, 0f
};
private FloatBuffer vertexBuffer;
private FloatBuffer fragmentBuffer;
private int program;
private int vPosition;
private int fPosition;
private int textureid;
private int sampler;
private int vboId;
//传入的纹理id
private int textureId;
public void setTextureId(int textureId) {
this.textureId = textureId;
}
public GMutiRender(Context context) {
this.context = context;
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 onSufaceCreated() {
String vertexSource = GShaderUtil.getRawResource(context, R.raw.vertex_shader);
String fragmentSource = GShaderUtil.getRawResource(context, R.raw.fragment_shader);
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);
}
@Override
public void onSufaceChanged(int width, int height) {
GLES20.glViewport(0,0,width,height);
}
@Override
public void onDrawFrame() {
//清屏
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//使用颜色清屏
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
//使用program
GLES20.glUseProgram(program);
//绑定纹理id
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
//绑定VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
//使用顶点坐标
GLES20.glEnableVertexAttribArray(vPosition);
//传0 从VBO中取值
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8, 0);
GLES20.glEnableVertexAttribArray(fPosition);
//VBO
GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8,
vertexData.length * 4);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
//解绑
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
//解绑VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
}
fragment_shader1.glsl 滤镜纹理
precision mediump float;
varying vec2 ft_Position;
uniform sampler2D sTexture;
void main() {
gl_FragColor = vec4(vec3(1.0 - texture2D(sTexture, ft_Position)), 1.0);
}
fragment_shader2.glsl
precision mediump float;
varying vec2 ft_Position;
uniform sampler2D sTexture;
void main() {
gl_FragColor = vec4(vec3(1.0 - texture2D(sTexture, ft_Position)), 1.0);
}
fragment_shader3.glsl
precision mediump float;
varying vec2 ft_Position;
uniform sampler2D sTexture;
void main() {
lowp vec4 textureColor = texture2D(sTexture, ft_Position);
gl_FragColor = vec4((textureColor.rgb + vec3(-0.5f)), textureColor.w);
}
GMutiRender
package com.example.opengldemo;
import android.content.Context;
import android.opengl.GLES20;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
public class GMutiRender implements MyGLSurfaceView.MyGLRender {
private Context context;
//顶点坐标
private final float[] vertexData = {
-1f, -1f,
1f, -1f,
-1f, 1f,
1f, 1f
};
//纹理坐标
private final float[] fragmentData = {
//fbo坐标
// 0f, 0f,
// 1f, 0f,
// 0f, 1f,
// 1f, 1f
0f, 1f,
1f, 1f,
0f, 0f,
1f, 0f
};
private FloatBuffer vertexBuffer;
private FloatBuffer fragmentBuffer;
private int program;
private int vPosition;
private int fPosition;
private int textureid;
private int sampler;
private int vboId;
//传入的纹理id
private int textureId;
/**************************多Surface渲染同一纹理_滤镜-START************************************/
//不同索引的片元着色器
private int index;
public void setTextureId(int textureId ,int index) {
this.textureId = textureId;
this.index = index;
}
/**************************多Surface渲染同一纹理_滤镜-END**************************************/
public GMutiRender(Context context) {
this.context = context;
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 onSufaceCreated() {
String vertexSource = GShaderUtil.getRawResource(context, R.raw.vertex_shader);
String fragmentSource = GShaderUtil.getRawResource(context, R.raw.fragment_shader);
/**************************多Surface渲染同一纹理_滤镜-START********************************/
if(index == 0){
fragmentSource = GShaderUtil.getRawResource(context, R.raw.fragment_shader1);
} else if(index == 1){
fragmentSource = GShaderUtil.getRawResource(context, R.raw.fragment_shader2);
} else if(index == 2){
fragmentSource = GShaderUtil.getRawResource(context, R.raw.fragment_shader3);
}
/**************************多Surface渲染同一纹理_滤镜-END**********************************/
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);
}
@Override
public void onSufaceChanged(int width, int height) {
GLES20.glViewport(0,0,width,height);
}
@Override
public void onDrawFrame() {
//清屏
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//使用颜色清屏
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
//使用program
GLES20.glUseProgram(program);
//绑定纹理id
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
//绑定VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
//使用顶点坐标
GLES20.glEnableVertexAttribArray(vPosition);
//传0 从VBO中取值
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8, 0);
GLES20.glEnableVertexAttribArray(fPosition);
//VBO
GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8,
vertexData.length * 4);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
//解绑
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
//解绑VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
}
GTextureActivity
package com.example.opengldemo;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class GTextureActivity extends AppCompatActivity {
private GGLTextureView gglTextureView;
private LinearLayout lyContent;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_texture);
gglTextureView = findViewById(R.id.g_gl_surface_view);
lyContent = findViewById(R.id.g_ly_content);
/**************************多Surface渲染同一纹理-START*************************************/
gglTextureView.getGglTextureRender().setOnRenderCreateListener(new GGLTextureRender.OnRenderCreateListener() {
@Override
public void onCreate(final int textureId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if(lyContent.getChildCount() > 0){
lyContent.removeAllViews();
}
for (int i = 0; i < 3; i++) {
GMutiSurfaceView gMutiSurfaceView = new GMutiSurfaceView(GTextureActivity.this);
/**************************多Surface渲染同一纹理_滤镜-START************************************/
gMutiSurfaceView.setTextureId(textureId ,i);
/**************************多Surface渲染同一纹理_滤镜-END**************************************/
gMutiSurfaceView.setSurfaceAndEglContext(null,gglTextureView.getEglContext());
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
layoutParams.width = 200;
layoutParams.height = 300;
gMutiSurfaceView.setLayoutParams(layoutParams);
lyContent.addView(gMutiSurfaceView);
}
}
});
}
});
/**************************多Surface渲染同一纹理-END***************************************/
}
}
FboRender
package com.example.glivepush.imgvideo;
import android.content.Context;
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 GImgVideoFboRender {
private Context context;
private float[] vertexData = {
-1f, -1f,
1f, -1f,
-1f, 1f,
1f, 1f
};
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 vboId;
public GImgVideoFboRender(Context context) {
this.context = context;
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()
{
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);
}
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.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
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);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
}