public class CameraGLSurfaceFragment extends Fragment {
private final BaseCamera mCamera;
private final byte[] grayData; // 这里应该是你的灰度图像数据
private final int width;
private final int height;
private final int[] textureId_yuv = new int[1];
private ByteBuffer y;
private int sampler_y;
private int program_yuv;
private final FloatBuffer vertexBuffer;
private final FloatBuffer textureBuffer;
private int avPosition_yuv;
private int afPosition_yuv;
private static final String VERTEX_SHADER =
"attribute vec4 av_Position;\n" +
"attribute vec2 af_Position;\n" +
"varying vec2 v_texCord;\n" +
"void main() {\n" +
"gl_Position = av_Position;\n" +
"v_texCord = af_Position;\n" +
"}\n";
private static final String FRAGMENT_SHADER =
"precision mediump float;\n" +
"uniform sampler2D sampler_y;\n" +
"varying vec2 v_texCord;\n" +
"void main() {\n" +
"gl_FragColor = texture2D(sampler_y, v_texCord);\n" +
"}\n";
ScheduledFuture<?> scheduledFuture;
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
public CameraGLSurfaceFragment(BaseCamera camera) {
mCamera = camera;
width = camera.getWidth();
height = camera.getHeight();
grayData = new byte[width * height];
//顶点坐标
float[] vertexData = {
-1f, -1f,
1f, -1f,
-1f, 1f,
1f, 1f
};
vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(vertexData);
vertexBuffer.position(0);
//纹理坐标
float[] textureData = {
0f, 1f,
1f, 1f,
0f, 0f,
1f, 0f
};
textureBuffer = ByteBuffer.allocateDirect(textureData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(textureData);
textureBuffer.position(0);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCamera.open();
}
@Override
public void onDestroy() {
super.onDestroy();
mCamera.close();
if (scheduledFuture != null) scheduledFuture.cancel(false);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_camera_gl_surface, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
GLSurfaceView glSurfaceView = view.findViewById(R.id.preview_gl);
glSurfaceView.setEGLContextClientVersion(2);
glSurfaceView.setRenderer(new GLSurfaceView.Renderer() {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//创建一个渲染程序
program_yuv = createProgram();
//得到着色器中的属性
avPosition_yuv = GLES20.glGetAttribLocation(program_yuv, "av_Position");
afPosition_yuv = GLES20.glGetAttribLocation(program_yuv, "af_Position");
sampler_y = GLES20.glGetUniformLocation(program_yuv, "sampler_y");
//创建纹理
GLES20.glGenTextures(1, textureId_yuv, 0);
//绑定纹理
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId_yuv[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);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// 设置视口大小
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
//
//Arrays.fill(grayData, (byte) ((Math.random() * 255 % 255) - 128));
mCamera.getData(grayData);
//Log.d("GLSurface", "onDrawFrame " + mCamera.getFrameIndex());
// 加载灰度图像数据到纹理中
y = ByteBuffer.allocateDirect(grayData.length);
y.put(grayData);
y.position(0);
// 清除屏幕
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(program_yuv);
GLES20.glEnableVertexAttribArray(avPosition_yuv);//使顶点属性数组有效
GLES20.glVertexAttribPointer(avPosition_yuv, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer);//为顶点属性赋值
GLES20.glEnableVertexAttribArray(afPosition_yuv);
GLES20.glVertexAttribPointer(afPosition_yuv, 2, GLES20.GL_FLOAT, false, 8, textureBuffer);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId_yuv[0]);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, width, height, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, y);//
GLES20.glUniform1i(sampler_y, 0);
// 绘制几何体(例如一个矩形覆盖整个屏幕)
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
});
glSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY);
scheduledFuture = executor.scheduleAtFixedRate(glSurfaceView::requestRender, 300, 50, TimeUnit.MILLISECONDS);
}
private int createProgram() {
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER);
return linkProgram(vertexShader, fragmentShader);
}
private static int loadShader(int type, String shaderSource) {
int shader = glCreateShader(type);
glShaderSource(shader, shaderSource);
glCompileShader(shader);
return shader;
}
private static int linkProgram(int verShader, int fragShader) {
int program = glCreateProgram();
glAttachShader(program, verShader);
glAttachShader(program, fragShader);
// 创建OpenGL ES程序可执行文件
glLinkProgram(program);
//告诉OpenGL ES使用此program
glUseProgram(program);
return program;
}
}