【发布时间】:2014-02-27 10:10:34
【问题描述】:
我有一个渲染脚本,它处理输出到分配的图像。 我想在我的 OpenGL 程序中将此分配用作纹理,但我不知道如何从分配中获取纹理 ID。
另一方面,我知道我可以使用图形渲染脚本,但由于它已被弃用,我想一定有其他方法可以达到相同的效果。
【问题讨论】:
标签: android opengl-es-2.0 renderscript
我有一个渲染脚本,它处理输出到分配的图像。 我想在我的 OpenGL 程序中将此分配用作纹理,但我不知道如何从分配中获取纹理 ID。
另一方面,我知道我可以使用图形渲染脚本,但由于它已被弃用,我想一定有其他方法可以达到相同的效果。
【问题讨论】:
标签: android opengl-es-2.0 renderscript
在创建分配时指定 USAGE_IO_OUTPUT。假设您在脚本中生成纹理数据,您还将添加 USAGE_SCRIPT。然后你可以调用
Allocation.setSurface(theGLSurface)
将分配链接到纹理。每次你想用你需要调用的脚本的内容来更新纹理。
Allocation.ioSend()
这将移动数据而不制作额外的副本。
【讨论】:
Allocation.setSurface(new Surface(new SurfaceTexture(textureID))) 才能将输出分配绑定到纹理ID。我正在运行脚本,然后将纹理渲染到屏幕上,但我看不到渲染的任何变化,因为脚本从未运行过
您已将问题表述为将分配转换为 纹理,但更容易想到创建纹理然后授予 该纹理的分配所有权。这样,你就会知道 在将纹理 ID 传递给分配之前。当心:分配 拥有radically change纹理属性的能力。
创建 GL 纹理
使用Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT创建分配
将 SurfaceTexture 传递给 setSurface() 的分配
将数据放入分配中
在分配上调用ioSend() 以更新纹理
重复第 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);
}
}
【讨论】: