• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Graphics
2parent.title=Renderscript
3parent.link=index.html
4
5@jd:body
6
7  <div id="qv-wrapper">
8    <div id="qv">
9      <h2>In this document</h2>
10
11      <ol>
12        <li>
13          <a href="#creating-graphics-rs">Creating a Graphics Renderscript</a>
14          <ol>
15            <li><a href="#creating-native">Creating the Renderscript file</a></li>
16            <li><a href="#creating-entry">Creating the Renderscript entry point class</a></li>
17            <li><a href="#creating-view">Creating the view class</a></li>
18            <li><a href="#creating-activity">Creating the activity class</a></li>
19          </ol>
20        </li>
21        <li>
22          <a href="#drawing">Drawing</a>
23          <ol>
24            <li><a href="#drawing-rsg">Simple drawing</a></li>
25            <li><a href="#drawing-mesh">Drawing with a mesh</a></li>
26          </ol>
27        </li>
28        <li>
29          <a href="#shaders">Shaders</a>
30          <ol>
31            <li><a href="#shader-bindings">Shader bindings</a></li>
32            <li><a href="#shader-sampler">Defining a sampler</a></li>
33          </ol>
34        </li>
35        <li>
36          <a href="#fbo">Rendering to a Framebuffer Object</a>
37        </li>
38      </ol>
39
40      <h2>Related Samples</h2>
41
42      <ol>
43        <li><a href="{@docRoot}resources/samples/RenderScript/Balls/index.html">Balls</a></li>
44
45        <li><a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a></li>
46
47        <li><a href="{@docRoot}resources/samples/RenderScript/FountainFbo/index.html">FountainFbo</a></li>
48
49        <li><a href="{@docRoot}resources/samples/RenderScript/HelloWorld/index.html">Hello
50World</a></li>
51
52        <li><a
53href="{@docRoot}resources/samples/RenderScript/MiscSamples/index.html">Misc Samples</a></li>
54      </ol>
55    </div>
56  </div>
57
58  <p>Renderscript provides a number of graphics APIs for rendering, both at the Android
59  framework level as well as at the Renderscript runtime level. For instance, the Android framework APIs let you
60  create meshes and define shaders to customize the graphical rendering pipeline. The native
61  Renderscript graphics APIs let you draw the actual meshes to render your scene. You need to
62  be familiar with both APIs to appropriately render graphics on an Android-powered device.</p>
63
64  <h2 id="creating-graphics-rs">Creating a Graphics Renderscript</h2>
65
66  <p>Renderscript applications require various layers of code, so it is useful to create the following
67  files to help keep your application organized:</p>
68
69  <dl>
70    <dt>The Renderscript <code>.rs</code> file</dt>
71
72    <dd>This file contains the logic to do the graphics rendering.</dd>
73
74    <dt>The Renderscript entry point <code>.java</code> class</dt>
75
76    <dd>This class allows the view class to interact with the code defined in the <code>.rs</code>
77    file. This class contains a Renderscript object (instance of
78    <code>ScriptC_<em>renderscript_file</em></code>), which allows your Android framework code to
79    call the Renderscript code. In general, this class does much of the setup for Renderscript
80    such as shader and mesh building and memory allocation and binding. The SDK samples follow the
81    convention of naming this file ActivityRS.java,
82    where Activity is the name of your main activity class.</dd>
83
84    <dt>The view <code>.java</code> class</dt>
85
86    <dd>This class extends {@link android.renderscript.RSSurfaceView} or {@link
87    android.renderscript.RSTextureView} to provide a surface to render on. A {@link
88    android.renderscript.RSSurfaceView} consumes a whole window, but a {@link
89    android.renderscript.RSTextureView} allows you to draw Renderscript graphics inside of a
90    view and add it to a {@link android.view.ViewGroup} alongside
91    other views. In this class, you create a {@link android.renderscript.RenderScriptGL} context object
92    with a call to {@link android.renderscript.RSSurfaceView#createRenderScriptGL
93    RSSurfaceView.createRenderscriptGL()} or {@link android.renderscript.RSTextureView#createRenderScriptGL
94    RSTextureView.createRenderscriptGL()}. The {@link android.renderscript.RenderScriptGL} context object
95    contains information about the current rendering state of Renderscript such as the vertex and
96    fragment shaders. You pass this context object to the Renderscript entry point class, so that
97    class can modify the rendering context if needed and bind the Renderscript code to the context. Once bound,
98    the view class can use the Renderscript code to display graphics.
99    The view class should also implement callbacks for events inherited from {@link
100    android.view.View}, such as {@link android.view.View#onTouchEvent onTouchEvent()} and {@link
101    android.view.View#onKeyDown onKeyDown()} if you want to detect these types of user interactions.
102    The SDK samples follow the convention of naming this file ActivityView.java,
103    where Activity is the name of your main activity class</dd>
104
105    <dt>The activity <code>.java</code> class</dt>
106
107    <dd>This class is the main activity class and sets your {@link android.renderscript.RSSurfaceView} as the main content
108    view for this activity or uses the {@link android.renderscript.RSTextureView} alongside other views.</dd>
109  </dl>
110  <p>Figure 1 describes how these classes interact with one another in a graphics Renderscript:</p>
111
112  <img src="{@docRoot}images/rs_graphics.png">
113  <p class="img-caption"><strong>Figure 1.</strong> Graphics Renderscript overview</p>
114
115
116  <p>The following sections describe how to create an application that uses a graphics Renderscript by using
117  the <a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Renderscript Fountain
118  sample</a> that is provided in the SDK as a guide (some code has been modified from its original
119  form for simplicity).</p>
120
121  <h3 id="creating-native">Creating the Renderscript file</h3>
122
123  <p>Your Renderscript code resides in <code>.rs</code> and <code>.rsh</code> (headers) files in the
124  <code>&lt;project_root&gt;/src/</code> directory. This code contains the logic to render your
125  graphics and declares all other necessary items such as variables, structs,
126  and pointers. Every graphics <code>.rs</code> file generally contains the following items:</p>
127
128  <ul>
129    <li>A pragma declaration (<code>#pragma rs java_package_name(<em>package.name</em>)</code>) that declares
130    the package name of the <code>.java</code> reflection of this Renderscript.</li>
131
132    <li>A pragma declaration (<code>#pragma version(1)</code>) that declares the version of Renderscript that
133    you are using (1 is the only value for now).</li>
134
135    <li>A <code>#include "rs_graphics.rsh"</code> declaration.</li>
136
137    <li>A <code>root()</code> function. This is the main worker function for your Renderscript and
138    calls Renderscript graphics functions to render scenes. This function is called every time a
139    frame refresh occurs, which is specified as its return value. A <code>0</code> (zero) specified for
140    the return value says to only render the frame when a property of the scene that you are
141    rendering changes. A non-zero positive integer specifies the refresh rate of the frame in
142    milliseconds.
143
144      <p class="note"><strong>Note:</strong> The Renderscript runtime makes its best effort to
145      refresh the frame at the specified rate. For example, if you are creating a live wallpaper
146      and set the return value to 20, the Renderscript runtime renders the wallpaper at 50fps if it has just
147      enough or more resources to do so. It renders as fast as it can if not enough resources
148      are available.</p>
149
150      <p>For more information on using the Renderscript graphics functions, see the <a href=
151      "#drawing">Drawing</a> section.</p>
152    </li>
153
154    <li>An <code>init()</code> function. This allows you to do initialization of your
155    Renderscript before the <code>root()</code> function runs, such as assigning values to variables. This
156    function runs once and is called automatically when the Renderscript starts, before anything
157    else in your Renderscript. Creating this function is optional.</li>
158
159    <li>Any variables, pointers, and structures that you wish to use in your Renderscript code (can
160    be declared in <code>.rsh</code> files if desired)</li>
161  </ul>
162
163  <p>The following code shows how the <code>fountain.rs</code> file is implemented:</p>
164  <pre>
165#pragma version(1)
166
167// Tell which java package name the reflected files should belong to
168#pragma rs java_package_name(com.example.android.rs.fountain)
169
170//declare shader binding
171#pragma stateFragment(parent)
172
173// header with graphics APIs, must include explicitly
174#include "rs_graphics.rsh"
175
176static int newPart = 0;
177
178// the mesh to render
179rs_mesh partMesh;
180
181// the point representing where a particle is rendered
182typedef struct __attribute__((packed, aligned(4))) Point {
183    float2 delta;
184    float2 position;
185    uchar4 color;
186} Point_t;
187Point_t *point;
188
189// main worker function that renders particles onto the screen
190int root() {
191    float dt = min(rsGetDt(), 0.1f);
192    rsgClearColor(0.f, 0.f, 0.f, 1.f);
193    const float height = rsgGetHeight();
194    const int size = rsAllocationGetDimX(rsGetAllocation(point));
195    float dy2 = dt * (10.f);
196    Point_t * p = point;
197    for (int ct=0; ct &lt; size; ct++) {
198        p-&gt;delta.y += dy2;
199        p-&gt;position += p-&gt;delta;
200        if ((p-&gt;position.y &gt; height) &amp;&amp; (p-&gt;delta.y &gt; 0)) {
201            p-&gt;delta.y *= -0.3f;
202        }
203        p++;
204    }
205
206    rsgDrawMesh(partMesh);
207    return 1;
208}
209
210// adds particles to the screen to render
211static float4 partColor[10];
212void addParticles(int rate, float x, float y, int index, bool newColor)
213{
214    if (newColor) {
215        partColor[index].x = rsRand(0.5f, 1.0f);
216        partColor[index].y = rsRand(1.0f);
217        partColor[index].z = rsRand(1.0f);
218    }
219    float rMax = ((float)rate) * 0.02f;
220    int size = rsAllocationGetDimX(rsGetAllocation(point));
221    uchar4 c = rsPackColorTo8888(partColor[index]);
222
223    Point_t * np = &amp;point[newPart];
224    float2 p = {x, y};
225    while (rate--) {
226        float angle = rsRand(3.14f * 2.f);
227        float len = rsRand(rMax);
228        np-&gt;delta.x = len * sin(angle);
229        np-&gt;delta.y = len * cos(angle);
230        np-&gt;position = p;
231        np-&gt;color = c;
232        newPart++;
233        np++;
234        if (newPart &gt;= size) {
235            newPart = 0;
236            np = &amp;point[newPart];
237        }
238    }
239}
240</pre>
241
242  <h3 id="creating-entry">Creating the Renderscript entry point class</h3>
243
244  <p>When you create a Renderscript (<code>.rs</code>) file, it is helpful to create a
245  corresponding Android framework class that is an entry point into the <code>.rs</code> file.
246  The most important thing this class does is receive a {@link android.renderscript.RenderScriptGL} rendering context
247  object from the <a href="#creating-view">view class</a> and binds the actual Renderscript
248  code to the rendering context. This notifies your view class of the code that it needs
249  to render graphics.
250  </p>
251
252  <p>In addition, this class should contain all of the things needed to set up Renderscript.
253  Some important things that you need to do in this class are:</p>
254
255  <ul>
256    <li>Create a Renderscript object
257  <code>ScriptC_<em>rs_filename</em></code>. The Renderscript object is attached to the Renderscript bytecode, which is platform-independent and
258  gets compiled on the device when the Renderscript application runs. The bytecode is referenced
259  as a raw resource and is passed into the constructor for the Renderscript object.
260  For example, this is how the <a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a>
261  sample creates the Renderscript object:
262  <pre>
263  RenderScriptGL rs;  //obtained from the view class
264  Resources res;      //obtained from the view class
265  ...
266  ScriptC_fountain mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
267  </pre>
268  </li>
269  <li>Allocate any necessary memory and bind it to your Renderscript code via the Renderscript object.</li>
270  <li>Build any necessary meshes and bind them to the Renderscript code via the Renderscript object.</li>
271  <li>Create any necessary programs and bind them to the Renderscript code via the Renderscript object.</li>
272  </ul>
273
274  <p>The following code shows how the <a href=
275  "{@docRoot}resources/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/FountainRS.html">
276  FountainRS</a> class is implemented:</p>
277  <pre>
278package com.example.android.rs.fountain;
279
280import android.content.res.Resources;
281import android.renderscript.*;
282import android.util.Log;
283
284public class FountainRS {
285    public static final int PART_COUNT = 50000;
286
287    public FountainRS() {
288    }
289
290    /**
291     * This provides us with the Renderscript context and resources
292     * that allow us to create the Renderscript object
293     */
294    private Resources mRes;
295    private RenderScriptGL mRS;
296
297    // Renderscript object
298    private ScriptC_fountain mScript;
299
300    // Called by the view class to initialize the Renderscript context and renderer
301    public void init(RenderScriptGL rs, Resources res) {
302        mRS = rs;
303        mRes = res;
304
305        /**
306         * Create a shader and bind to the Renderscript context
307         */
308        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
309        pfb.setVaryingColor(true);
310        rs.bindProgramFragment(pfb.create());
311
312        /**
313         * Allocate memory for the particles to render and create the mesh to draw
314         */
315        ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);
316        Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
317        smb.addVertexAllocation(points.getAllocation());
318        smb.addIndexSetType(Mesh.Primitive.POINT);
319        Mesh sm = smb.create();
320
321       /**
322        * Create and bind the Renderscript object to the Renderscript context
323        */
324        mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
325        mScript.set_partMesh(sm);
326        mScript.bind_point(points);
327        mRS.bindRootScript(mScript);
328    }
329
330    boolean holdingColor[] = new boolean[10];
331
332    /**
333     * Calls Renderscript functions (invoke_addParticles)
334     * via the Renderscript object to add particles to render
335     * based on where a user touches the screen.
336     */
337    public void newTouchPosition(float x, float y, float pressure, int id) {
338        if (id &gt;= holdingColor.length) {
339            return;
340        }
341        int rate = (int)(pressure * pressure * 500.f);
342        if (rate &gt; 500) {
343            rate = 500;
344        }
345        if (rate &gt; 0) {
346            mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);
347            holdingColor[id] = true;
348        } else {
349            holdingColor[id] = false;
350        }
351
352    }
353}
354</pre>
355
356
357  <h3 id="creating-view">Creating the view class</h3>
358
359
360  <p>To display graphics, you need a view to render on. Create a class that extends {@link
361  android.renderscript.RSSurfaceView} or {@link android.renderscript.RSTextureView}. This class
362  allows you to create a {@link android.renderscript.RenderScriptGL} context object by calling and
363  pass it to the Rendscript entry point class to bind the two. Once bound, the content is aware
364  of the code that it needs to use to render graphics with. If your Renderscript code
365  depends on any type of information that the view is aware of, such as touches from the user,
366  you can also use this class to relay that information to the Renderscript entry point class.
367  The following code shows how the <code>FountainView</code> class is implemented:</p>
368  <pre>
369package com.example.android.rs.fountain;
370
371import android.renderscript.RSTextureView;
372import android.renderscript.RenderScriptGL;
373import android.content.Context;
374import android.view.MotionEvent;
375
376public class FountainView extends RSTextureView {
377
378    public FountainView(Context context) {
379        super(context);
380    }
381    // Renderscript context
382    private RenderScriptGL mRS;
383    // Renderscript entry point object that calls Renderscript code
384    private FountainRS mRender;
385
386    /**
387     * Create Renderscript context and initialize Renderscript entry point
388     */
389    &#064;Override
390    protected void onAttachedToWindow() {
391        super.onAttachedToWindow();
392        android.util.Log.e("rs", "onAttachedToWindow");
393        if (mRS == null) {
394            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
395            mRS = createRenderScriptGL(sc);
396            mRender = new FountainRS();
397            mRender.init(mRS, getResources());
398        }
399    }
400
401    &#064;Override
402    protected void onDetachedFromWindow() {
403        super.onDetachedFromWindow();
404        android.util.Log.e("rs", "onDetachedFromWindow");
405        if (mRS != null) {
406            mRS = null;
407            destroyRenderScriptGL();
408        }
409    }
410
411
412    /**
413     * Use callbacks to relay data to Renderscript entry point class
414     */
415    &#064;Override
416    public boolean onTouchEvent(MotionEvent ev)
417    {
418        int act = ev.getActionMasked();
419        if (act == ev.ACTION_UP) {
420            mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
421            return false;
422        } else if (act == MotionEvent.ACTION_POINTER_UP) {
423            // only one pointer going up, we can get the index like this
424            int pointerIndex = ev.getActionIndex();
425            int pointerId = ev.getPointerId(pointerIndex);
426            mRender.newTouchPosition(0, 0, 0, pointerId);
427        }
428        int count = ev.getHistorySize();
429        int pcount = ev.getPointerCount();
430
431        for (int p=0; p &lt; pcount; p++) {
432            int id = ev.getPointerId(p);
433            mRender.newTouchPosition(ev.getX(p),
434                                     ev.getY(p),
435                                     ev.getPressure(p),
436                                     id);
437
438            for (int i=0; i &lt; count; i++) {
439                mRender.newTouchPosition(ev.getHistoricalX(p, i),
440                                         ev.getHistoricalY(p, i),
441                                         ev.getHistoricalPressure(p, i),
442                                         id);
443            }
444        }
445        return true;
446    }
447}
448</pre>
449
450  <h3 id="creating-activity">Creating the activity class</h3>
451
452  <p>Applications that use Renderscript still behave like normal Android applications, so you
453   need an activity class that handles activity lifecycle callback events appropriately. The activity class
454   also sets your {@link android.renderscript.RSSurfaceView} view class to be the main content view of the
455   activity or uses your {@link android.renderscript.RSTextureView}
456  in a {@link android.view.ViewGroup} alongside other views.</p>
457
458  <p>The following code shows how the <a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a>
459  sample declares its activity class:</p>
460  <pre>
461package com.example.android.rs.fountain;
462
463import android.app.Activity;
464import android.os.Bundle;
465import android.util.Log;
466
467public class Fountain extends Activity {
468
469    private static final String LOG_TAG = "libRS_jni";
470    private static final boolean DEBUG  = false;
471    private static final boolean LOG_ENABLED = false;
472
473    private FountainView mView;
474
475    &#064;Override
476    public void onCreate(Bundle icicle) {
477        super.onCreate(icicle);
478
479        // Create our Preview view and set it as
480        // the content of our activity
481        mView = new FountainView(this);
482        setContentView(mView);
483    }
484
485    &#064;Override
486    protected void onResume() {
487        Log.e("rs", "onResume");
488
489        // Ideally a game should implement onResume() and onPause()
490        // to take appropriate action when the activity looses focus
491        super.onResume();
492        mView.resume();
493    }
494
495    &#064;Override
496    protected void onPause() {
497        Log.e("rs", "onPause");
498
499        // Ideally a game should implement onResume() and onPause()
500        // to take appropriate action when the activity looses focus
501        super.onPause();
502        mView.pause();
503
504    }
505
506    static void log(String message) {
507        if (LOG_ENABLED) {
508            Log.v(LOG_TAG, message);
509        }
510    }
511}
512</pre>
513
514<p>Now that you have an idea of what is involved in a Renderscript graphics application, you can
515start building your own. It might be easiest to begin with one of the
516<a href="{@docRoot}resources/samples/RenderScript/index.html">Renderscript samples</a> as a starting
517point if this is your first time using Renderscript.</p>
518
519  <h2 id="drawing">Drawing</h2>
520  <p>The following sections describe how to use the graphics functions to draw with Renderscript.</p>
521
522  <h3 id="drawing-rsg">Simple drawing</h3>
523
524  <p>The native Renderscript APIs provide a few convenient functions to easily draw a polygon or text to
525  the screen. You call these in your <code>root()</code> function to have them render to the {@link
526  android.renderscript.RSSurfaceView} or {@link android.renderscript.RSTextureView}. These functions are
527  available for simple drawing and should not be used for complex graphics rendering:</p>
528
529  <ul>
530    <li><code>rsgDrawRect()</code>: Sets up a mesh and draws a rectangle to the screen. It uses the
531    top left vertex and bottom right vertex of the rectangle to draw.</li>
532
533    <li><code>rsgDrawQuad()</code>: Sets up a mesh and draws a quadrilateral to the screen.</li>
534
535    <li><code>rsgDrawQuadTexCoords()</code>: Sets up a mesh and draws a quadrilateral to the screen
536    using the provided coordinates of a texture.</li>
537
538    <li><code>rsgDrawText()</code>: Draws specified text to the screen. Use <code>rsgFontColor()</code>
539    to set the color of the text.</li>
540  </ul>
541
542  <h3 id="drawing-mesh">Drawing with a mesh</h3>
543
544  <p>When you want to render complex scenes to the screen, instantiate a {@link
545  android.renderscript.Mesh} and draw it with <code>rsgDrawMesh()</code>. A {@link
546  android.renderscript.Mesh} is a collection of allocations that represent vertex data (positions,
547  normals, texture coordinates) and index data that provides information on how to draw triangles
548  and lines with the provided vertex data. You can build a Mesh in three different ways:</p>
549
550  <ul>
551    <li>Build the mesh with the {@link android.renderscript.Mesh.TriangleMeshBuilder} class, which
552    allows you to specify a set of vertices and indices for each triangle that you want to draw.</li>
553
554    <li>Build the mesh using an {@link android.renderscript.Allocation} or a set of {@link
555    android.renderscript.Allocation}s with the {@link android.renderscript.Mesh.AllocationBuilder}
556    class. This approach allows you to build a mesh with vertices already stored in memory, which allows you
557    to specify the vertices in Renderscript or Android framework code.</li>
558
559    <li>Build the mesh with the {@link android.renderscript.Mesh.Builder} class. You should use
560    this convenience method when you know the data types you want to use to build your mesh, but
561    don't want to make separate memory allocations like with {@link
562    android.renderscript.Mesh.AllocationBuilder}. You can specify the types that you want and this
563    mesh builder automatically creates the memory allocations for you.</li>
564  </ul>
565
566  <p>To create a mesh using the {@link android.renderscript.Mesh.TriangleMeshBuilder}, you need to
567  supply it with a set of vertices and the indices for the vertices that comprise the triangle. For
568  example, the following code specifies three vertices, which are added to an internal array,
569  indexed in the order they were added. The call to {@link
570  android.renderscript.Mesh.TriangleMeshBuilder#addTriangle addTriangle()} draws the triangle with
571  vertex 0, 1, and 2 (the vertices are drawn counter-clockwise).</p>
572  <pre>
573int float2VtxSize = 2;
574Mesh.TriangleMeshBuilder triangles = new Mesh.TriangleMeshBuilder(renderscriptGL,
575float2VtxSize, Mesh.TriangleMeshBuilder.COLOR);
576triangles.addVertex(300.f, 300.f);
577triangles.addVertex(150.f, 450.f);
578triangles.addVertex(450.f, 450.f);
579triangles.addTriangle(0 , 1, 2);
580Mesh smP = triangle.create(true);
581script.set_mesh(smP);
582</pre>
583
584  <p>To draw a mesh using the {@link android.renderscript.Mesh.AllocationBuilder}, you need to
585  supply it with one or more allocations that contain the vertex data:</p>
586  <pre>
587Allocation vertices;
588
589...
590Mesh.AllocationBuilder triangle = new Mesh.AllocationBuilder(mRS);
591smb.addVertexAllocation(vertices.getAllocation());
592smb.addIndexSetType(Mesh.Primitive.TRIANGLE);
593Mesh smP = smb.create();
594script.set_mesh(smP);
595</pre>
596
597  <p>In your Renderscript code, draw the built mesh to the screen:</p>
598  <pre>
599rs_mesh mesh;
600...
601
602int root(){
603...
604rsgDrawMesh(mesh);
605...
606return 0; //specify a non zero, positive integer to specify the frame refresh.
607          //0 refreshes the frame only when the mesh changes.
608}
609</pre>
610
611  <h2 id="shader">Programs</h2>
612
613  <p>You can attach four program objects to the {@link android.renderscript.RenderScriptGL} context
614  to customize the rendering pipeline. For example, you can create vertex and fragment shaders in
615  GLSL or build a raster program object that controls culling. The four programs mirror a
616  traditional graphical rendering pipeline:</p>
617
618  <table>
619    <tr>
620      <th>Android Object Type</th>
621
622      <th>Renderscript Native Type</th>
623
624      <th>Description</th>
625    </tr>
626
627    <tr>
628      <td>{@link android.renderscript.ProgramVertex}</td>
629
630      <td>rs_program_vertex</td>
631
632      <td>
633        <p>The Renderscript vertex program, also known as a vertex shader, describes the stage in
634        the graphics pipeline responsible for manipulating geometric data in a user-defined way.
635        The object is constructed by providing Renderscript with the following data:</p>
636
637        <ul>
638          <li>An {@link android.renderscript.Element} describing its varying inputs or attributes</li>
639
640          <li>GLSL shader string that defines the body of the program</li>
641
642          <li>a {@link android.renderscript.Type} that describes the layout of an
643          Allocation containing constant or uniform inputs</li>
644        </ul>
645
646        <p>Once the program is created, bind it to the {@link android.renderscript.RenderScriptGL}
647        graphics context by calling {@link android.renderscript.RenderScriptGL#bindProgramVertex
648        bindProgramVertex()}. It is then used for all subsequent draw calls until you bind a new
649        program. If the program has constant inputs, the user needs to bind an allocation
650        containing those inputs. The allocation's type must match the one provided during creation.
651        </p>
652
653        <p>The Renderscript runtime then does all the necessary plumbing to send those constants to
654        the graphics hardware. Varying inputs to the shader, such as position, normal, and texture
655        coordinates are matched by name between the input {@link android.renderscript.Element}
656        and the mesh object that is being drawn. The signatures don't have to be exact or in any
657        strict order. As long as the input name in the shader matches a channel name and size
658        available on the mesh, the Renderscript runtime handles connecting the two. Unlike OpenGL
659        there is no need to link the vertex and fragment programs.</p>
660
661        <p>To bind shader constants to the program, declare a <code>struct</code> that contains the necessary
662        shader constants in your Renderscript code. This <code>struct</code> is generated into a
663        reflected class that you can use as a constant input element during the program's creation.
664        It is an easy way to create an instance of this <code>struct</code> as an allocation. You would then
665        bind this {@link android.renderscript.Allocation} to the program and the
666        Renderscript runtime sends the data that is contained in the <code>struct</code> to the hardware
667        when necessary. To update shader constants, you change the values in the
668        {@link android.renderscript.Allocation} and notify the Renderscript
669        code of the change.</p>
670
671        <p>The {@link android.renderscript.ProgramVertexFixedFunction.Builder} class also
672        lets you build a simple vertex shader without writing GLSL code.
673        </p>
674      </td>
675    </tr>
676
677    <tr>
678      <td>{@link android.renderscript.ProgramFragment}</td>
679
680      <td>rs_program_fragment</td>
681
682      <td>
683        <p>The Renderscript fragment program, also known as a fragment shader, is responsible for
684        manipulating pixel data in a user-defined way. It's constructed from a GLSL shader string
685        containing the program body, texture inputs, and a {@link android.renderscript.Type}
686        object that describes the constants
687        used by the program. Like the vertex programs, when an {@link android.renderscript.Allocation}
688        with constant input
689        values is bound to the shader, its values are sent to the graphics program automatically.
690        Note that the values inside the {@link android.renderscript.Allocation} are not explicitly tracked.
691        If they change between two draw calls using the same program object, notify the runtime of that change by
692        calling <code>rsgAllocationSyncAll()</code>, so it can send the new values to hardware. Communication
693        between the vertex and fragment programs is handled internally in the GLSL code. For
694        example, if the fragment program is expecting a varying input called <code>varTex0</code>, the GLSL code
695        inside the program vertex must provide it.</p>
696
697        <p>To bind shader constructs to the program, declare a <code>struct</code> that contains the necessary
698        shader constants in your Renderscript code. This <code>struct</code> is generated into a
699        reflected class that you can use as a constant input element during the program's creation.
700        It is an easy way to create an instance of this <code>struct</code> as an allocation. You would then
701        bind this {@link android.renderscript.Allocation} to the program and the
702        Renderscript runtime sends the data that is contained in the <code>struct</code> to the hardware
703        when necessary. To update shader constants, you change the values in the
704        {@link android.renderscript.Allocation} and notify the Renderscript
705        code of the change.</p>
706
707        <p>The {@link android.renderscript.ProgramFragmentFixedFunction.Builder} class also
708        lets you build a simple fragment shader without writing GLSL code.
709        </p>
710      </td>
711    </tr>
712
713    <tr>
714      <td>{@link android.renderscript.ProgramStore}</td>
715
716      <td>rs_program_store</td>
717
718      <td>The Renderscript store program contains a set of parameters that control how the graphics
719      hardware writes to the framebuffer. It could be used to enable and disable depth writes and
720      testing, setup various blending modes for effects like transparency and define write masks
721      for color components.</td>
722    </tr>
723
724    <tr>
725      <td>{@link android.renderscript.ProgramRaster}</td>
726
727      <td>rs_program_raster</td>
728
729      <td>The Renderscript raster program is primarily used to specify whether point sprites are enabled and to
730      control the culling mode. By default back faces are culled.</td>
731    </tr>
732  </table>
733
734  <p>The following example defines a vertex shader in GLSL and binds it to a Renderscript context object:</p>
735  <pre>
736    private RenderScriptGL glRenderer;      //rendering context
737    private ScriptField_Point mPoints;      //vertices
738    private ScriptField_VpConsts mVpConsts; //shader constants
739
740    ...
741
742     ProgramVertex.Builder sb = new ProgramVertex.Builder(glRenderer);
743        String t =  "varying vec4 varColor;\n" +
744                    "void main() {\n" +
745                    "  vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
746                    "  pos.xy = ATTRIB_position;\n" +
747                    "  gl_Position = UNI_MVP * pos;\n" +
748                    "  varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
749                    "  gl_PointSize = ATTRIB_size;\n" +
750                    "}\n";
751        sb.setShader(t);
752        sb.addConstant(mVpConsts.getType());
753        sb.addInput(mPoints.getElement());
754        ProgramVertex pvs = sb.create();
755        pvs.bindConstants(mVpConsts.getAllocation(), 0);
756        glRenderer.bindProgramVertex(pvs);
757</pre>
758
759
760  <p>The <a href=
761  "{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html">
762  RsRenderStatesRS</a> sample has many examples on how to create a shader without writing GLSL.</p>
763
764  <h3 id="shader-bindings">Program bindings</h3>
765
766  <p>You can also declare four pragmas that control default program bindings to the {@link
767  android.renderscript.RenderScriptGL} context when the script is executing:</p>
768
769  <ul>
770    <li><code>stateVertex</code></li>
771
772    <li><code>stateFragment</code></li>
773
774    <li><code>stateRaster</code></li>
775
776    <li><code>stateStore</code></li>
777  </ul>
778
779  <p>The possible values for each pragma are <code>parent</code> or <code>default</code>. Using
780  <code>default</code> binds the shaders to the graphical context with the system defaults.</p>
781
782  <p>Using <code>parent</code> binds the shaders in the same manner as it is bound in the calling
783  script. If this is the root script, the parent state is taken from the bind points that are set
784  by the {@link android.renderscript.RenderScriptGL} bind methods.</p>
785
786  <p>For example, you can define this at the top of your graphics Renderscript code to have
787  the vertex and store programs inherent the bind properties from their parent scripts:</p>
788  <pre>
789#pragma stateVertex(parent)
790#pragma stateStore(parent)
791</pre>
792
793  <h3 id="shader-sampler">Defining a sampler</h3>
794
795  <p>A {@link android.renderscript.Sampler} object defines how data is extracted from textures.
796  Samplers are bound to a {@link android.renderscript.ProgramFragment} alongside the texture
797  whose sampling they control. These
798  objects are used to specify such things as edge clamping behavior, whether mip-maps are used, and
799  the amount of anisotropy required. There might be situations where hardware does not support the
800  desired behavior of the sampler. In these cases, the Renderscript runtime attempts to provide the
801  closest possible approximation. For example, the user requested 16x anisotropy, but only 8x was
802  set because it's the best available on the hardware.</p>
803
804  <p>The <a href=
805  "{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html">
806  RsRenderStatesRS</a> sample has many examples on how to create a sampler and bind it to a
807  Fragment program.</p>
808
809
810
811<h2 id="fbo">Rendering to a Framebuffer Object</h2>
812
813<p>Framebuffer objects allow you to render offscreen instead of in the default onscreen
814framebuffer. This approach might be useful for situations where you need to post-process a texture before
815rendering it to the screen, or when you want to composite two scenes in one such as rendering a rear-view
816mirror of a car. There are two buffers associated with a framebuffer object: a color buffer
817and a depth buffer. The color buffer (required) contains the actual pixel data of the scene
818that you are rendering, and the depth buffer (optional) contains the values necessary to figure
819out what vertices are drawn depending on their z-values.</p>
820
821<p>In general, you need to do the following to render to a framebuffer object:</p>
822
823<ul>
824  <li>Create {@link android.renderscript.Allocation} objects for the color buffer and
825  depth buffer (if needed). Specify the {@link
826  android.renderscript.Allocation#USAGE_GRAPHICS_RENDER_TARGET} usage attribute for these
827  allocations to notify the Renderscript runtime to use these allocations for the framebuffer
828  object. For the color buffer allocation, you most likely need to declare the {@link
829  android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} usage attribute
830  to use the color buffer as a texture, which is the most common use of the framebuffer object.</li>
831
832  <li>Tell the Renderscript runtime to render to the framebuffer object instead of the default
833  framebuffer by calling <code>rsgBindColorTarget()</code> and passing it the color buffer
834  allocation. If applicable, call <code>rsgBindDepthTarget()</code> passing in the depth buffer
835  allocation as well.</li>
836
837  <li>Render your scene normally with the <code>rsgDraw</code> functions. The scene will be
838  rendered into the color buffer instead of the default onscreen framebuffer.</li>
839
840  <li>When done, tell the Renderscript runtime stop rendering to the color buffer and back
841  to the default framebuffer by calling <code>rsgClearAllRenderTargets()</code>.</li>
842
843  <li>Create a fragment shader and bind a the color buffer to it as a texture.</li>
844
845  <li>Render your scene to the default framebuffer. The texture will be used according
846  to the way you setup your fragment shader.</li>
847</ul>
848
849<p>The following example shows you how to render to a framebuffer object by modifying the
850<a href="{@docRoot}guide/resources/renderscript/Fountain/">Fountain</a> Renderscript sample. The end
851result is the <a href="{@docRoot}guide/resources/renderscript/FountainFBO/">FountainFBO</a> sample.
852The modifications render the exact same scene into a framebuffer object as it does the default
853framebuffer. The framebuffer object is then rendered into the default framebuffer in a small
854area at the top left corner of the screen.</p>
855
856<ol>
857  <li>Modify <code>fountain.rs</code> and add the following global variables. This creates setter
858  methods when this file is reflected into a <code>.java</code> file, allowing you to allocate
859  memory in your Android framework code and binding it to the Renderscript runtime.
860<pre>
861//allocation for color buffer
862rs_allocation gColorBuffer;
863//fragment shader for rendering without a texture (used for rendering to framebuffer object)
864rs_program_fragment gProgramFragment;
865//fragment shader for rendering with a texture (used for rendering to default framebuffer)
866rs_program_fragment gTextureProgramFragment;
867</pre>
868  </li>
869
870  <li>Modify the root function of <code>fountain.rs</code> to look like the following code. The
871  modifications are commented:
872<pre>
873int root() {
874    float dt = min(rsGetDt(), 0.1f);
875    rsgClearColor(0.f, 0.f, 0.f, 1.f);
876    const float height = rsgGetHeight();
877    const int size = rsAllocationGetDimX(rsGetAllocation(point));
878    float dy2 = dt * (10.f);
879    Point_t * p = point;
880    for (int ct=0; ct < size; ct++) {
881        p->delta.y += dy2;
882        p->position += p->delta;
883        if ((p->position.y > height) && (p->delta.y > 0)) {
884            p->delta.y *= -0.3f;
885        }
886        p++;
887    }
888    //Tell Renderscript runtime to render to the frame buffer object
889    rsgBindColorTarget(gColorBuffer, 0);
890    //Begin rendering on a white background
891    rsgClearColor(1.f, 1.f, 1.f, 1.f);
892    rsgDrawMesh(partMesh);
893
894    //When done, tell Renderscript runtime to stop rendering to framebuffer object
895    rsgClearAllRenderTargets();
896
897    //Bind a new fragment shader that declares the framebuffer object to be used as a texture
898    rsgBindProgramFragment(gTextureProgramFragment);
899
900    //Bind the framebuffer object to the fragment shader at slot 0 as a texture
901    rsgBindTexture(gTextureProgramFragment, 0, gColorBuffer);
902    //Draw a quad using the framebuffer object as the texture
903    float startX = 10, startY = 10;
904    float s = 256;
905    rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
906                         startX, startY + s, 0, 0, 0,
907                         startX + s, startY + s, 0, 1, 0,
908                         startX + s, startY, 0, 1, 1);
909
910    //Rebind the original fragment shader to render as normal
911    rsgBindProgramFragment(gProgramFragment);
912
913    //Render the main scene
914    rsgDrawMesh(partMesh);
915
916    return 1;
917}
918</pre>
919  </li>
920
921  <li>In the <code>FountainRS.java</code> file, modify the <code>init()</code> method to look
922  like the following code. The modifications are commented:
923
924<pre>
925/* Add necessary members */
926private ScriptC_fountainfbo mScript;
927private Allocation mColorBuffer;
928private ProgramFragment mProgramFragment;
929private ProgramFragment mTextureProgramFragment;
930
931public void init(RenderScriptGL rs, Resources res) {
932    mRS = rs;
933    mRes = res;
934
935    ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);
936
937    Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
938    smb.addVertexAllocation(points.getAllocation());
939    smb.addIndexSetType(Mesh.Primitive.POINT);
940    Mesh sm = smb.create();
941
942    mScript = new ScriptC_fountainfbo(mRS, mRes, R.raw.fountainfbo);
943    mScript.set_partMesh(sm);
944    mScript.bind_point(points);
945
946    ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
947    pfb.setVaryingColor(true);
948    mProgramFragment = pfb.create();
949    mScript.set_gProgramFragment(mProgramFragment);
950
951    /* Second fragment shader to use a texture (framebuffer object) to draw with */
952    pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
953        ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
954
955    /* Set the fragment shader in the Renderscript runtime */
956    mTextureProgramFragment = pfb.create();
957    mScript.set_gTextureProgramFragment(mTextureProgramFragment);
958
959    /* Create the allocation for the color buffer */
960    Type.Builder colorBuilder = new Type.Builder(mRS, Element.RGBA_8888(mRS));
961    colorBuilder.setX(256).setY(256);
962    mColorBuffer = Allocation.createTyped(mRS, colorBuilder.create(),
963    Allocation.USAGE_GRAPHICS_TEXTURE |
964    Allocation.USAGE_GRAPHICS_RENDER_TARGET);
965
966    /* Set the allocation in the Renderscript runtime */
967    mScript.set_gColorBuffer(mColorBuffer);
968
969    mRS.bindRootScript(mScript);
970}
971</pre>
972
973<p class="note"><strong>Note:</strong> This sample doesn't use a depth buffer, but the following code
974shows you how to declare an example depth buffer if you need to use
975one for your application. The depth buffer must have the same dimensions as the color buffer:
976
977<pre>
978Allocation mDepthBuffer;
979
980...
981
982Type.Builder b = new Type.Builder(mRS, Element.createPixel(mRS, DataType.UNSIGNED_16,
983    DataKind.PIXEL_DEPTH));
984b.setX(256).setY(256);
985mDepthBuffer = Allocation.createTyped(mRS, b.create(),
986Allocation.USAGE_GRAPHICS_RENDER_TARGET);
987
988</pre>
989</p>
990</li>
991
992  <li>Run and use the sample. The smaller, white quad on the top-left corner is using the
993  framebuffer object as a texture, which renders the same scene as the main rendering.</li>
994</ol>
995