blob: 1c6d0de41c6785b68304967131de6927157226b1 [file] [log] [blame]
Robert Lyb078d942012-01-05 10:50:39 -08001page.title=Graphics
2parent.title=Renderscript
Robert Lyf197b632011-06-08 22:23:42 -07003parent.link=index.html
Robert Lyb078d942012-01-05 10:50:39 -08004
Robert Lyf197b632011-06-08 22:23:42 -07005@jd:body
6
7 <div id="qv-wrapper">
8 <div id="qv">
9 <h2>In this document</h2>
10
11 <ol>
12 <li>
Robert Ly84975932011-10-18 17:14:26 -070013 <a href="#creating-graphics-rs">Creating a Graphics Renderscript</a>
Robert Lyf197b632011-06-08 22:23:42 -070014 <ol>
Robert Lyb078d942012-01-05 10:50:39 -080015 <li><a href="#creating-native">Creating the Renderscript file</a></li>
Robert Ly84975932011-10-18 17:14:26 -070016 <li><a href="#creating-entry">Creating the Renderscript entry point class</a></li>
Robert Lyb078d942012-01-05 10:50:39 -080017 <li><a href="#creating-view">Creating the view class</a></li>
18 <li><a href="#creating-activity">Creating the activity class</a></li>
Robert Ly84975932011-10-18 17:14:26 -070019 </ol>
20 </li>
21 <li>
22 <a href="#drawing">Drawing</a>
23 <ol>
Robert Lyb078d942012-01-05 10:50:39 -080024 <li><a href="#drawing-rsg">Simple drawing</a></li>
Robert Ly84975932011-10-18 17:14:26 -070025 <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>
Robert Lyf197b632011-06-08 22:23:42 -070033 </ol>
34 </li>
Robert Lyb078d942012-01-05 10:50:39 -080035 <li>
36 <a href="#fbo">Rendering to a Framebuffer Object</a>
37 </li>
Robert Lyf197b632011-06-08 22:23:42 -070038 </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
Scott Main19aad292011-10-18 16:57:32 -070045 <li><a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a></li>
Robert Lyf197b632011-06-08 22:23:42 -070046
Robert Lyb078d942012-01-05 10:50:39 -080047 <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 World</a></li>
Robert Lyf197b632011-06-08 22:23:42 -070050
Scott Main19aad292011-10-18 16:57:32 -070051 <li><a
52href="{@docRoot}resources/samples/RenderScript/MiscSamples/index.html">Misc Samples</a></li>
Robert Lyf197b632011-06-08 22:23:42 -070053 </ol>
54 </div>
55 </div>
56
Robert Lyb078d942012-01-05 10:50:39 -080057 <p>Renderscript provides a number of graphics APIs for rendering, both at the Android
58 framework level as well as at the Renderscript runtime level. For instance, the Android framework APIs let you
Robert Lyf197b632011-06-08 22:23:42 -070059 create meshes and define shaders to customize the graphical rendering pipeline. The native
Robert Lyb078d942012-01-05 10:50:39 -080060 Renderscript graphics APIs let you draw the actual meshes to render your scene. You need to
61 be familiar with both APIs to appropriately render graphics on an Android-powered device.</p>
Robert Lyf197b632011-06-08 22:23:42 -070062
Robert Lyb078d942012-01-05 10:50:39 -080063 <h2 id="creating-graphics-rs">Creating a Graphics Renderscript</h2>
Robert Lyf197b632011-06-08 22:23:42 -070064
Robert Lyb078d942012-01-05 10:50:39 -080065 <p>Renderscript applications require various layers of code, so it is useful to create the following
66 files to help keep your application organized:</p>
Robert Lyf197b632011-06-08 22:23:42 -070067
Robert Lyb078d942012-01-05 10:50:39 -080068 <dl>
69 <dt>The Renderscript <code>.rs</code> file</dt>
Robert Lyf197b632011-06-08 22:23:42 -070070
Robert Lyb078d942012-01-05 10:50:39 -080071 <dd>This file contains the logic to do the graphics rendering.</dd>
72
73 <dt>The Renderscript entry point <code>.java</code> class</dt>
74
75 <dd>This class allows the view class to interact with the code defined in the <code>.rs</code>
76 file. This class contains a Renderscript object (instance of
Robert Lyf197b632011-06-08 22:23:42 -070077 <code>ScriptC_<em>renderscript_file</em></code>), which allows your Android framework code to
Robert Lyb078d942012-01-05 10:50:39 -080078 call the Renderscript code. In general, this class does much of the setup for Renderscript
79 such as shader and mesh building and memory allocation and binding. The SDK samples follow the
80 convention of naming this file ActivityRS.java,
81 where Activity is the name of your main activity class.</dd>
Robert Lyf197b632011-06-08 22:23:42 -070082
Robert Lyb078d942012-01-05 10:50:39 -080083 <dt>The view <code>.java</code> class</dt>
84
85 <dd>This class extends {@link android.renderscript.RSSurfaceView} or {@link
86 android.renderscript.RSTextureView} to provide a surface to render on. A {@link
87 android.renderscript.RSSurfaceView} consumes a whole window, but a {@link
88 android.renderscript.RSTextureView} allows you to draw Renderscript graphics inside of a
89 view and add it to a {@link android.view.ViewGroup} alongside
90 other views. In this class, you create a {@link android.renderscript.RenderScriptGL} context object
91 with a call to {@link android.renderscript.RSSurfaceView#createRenderScriptGL
92 RSSurfaceView.createRenderscriptGL()} or {@link android.renderscript.RSTextureView#createRenderScriptGL
93 RSTextureView.createRenderscriptGL()}. The {@link android.renderscript.RenderScriptGL} context object
94 contains information about the current rendering state of Renderscript such as the vertex and
95 fragment shaders. You pass this context object to the Renderscript entry point class, so that
96 class can modify the rendering context if needed and bind the Renderscript code to the context. Once bound,
97 the view class can use the Renderscript code to display graphics.
98 The view class should also implement callbacks for events inherited from {@link
Robert Lyf197b632011-06-08 22:23:42 -070099 android.view.View}, such as {@link android.view.View#onTouchEvent onTouchEvent()} and {@link
Robert Lyb078d942012-01-05 10:50:39 -0800100 android.view.View#onKeyDown onKeyDown()} if you want to detect these types of user interactions.
101 The SDK samples follow the convention of naming this file ActivityView.java,
102 where Activity is the name of your main activity class</dd>
Robert Lyf197b632011-06-08 22:23:42 -0700103
Robert Lyb078d942012-01-05 10:50:39 -0800104 <dt>The activity <code>.java</code> class</dt>
Robert Lyf197b632011-06-08 22:23:42 -0700105
Robert Lyb078d942012-01-05 10:50:39 -0800106 <dd>This class is the main activity class and sets your {@link android.renderscript.RSSurfaceView} as the main content
107 view for this activity or uses the {@link android.renderscript.RSTextureView} alongside other views.</dd>
108 </dl>
109 <p>Figure 1 describes how these classes interact with one another in a graphics Renderscript:</p>
110
111 <img src="{@docRoot}images/rs_graphics.png">
112 <p class="img-caption"><strong>Figure 1.</strong> Graphics Renderscript overview</p>
Robert Lyf197b632011-06-08 22:23:42 -0700113
Robert Lyf197b632011-06-08 22:23:42 -0700114
Robert Lyb078d942012-01-05 10:50:39 -0800115 <p>The following sections describe how to create an application that uses a graphics Renderscript by using
116 the <a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Renderscript Fountain
117 sample</a> that is provided in the SDK as a guide (some code has been modified from its original
118 form for simplicity).</p>
119
120 <h3 id="creating-native">Creating the Renderscript file</h3>
121
122 <p>Your Renderscript code resides in <code>.rs</code> and <code>.rsh</code> (headers) files in the
123 <code>&lt;project_root&gt;/src/</code> directory. This code contains the logic to render your
124 graphics and declares all other necessary items such as variables, structs,
Robert Lyf197b632011-06-08 22:23:42 -0700125 and pointers. Every graphics <code>.rs</code> file generally contains the following items:</p>
126
127 <ul>
Robert Lyb078d942012-01-05 10:50:39 -0800128 <li>A pragma declaration (<code>#pragma rs java_package_name(<em>package.name</em>)</code>) that declares
129 the package name of the <code>.java</code> reflection of this Renderscript.</li>
Robert Lyf197b632011-06-08 22:23:42 -0700130
Robert Lyb078d942012-01-05 10:50:39 -0800131 <li>A pragma declaration (<code>#pragma version(1)</code>) that declares the version of Renderscript that
Robert Lyf197b632011-06-08 22:23:42 -0700132 you are using (1 is the only value for now).</li>
133
Robert Lyb078d942012-01-05 10:50:39 -0800134 <li>A <code>#include "rs_graphics.rsh"</code> declaration.</li>
Robert Lyf197b632011-06-08 22:23:42 -0700135
Robert Lyb078d942012-01-05 10:50:39 -0800136 <li>A <code>root()</code> function. This is the main worker function for your Renderscript and
137 calls Renderscript graphics functions to render scenes. This function is called every time a
138 frame refresh occurs, which is specified as its return value. A <code>0</code> (zero) specified for
139 the return value says to only render the frame when a property of the scene that you are
Robert Lyf197b632011-06-08 22:23:42 -0700140 rendering changes. A non-zero positive integer specifies the refresh rate of the frame in
141 milliseconds.
142
Robert Lyb078d942012-01-05 10:50:39 -0800143 <p class="note"><strong>Note:</strong> The Renderscript runtime makes its best effort to
Robert Lyf197b632011-06-08 22:23:42 -0700144 refresh the frame at the specified rate. For example, if you are creating a live wallpaper
Robert Lyb078d942012-01-05 10:50:39 -0800145 and set the return value to 20, the Renderscript runtime renders the wallpaper at 20fps if it has just
146 enough or more resources to do so. It renders as fast as it can if not enough resources
147 are available.</p>
148
149 <p>For more information on using the Renderscript graphics functions, see the <a href=
Robert Ly84975932011-10-18 17:14:26 -0700150 "#drawing">Drawing</a> section.</p>
Robert Lyf197b632011-06-08 22:23:42 -0700151 </li>
152
Robert Lyb078d942012-01-05 10:50:39 -0800153 <li>An <code>init()</code> function. This allows you to do initialization of your
154 Renderscript before the <code>root()</code> function runs, such as assigning values to variables. This
155 function runs once and is called automatically when the Renderscript starts, before anything
156 else in your Renderscript. Creating this function is optional.</li>
Robert Lyf197b632011-06-08 22:23:42 -0700157
Robert Lyb078d942012-01-05 10:50:39 -0800158 <li>Any variables, pointers, and structures that you wish to use in your Renderscript code (can
Robert Lyf197b632011-06-08 22:23:42 -0700159 be declared in <code>.rsh</code> files if desired)</li>
160 </ul>
161
Robert Lyb078d942012-01-05 10:50:39 -0800162 <p>The following code shows how the <code>fountain.rs</code> file is implemented:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700163 <pre>
164#pragma version(1)
165
166// Tell which java package name the reflected files should belong to
Robert Lyb078d942012-01-05 10:50:39 -0800167#pragma rs java_package_name(com.example.android.rs.fountain)
Robert Lyf197b632011-06-08 22:23:42 -0700168
Robert Lyb078d942012-01-05 10:50:39 -0800169//declare shader binding
170#pragma stateFragment(parent)
171
172// header with graphics APIs, must include explicitly
Robert Lyf197b632011-06-08 22:23:42 -0700173#include "rs_graphics.rsh"
174
Robert Lyb078d942012-01-05 10:50:39 -0800175static int newPart = 0;
Robert Lyf197b632011-06-08 22:23:42 -0700176
Robert Lyb078d942012-01-05 10:50:39 -0800177// the mesh to render
178rs_mesh partMesh;
179
180// the point representing where a particle is rendered
181typedef struct __attribute__((packed, aligned(4))) Point {
182 float2 delta;
183 float2 position;
184 uchar4 color;
185} Point_t;
186Point_t *point;
187
188// main worker function that renders particles onto the screen
189int root() {
190 float dt = min(rsGetDt(), 0.1f);
191 rsgClearColor(0.f, 0.f, 0.f, 1.f);
192 const float height = rsgGetHeight();
193 const int size = rsAllocationGetDimX(rsGetAllocation(point));
194 float dy2 = dt * (10.f);
195 Point_t * p = point;
196 for (int ct=0; ct &lt; size; ct++) {
197 p-&gt;delta.y += dy2;
198 p-&gt;position += p-&gt;delta;
199 if ((p-&gt;position.y &gt; height) &amp;&amp; (p-&gt;delta.y &gt; 0)) {
200 p-&gt;delta.y *= -0.3f;
201 }
202 p++;
203 }
204
205 rsgDrawMesh(partMesh);
206 return 1;
Robert Lyf197b632011-06-08 22:23:42 -0700207}
208
Robert Lyb078d942012-01-05 10:50:39 -0800209// adds particles to the screen to render
210static float4 partColor[10];
211void addParticles(int rate, float x, float y, int index, bool newColor)
212{
213 if (newColor) {
214 partColor[index].x = rsRand(0.5f, 1.0f);
215 partColor[index].y = rsRand(1.0f);
216 partColor[index].z = rsRand(1.0f);
217 }
218 float rMax = ((float)rate) * 0.02f;
219 int size = rsAllocationGetDimX(rsGetAllocation(point));
220 uchar4 c = rsPackColorTo8888(partColor[index]);
Robert Lyf197b632011-06-08 22:23:42 -0700221
Robert Lyb078d942012-01-05 10:50:39 -0800222 Point_t * np = &amp;point[newPart];
223 float2 p = {x, y};
224 while (rate--) {
225 float angle = rsRand(3.14f * 2.f);
226 float len = rsRand(rMax);
227 np-&gt;delta.x = len * sin(angle);
228 np-&gt;delta.y = len * cos(angle);
229 np-&gt;position = p;
230 np-&gt;color = c;
231 newPart++;
232 np++;
233 if (newPart &gt;= size) {
234 newPart = 0;
235 np = &amp;point[newPart];
236 }
237 }
Robert Lyf197b632011-06-08 22:23:42 -0700238}
239</pre>
240
Robert Lyb078d942012-01-05 10:50:39 -0800241 <h3 id="creating-entry">Creating the Renderscript entry point class</h3>
Robert Lyf197b632011-06-08 22:23:42 -0700242
Robert Lyb078d942012-01-05 10:50:39 -0800243 <p>When you create a Renderscript (<code>.rs</code>) file, it is helpful to create a
244 corresponding Android framework class that is an entry point into the <code>.rs</code> file.
245 The most important thing this class does is receive a {@link android.renderscript.RenderScriptGL} rendering context
246 object from the <a href="#creating-view">view class</a> and binds the actual Renderscript
247 code to the rendering context. This notifies your view class of the code that it needs
248 to render graphics.
249 </p>
Robert Lyf197b632011-06-08 22:23:42 -0700250
Robert Lyb078d942012-01-05 10:50:39 -0800251 <p>In addition, this class should contain all of the things needed to set up Renderscript.
252 Some important things that you need to do in this class are:</p>
253
254 <ul>
255 <li>Create a Renderscript object
256 <code>ScriptC_<em>rs_filename</em></code>. The Renderscript object is attached to the Renderscript bytecode, which is platform-independent and
257 gets compiled on the device when the Renderscript application runs. The bytecode is referenced
258 as a raw resource and is passed into the constructor for the Renderscript object.
259 For example, this is how the <a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a>
260 sample creates the Renderscript object:
Robert Lyf197b632011-06-08 22:23:42 -0700261 <pre>
Robert Lyb078d942012-01-05 10:50:39 -0800262 RenderScriptGL rs; //obtained from the view class
263 Resources res; //obtained from the view class
264 ...
265 ScriptC_fountain mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
266 </pre>
267 </li>
268 <li>Allocate any necessary memory and bind it to your Renderscript code via the Renderscript object.</li>
269 <li>Build any necessary meshes and bind them to the Renderscript code via the Renderscript object.</li>
270 <li>Create any necessary programs and bind them to the Renderscript code via the Renderscript object.</li>
271 </ul>
272
273 <p>The following code shows how the <a href=
274 "{@docRoot}resources/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/FountainRS.html">
275 FountainRS</a> class is implemented:</p>
276 <pre>
277package com.example.android.rs.fountain;
Robert Lyf197b632011-06-08 22:23:42 -0700278
279import android.content.res.Resources;
280import android.renderscript.*;
Robert Lyb078d942012-01-05 10:50:39 -0800281import android.util.Log;
Robert Lyf197b632011-06-08 22:23:42 -0700282
Robert Lyb078d942012-01-05 10:50:39 -0800283public class FountainRS {
284 public static final int PART_COUNT = 50000;
285
286 public FountainRS() {
287 }
288
289 /**
290 * This provides us with the Renderscript context and resources
291 * that allow us to create the Renderscript object
292 */
Robert Lyf197b632011-06-08 22:23:42 -0700293 private Resources mRes;
294 private RenderScriptGL mRS;
295
Robert Lyb078d942012-01-05 10:50:39 -0800296 // Renderscript object
297 private ScriptC_fountain mScript;
Robert Lyf197b632011-06-08 22:23:42 -0700298
Robert Lyb078d942012-01-05 10:50:39 -0800299 // Called by the view class to initialize the Renderscript context and renderer
Robert Lyf197b632011-06-08 22:23:42 -0700300 public void init(RenderScriptGL rs, Resources res) {
301 mRS = rs;
302 mRes = res;
Robert Lyb078d942012-01-05 10:50:39 -0800303
304 /**
305 * Create a shader and bind to the Renderscript context
306 */
307 ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
308 pfb.setVaryingColor(true);
309 rs.bindProgramFragment(pfb.create());
310
311 /**
312 * Allocate memory for the particles to render and create the mesh to draw
313 */
314 ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);
315 Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
316 smb.addVertexAllocation(points.getAllocation());
317 smb.addIndexSetType(Mesh.Primitive.POINT);
318 Mesh sm = smb.create();
319
320 /**
321 * Create and bind the Renderscript object to the Renderscript context
322 */
323 mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
324 mScript.set_partMesh(sm);
325 mScript.bind_point(points);
Robert Lyf197b632011-06-08 22:23:42 -0700326 mRS.bindRootScript(mScript);
327 }
Robert Lyf197b632011-06-08 22:23:42 -0700328
Robert Lyb078d942012-01-05 10:50:39 -0800329 boolean holdingColor[] = new boolean[10];
330
331 /**
332 * Calls Renderscript functions (invoke_addParticles)
333 * via the Renderscript object to add particles to render
334 * based on where a user touches the screen.
335 */
336 public void newTouchPosition(float x, float y, float pressure, int id) {
337 if (id &gt;= holdingColor.length) {
338 return;
339 }
340 int rate = (int)(pressure * pressure * 500.f);
341 if (rate &gt; 500) {
342 rate = 500;
343 }
344 if (rate &gt; 0) {
345 mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);
346 holdingColor[id] = true;
347 } else {
348 holdingColor[id] = false;
349 }
350
351 }
352}
Robert Lyf197b632011-06-08 22:23:42 -0700353</pre>
354
Robert Lyf197b632011-06-08 22:23:42 -0700355
Robert Lyb078d942012-01-05 10:50:39 -0800356 <h3 id="creating-view">Creating the view class</h3>
357
358
359 <p>To display graphics, you need a view to render on. Create a class that extends {@link
360 android.renderscript.RSSurfaceView} or {@link android.renderscript.RSTextureView}. This class
361 allows you to create a {@link android.renderscript.RenderScriptGL} context object by calling and
362 pass it to the Rendscript entry point class to bind the two. Once bound, the content is aware
363 of the code that it needs to use to render graphics with. If your Renderscript code
364 depends on any type of information that the view is aware of, such as touches from the user,
365 you can also use this class to relay that information to the Renderscript entry point class.
366 The following code shows how the <code>FountainView</code> class is implemented:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700367 <pre>
Robert Lyb078d942012-01-05 10:50:39 -0800368package com.example.android.rs.fountain;
Robert Lyf197b632011-06-08 22:23:42 -0700369
Robert Lyb078d942012-01-05 10:50:39 -0800370import android.renderscript.RSTextureView;
Robert Lyf197b632011-06-08 22:23:42 -0700371import android.renderscript.RenderScriptGL;
372import android.content.Context;
373import android.view.MotionEvent;
374
Robert Lyb078d942012-01-05 10:50:39 -0800375public class FountainView extends RSTextureView {
Robert Lyf197b632011-06-08 22:23:42 -0700376
Robert Lyb078d942012-01-05 10:50:39 -0800377 public FountainView(Context context) {
Robert Lyf197b632011-06-08 22:23:42 -0700378 super(context);
Robert Lyf197b632011-06-08 22:23:42 -0700379 }
Robert Lyb078d942012-01-05 10:50:39 -0800380 // Renderscript context
381 private RenderScriptGL mRS;
382 // Renderscript entry point object that calls Renderscript code
383 private FountainRS mRender;
Robert Lyf197b632011-06-08 22:23:42 -0700384
Robert Lyb078d942012-01-05 10:50:39 -0800385 /**
386 * Create Renderscript context and initialize Renderscript entry point
387 */
388 &#064;Override
389 protected void onAttachedToWindow() {
390 super.onAttachedToWindow();
391 android.util.Log.e("rs", "onAttachedToWindow");
Robert Lyf197b632011-06-08 22:23:42 -0700392 if (mRS == null) {
Robert Lyf197b632011-06-08 22:23:42 -0700393 RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
Robert Lyf197b632011-06-08 22:23:42 -0700394 mRS = createRenderScriptGL(sc);
Robert Lyb078d942012-01-05 10:50:39 -0800395 mRender = new FountainRS();
Robert Lyf197b632011-06-08 22:23:42 -0700396 mRender.init(mRS, getResources());
397 }
398 }
399
Robert Lyb078d942012-01-05 10:50:39 -0800400 &#064;Override
Robert Lyf197b632011-06-08 22:23:42 -0700401 protected void onDetachedFromWindow() {
Robert Lyb078d942012-01-05 10:50:39 -0800402 super.onDetachedFromWindow();
403 android.util.Log.e("rs", "onDetachedFromWindow");
Robert Lyf197b632011-06-08 22:23:42 -0700404 if (mRS != null) {
405 mRS = null;
406 destroyRenderScriptGL();
407 }
408 }
409
Robert Lyf197b632011-06-08 22:23:42 -0700410
Robert Lyb078d942012-01-05 10:50:39 -0800411 /**
412 * Use callbacks to relay data to Renderscript entry point class
413 */
414 &#064;Override
415 public boolean onTouchEvent(MotionEvent ev)
416 {
417 int act = ev.getActionMasked();
418 if (act == ev.ACTION_UP) {
419 mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
420 return false;
421 } else if (act == MotionEvent.ACTION_POINTER_UP) {
422 // only one pointer going up, we can get the index like this
423 int pointerIndex = ev.getActionIndex();
424 int pointerId = ev.getPointerId(pointerIndex);
425 mRender.newTouchPosition(0, 0, 0, pointerId);
426 }
427 int count = ev.getHistorySize();
428 int pcount = ev.getPointerCount();
429
430 for (int p=0; p &lt; pcount; p++) {
431 int id = ev.getPointerId(p);
432 mRender.newTouchPosition(ev.getX(p),
433 ev.getY(p),
434 ev.getPressure(p),
435 id);
436
437 for (int i=0; i &lt; count; i++) {
438 mRender.newTouchPosition(ev.getHistoricalX(p, i),
439 ev.getHistoricalY(p, i),
440 ev.getHistoricalPressure(p, i),
441 id);
442 }
443 }
444 return true;
Robert Lyf197b632011-06-08 22:23:42 -0700445 }
446}
Robert Lyf197b632011-06-08 22:23:42 -0700447</pre>
448
Robert Lyb078d942012-01-05 10:50:39 -0800449 <h3 id="creating-activity">Creating the activity class</h3>
Robert Lyf197b632011-06-08 22:23:42 -0700450
Robert Lyb078d942012-01-05 10:50:39 -0800451 <p>Applications that use Renderscript still behave like normal Android applications, so you
452 need an activity class that handles activity lifecycle callback events appropriately. The activity class
453 also sets your {@link android.renderscript.RSSurfaceView} view class to be the main content view of the
454 activity or uses your {@link android.renderscript.RSTextureView}
455 in a {@link android.view.ViewGroup} alongside other views.</p>
456
457 <p>The following code shows how the <a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a>
458 sample declares its activity class:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700459 <pre>
Robert Lyb078d942012-01-05 10:50:39 -0800460package com.example.android.rs.fountain;
Robert Lyf197b632011-06-08 22:23:42 -0700461
Robert Lyb078d942012-01-05 10:50:39 -0800462import android.app.Activity;
463import android.os.Bundle;
464import android.util.Log;
Robert Lyf197b632011-06-08 22:23:42 -0700465
Robert Lyb078d942012-01-05 10:50:39 -0800466public class Fountain extends Activity {
467
468 private static final String LOG_TAG = "libRS_jni";
469 private static final boolean DEBUG = false;
470 private static final boolean LOG_ENABLED = false;
471
472 private FountainView mView;
473
474 &#064;Override
Robert Lyf197b632011-06-08 22:23:42 -0700475 public void onCreate(Bundle icicle) {
476 super.onCreate(icicle);
Robert Lyb078d942012-01-05 10:50:39 -0800477
478 // Create our Preview view and set it as
479 // the content of our activity
480 mView = new FountainView(this);
481 setContentView(mView);
Robert Lyf197b632011-06-08 22:23:42 -0700482 }
483
Robert Lyb078d942012-01-05 10:50:39 -0800484 &#064;Override
Robert Lyf197b632011-06-08 22:23:42 -0700485 protected void onResume() {
Robert Lyb078d942012-01-05 10:50:39 -0800486 Log.e("rs", "onResume");
487
488 // Ideally a game should implement onResume() and onPause()
489 // to take appropriate action when the activity looses focus
Robert Lyf197b632011-06-08 22:23:42 -0700490 super.onResume();
Robert Lyb078d942012-01-05 10:50:39 -0800491 mView.resume();
Robert Lyf197b632011-06-08 22:23:42 -0700492 }
493
Robert Lyb078d942012-01-05 10:50:39 -0800494 &#064;Override
Robert Lyf197b632011-06-08 22:23:42 -0700495 protected void onPause() {
Robert Lyb078d942012-01-05 10:50:39 -0800496 Log.e("rs", "onPause");
497
498 // Ideally a game should implement onResume() and onPause()
499 // to take appropriate action when the activity looses focus
Robert Lyf197b632011-06-08 22:23:42 -0700500 super.onPause();
Robert Lyb078d942012-01-05 10:50:39 -0800501 mView.pause();
502
503 }
504
505 static void log(String message) {
506 if (LOG_ENABLED) {
507 Log.v(LOG_TAG, message);
508 }
Robert Lyf197b632011-06-08 22:23:42 -0700509 }
510}
511</pre>
512
Robert Lyb078d942012-01-05 10:50:39 -0800513<p>Now that you have an idea of what is involved in a Renderscript graphics application, you can
514start building your own. It might be easiest to begin with one of the
515<a href="{@docRoot}resources/samples/RenderScript/index.html">Renderscript samples</a> as a starting
516point if this is your first time using Renderscript.</p>
517
Robert Ly84975932011-10-18 17:14:26 -0700518 <h2 id="drawing">Drawing</h2>
519 <p>The following sections describe how to use the graphics functions to draw with Renderscript.</p>
Robert Lyf197b632011-06-08 22:23:42 -0700520
Robert Lyb078d942012-01-05 10:50:39 -0800521 <h3 id="drawing-rsg">Simple drawing</h3>
522
523 <p>The native Renderscript APIs provide a few convenient functions to easily draw a polygon or text to
524 the screen. You call these in your <code>root()</code> function to have them render to the {@link
525 android.renderscript.RSSurfaceView} or {@link android.renderscript.RSTextureView}. These functions are
526 available for simple drawing and should not be used for complex graphics rendering:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700527
528 <ul>
529 <li><code>rsgDrawRect()</code>: Sets up a mesh and draws a rectangle to the screen. It uses the
530 top left vertex and bottom right vertex of the rectangle to draw.</li>
531
532 <li><code>rsgDrawQuad()</code>: Sets up a mesh and draws a quadrilateral to the screen.</li>
533
Robert Lyb078d942012-01-05 10:50:39 -0800534 <li><code>rsgDrawQuadTexCoords()</code>: Sets up a mesh and draws a quadrilateral to the screen
535 using the provided coordinates of a texture.</li>
536
537 <li><code>rsgDrawText()</code>: Draws specified text to the screen. Use <code>rsgFontColor()</code>
538 to set the color of the text.</li>
Robert Lyf197b632011-06-08 22:23:42 -0700539 </ul>
540
Robert Ly84975932011-10-18 17:14:26 -0700541 <h3 id="drawing-mesh">Drawing with a mesh</h3>
Robert Lyf197b632011-06-08 22:23:42 -0700542
Robert Lyb078d942012-01-05 10:50:39 -0800543 <p>When you want to render complex scenes to the screen, instantiate a {@link
544 android.renderscript.Mesh} and draw it with <code>rsgDrawMesh()</code>. A {@link
Robert Lyf197b632011-06-08 22:23:42 -0700545 android.renderscript.Mesh} is a collection of allocations that represent vertex data (positions,
Robert Lyb078d942012-01-05 10:50:39 -0800546 normals, texture coordinates) and index data that provides information on how to draw triangles
547 and lines with the provided vertex data. You can build a Mesh in three different ways:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700548
549 <ul>
550 <li>Build the mesh with the {@link android.renderscript.Mesh.TriangleMeshBuilder} class, which
Robert Lyb078d942012-01-05 10:50:39 -0800551 allows you to specify a set of vertices and indices for each triangle that you want to draw.</li>
Robert Lyf197b632011-06-08 22:23:42 -0700552
553 <li>Build the mesh using an {@link android.renderscript.Allocation} or a set of {@link
554 android.renderscript.Allocation}s with the {@link android.renderscript.Mesh.AllocationBuilder}
Robert Lyb078d942012-01-05 10:50:39 -0800555 class. This approach allows you to build a mesh with vertices already stored in memory, which allows you
556 to specify the vertices in Renderscript or Android framework code.</li>
Robert Lyf197b632011-06-08 22:23:42 -0700557
Robert Lyb078d942012-01-05 10:50:39 -0800558 <li>Build the mesh with the {@link android.renderscript.Mesh.Builder} class. You should use
559 this convenience method when you know the data types you want to use to build your mesh, but
Robert Lyf197b632011-06-08 22:23:42 -0700560 don't want to make separate memory allocations like with {@link
561 android.renderscript.Mesh.AllocationBuilder}. You can specify the types that you want and this
562 mesh builder automatically creates the memory allocations for you.</li>
563 </ul>
564
565 <p>To create a mesh using the {@link android.renderscript.Mesh.TriangleMeshBuilder}, you need to
566 supply it with a set of vertices and the indices for the vertices that comprise the triangle. For
567 example, the following code specifies three vertices, which are added to an internal array,
568 indexed in the order they were added. The call to {@link
569 android.renderscript.Mesh.TriangleMeshBuilder#addTriangle addTriangle()} draws the triangle with
570 vertex 0, 1, and 2 (the vertices are drawn counter-clockwise).</p>
571 <pre>
572int float2VtxSize = 2;
573Mesh.TriangleMeshBuilder triangle = new Mesh.TriangleMeshBuilder(renderscriptGL,
574float2VtxSize, Mesh.TriangleMeshBuilder.COLOR);
575triangles.addVertex(300.f, 300.f);
576triangles.addVertex(150.f, 450.f);
577triangles.addVertex(450.f, 450.f);
578triangles.addTriangle(0 , 1, 2);
579Mesh smP = triangle.create(true);
580script.set_mesh(smP);
581</pre>
582
583 <p>To draw a mesh using the {@link android.renderscript.Mesh.AllocationBuilder}, you need to
584 supply it with one or more allocations that contain the vertex data:</p>
585 <pre>
586Allocation vertices;
587
588...
589Mesh.AllocationBuilder triangle = new Mesh.AllocationBuilder(mRS);
590smb.addVertexAllocation(vertices.getAllocation());
591smb.addIndexSetType(Mesh.Primitive.TRIANGLE);
592Mesh smP = smb.create();
593script.set_mesh(smP);
594</pre>
595
Robert Lyb078d942012-01-05 10:50:39 -0800596 <p>In your Renderscript code, draw the built mesh to the screen:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700597 <pre>
598rs_mesh mesh;
599...
600
601int root(){
602...
603rsgDrawMesh(mesh);
604...
605return 0; //specify a non zero, positive integer to specify the frame refresh.
606 //0 refreshes the frame only when the mesh changes.
607}
608</pre>
609
Robert Lyb078d942012-01-05 10:50:39 -0800610 <h2 id="shader">Programs</h2>
Robert Lyf197b632011-06-08 22:23:42 -0700611
612 <p>You can attach four program objects to the {@link android.renderscript.RenderScriptGL} context
613 to customize the rendering pipeline. For example, you can create vertex and fragment shaders in
Robert Lyb078d942012-01-05 10:50:39 -0800614 GLSL or build a raster program object that controls culling. The four programs mirror a
615 traditional graphical rendering pipeline:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700616
617 <table>
618 <tr>
619 <th>Android Object Type</th>
620
Robert Lyb078d942012-01-05 10:50:39 -0800621 <th>Renderscript Native Type</th>
Robert Lyf197b632011-06-08 22:23:42 -0700622
623 <th>Description</th>
624 </tr>
625
626 <tr>
627 <td>{@link android.renderscript.ProgramVertex}</td>
628
629 <td>rs_program_vertex</td>
630
631 <td>
Robert Lyb078d942012-01-05 10:50:39 -0800632 <p>The Renderscript vertex program, also known as a vertex shader, describes the stage in
Robert Lyf197b632011-06-08 22:23:42 -0700633 the graphics pipeline responsible for manipulating geometric data in a user-defined way.
Robert Lyb078d942012-01-05 10:50:39 -0800634 The object is constructed by providing Renderscript with the following data:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700635
636 <ul>
Robert Lyb078d942012-01-05 10:50:39 -0800637 <li>An {@link android.renderscript.Element} describing its varying inputs or attributes</li>
Robert Lyf197b632011-06-08 22:23:42 -0700638
639 <li>GLSL shader string that defines the body of the program</li>
640
Robert Lyb078d942012-01-05 10:50:39 -0800641 <li>a {@link android.renderscript.Type} that describes the layout of an
642 Allocation containing constant or uniform inputs</li>
Robert Lyf197b632011-06-08 22:23:42 -0700643 </ul>
644
645 <p>Once the program is created, bind it to the {@link android.renderscript.RenderScriptGL}
646 graphics context by calling {@link android.renderscript.RenderScriptGL#bindProgramVertex
647 bindProgramVertex()}. It is then used for all subsequent draw calls until you bind a new
648 program. If the program has constant inputs, the user needs to bind an allocation
649 containing those inputs. The allocation's type must match the one provided during creation.
Robert Lyb078d942012-01-05 10:50:39 -0800650 </p>
Robert Lyf197b632011-06-08 22:23:42 -0700651
Robert Lyb078d942012-01-05 10:50:39 -0800652 <p>The Renderscript runtime then does all the necessary plumbing to send those constants to
653 the graphics hardware. Varying inputs to the shader, such as position, normal, and texture
654 coordinates are matched by name between the input {@link android.renderscript.Element}
655 and the mesh object that is being drawn. The signatures don't have to be exact or in any
656 strict order. As long as the input name in the shader matches a channel name and size
657 available on the mesh, the Renderscript runtime handles connecting the two. Unlike OpenGL
658 there is no need to link the vertex and fragment programs.</p>
659
660 <p>To bind shader constants to the program, declare a <code>struct</code> that contains the necessary
661 shader constants in your Renderscript code. This <code>struct</code> is generated into a
662 reflected class that you can use as a constant input element during the program's creation.
663 It is an easy way to create an instance of this <code>struct</code> as an allocation. You would then
664 bind this {@link android.renderscript.Allocation} to the program and the
665 Renderscript runtime sends the data that is contained in the <code>struct</code> to the hardware
666 when necessary. To update shader constants, you change the values in the
667 {@link android.renderscript.Allocation} and notify the Renderscript
668 code of the change.</p>
669
670 <p>The {@link android.renderscript.ProgramVertexFixedFunction.Builder} class also
671 lets you build a simple vertex shader without writing GLSL code.
672 </p>
Robert Lyf197b632011-06-08 22:23:42 -0700673 </td>
674 </tr>
675
676 <tr>
677 <td>{@link android.renderscript.ProgramFragment}</td>
678
679 <td>rs_program_fragment</td>
680
681 <td>
Robert Lyb078d942012-01-05 10:50:39 -0800682 <p>The Renderscript fragment program, also known as a fragment shader, is responsible for
Robert Lyf197b632011-06-08 22:23:42 -0700683 manipulating pixel data in a user-defined way. It's constructed from a GLSL shader string
Robert Lyb078d942012-01-05 10:50:39 -0800684 containing the program body, texture inputs, and a {@link android.renderscript.Type}
685 object that describes the constants
686 used by the program. Like the vertex programs, when an {@link android.renderscript.Allocation}
687 with constant input
Robert Lyf197b632011-06-08 22:23:42 -0700688 values is bound to the shader, its values are sent to the graphics program automatically.
Robert Lyb078d942012-01-05 10:50:39 -0800689 Note that the values inside the {@link android.renderscript.Allocation} are not explicitly tracked.
690 If they change between two draw calls using the same program object, notify the runtime of that change by
691 calling <code>rsgAllocationSyncAll()</code>, so it can send the new values to hardware. Communication
Robert Lyf197b632011-06-08 22:23:42 -0700692 between the vertex and fragment programs is handled internally in the GLSL code. For
Robert Lyb078d942012-01-05 10:50:39 -0800693 example, if the fragment program is expecting a varying input called <code>varTex0</code>, the GLSL code
Robert Lyf197b632011-06-08 22:23:42 -0700694 inside the program vertex must provide it.</p>
695
Robert Lyb078d942012-01-05 10:50:39 -0800696 <p>To bind shader constructs to the program, declare a <code>struct</code> that contains the necessary
697 shader constants in your Renderscript code. This <code>struct</code> is generated into a
698 reflected class that you can use as a constant input element during the program's creation.
699 It is an easy way to create an instance of this <code>struct</code> as an allocation. You would then
700 bind this {@link android.renderscript.Allocation} to the program and the
701 Renderscript runtime sends the data that is contained in the <code>struct</code> to the hardware
702 when necessary. To update shader constants, you change the values in the
703 {@link android.renderscript.Allocation} and notify the Renderscript
704 code of the change.</p>
705
706 <p>The {@link android.renderscript.ProgramFragmentFixedFunction.Builder} class also
707 lets you build a simple fragment shader without writing GLSL code.
708 </p>
Robert Lyf197b632011-06-08 22:23:42 -0700709 </td>
710 </tr>
711
712 <tr>
713 <td>{@link android.renderscript.ProgramStore}</td>
714
715 <td>rs_program_store</td>
716
Robert Lyb078d942012-01-05 10:50:39 -0800717 <td>The Renderscript store program contains a set of parameters that control how the graphics
Robert Lyf197b632011-06-08 22:23:42 -0700718 hardware writes to the framebuffer. It could be used to enable and disable depth writes and
719 testing, setup various blending modes for effects like transparency and define write masks
720 for color components.</td>
721 </tr>
722
723 <tr>
724 <td>{@link android.renderscript.ProgramRaster}</td>
725
726 <td>rs_program_raster</td>
727
Robert Lyb078d942012-01-05 10:50:39 -0800728 <td>The Renderscript raster program is primarily used to specify whether point sprites are enabled and to
Robert Lyf197b632011-06-08 22:23:42 -0700729 control the culling mode. By default back faces are culled.</td>
730 </tr>
731 </table>
732
Robert Lyb078d942012-01-05 10:50:39 -0800733 <p>The following example defines a vertex shader in GLSL and binds it to a Renderscript context object:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700734 <pre>
735 private RenderScriptGL glRenderer; //rendering context
736 private ScriptField_Point mPoints; //vertices
737 private ScriptField_VpConsts mVpConsts; //shader constants
738
739 ...
740
741 ProgramVertex.Builder sb = new ProgramVertex.Builder(glRenderer);
742 String t = "varying vec4 varColor;\n" +
743 "void main() {\n" +
744 " vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
745 " pos.xy = ATTRIB_position;\n" +
746 " gl_Position = UNI_MVP * pos;\n" +
747 " varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
748 " gl_PointSize = ATTRIB_size;\n" +
749 "}\n";
750 sb.setShader(t);
751 sb.addConstant(mVpConsts.getType());
752 sb.addInput(mPoints.getElement());
753 ProgramVertex pvs = sb.create();
754 pvs.bindConstants(mVpConsts.getAllocation(), 0);
755 glRenderer.bindProgramVertex(pvs);
Robert Lyf197b632011-06-08 22:23:42 -0700756</pre>
757
Robert Lyb078d942012-01-05 10:50:39 -0800758
Robert Lyf197b632011-06-08 22:23:42 -0700759 <p>The <a href=
760 "{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html">
761 RsRenderStatesRS</a> sample has many examples on how to create a shader without writing GLSL.</p>
762
Robert Lyb078d942012-01-05 10:50:39 -0800763 <h3 id="shader-bindings">Program bindings</h3>
Robert Lyf197b632011-06-08 22:23:42 -0700764
Robert Lyb078d942012-01-05 10:50:39 -0800765 <p>You can also declare four pragmas that control default program bindings to the {@link
Robert Lyf197b632011-06-08 22:23:42 -0700766 android.renderscript.RenderScriptGL} context when the script is executing:</p>
767
768 <ul>
Robert Lyb078d942012-01-05 10:50:39 -0800769 <li><code>stateVertex</code></li>
Robert Lyf197b632011-06-08 22:23:42 -0700770
Robert Lyb078d942012-01-05 10:50:39 -0800771 <li><code>stateFragment</code></li>
Robert Lyf197b632011-06-08 22:23:42 -0700772
Robert Lyb078d942012-01-05 10:50:39 -0800773 <li><code>stateRaster</code></li>
Robert Lyf197b632011-06-08 22:23:42 -0700774
Robert Lyb078d942012-01-05 10:50:39 -0800775 <li><code>stateStore</code></li>
Robert Lyf197b632011-06-08 22:23:42 -0700776 </ul>
777
778 <p>The possible values for each pragma are <code>parent</code> or <code>default</code>. Using
Robert Lyb078d942012-01-05 10:50:39 -0800779 <code>default</code> binds the shaders to the graphical context with the system defaults.</p>
Robert Lyf197b632011-06-08 22:23:42 -0700780
781 <p>Using <code>parent</code> binds the shaders in the same manner as it is bound in the calling
782 script. If this is the root script, the parent state is taken from the bind points that are set
783 by the {@link android.renderscript.RenderScriptGL} bind methods.</p>
784
Robert Lyb078d942012-01-05 10:50:39 -0800785 <p>For example, you can define this at the top of your graphics Renderscript code to have
786 the vertex and store programs inherent the bind properties from their parent scripts:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700787 <pre>
788#pragma stateVertex(parent)
789#pragma stateStore(parent)
790</pre>
791
Robert Ly84975932011-10-18 17:14:26 -0700792 <h3 id="shader-sampler">Defining a sampler</h3>
Robert Lyf197b632011-06-08 22:23:42 -0700793
794 <p>A {@link android.renderscript.Sampler} object defines how data is extracted from textures.
Robert Lyb078d942012-01-05 10:50:39 -0800795 Samplers are bound to a {@link android.renderscript.ProgramFragment} alongside the texture
796 whose sampling they control. These
797 objects are used to specify such things as edge clamping behavior, whether mip-maps are used, and
798 the amount of anisotropy required. There might be situations where hardware does not support the
799 desired behavior of the sampler. In these cases, the Renderscript runtime attempts to provide the
800 closest possible approximation. For example, the user requested 16x anisotropy, but only 8x was
801 set because it's the best available on the hardware.</p>
Robert Lyf197b632011-06-08 22:23:42 -0700802
803 <p>The <a href=
804 "{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html">
805 RsRenderStatesRS</a> sample has many examples on how to create a sampler and bind it to a
806 Fragment program.</p>
Robert Lyb078d942012-01-05 10:50:39 -0800807
808
809
810<h2 id="fbo">Rendering to a Framebuffer Object</h2>
811
812<p>Framebuffer objects allow you to render offscreen instead of in the default onscreen
813framebuffer. This approach might be useful for situations where you need to post-process a texture before
814rendering it to the screen, or when you want to composite two scenes in one such as rendering a rear-view
815mirror of a car. There are two buffers associated with a framebuffer object: a color buffer
816and a depth buffer. The color buffer (required) contains the actual pixel data of the scene
817that you are rendering, and the depth buffer (optional) contains the values necessary to figure
818out what vertices are drawn depending on their z-values.</p>
819
820<p>In general, you need to do the following to render to a framebuffer object:</p>
821
822<ul>
823 <li>Create {@link android.renderscript.Allocation} objects for the color buffer and
824 depth buffer (if needed). Specify the {@link
825 android.renderscript.Allocation#USAGE_GRAPHICS_RENDER_TARGET} usage attribute for these
826 allocations to notify the Renderscript runtime to use these allocations for the framebuffer
827 object. For the color buffer allocation, you most likely need to declare the {@link
828 android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} usage attribute
829 to use the color buffer as a texture, which is the most common use of the framebuffer object.</li>
830
831 <li>Tell the Renderscript runtime to render to the framebuffer object instead of the default
832 framebuffer by calling <code>rsgBindColorTarget()</code> and passing it the color buffer
833 allocation. If applicable, call <code>rsgBindDepthTarget()</code> passing in the depth buffer
834 allocation as well.</li>
835
836 <li>Render your scene normally with the <code>rsgDraw</code> functions. The scene will be
837 rendered into the color buffer instead of the default onscreen framebuffer.</li>
838
839 <li>When done, tell the Renderscript runtime stop rendering to the color buffer and back
840 to the default framebuffer by calling <code>rsgClearAllRenderTargets()</code>.</li>
841
842 <li>Create a fragment shader and bind a the color buffer to it as a texture.</li>
843
844 <li>Render your scene to the default framebuffer. The texture will be used according
845 to the way you setup your fragment shader.</li>
846</ul>
847
848<p>The following example shows you how to render to a framebuffer object by modifying the
849<a href="{@docRoot}guide/resources/renderscript/Fountain/">Fountain</a> Renderscript sample. The end
850result is the <a href="{@docRoot}guide/resources/renderscript/FountainFBO/">FountainFBO</a> sample.
851The modifications render the exact same scene into a framebuffer object as it does the default
852framebuffer. The framebuffer object is then rendered into the default framebuffer in a small
853area at the top left corner of the screen.</p>
854
855<ol>
856 <li>Modify <code>fountain.rs</code> and add the following global variables. This creates setter
857 methods when this file is reflected into a <code>.java</code> file, allowing you to allocate
858 memory in your Android framework code and binding it to the Renderscript runtime.
859<pre>
860//allocation for color buffer
861rs_allocation gColorBuffer;
862//fragment shader for rendering without a texture (used for rendering to framebuffer object)
863rs_program_fragment gProgramFragment;
864//fragment shader for rendering with a texture (used for rendering to default framebuffer)
865rs_program_fragment gTextureProgramFragment;
866</pre>
867 </li>
868
869 <li>Modify the root function of <code>fountain.rs</code> to look like the following code. The
870 modifications are commented:
871<pre>
872int root() {
873 float dt = min(rsGetDt(), 0.1f);
874 rsgClearColor(0.f, 0.f, 0.f, 1.f);
875 const float height = rsgGetHeight();
876 const int size = rsAllocationGetDimX(rsGetAllocation(point));
877 float dy2 = dt * (10.f);
878 Point_t * p = point;
879 for (int ct=0; ct < size; ct++) {
880 p->delta.y += dy2;
881 p->position += p->delta;
882 if ((p->position.y > height) && (p->delta.y > 0)) {
883 p->delta.y *= -0.3f;
884 }
885 p++;
886 }
887 //Tell Renderscript runtime to render to the frame buffer object
888 rsgBindColorTarget(gColorBuffer, 0);
889 //Begin rendering on a white background
890 rsgClearColor(1.f, 1.f, 1.f, 1.f);
891 rsgDrawMesh(partMesh);
892
893 //When done, tell Renderscript runtime to stop rendering to framebuffer object
894 rsgClearAllRenderTargets();
895
896 //Bind a new fragment shader that declares the framebuffer object to be used as a texture
897 rsgBindProgramFragment(gTextureProgramFragment);
898
899 //Bind the framebuffer object to the fragment shader at slot 0 as a texture
900 rsgBindTexture(gTextureProgramFragment, 0, gColorBuffer);
901 //Draw a quad using the framebuffer object as the texture
902 float startX = 10, startY = 10;
903 float s = 256;
904 rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
905 startX, startY + s, 0, 0, 0,
906 startX + s, startY + s, 0, 1, 0,
907 startX + s, startY, 0, 1, 1);
908
909 //Rebind the original fragment shader to render as normal
910 rsgBindProgramFragment(gProgramFragment);
911
912 //Render the main scene
913 rsgDrawMesh(partMesh);
914
915 return 1;
916}
917</pre>
918 </li>
919
920 <li>In the <code>FountainRS.java</code> file, modify the <code>init()</code> method to look
921 like the following code. The modifications are commented:
922
923<pre>
924/* Add necessary members */
925private ScriptC_fountainfbo mScript;
926private Allocation mColorBuffer;
927private ProgramFragment mProgramFragment;
928private ProgramFragment mTextureProgramFragment;
929
930public void init(RenderScriptGL rs, Resources res) {
931 mRS = rs;
932 mRes = res;
933
934 ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);
935
936 Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
937 smb.addVertexAllocation(points.getAllocation());
938 smb.addIndexSetType(Mesh.Primitive.POINT);
939 Mesh sm = smb.create();
940
941 mScript = new ScriptC_fountainfbo(mRS, mRes, R.raw.fountainfbo);
942 mScript.set_partMesh(sm);
943 mScript.bind_point(points);
944
945 ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
946 pfb.setVaryingColor(true);
947 mProgramFragment = pfb.create();
948 mScript.set_gProgramFragment(mProgramFragment);
949
950 /* Second fragment shader to use a texture (framebuffer object) to draw with */
951 pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
952 ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
953
954 /* Set the fragment shader in the Renderscript runtime */
955 mTextureProgramFragment = pfb.create();
956 mScript.set_gTextureProgramFragment(mTextureProgramFragment);
957
958 /* Create the allocation for the color buffer */
959 Type.Builder colorBuilder = new Type.Builder(mRS, Element.RGBA_8888(mRS));
960 colorBuilder.setX(256).setY(256);
961 mColorBuffer = Allocation.createTyped(mRS, colorBuilder.create(),
962 Allocation.USAGE_GRAPHICS_TEXTURE |
963 Allocation.USAGE_GRAPHICS_RENDER_TARGET);
964
965 /* Set the allocation in the Renderscript runtime */
966 mScript.set_gColorBuffer(mColorBuffer);
967
968 mRS.bindRootScript(mScript);
969}
970</pre>
971
972<p class="note"><strong>Note:</strong> This sample doesn't use a depth buffer, but the following code
973shows you how to declare an example depth buffer if you need to use
974one for your application. The depth buffer must have the same dimensions as the color buffer:
975
976<pre>
977Allocation mDepthBuffer;
978
979...
980
981Type.Builder b = new Type.Builder(mRS, Element.createPixel(mRS, DataType.UNSIGNED_16,
982 DataKind.PIXEL_DEPTH));
983b.setX(256).setY(256);
984mDepthBuffer = Allocation.createTyped(mRS, b.create(),
985Allocation.USAGE_GRAPHICS_RENDER_TARGET);
986
987</pre>
988</p>
989</li>
990
991 <li>Run and use the sample. The smaller, white quad on the top-left corner is using the
992 framebuffer object as a texture, which renders the same scene as the main rendering.</li>
993</ol>