6

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

另一方面,我知道我可以使用图形渲染脚本,但由于它已被弃用,我想必须有其他方法来实现相同的结果。

4

2 回答 2

7

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

Allocation.setSurface(GLSurface)

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

分配.ioSend()

这将在不制作额外副本的情况下移动数据。

于 2013-03-07T16:51:45.513 回答
2

您已经根据将分配转换为纹理来表达问题,但更容易想到创建纹理然后授予该纹理的分配所有权。这样,您将在将纹理 ID 传递给分配之前知道它。当心:分配有能力从根本上改变纹理的属性。

一步步:

  1. 创建 GL 纹理

  2. 使用其 ID创建SurfaceTexture

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

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

  5. 将数据放入分配

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

  7. 尽可能频繁地重复步骤 5 和 6,以更新纹理

我离 GL 专家还很远,所以第 2 步坦率地说是猜想。下面是对 HelloCompute 示例的改编,我在其中替换 displayoutTextureView,这是一个可以为我轻松创建纹理和 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);
    }
}
于 2014-02-27T02:10:34.037 回答