我有GLSurfaceView
我正在放置图像并应用GRAYSCALE
效果,如下所示:
final GLSurfaceView glView = (GLSurfaceView) findViewById(R.id.glSurfaceImg);
glView.setEGLContextClientVersion(2);
glView.setRenderer(new EffectsRenderer(this, bitmap_resized, EffectFactory.EFFECT_GRAYSCALE));
glView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
上面的代码工作正常,也就是说,图像显示正确,也有正确的过滤器。但我也有一个按钮,点击它,我希望图像上的滤镜效果从EFFECT_GRAYSCALE
更改为EFFECT_GRAIN
,我正在运行以下代码:
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
glView.setRenderer(new EffectsRenderer(ImageFiltersActivity.this, bitmap_resized, EffectFactory.EFFECT_GRAIN));
}
});
但上面的代码不起作用。当我点击按钮时,出现以下错误:java.lang.IllegalStateException: setRenderer has already been called for this instance.
我现在该做什么作为此问题的转变,以实现我在点击我的按钮时对图像应用不同过滤器的目标?
我的EffectsRenderer
课程如下(如果需要参考):
public class EffectsRenderer implements GLSurfaceView.Renderer {
private Bitmap photo;
private int photoWidth, photoHeight;
private int textures[] = new int[2];
private Square square;
private String filter;
private EffectContext effectContext;
private Effect effect;
public EffectsRenderer(Context context, Bitmap bitmap, String filter){
super();
photo = bitmap;
this.filter = filter;
photoWidth = photo.getWidth();
photoHeight = photo.getHeight();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0,0,width, height);
GLES20.glClearColor(0,0,0,1);
generateSquare();
}
@Override
public void onDrawFrame(GL10 gl) {
if(effectContext==null) {
effectContext = EffectContext.createWithCurrentGlContext();
}
if(effect!=null){
effect.release();
}
applyFilter();
square.draw(textures[1]);
}
private void generateSquare(){
GLES20.glGenTextures(2, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
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);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, photo, 0);
square = new Square();
}
private void applyFilter(){
EffectFactory factory = effectContext.getFactory();
effect = factory.createEffect(filter);
effect.apply(textures[0], photoWidth, photoHeight, textures[1]);
}
}
答案 0 :(得分:1)
您不能多次拨打setRenderer()
,noted in the documentation。
相反,使用单个Renderer实例,并让它切换行为。修改您的onDrawFrame()
以检测所请求的过滤器是否已更改,并做出适当的反应。