Jusqu'à présent, j'ai utilisé différents shaders et les ai appliqués à un VideoSurfaceView personnalisé pendant la lecture d'une vidéo. Tout fonctionnait bien jusqu'à aujourd'hui quand je voulais ajouter un effet gamma:Erreur GLES 1282 inattendue sur Android
public class GammaEffect implements ShaderInterface {
/**
* Initialize Effect
*/
public GammaEffect() {
}
@Override
public String getShader(GLSurfaceView mGlSurfaceView) {
String shader = "#extension GL_OES_EGL_image_external : require\n"
+"precision mediump float;\n"
+"varying vec2 textureCoordinate;\n"
+"uniform sampler2D inputImageTexture;\n"
+"uniform float gamma;\n"
+"void main() {\n"
+"vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n"
+"gl_FragColor = vec4(pow(textureColor.rgb, vec3(gamma)), textureColor.w);\n"
+"}\n";
return shader;
}
}
Et la classe VideoSurface personnalisée:
public class VideoSurfaceView extends GLSurfaceView {
private static final String TAG = "VideoSurfaceView";
private VideoRender mRenderer;
private MediaPlayer mMediaPlayer = null;
private static VideoSurfaceView mSurfaceView;
private Context mContext;
private static ShaderInterface effect;
public VideoSurfaceView(Context context) {
super(context);
mContext = context;
setEGLContextClientVersion(2);
mRenderer = new VideoRender(mContext);
setRenderer(mRenderer);
mSurfaceView = this;
}
public VideoSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setEGLContextClientVersion(2);
mRenderer = new VideoRender(mContext);
setRenderer(mRenderer);
mSurfaceView = this;
}
/**
* initializes media player and the effect that is going to be applied on
* video. The video is played automatically so you dont need to call play.
*
* @param mediaPlayer instance of {@link MediaPlayer}
* @param shaderEffect any effect that implements {@link ShaderInterface}
*/
public void init(MediaPlayer mediaPlayer, ShaderInterface shaderEffect) {
if (mediaPlayer == null)
Toast.makeText(mContext, "Set MediaPlayer before continuing",
Toast.LENGTH_LONG).show();
else
mMediaPlayer = mediaPlayer;
if (shaderEffect == null)
effect = new NoEffect();
else
effect = shaderEffect;
}
@Override
public void onResume() {
if (mMediaPlayer == null) {
Log.e(TAG, "Call init() before Continuing");
return;
}
queueEvent(new Runnable() {
@Override
public void run() {
mRenderer.setMediaPlayer(mMediaPlayer);
}
});
super.onResume();
}
private static class VideoRender implements Renderer,
SurfaceTexture.OnFrameAvailableListener {
private static String TAG = "VideoRender";
private static final int FLOAT_SIZE_BYTES = 4;
private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
private final float[] mTriangleVerticesData = {
// X, Y, Z, U, V
-1.0f, -1.0f, 0, 0.f, 0.f, 1.0f, -1.0f, 0, 1.f, 0.f, -1.0f,
1.0f, 0, 0.f, 1.f, 1.0f, 1.0f, 0, 1.f, 1.f,};
private FloatBuffer mTriangleVertices;
private final String mVertexShader = "uniform mat4 uMVPMatrix;\n"
+ "uniform mat4 uSTMatrix;\n" + "attribute vec4 aPosition;\n"
+ "attribute vec4 aTextureCoord;\n"
+ "varying vec2 vTextureCoord;\n" + "void main() {\n"
+ " gl_Position = uMVPMatrix * aPosition;\n"
+ " vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" + "}\n";
private float[] mMVPMatrix = new float[16];
private float[] mSTMatrix = new float[16];
private int mProgram;
private int mTextureID[] = new int[2];
private int muMVPMatrixHandle;
private int muSTMatrixHandle;
private int maPositionHandle;
private int maTextureHandle;
private SurfaceTexture mSurface;
private boolean updateSurface = false;
private static int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
private MediaPlayer mMediaPlayer;
public VideoRender(Context context) {
mTriangleVertices = ByteBuffer
.allocateDirect(
mTriangleVerticesData.length * FLOAT_SIZE_BYTES)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mTriangleVertices.put(mTriangleVerticesData).position(0);
Matrix.setIdentityM(mSTMatrix, 0);
}
public void setMediaPlayer(MediaPlayer player) {
mMediaPlayer = player;
}
@Override
public void onDrawFrame(GL10 glUnused) {
synchronized (this) {
if (updateSurface) {
mSurface.updateTexImage();
mSurface.getTransformMatrix(mSTMatrix);
updateSurface = false;
}
}
mProgram = createProgram(mVertexShader,
effect.getShader(mSurfaceView));
GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT
| GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(mProgram);
checkGlError("glUseProgram");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID[0]);
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT,
false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES,
mTriangleVertices);
checkGlError("glVertexAttribPointer maPosition");
GLES20.glEnableVertexAttribArray(maPositionHandle);
checkGlError("glEnableVertexAttribArray maPositionHandle");
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT,
false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES,
mTriangleVertices);
checkGlError("glVertexAttribPointer maTextureHandle");
GLES20.glEnableVertexAttribArray(maTextureHandle);
checkGlError("glEnableVertexAttribArray maTextureHandle");
Matrix.setIdentityM(mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix,
0);
GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
checkGlError("glDrawArrays");
GLES20.glFinish();
}
@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
}
@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
mProgram = createProgram(mVertexShader,
effect.getShader(mSurfaceView));
if (mProgram == 0) {
return;
}
maPositionHandle = GLES20
.glGetAttribLocation(mProgram, "aPosition");
checkGlError("glGetAttribLocation aPosition");
if (maPositionHandle == -1) {
throw new RuntimeException(
"Could not get attrib location for aPosition");
}
maTextureHandle = GLES20.glGetAttribLocation(mProgram,
"aTextureCoord");
checkGlError("glGetAttribLocation aTextureCoord");
if (maTextureHandle == -1) {
throw new RuntimeException(
"Could not get attrib location for aTextureCoord");
}
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram,
"uMVPMatrix");
checkGlError("glGetUniformLocation uMVPMatrix");
if (muMVPMatrixHandle == -1) {
throw new RuntimeException(
"Could not get attrib location for uMVPMatrix");
}
muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram,
"uSTMatrix");
checkGlError("glGetUniformLocation uSTMatrix");
if (muSTMatrixHandle == -1) {
throw new RuntimeException(
"Could not get attrib location for uSTMatrix");
}
// int[] textures = new int[1];
GLES20.glGenTextures(2, mTextureID, 0);
// GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID[0]);
// mTextureID = textures[0];
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID[0]);
checkGlError("glBindTexture mTextureID");
// GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES,
// GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
// GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES,
// GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
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);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
/*
* Create the SurfaceTexture that will feed this textureID, and pass
* it to the MediaPlayer
*/
mSurface = new SurfaceTexture(mTextureID[0]);
mSurface.setOnFrameAvailableListener(this);
Surface surface = new Surface(mSurface);
mMediaPlayer.setSurface(surface);
mMediaPlayer.setScreenOnWhilePlaying(true);
surface.release();
try {
mMediaPlayer.prepare();
} catch (IOException t) {
Log.e(TAG, "media player prepare failed");
}
synchronized (this) {
updateSurface = false;
}
mMediaPlayer.start();
}
@Override
synchronized public void onFrameAvailable(SurfaceTexture surface) {
updateSurface = true;
}
private int loadShader(int shaderType, String source) {
int shader = GLES20.glCreateShader(shaderType);
if (shader != 0) {
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS,
compiled, 0);
if (compiled[0] == 0) {
Log.e(TAG, "Could not compile shader " + shaderType + ":");
Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
shader = 0;
}
}
return shader;
}
private int createProgram(String vertexSource, String fragmentSource) {
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0) {
return 0;
}
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentSource);
if (pixelShader == 0) {
return 0;
}
int program = GLES20.glCreateProgram();
if (program != 0) {
GLES20.glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
GLES20.glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
GLES20.glLinkProgram(program);
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS,
linkStatus, 0);
if (linkStatus[0] != GLES20.GL_TRUE) {
Log.e(TAG, "Could not link program: ");
Log.e(TAG, GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
program = 0;
}
}
return program;
}
private void checkGlError(String op) {
int error;
if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e(TAG, op + ": glError " + error);
throw new RuntimeException(op + ": glError " + error);
}
}
} // End of class VideoRender.
} // End of class VideoSurfaceView.
La méthode « checkGLError » renvoie 1282. Il est la première fois il le fait et je ne comprends pas pourquoi.
J'ai cherché sur Stack pour les réponses et je n'ai pas trouvé quelque chose de convenable pour ce cas. Pouvez-vous s'il vous plaît donner votre opinion sur ce qui doit être changé?
Copie possible de [Vec shader - hue video filtering] (http://stackoverflow.com/questions/40619903/vec-shader-hue-video-filtering) – solidpixel
N'est-ce pas juste une copie du même problème dans votre autre question? – solidpixel
Selon l'autre question. (1) Précisément quelle fonction échoue - vous avez plusieurs appels à checkGlError? Juste nous dire la chaîne de journal aiderait. (2) L'erreur est GL_INVALID_OPERATION. Utilisez (1) et (2) et lisez le manuel - le manuel GL est assez bon pour expliquer les causes d'erreur ... – solidpixel