| page.title=3D Graphics |
| parent.title=RenderScript |
| parent.link=index.html |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>In this document</h2> |
| |
| <ol> |
| <li> |
| <a href="#developing">Developing a RenderScript application</a> |
| |
| <ol> |
| <li><a href="#hello-graphics">The Hello Graphics application</a></li> |
| </ol> |
| </li> |
| </ol> |
| |
| <h2>Related Samples</h2> |
| |
| <ol> |
| <li><a href="{@docRoot}resources/samples/RenderScript/Balls/index.html">Balls</a></li> |
| |
| <li><a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a></li> |
| |
| <li><a href="{@docRoot}resources/samples/RenderScript/HelloWorld/index.html">Hello |
| World</a></li> |
| |
| <li><a |
| href="{@docRoot}resources/samples/RenderScript/MiscSamples/index.html">Misc Samples</a></li> |
| </ol> |
| </div> |
| </div> |
| |
| <p>RenderScript provides a number of graphics APIs for 3D rendering, both at the Android |
| framework level as well as at the native level. For instance, the Android framework APIs let you |
| create meshes and define shaders to customize the graphical rendering pipeline. The native |
| RenderScript graphics APIs lets you draw the actual meshes to render your scene. In general, you |
| will need to be familiar with APIs to appropriately render 3D graphics on an Android-powered |
| device.</p> |
| |
| <h2>Creating a Graphics RenderScript</h2> |
| |
| <p>Because of the various layers of code when writing a RenderScript application, it is useful to |
| create the following files for a scene that you want to render:</p> |
| |
| <ul> |
| <li>The native RenderScript <code>.rs</code> file. This file contains the logic to do the |
| graphics rendering.</li> |
| |
| <li>The RenderScript entry point class that allows your view to interact with the code defined |
| in the <code>.rs</code> file. This class contains a RenderScript object(instance of |
| <code>ScriptC_<em>renderscript_file</em></code>), which allows your Android framework code to |
| call the native RenderScript code. This class also creates the {@link |
| android.renderscript.RenderScriptGL} context object, which contains the current rendering state |
| of the RenderScript such as programs (vertex and fragment shaders, for example) that you want |
| to define and bind to the graphics pipeline. The context object attaches to the RenderScript |
| object (instance of <code><em>ScriptC_renderscript_file</em></code>) that does the rendering. |
| Our example names this class <code>HelloWorldRS</code>.</li> |
| |
| <li>Create a class that extends {@link android.renderscript.RSSurfaceView} to provide a surface |
| to render on. If you want to implement callbacks from events inherited from {@link |
| android.view.View}, such as {@link android.view.View#onTouchEvent onTouchEvent()} and {@link |
| android.view.View#onKeyDown onKeyDown()}, do so in this class as well.</li> |
| |
| <li>Create a class that is the main Activity class, like you would with any Android |
| application. This class sets your {@link android.renderscript.RSSurfaceView} as the content |
| view for this Activity.</li> |
| </ul> |
| |
| <p>The following sections describe how to implement these three classes by using the HelloWorld |
| RenderScript sample that is provided in the SDK as a guide (some code has been modified from its |
| original form for simplicity).</p> |
| |
| <h3>Creating the native RenderScript file</h3> |
| |
| <p>Your native RenderScript code resides in a <code>.rs</code> file in the |
| <code><project_root>/src/</code> directory. You can also define <code>.rsh</code> header |
| files. This code contains the logic to render your graphics and declares all necessary variables |
| and pointers. Every graphics <code>.rs</code> file generally contains the following items:</p> |
| |
| <ul> |
| <li>A pragma (<code>#pragma rs java_package_name(<em>package.name</em>)</code>) that declares |
| the package name of the <code>.java</code> reflection of this RenderScript.</li> |
| |
| <li>A pragma (<code>#pragma version(1)</code>) that declares the version of RenderScript that |
| you are using (1 is the only value for now).</li> |
| |
| <li>A <code>#include</code> of the rs_graphics.rsh header file.</li> |
| |
| <li>A <code>root()</code> function. This is the main worker function for your RenderScript and |
| calls RenderScript graphics APIs to draw meshes to the surface. This function is called every |
| time a frame refresh occurs, which is specified as its return value. A <code>0</code> specified |
| for the return value says to only render the frame when a property of the scene that you are |
| rendering changes. A non-zero positive integer specifies the refresh rate of the frame in |
| milliseconds. |
| |
| <p class="note"><strong>Note:</strong> The RenderScript runtime makes its best effort to |
| refresh the frame at the specified rate. For example, if you are creating a live wallpaper |
| and set the return value to 50, the runtime renders the wallpaper at 20fps if it has just |
| enough or more resources to do so, and renders as fast as it can if it does not.</p> |
| |
| <p>For more |
| information on using the RenderScript graphics functions, see <a href= |
| "using-graphics-api">Using the Graphics APIs</a>.</p> |
| </li> |
| |
| <li>An <code>init()</code> function. This allows you to do any initialization of your |
| RenderScript before the <code>root()</code> function runs, such as initializing variables. This |
| function runs once and is called automatically when the RenderScript starts, before anything |
| else in your RenderScript. Creating this function is optional.</li> |
| |
| <li>Any variables, pointers, and structures that you wish to use in your RenderScript code (can |
| be declared in <code>.rsh</code> files if desired)</li> |
| </ul> |
| |
| <p>The following code shows how the <code>helloworld.rs</code> file is implemented:</p> |
| <pre> |
| #pragma version(1) |
| |
| // Tell which java package name the reflected files should belong to |
| #pragma rs java_package_name(com.android.rs.helloworld) |
| |
| // Built-in header with graphics APIs |
| #include "rs_graphics.rsh" |
| |
| // gTouchX and gTouchY are variables that are reflected for use |
| // by the Android framework API. This RenderScript uses them to be notified of touch events. |
| int gTouchX; |
| int gTouchY; |
| |
| // This is invoked automatically when the script is created and initializes the variables |
| // in the Android framework layer as well. |
| void init() { |
| gTouchX = 50.0f; |
| gTouchY = 50.0f; |
| } |
| |
| int root(int launchID) { |
| |
| // Clear the background color |
| rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| // Tell the runtime what the font color should be |
| rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); |
| // Introuduce ourselves to the world by drawing a greeting |
| // at the position user touched on the screen |
| rsgDrawText("Hello World!", gTouchX, gTouchY); |
| |
| // Return value tells RS roughly how often to redraw |
| // in this case 20 ms |
| return 20; |
| } |
| </pre> |
| |
| <h3>Creating the RenderScript entry point class</h3> |
| |
| <p>When you create a RenderScript (<code>.rs</code>) file, it is helpful to create a |
| corresponding Android framework class that is an entry point into the <code>.rs</code> file. In |
| this entry point class, you create a RenderScript object by instantiating a |
| <code>ScriptC_<em>rs_filename</em></code> and binding it to the RenderScript context. The |
| RenderScript object is attached to the RenderScript bytecode, which is platform-independent and |
| gets compiled on the device when the RenderScript application runs. Both the |
| <code>ScriptC_<em>rs_filename</em></code> class and bytecode is generated by the Android build |
| tools and is packaged with the <code>.apk</code> file. The bytecode file is located in the |
| <code><project_root>/res/raw/</code> directory and is named <code>rs_filename.bc</code>. |
| You refer to the bytecode as a resource (<code>R.raw.<em>rs_filename</em></code>). when creating |
| the RenderScript object..</p> |
| |
| <p>You then bind the RenderScript object to the RenderScript context, so that the surface view |
| knows what code to use to render graphics. The following code shows how the |
| <code>HelloWorldRS</code> class is implemented:</p> |
| <pre> |
| package com.android.rs.helloworld; |
| |
| import android.content.res.Resources; |
| import android.renderscript.*; |
| |
| public class HelloWorldRS { |
| //context and resources are obtained from RSSurfaceView, which calls init() |
| private Resources mRes; |
| private RenderScriptGL mRS; |
| |
| //Declare the RenderScript object |
| private ScriptC_helloworld mScript; |
| |
| public HelloWorldRS() { |
| } |
| |
| /** |
| * This provides us with the RenderScript context and resources |
| * that allow us to create the RenderScript object |
| */ |
| public void init(RenderScriptGL rs, Resources res) { |
| mRS = rs; |
| mRes = res; |
| initRS(); |
| } |
| /** |
| * Calls native RenderScript functions (set_gTouchX and set_gTouchY) |
| * through the reflected layer class ScriptC_helloworld to pass in |
| * touch point data. |
| */ |
| public void onActionDown(int x, int y) { |
| mScript.set_gTouchX(x); |
| mScript.set_gTouchY(y); |
| } |
| /** |
| * Binds the RenderScript object to the RenderScript context |
| */ |
| private void initRS() { |
| //create the RenderScript object |
| mScript = new ScriptC_helloworld(mRS, mRes, R.raw.helloworld); |
| //bind the RenderScript object to the RenderScript context |
| mRS.bindRootScript(mScript); |
| } |
| } |
| |
| </pre> |
| |
| <h3>Creating the surface view</h3> |
| |
| <p>To create a surface view to render graphics on, create a class that extends {@link |
| android.renderscript.RSSurfaceView}. This class also creates a RenderScript context object |
| ({@link android.renderscript.RenderScriptGL} and passes it to the Rendscript entry point class to |
| bind the two. The following code shows how the <code>HelloWorldView</code> class is |
| implemented:</p> |
| <pre> |
| package com.android.rs.helloworld; |
| |
| import android.renderscript.RSSurfaceView; |
| import android.renderscript.RenderScriptGL; |
| import android.content.Context; |
| import android.view.MotionEvent; |
| |
| public class HelloWorldView extends RSSurfaceView { |
| // RenderScript context |
| private RenderScriptGL mRS; |
| // RenderScript entry point object that does the rendering |
| private HelloWorldRS mRender; |
| |
| public HelloWorldView(Context context) { |
| super(context); |
| initRS(); |
| } |
| |
| private void initRS() { |
| if (mRS == null) { |
| // Initialize RenderScript with default surface characteristics. |
| RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); |
| //Create the RenderScript context |
| mRS = createRenderScriptGL(sc); |
| // Create an instance of the RenderScript entry point class |
| mRender = new HelloWorldRS(); |
| // Call the entry point class to bind it to this context |
| mRender.init(mRS, getResources()); |
| } |
| } |
| |
| /** |
| * Rebind everything when the window becomes attached |
| */ |
| protected void onAttachedToWindow() { |
| super.onAttachedToWindow(); |
| initRS(); |
| } |
| |
| /** |
| * Stop rendering when window becomes detached |
| */ |
| protected void onDetachedFromWindow() { |
| // Handle the system event and clean up |
| mRender = null; |
| if (mRS != null) { |
| mRS = null; |
| destroyRenderScriptGL(); |
| } |
| } |
| |
| /** |
| * Use callbacks to relay data to RenderScript entry point class |
| */ |
| public boolean onTouchEvent(MotionEvent ev) { |
| // Pass touch events from the system to the rendering script |
| if (ev.getAction() == MotionEvent.ACTION_DOWN) { |
| mRender.onActionDown((int)ev.getX(), (int)ev.getY()); |
| return true; |
| } |
| |
| return false; |
| } |
| } |
| |
| </pre> |
| |
| <h3>Creating the Activity</h3> |
| |
| <p>Applications that use RenderScript still adhere to activity lifecyle, and are part of the same |
| view hierarchy as traditional Android applications, which is handled by the Android VM. This |
| Activity class sets its view to be the {@link android.renderscript.RSSurfaceView} and handles |
| lifecycle callback events appropriately. The following code shows how the <code>HelloWorld</code> |
| class is implemented:</p> |
| <pre> |
| public class HelloWorldActivity extends Activity { |
| |
| //Custom view to use with RenderScript |
| private HelloWorldView view; |
| |
| public void onCreate(Bundle icicle) { |
| super.onCreate(icicle); |
| // Create surface view and set it as the content of our Activity |
| mView = new HelloWorldView(this); |
| setContentView(view); |
| } |
| |
| protected void onResume() { |
| // Ideally an app should implement onResume() and onPause() |
| // to take appropriate action when the activity loses focus |
| super.onResume(); |
| view.resume(); |
| } |
| |
| protected void onPause() { |
| // Ideally an app should implement onResume() and onPause() |
| // to take appropriate action when the activity loses focus |
| super.onPause(); |
| view.pause(); |
| } |
| } |
| </pre> |
| |
| <h2>Drawing</h2> |
| |
| <h3>Drawing using the rsgDraw functions</h3> |
| |
| <p>The native RenderScript APIs provide a few convenient functions to easily draw a polygon to |
| the screen. You call these in your <code>root()</code> function to have them render to the |
| surface view. These functions are available for simple drawing and should not be used for complex |
| graphics rendering:</p> |
| |
| <ul> |
| <li><code>rsgDrawRect()</code>: Sets up a mesh and draws a rectangle to the screen. It uses the |
| top left vertex and bottom right vertex of the rectangle to draw.</li> |
| |
| <li><code>rsgDrawQuad()</code>: Sets up a mesh and draws a quadrilateral to the screen.</li> |
| |
| <li><code>rsgDrawQuadTexCoords()</code>: Sets up a mesh and draws a textured quadrilateral to |
| the screen.</li> |
| </ul> |
| |
| <h3>Drawing with a mesh</h3> |
| |
| <p>When you want to draw complex shapes and textures to the screen, instantiate a {@link |
| android.renderscript.Mesh} and draw it to the screen with <code>rsgDrawMesh()</code>. A {@link |
| android.renderscript.Mesh} is a collection of allocations that represent vertex data (positions, |
| normals, texture coordinates) and index data such as triangles and lines. You can build a Mesh in |
| three different ways:</p> |
| |
| <ul> |
| <li>Build the mesh with the {@link android.renderscript.Mesh.TriangleMeshBuilder} class, which |
| allows you to specify a set of vertices and indices for each triangle that you want to draw. |
| The downside of doing it this way is there is no way to specify the vertices in your native |
| RenderScript code.</li> |
| |
| <li>Build the mesh using an {@link android.renderscript.Allocation} or a set of {@link |
| android.renderscript.Allocation}s with the {@link android.renderscript.Mesh.AllocationBuilder} |
| class. This allows you to build a mesh with vertices already stored in memory, which allows you |
| to set the vertices in native or Android code.</li> |
| |
| <li>Build the mesh with the {@link android.renderscript.Mesh.Builder} class. This is a |
| convenience method for when you know what data types you want to use to build your mesh, but |
| don't want to make separate memory allocations like with {@link |
| android.renderscript.Mesh.AllocationBuilder}. You can specify the types that you want and this |
| mesh builder automatically creates the memory allocations for you.</li> |
| </ul> |
| |
| <p>To create a mesh using the {@link android.renderscript.Mesh.TriangleMeshBuilder}, you need to |
| supply it with a set of vertices and the indices for the vertices that comprise the triangle. For |
| example, the following code specifies three vertices, which are added to an internal array, |
| indexed in the order they were added. The call to {@link |
| android.renderscript.Mesh.TriangleMeshBuilder#addTriangle addTriangle()} draws the triangle with |
| vertex 0, 1, and 2 (the vertices are drawn counter-clockwise).</p> |
| <pre> |
| int float2VtxSize = 2; |
| Mesh.TriangleMeshBuilder triangle = new Mesh.TriangleMeshBuilder(renderscriptGL, |
| float2VtxSize, Mesh.TriangleMeshBuilder.COLOR); |
| triangles.addVertex(300.f, 300.f); |
| triangles.addVertex(150.f, 450.f); |
| triangles.addVertex(450.f, 450.f); |
| triangles.addTriangle(0 , 1, 2); |
| Mesh smP = triangle.create(true); |
| script.set_mesh(smP); |
| </pre> |
| |
| <p>To draw a mesh using the {@link android.renderscript.Mesh.AllocationBuilder}, you need to |
| supply it with one or more allocations that contain the vertex data:</p> |
| <pre> |
| Allocation vertices; |
| |
| ... |
| Mesh.AllocationBuilder triangle = new Mesh.AllocationBuilder(mRS); |
| smb.addVertexAllocation(vertices.getAllocation()); |
| smb.addIndexSetType(Mesh.Primitive.TRIANGLE); |
| Mesh smP = smb.create(); |
| script.set_mesh(smP); |
| </pre> |
| |
| <p>In your native RenderScript code, draw the built mesh to the screen:</p> |
| <pre> |
| rs_mesh mesh; |
| ... |
| |
| int root(){ |
| ... |
| rsgDrawMesh(mesh); |
| ... |
| return 0; //specify a non zero, positive integer to specify the frame refresh. |
| //0 refreshes the frame only when the mesh changes. |
| } |
| </pre> |
| |
| <h2 id="shaders">Shaders</h2> |
| |
| <p>You can attach four program objects to the {@link android.renderscript.RenderScriptGL} context |
| to customize the rendering pipeline. For example, you can create vertex and fragment shaders in |
| GLSL or build a raster program object with provided methods without writing GLSL code. The four |
| program objects mirror a traditional graphical rendering pipeline:</p> |
| |
| <table> |
| <tr> |
| <th>Android Object Type</th> |
| |
| <th>RenderScript Native Type</th> |
| |
| <th>Description</th> |
| </tr> |
| |
| <tr> |
| <td>{@link android.renderscript.ProgramVertex}</td> |
| |
| <td>rs_program_vertex</td> |
| |
| <td> |
| <p>The RenderScript vertex program, also known as a vertex shader, describes the stage in |
| the graphics pipeline responsible for manipulating geometric data in a user-defined way. |
| The object is constructed by providing RenderScript with the following data:</p> |
| |
| <ul> |
| <li>An Element describing its varying inputs or attributes</li> |
| |
| <li>GLSL shader string that defines the body of the program</li> |
| |
| <li>a Type that describes the layout of an Allocation containing constant or uniform |
| inputs</li> |
| </ul> |
| |
| <p>Once the program is created, bind it to the {@link android.renderscript.RenderScriptGL} |
| graphics context by calling {@link android.renderscript.RenderScriptGL#bindProgramVertex |
| bindProgramVertex()}. It is then used for all subsequent draw calls until you bind a new |
| program. If the program has constant inputs, the user needs to bind an allocation |
| containing those inputs. The allocation's type must match the one provided during creation. |
| The RenderScript library then does all the necessary plumbing to send those constants to |
| the graphics hardware. Varying inputs to the shader, such as position, normal, and texture |
| coordinates are matched by name between the input Element and the Mesh object being drawn. |
| The signatures don't have to be exact or in any strict order. As long as the input name in |
| the shader matches a channel name and size available on the mesh, the run-time would take |
| care of connecting the two. Unlike OpenGL, there is no need to link the vertex and fragment |
| programs.</p> |
| |
| <p>To bind shader constructs to the Program, declare a struct containing the necessary |
| shader constants in your native RenderScript code. This struct is generated into a |
| reflected class that you can use as a constant input element during the Program's creation. |
| It is an easy way to create an instance of this struct as an allocation. You would then |
| bind this Allocation to the Program and the RenderScript system sends the data that is |
| contained in the struct to the hardware when necessary. To update shader constants, you |
| change the values in the Allocation and notify the native RenderScript code of the |
| change.</p> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>{@link android.renderscript.ProgramFragment}</td> |
| |
| <td>rs_program_fragment</td> |
| |
| <td> |
| <p>The RenderScript fragment program, also known as the fragment shader, is responsible for |
| manipulating pixel data in a user-defined way. It's constructed from a GLSL shader string |
| containing the program body, textures inputs, and a Type object describing the constants |
| used by the program. Like the vertex programs, when an allocation with constant input |
| values is bound to the shader, its values are sent to the graphics program automatically. |
| Note that the values inside the allocation are not explicitly tracked. If they change |
| between two draw calls using the same program object, notify the runtime of that change by |
| calling rsgAllocationSyncAll so it could send the new values to hardware. Communication |
| between the vertex and fragment programs is handled internally in the GLSL code. For |
| example, if the fragment program is expecting a varying input called varTex0, the GLSL code |
| inside the program vertex must provide it.</p> |
| |
| <p>To bind shader constants to this program, declare a struct containing the necessary |
| shader constants in your native RenderScript code. This struct is generated into a |
| reflected class that you can use as a constant input element during the Program's creation. |
| It is an easy way to create an instance of this struct as an allocation. You would then |
| bind this Allocation to the Program and the RenderScript system sends the data that is |
| contained in the struct to the hardware when necessary. To update shader constants, you |
| change the values in the Allocation and notify the native RenderScript code of the |
| change.</p> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>{@link android.renderscript.ProgramStore}</td> |
| |
| <td>rs_program_store</td> |
| |
| <td>The RenderScript ProgramStore contains a set of parameters that control how the graphics |
| hardware writes to the framebuffer. It could be used to enable and disable depth writes and |
| testing, setup various blending modes for effects like transparency and define write masks |
| for color components.</td> |
| </tr> |
| |
| <tr> |
| <td>{@link android.renderscript.ProgramRaster}</td> |
| |
| <td>rs_program_raster</td> |
| |
| <td>Program raster is primarily used to specify whether point sprites are enabled and to |
| control the culling mode. By default back faces are culled.</td> |
| </tr> |
| </table> |
| |
| <p>The following example defines a vertex shader in GLSL and binds it to the RenderScript:</p> |
| <pre> |
| private RenderScriptGL glRenderer; //rendering context |
| private ScriptField_Point mPoints; //vertices |
| private ScriptField_VpConsts mVpConsts; //shader constants |
| |
| ... |
| |
| ProgramVertex.Builder sb = new ProgramVertex.Builder(glRenderer); |
| String t = "varying vec4 varColor;\n" + |
| "void main() {\n" + |
| " vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" + |
| " pos.xy = ATTRIB_position;\n" + |
| " gl_Position = UNI_MVP * pos;\n" + |
| " varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" + |
| " gl_PointSize = ATTRIB_size;\n" + |
| "}\n"; |
| sb.setShader(t); |
| sb.addConstant(mVpConsts.getType()); |
| sb.addInput(mPoints.getElement()); |
| ProgramVertex pvs = sb.create(); |
| pvs.bindConstants(mVpConsts.getAllocation(), 0); |
| glRenderer.bindProgramVertex(pvs); |
| |
| |
| </pre> |
| |
| <p>The <a href= |
| "{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html"> |
| RsRenderStatesRS</a> sample has many examples on how to create a shader without writing GLSL.</p> |
| |
| <h3>Shader bindings</h3> |
| |
| <p>You can also set four pragmas that control the shaders' default bindings to the {@link |
| android.renderscript.RenderScriptGL} context when the script is executing:</p> |
| |
| <ul> |
| <li>stateVertex</li> |
| |
| <li>stateFragment</li> |
| |
| <li>stateRaster</li> |
| |
| <li>stateStore</li> |
| </ul> |
| |
| <p>The possible values for each pragma are <code>parent</code> or <code>default</code>. Using |
| <code>default</code> binds the shaders to the graphical context with the system defaults. The |
| default shader is defined below:</p> |
| <pre> |
| ("varying vec4 varColor;\n"); |
| ("varying vec2 varTex0;\n"); |
| ("void main() {\n"); |
| (" gl_Position = UNI_MVP * ATTRIB_position;\n"); |
| (" gl_PointSize = 1.0;\n"); |
| (" varColor = ATTRIB_color;\n"); |
| (" varTex0 = ATTRIB_texture0;\n"); |
| ("}\n"); |
| </pre> |
| |
| <p>Using <code>parent</code> binds the shaders in the same manner as it is bound in the calling |
| script. If this is the root script, the parent state is taken from the bind points that are set |
| by the {@link android.renderscript.RenderScriptGL} bind methods.</p> |
| |
| <p>For example, you can define this at the top of your native graphics RenderScript code to have |
| the Vertex and Store shaders inherent the bind properties from their parent scripts:</p> |
| <pre> |
| #pragma stateVertex(parent) |
| #pragma stateStore(parent) |
| </pre> |
| |
| <h3>Defining a sampler</h3> |
| |
| <p>A {@link android.renderscript.Sampler} object defines how data is extracted from textures. |
| Samplers are bound to Program objects (currently only a Fragment Program) alongside the texture |
| whose sampling they control. These objects are used to specify such things as edge clamping |
| behavior, whether mip-maps are used, and the amount of anisotropy required. There might be |
| situations where hardware does not support the desired behavior of the sampler. In these cases, |
| the runtime attempts to provide the closest possible approximation. For example, the user |
| requested 16x anisotropy, but only 8x was set because it's the best available on the |
| hardware.</p> |
| |
| <p>The <a href= |
| "{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html"> |
| RsRenderStatesRS</a> sample has many examples on how to create a sampler and bind it to a |
| Fragment program.</p> |
| |
| </body> |
| </html> |