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><project_root>/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 < size; ct++) { 198 p->delta.y += dy2; 199 p->position += p->delta; 200 if ((p->position.y > height) && (p->delta.y > 0)) { 201 p->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 = &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->delta.x = len * sin(angle); 229 np->delta.y = len * cos(angle); 230 np->position = p; 231 np->color = c; 232 newPart++; 233 np++; 234 if (newPart >= size) { 235 newPart = 0; 236 np = &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 >= holdingColor.length) { 339 return; 340 } 341 int rate = (int)(pressure * pressure * 500.f); 342 if (rate > 500) { 343 rate = 500; 344 } 345 if (rate > 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 @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 @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 @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 < 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 < 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 @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 @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 @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