GLSurfaceView的setRenderer函数不能多次调用

时间:2015-12-30 18:42:19

标签: android glsurfaceview

我有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]);
    }
}

1 个答案:

答案 0 :(得分:1)

您不能多次拨打setRenderer()noted in the documentation

相反,使用单个Renderer实例,并让它切换行为。修改您的onDrawFrame()以检测所请求的过滤器是否已更改,并做出适当的反应。