I have a Renderscript which processes an image that is given in output to an Allocation. I want to use this Allocation as a texture in my OpenGL program but I don't know how to get a texture ID from the Allocation.
On the other hand, I know I could use a graphic Renderscript, but since it has been deprecated, I guess there must be some other way to achieve the same result.
Allocation objects allow arrays to be passed from Java code to RenderScript code and vice-versa. Allocation objects are typically created using createTyped () or createFromBitmap (). Create whatever scripts are necessary. There are two types of scripts available to you when using RenderScript:
OpenGL in Android is a graphics library that is used for 2D and 3D graphics development in Android applications. OpenGL provides cross-platform APIs. It processes high-performance data transfer between CPU and GPU.
There are three important concepts for using Renderscripts in an Android application: A context – A managed API provided by the Android SDK that allocates resources to Renderscript and allows the Android app to pass and receive data from the Renderscript. A compute kernel – Also known as the root kernel or kernel, this a routine that does the work.
The rendering pipeline process of OpenGL in Android consists of six stages as below : The first and foremost step to render an image is geometry data that has to be converted from one coordinate system into another coordinate system.
Specify USAGE_IO_OUTPUT when you create the Allocation. Assuming you are generating the texture data in a script you would also add USAGE_SCRIPT. You can then call
Allocation.setSurface(theGLSurface)
to link the allocation to a texture. Each time you want to update the texture with the contents of the script you need to call.
Allocation.ioSend()
This will move the data without making extra copies.
You have phrased the question in terms of transforming an Allocation into a texture, but it's easier to think of creating a texture then granting the Allocation ownership of that texture. This way, you would know the texture ID before passing it to the Allocation. Beware: the Allocation has the power to radically change properties of the texture.
Create a GL texture
Create a SurfaceTexture using its ID
Create an Allocation with usage Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT
Pass the SurfaceTexture to the Allocation with setSurface()
Put data in the Allocation
Call ioSend()
on the Allocation to update the texture
Repeat steps 5 and 6 as often as you want to update the texture
I am very far from a GL expert, so step 2 is frankly conjecture.
Below is an adaptation of the HelloCompute sample in which I replace
displayout
with a TextureView,
which is a View that handily creates a texture and a SurfaceTexture for me.
From then on I follow the steps above.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With