Renderscript on Android – basics

With Renderscript for Android there are three parts, two that you need to implement yourself, one in Java and one in c99, and then there is a generated api that binds the other two parts togeather. The java code calls the api that in turn calls the c99 code. This example tries to show a basic use-case of renderscript, by rendering a julia fractal based on where on the screen the user taps. It consists of one renderscript file ‘julia.rs‘ and one java file ‘JuliaRSActivity.java‘.
The julia.rs. file starts of with:

#pragma version(1)
#pragma rs java_package_name(com.android.rs.julia)

The first line just tells what version of the api we are using (there is currently only one version, 1) and the second what package name the reflected java classes will have. More about that here.
Next we define a few constants. For ex. “int precision;” that we can get and set from Java:

RenderScript rs = RenderScript.create(this);
ScriptC_julia script = new ScriptC_julia(rs, getResources(), R.raw.julia);
script.set_precision(24);
int precision = script.get_precision();

Next comes the root function.

void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
...
}

The root function will be called from the api when we call the forEach_root() method in java. But before we can call the forEach_root() method we need to define a Allocation that the forEach_root method can pick Element‘s from when called. In this example the Allocation is based on a bitmap and this causes the root() function to be called once per pixel in that bitmap.

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = (int) (size.x);
int height = (int) (size.y);
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
bitmap = Bitmap.createBitmap(width, height, conf);
private RenderScript rs = RenderScript.create(this);
inAllocation = Allocation.createFromBitmap(rs, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
outAllocation = Allocation.createFromBitmap(rs, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
script = new ScriptC_julia(rs, getResources(), R.raw.julia);
script.forEach_root(inAllocation, outAllocation);

The “forEach_root” tells the api to run the root function for each element (each pixels color data is visible in c99 through -> const uchar4 *in) in the inAllocation.
The root function in this example does some maths and uses the result to determine a new color for the current pixel/element.

void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
    float3 pixel = convert_float4(in[0]).rgb;

    float fx=(float)((x/width)*2.f-1.f);
    float fy=(float)((y/height)*2.f-1.f);

    float t=0;

    int k=0;
    int COLOR_MULT = (255 / precision);

    while(k= 4) break;
        k++;
    }
    pixel.z = k*COLOR_MULT;
    pixel.y = 255-k*COLOR_MULT;
    pixel.x = k*COLOR_MULT/3;

    out->xyz = convert_uchar3(pixel);
}

To run this example for yourself, just clone it from github: ‘git clone git@github.com:carlemil/JuliaLiveWallpaper.git’
You can find the github project here.

Leave a Reply

Close Menu