【问题标题】:How to share a Renderscript allocation with OpenGL in Android如何在 Android 中与 OpenGL 共享 Renderscript 分配
【发布时间】:2014-02-27 10:10:34
【问题描述】:

我有一个渲染脚本,它处理输出到分配的图像。 我想在我的 OpenGL 程序中将此分配用作纹理,但我不知道如何从分配中获取纹理 ID。

另一方面,我知道我可以使用图形渲染脚本,但由于它已被弃用,我想一定有其他方法可以达到相同的效果。

【问题讨论】:

    标签: android opengl-es-2.0 renderscript


    【解决方案1】:

    在创建分配时指定 USAGE_IO_OUTPUT。假设您在脚本中生成纹理数据,您还将添加 USAGE_SCRIPT。然后你可以调用

    Allocation.setSurface(theGLSurface)

    将分配链接到纹理。每次你想用你需要调用的脚本的内容来更新纹理。

    Allocation.ioSend()

    这将移动数据而不制作额外的副本。

    【讨论】:

    • 所以,我想我必须做一个Allocation.setSurface(new Surface(new SurfaceTexture(textureID))) 才能将输出分配绑定到纹理ID。我正在运行脚本,然后将纹理渲染到屏幕上,但我看不到渲染的任何变化,因为脚本从未运行过
    • 我试过这个,但是当 Renderscript 上下文被释放时会导致崩溃,见stackoverflow.com/questions/13842609/…
    【解决方案2】:

    您已将问题表述为将分配转换为 纹理,但更容易想到创建纹理然后授予 该纹理的分配所有权。这样,你就会知道 在将纹理 ID 传递给分配之前。当心:分配 拥有radically change纹理属性的能力。

    一步一步:

    1. 创建 GL 纹理

    2. 创建SurfaceTexture using its ID

    3. 使用Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT创建分配

    4. 将 SurfaceTexture 传递给 setSurface() 的分配

    5. 将数据放入分配中

    6. 在分配上调用ioSend() 以更新纹理

    7. 重复第 5 步和第 6 步,以更新纹理

    我离 GL 专家还很远,所以第 2 步坦率地说是猜想。 下面是我替换的 HelloCompute 示例的改编 displayout 和 TextureView, 这是一个为我轻松创建纹理和 SurfaceTexture 的视图。 从那时起,我按照上面的步骤操作。

    package com.example.android.rs.hellocompute;
    
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.SurfaceTexture;
    import android.os.Bundle;
    import android.renderscript.Allocation;
    import android.renderscript.Element;
    import android.renderscript.RenderScript;
    import android.renderscript.Type;
    import android.view.Surface;
    import android.view.Surface.OutOfResourcesException;
    import android.view.TextureView;
    import android.widget.ImageView;
    
    public class HelloCompute extends Activity {
        private Bitmap mBitmapIn;
    
        private RenderScript mRS;
        private ScriptC_mono mScript;
        private Allocation mSurfaceAllocation;
        private Allocation mCanvasAllocation;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            mBitmapIn = loadBitmap(R.drawable.data);
            int x = mBitmapIn.getWidth();
            int y = mBitmapIn.getHeight();
    
            ImageView in = (ImageView) findViewById(R.id.displayin);
            in.setImageBitmap(mBitmapIn);
    
            mRS = RenderScript.create(this);
            mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono);
    
            mCanvasAllocation = Allocation.createTyped(mRS, 
                    new Type.Builder(mRS, Element.RGBA_8888(mRS))
                        .setX(x).setY(y).create(), 
                    Allocation.USAGE_IO_INPUT | Allocation.USAGE_SCRIPT);
    
            mSurfaceAllocation = Allocation.createTyped(mRS, 
                    new Type.Builder(mRS, Element.RGBA_8888(mRS))
                        .setX(x).setY(y).create(), 
                    Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT);
    
            TextureView mTextureView = (TextureView) findViewById(R.id.displayout);
            mTextureView.setSurfaceTextureListener(
              new TextureView.SurfaceTextureListener() {
                @Override
                public void onSurfaceTextureAvailable(SurfaceTexture s, 
                        int w, int h) {
                    if(s != null) mSurfaceAllocation.setSurface(new Surface(s));
                    mScript.forEach_root(mCanvasAllocation, mSurfaceAllocation);
                    mSurfaceAllocation.ioSend();
                }
    
                @Override
                public void onSurfaceTextureUpdated(SurfaceTexture s) {
                }
    
                @Override
                public void onSurfaceTextureSizeChanged(SurfaceTexture s, 
                        int w, int h) {
                    if(s != null) mSurfaceAllocation.setSurface(new Surface(s));
                }
    
                @Override
                public boolean onSurfaceTextureDestroyed(SurfaceTexture s) {
                    mSurfaceAllocation.setSurface(null);
                    return true;
                }
            });
    
            try {
                Surface surface = mCanvasAllocation.getSurface();
                Canvas canvas = surface.lockCanvas(new Rect(0,0,100,100));
                canvas.drawBitmap(mBitmapIn, 0, 0, new Paint());
                surface.unlockCanvasAndPost(canvas);
                mCanvasAllocation.ioReceive();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (OutOfResourcesException e) {
                e.printStackTrace();
            }
        }
    
        private Bitmap loadBitmap(int resource) {
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
            return BitmapFactory.decodeResource(getResources(), resource, options);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-25
      • 1970-01-01
      • 1970-01-01
      • 2018-10-28
      相关资源
      最近更新 更多