Android 截图使用OpenGL显示图像错误问题

RyanRq 2017-03-07 03:55:08
先上代码
package com.ryan.screenrecoder.ui.activity;

import android.Manifest;
import android.content.Intent;
import android.graphics.SurfaceTexture;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaPlayer;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.os.EnvironmentCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;
import android.widget.LinearLayout;

import com.ryan.screenrecoder.R;
import com.ryan.screenrecoder.util.RawResourceReader;
import com.ryan.screenrecoder.util.ShaderHelper;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;


public class MainActivity extends AppCompatActivity implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
private MediaProjectionManager mediaProjectionManager;
private GLSurfaceView surfaceview;
private LinearLayout linearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayout = ((LinearLayout) findViewById(R.id.linearlayout));
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);

}


/**
* 初始化摄像头
*/
private void initCamera() {
surfaceview = new GLSurfaceView(this);
linearLayout.addView(surfaceview);
surfaceview.setEGLContextClientVersion(2);
surfaceview.setRenderer(this);
}


private MediaProjection mediaProjection;

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
initCamera();
}


@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
setupGraphics();
setupVertexBuffer();
setupTexture();
//
}

private int width=1080;
private int height=1920;
private MediaPlayer mediaPlayer;
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
this.width = width;
this.height = height;
// if (mediaPlayer == null) {
// mediaPlayer = new MediaPlayer();
// mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// @Override
// public void onPrepared(MediaPlayer mp) {
// mp.start();
// }
// });
// Surface surface = new Surface(videoTexture);
// mediaPlayer.setSurface(surface);
// surface.release();
// try {
// mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath()+"/1.mp4");
// mediaPlayer.prepareAsync();
// } catch (IOException e) {
// e.printStackTrace();
// }
// } else {
// mediaPlayer.start();
// }
Surface surface = new Surface(videoTexture);
VirtualDisplay display = mediaProjection.createVirtualDisplay("aa", 1080, 1920, 32,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, surface, null, null);
}

private float[] videoTextureTransform = new float[16];

@Override
public void onDrawFrame(GL10 gl) {
synchronized (this) {
if (frameAvailable) {
videoTexture.updateTexImage();
videoTexture.getTransformMatrix(videoTextureTransform);
frameAvailable = false;
}
}
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);
// Draw a rectangle and render the video frame as a texture on it.
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
// GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

// GLES20.glViewport(0, 0, width, height);
this.drawTexture();
}

private int shaderProgram;
int textureParamHandle;
int textureCoordinateHandle;
int positionHandle;
int textureTranformHandle;
private static short drawOrder[] = {0, 1, 2, 0, 2, 3};
private FloatBuffer vertexBuffer;
private ShortBuffer drawListBuffer;
private static float squareSize = 0.5f;
private static float squareCoords[] = {
-squareSize, squareSize, // top left
-squareSize, -squareSize, // bottom left
squareSize, -squareSize, // bottom right
squareSize, squareSize}; // top right
private FloatBuffer textureBuffer;
private float textureCoords[] = {
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f};
private int[] textures = new int[1];
private SurfaceTexture videoTexture;
private void setupGraphics() {

final String vertexShader = RawResourceReader.readTextFileFromRawResource(this, R.raw.vetext_sharder);
final String fragmentShader = RawResourceReader.readTextFileFromRawResource(this, R.raw.fragment_sharder);

final int vertexShaderHandle = ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, vertexShader);
final int fragmentShaderHandle = ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader);
shaderProgram = ShaderHelper.createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle,
new String[]{"texture", "vPosition", "vTexCoordinate", "textureTransform"});

GLES20.glUseProgram(shaderProgram);
textureParamHandle = GLES20.glGetUniformLocation(shaderProgram, "texture");
textureCoordinateHandle = GLES20.glGetAttribLocation(shaderProgram, "vTexCoordinate");
positionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition");
textureTranformHandle = GLES20.glGetUniformLocation(shaderProgram, "textureTransform");
}

private void setupVertexBuffer() {
// Draw list buffer
ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);

// Initialize the texture holder
ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4);
bb.order(ByteOrder.nativeOrder());

vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(squareCoords);
vertexBuffer.position(0);
}

private void setupTexture() {
ByteBuffer texturebb = ByteBuffer.allocateDirect(textureCoords.length * 4);
texturebb.order(ByteOrder.nativeOrder());

textureBuffer = texturebb.asFloatBuffer();
textureBuffer.put(textureCoords);
textureBuffer.position(0);

// Generate the actual texture
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glGenTextures(1, textures, 0);
// checkGlError("Texture generate");


GLES20.glBindTexture(GLES20.GL_TEXTURE_BINDING_2D, textures[0]);
// checkGlError("Texture bind");

videoTexture = new SurfaceTexture(textures[0]);
videoTexture.setOnFrameAvailableListener(this);
}

private boolean frameAvailable = false;

@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
synchronized (this) {
Log.e("---", "onFrameAvailable: ");
frameAvailable = true;
}
}

private void drawTexture() {
// Draw texture

GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer);


GLES20.glEnableVertexAttribArray(textureCoordinateHandle);
GLES20.glVertexAttribPointer(textureCoordinateHandle, 4, GLES20.GL_FLOAT, false, 0, textureBuffer);

GLES20.glUniformMatrix4fv(textureTranformHandle, 1, false, videoTextureTransform, 0);

GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
}
}


fragment_sharder
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES texture;
varying vec2 v_TexCoordinate;

void main () {
vec4 color = texture2D(texture, v_TexCoordinate);
gl_FragColor = color;
}
vetext_sharder
attribute vec4 vPosition;
attribute vec4 vTexCoordinate;
uniform mat4 textureTransform;
varying vec2 v_TexCoordinate;

void main () {
v_TexCoordinate = (textureTransform * vTexCoordinate).xy;
gl_Position = vPosition;
}
用mediaplayer可以正常显示,用virticaldisplay就无法正长显示,为什么求大神帮助!!!

...全文
350 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

80,472

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧