android--graphics
来源:互联网 发布:淘宝商铺怎么激活 编辑:程序博客网 时间:2024/05/17 01:43
Graphics
View
widgets that provide general functionality for a wide array of user interfaces. You can also extend these widgets to modify the way they look or behave. In addition, you can do your own custom 2D rendering using the various drawing methods contained in the Canvas
class or create Drawable
objects for things such as textured buttons or frame-by-frame animations.docs/
directory of the NDK download.GLSurfaceView.setRenderer()使其关联到GLSurfaceView
String extensions = javax.microedition.khronos.opengles.GL10.glGetString(GL10.GL_EXTENSIONS);
Renderscript:
Renderscript提供高性能3D图形和计算,处于native level,使用C99标准,
优点是:
- Portability:可使用在不同处理架构的设备上(CPU, GPU, and DSP for instance) ,It supports all of these architectures without having to target each device, because the code is compiled and cached on the device at runtime.
- Performance:Renderscript provides similar performance to OpenGL with the NDK and also provides a high performance compute API that is not offered by OpenGL.
- Usability:Renderscript simplifies development when possible, such as eliminating JNI glue code and simplifying mesh setup.
- Development complexity:Renderscript introduces a new set of APIs that you have to learn,Renderscript also allocates memory differently compared to OpenGL with the Android framework APIs.
- Debugging visibility: debug难度加大
Renderscript概述:
Renderscript运行在native level,但是仍然需要与android VM通信,因此Renderscript应用程序跟纯VM应用程序不同。Renderscript平台独立。
Renderscript采用C/S结构,底层的Renderscript程序由vm中运行高层的android系统控制。android vm管理内存绑定分配给Renderscript 运行时以供Renderscript程序使用。android framework异步调用renderscript,
在使用renderscropt时,有3个层次的api为renderscript和android framework之间提供通信android.renderscript
package, allow you to build your application using traditional Android components such as activities and views. When using Renderscript, this layer calls the reflected layer to access the Renderscript runtime.#include "rs_graphics.rsh"
更多可用函数,请参考Renderscript runtime API reference。project_root/gen/package/name/ScriptC_renderscript_filename
的类。这个文件是一个与.rs文件对应的java文件,以供android framework调用。这个类包含以下内容():project_root/gen/package/name/ScriptField_struct_name的继承自Script.FieldBase的自有类。这个类代表这个结构的数组,这些数组允许为这些结构的实体分配空间。
void touch(float x, float y, float pressure, int id) { if (id >= 10) { return; } touchPos[id].x = x; touchPos[id].y = y; touchPressure[id] = pressure;}映射成的脚本类:
public void invoke_touch(float x, float y, float pressure, int id) { FieldPacker touch_fp = new FieldPacker(16); touch_fp.addF32(x); touch_fp.addF32(y); touch_fp.addF32(pressure); touch_fp.addI32(id); invoke(mExportFuncIdx_touch, touch_fp);}函数不能有返回值,因为renderscript系统是异步系统。当android framework调用renderscript时,调用被放到队列中并适时执行。这个限制This restriction allows the Renderscript system to function without constant interruption and increases efficiency.如果允许函数有返回值,这个调用就会被中断等待返回值。如果renderscript需要传递变量到android framework,使用
rsSendToClient()函数。
变量
许多类型可以映射成脚本类,脚本类路径为:project_root/gen/package/name/ScriptC_renderscript_filename,每一个变量都会有一个accessor methods,如在renderscript 代码中声明一个变量,
uint32_t unsignedInteger = 1;
private long mExportVar_unsignedInteger;public void set_unsignedInteger(long v){ mExportVar_unsignedInteger = v; setVar(mExportVarIdx_unsignedInteger, v);}public long get_unsignedInteger(){ return mExportVar_unsignedInteger;}
typedef struct Point { float2 position; float size;} Point_t;映射生成的类为:
ScriptField_Point.java文件,如下所示:
package com.example.android.rs.hellocompute;import android.renderscript.*;import android.content.res.Resources; /** * @hide */public class ScriptField_Point extends android.renderscript.Script.FieldBase { static public class Item { public static final int sizeof = 12; Float2 position; float size; Item() { position = new Float2(); } } private Item mItemArray[]; private FieldPacker mIOBuffer; public static Element createElement(RenderScript rs) { Element.Builder eb = new Element.Builder(rs); eb.add(Element.F32_2(rs), "position"); eb.add(Element.F32(rs), "size"); return eb.create(); } public ScriptField_Point(RenderScript rs, int count) { mItemArray = null; mIOBuffer = null; mElement = createElement(rs); init(rs, count); } public ScriptField_Point(RenderScript rs, int count, int usages) { mItemArray = null; mIOBuffer = null; mElement = createElement(rs); init(rs, count, usages); } private void copyToArray(Item i, int index) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); mIOBuffer.reset(index * Item.sizeof); mIOBuffer.addF32(i.position); mIOBuffer.addF32(i.size); } public void set(Item i, int index, boolean copyNow) { if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; mItemArray[index] = i; if (copyNow) { copyToArray(i, index); mAllocation.setFromFieldPacker(index, mIOBuffer); } } public Item get(int index) { if (mItemArray == null) return null; return mItemArray[index]; } public void set_position(int index, Float2 v, boolean copyNow) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; if (mItemArray[index] == null) mItemArray[index] = new Item(); mItemArray[index].position = v; if (copyNow) { mIOBuffer.reset(index * Item.sizeof); mIOBuffer.addF32(v); FieldPacker fp = new FieldPacker(8); fp.addF32(v); mAllocation.setFromFieldPacker(index, 0, fp); } } public void set_size(int index, float v, boolean copyNow) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; if (mItemArray[index] == null) mItemArray[index] = new Item(); mItemArray[index].size = v; if (copyNow) { mIOBuffer.reset(index * Item.sizeof + 8); mIOBuffer.addF32(v); FieldPacker fp = new FieldPacker(4); fp.addF32(v); mAllocation.setFromFieldPacker(index, 1, fp); } } public Float2 get_position(int index) { if (mItemArray == null) return null; return mItemArray[index].position; } public float get_size(int index) { if (mItemArray == null) return 0; return mItemArray[index].size; } public void copyAll() { for (int ct = 0; ct < mItemArray.length; ct++) copyToArray(mItemArray[ct], ct); mAllocation.setFromFieldPacker(0, mIOBuffer); } public void resize(int newSize) { if (mItemArray != null) { int oldSize = mItemArray.length; int copySize = Math.min(oldSize, newSize); if (newSize == oldSize) return; Item ni[] = new Item[newSize]; System.arraycopy(mItemArray, 0, ni, 0, copySize); mItemArray = ni; } mAllocation.resize(newSize); if (mIOBuffer != null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); }}产生的这些代码的意义:The generated code is provided to you as a convenience to allocate memory for structs requested by the Renderscript runtime and to interact with
struct
s in memory.每个结构的类定义如下的方法的构造函数:- Overloaded constructors that allow you to allocate memory
- A static nested class,
Item
, allows you to create an instance of thestruct
, in the form of an object. - The
createElement()
method creates a description of the struct in memory. resize()
works much like arealloc()
in C, allowing you to expand previously allocated memory, maintaining the current values that were previously created.copyAll()
synchronizes memory that was set on the framework level to the Renderscript runtime.
typedef struct Point { float2 position; float size;} Point_t;Point_t *touchPoints;int32_t *intPointer;
private ScriptField_Point mExportVar_touchPoints;public void bind_touchPoints(ScriptField_Point v) { mExportVar_touchPoints = v; if (v == null) bindAllocation(null, mExportVarIdx_touchPoints); else bindAllocation(v.getAllocation(), mExportVarIdx_touchPoints);}public ScriptField_Point get_touchPoints() { return mExportVar_touchPoints;}private Allocation mExportVar_intPointer;public void bind_intPointer(Allocation v) { mExportVar_intPointer = v; if (v == null) bindAllocation(null, mExportVarIdx_intPointer); else bindAllocation(v, mExportVarIdx_intPointer);}public Allocation get_intPointer() { return mExportVar_intPointer;}
bind_pointer_name(代替set)的特殊方法。这个方法允许绑定由vm分配给renderscript runtime的内存。例如,Working with Allocated Memory
Memory Allocation APIs
array = (int *)malloc(sizeof(int)*10);
Element
An element describes one cell of a memory allocation and can have two forms: basic or complex.
A basic element contains a single component of data of any valid Renderscript data type. Examples of basic element data types include a single float
value, a float4
vector, or a single RGB-565 color.
Complex elements contain a list of basic elements and are created from struct
s that you declare in your Renderscript code. For instance an allocation can contain multiplestruct
s arranged in order in memory. Each struct is considered as its own element, rather than each data type within that struct.
Type
A type is a memory allocation template and consists of an element and one or more dimensions. It describes the layout of the memory (basically an array of Element
s) but does not allocate the memory for the data that it describes.
A type consists of five dimensions: X, Y, Z, LOD (level of detail), and Faces (of a cube map). You can assign the X,Y,Z dimensions to any positive integer value within the constraints of available memory. A single dimension allocation has an X dimension of greater than zero while the Y and Z dimensions are zero to indicate not present. For example, an allocation of x=10, y=1 is considered two dimensional and x=10, y=0 is considered one dimensional. The LOD and Faces dimensions are booleans to indicate present or not present.
Allocation
An allocation provides the memory for applications based on a description of the memory that is represented by a Type
. Allocated memory can exist in many memory spaces concurrently. If memory is modified in one space, you must explicitly synchronize the memory, so that it is updated in all the other spaces in which it exists.
Allocation data is uploaded in one of two primary ways: type checked and type unchecked. For simple arrays there are copyFrom()
functions that take an array from the Android system and copy it to the native layer memory store. The unchecked variants allow the Android system to copy over arrays of structures because it does not support structures. For example, if there is an allocation that is an array of n floats, the data contained in a float[n] array or a byte[n*4]
array can be copied.
Allocating and binding dynamic memory to the Renderscript
Script.FieldBase
类的构造函数,也可以通过手动创建Allocation。但是更为简单的方法是使用Script.FieldBase 。当申请完内存后,调用reflected layer的bind方法将内存绑定到renderscript runtime。intPointer
, and a pointer to a struct, touchPoints
. It also binds the memory to the Renderscript:private RenderScriptGL glRenderer;private ScriptC_example script;private Resources resources;public void init(RenderScriptGL rs, Resources res) { //get the rendering context and resources from the calling method glRenderer = rs; resources = res; //allocate memory for the struct pointer, calling the constructor ScriptField_Point touchPoints = new ScriptField_Point(glRenderer, 2); //Create an element manually and allocate memory for the int pointer intPointer = Allocation.createSized(glRenderer, Element.I32(glRenderer), 2); //create an instance of the Renderscript, pointing it to the bytecode resource mScript = new ScriptC_example(glRenderer, resources, R.raw.example); //bind the struct and int pointers to the Renderscript mScript.bind_touchPoints(touchPoints); script.bind_intPointer(intPointer); ...}
Reading and writing to memory
rsSendToClient
来克服这个限制。Reading and writing to global variables
Reading and writing to global variables is a straightforward process. You can use the accessor methods at the Android framework level or set them directly in the Renderscript code. Keep in mind that any changes that you make in your Renderscript code are not propagated back to the Android framework layer.
For example, given the following struct declared in a file named rsfile.rs
:
typedef struct Point { int x; int y;} Point_t;Point_t point;
You can assign values to the struct like this directly in rsfile.rs
. These values are not propagated back to the Android framework level:
point.x = 1;point.y = 1;
You can assign values to the struct at the Android framework layer like this. These values are propagated back to the Renderscript runtime level:
ScriptC_rsfile mScript;...Item i = new ScriptField_Point.Item();i.x = 1;i.y = 1;mScript.set_point(i);
You can read the values in your Renderscript code like this:
rsDebug("Printing out a Point", point.x, point.y);
You can read the values in the Android framework layer with the following code. Keep in mind that this code only returns a value if one was set at the Android framework level. You will get a null pointer exception if you only set the value at the Renderscript runtime level:
Log.i("TAGNAME", "Printing out a Point: " + mScript.get_point().x + " " + mScript.get_point().y);System.out.println(point.get_x() + " " + point.get_y());
Reading and writing global pointers
Assuming that memory has been allocated in the Android framework level and bound to the Renderscript runtime, you can read and write memory from the Android framework level by using the get
and set
methods for that pointer. In the Renderscript runtime layer, you can read and write to memory with pointers as normal and the changes are propagated back to the Android framework layer, unlike with statically allocated memory.
For example, given the following pointer to a struct
in a file named rsfile.rs
:
typedef struct Point { int x; int y;} Point_t;Point_t *point;
Assuming you already allocated memory at the Android framework layer, you can access values in the struct
as normal. Any changes you make to the struct via its pointer variable are automatically available to the Android framework layer:
point[index].x = 1;point[index].y = 1;
You can read and write values to the pointer at the Android framework layer as well:
ScriptField_Point p = new ScriptField_Point(mRS, 1); Item i = new ScriptField_Point.Item(); i.x=100; i.y = 100; p.set(i, 0, true); mScript.bind_point(p); points.get_x(0); //read x and y from index 0 points.get_x(0);
Once memory is already bound, you do not have to rebind the memory to the Renderscript runtime every time you make a change to a value。
Compute API用于密集计算,在context of a graphics Renderscript 中使用,比如计算位置,也可以用于脱机计算renderscript,比如图像处理和照片编辑等。
Simple drawing简单的绘图:
RSTextureView
。rsgDrawRect()
: 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.rsgDrawQuad()
: Sets up a mesh and draws a quadrilateral to the screen.rsgDrawQuadTexCoords()
: Sets up a mesh and draws a quadrilateral to the screen using the provided coordinates of a texture.rsgDrawText()
: Draws specified text to the screen. UsersgFontColor()
to set the color of the text.
Drawing with a mesh:
- Build the mesh with the
Mesh.TriangleMeshBuilder
class, which allows you to specify a set of vertices and indices for each triangle that you want to draw. - Build the mesh using an
Allocation
or a set ofAllocation
s with theMesh.AllocationBuilder
class. This approach allows you to build a mesh with vertices already stored in memory, which allows you to specify the vertices in Renderscript or Android framework code. - Build the mesh with the
Mesh.Builder
class. You should use this convenience method when you know the data types you want to use to build your mesh, but don't want to make separate memory allocations like withMesh.AllocationBuilder
. You can specify the types that you want and this mesh builder automatically creates the memory allocations for you.
Mesh.TriangleMeshBuilder
创建mesh,需要提供构成三角形的顶点和索引。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 addTriangle()
draws the triangle with vertex 0, 1, and 2 (the vertices are drawn counter-clockwise).int float2VtxSize = 2;Mesh.TriangleMeshBuilder triangles = 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);
Mesh.AllocationBuilder创建mesh,
you need to supply it with one or more allocations that contain the vertex data:
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);
In your Renderscript code, draw the built mesh to the screen:
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.}
ProgramVertex
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:
- An
Element
describing its varying inputs or attributes - GLSL shader string that defines the body of the program
- a
Type
that describes the layout of an Allocation containing constant or uniform inputs
Once the program is created, bind it to the RenderScriptGL
graphics context by calling 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 runtime 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 that is 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 Renderscript runtime handles connecting the two. Unlike OpenGL there is no need to link the vertex and fragment programs.
To bind shader constants to the program, declare a struct
that contains the necessary shader constants in your 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 runtime sends the data that is contained in thestruct
to the hardware when necessary. To update shader constants, you change the values in the Allocation
and notify the Renderscript code of the change.
The ProgramVertexFixedFunction.Builder
class also lets you build a simple vertex shader without writing GLSL code.
ProgramFragment
rs_program_fragmentThe Renderscript fragment program, also known as a 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, texture inputs, and a Type
object that describes 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 can 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.
To bind shader constructs to the program, declare a struct
that contains the necessary shader constants in your 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 runtime sends the data that is contained in thestruct
to the hardware when necessary. To update shader constants, you change the values in the Allocation
and notify the Renderscript code of the change.
The ProgramFragmentFixedFunction.Builder
class also lets you build a simple fragment shader without writing GLSL code.
ProgramStore
rs_program_storeThe Renderscript store program 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.ProgramRaster
rs_program_rasterThe Renderscript raster program is primarily used to specify whether point sprites are enabled and to control the culling mode. By default back faces are culled.
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);
The RsRenderStatesRS sample has many examples on how to create a shader without writing GLSL.
Rendering to a Framebuffer Object:渲染到framebuffer对象,framebuffer用在存放即将渲染到屏幕上的数据信息,一个framebuffer对象有两个缓冲区:颜色缓冲区和深度缓冲区。
一般情况下,渲染到framebuffer需要做的事情:
1、为颜色缓冲区和深度缓冲区创建Allocation 对象,然后具体化它们的
USAGE_GRAPHICS_RENDER_TARGET属性,以通知renderscript runtime 的framebuffer对象使用它们。对于颜色缓冲区,必须声明 USAGE_GRAPHICS_TEXTURE
属性来使用颜色缓冲区作为纹理,这是framebuffer对象的常用法。
2、通过调用rsgBindColorTarget来通知renderscript runtime使用渲染到framebuffer对象来代替其默认的framebuffer,同时传递颜色缓冲区Allocation。适当的时候,深度缓冲区也需要这么做,但是需要调用rsgBindDepthTarget而不是rsgBindColorTarget。
3、一般使用rsgDraw函数渲染场景,这些场景会被渲染到颜色缓冲区而不是默认直接显示到屏幕上。
4、当完成第3步的时候,告诉renderscript runtime停止渲染到颜色缓冲区而恢复到渲染默认缓冲区通过调用rsgClearAllRenderTargets。
5、创建片段着色器并将其作为纹理绑定到颜色缓冲区。
6、渲染场景到默认的framebuffer。根据setup片段着色器的方式使用这些纹理。
例子FountainFBO是通过修改Fountain 这个例子来展示如何渲染到framebuffer对象。二者的不同之处是,同样的场景,一个是渲染到默认的framebuffer,一个是渲染到framebuffer对象。
- Modify
fountain.rs
and add the following global variables. This creates setter methods when this file is reflected into a.java
file, allowing you to allocate memory in your Android framework code and binding it to the Renderscript runtime.//allocation for color bufferrs_allocation gColorBuffer;//fragment shader for rendering without a texture (used for rendering to framebuffer object)rs_program_fragment gProgramFragment;//fragment shader for rendering with a texture (used for rendering to default framebuffer)rs_program_fragment gTextureProgramFragment;
- Modify the root function of
fountain.rs
to look like the following code. The modifications are commented:int root() { float dt = min(rsGetDt(), 0.1f); rsgClearColor(0.f, 0.f, 0.f, 1.f); const float height = rsgGetHeight(); const int size = rsAllocationGetDimX(rsGetAllocation(point)); float dy2 = dt * (10.f); Point_t * p = point; for (int ct=0; ct < size; ct++) { p->delta.y += dy2; p->position += p->delta; if ((p->position.y > height) && (p->delta.y > 0)) { p->delta.y *= -0.3f; } p++; } //Tell Renderscript runtime to render to the frame buffer object rsgBindColorTarget(gColorBuffer, 0); //Begin rendering on a white background rsgClearColor(1.f, 1.f, 1.f, 1.f); rsgDrawMesh(partMesh); //When done, tell Renderscript runtime to stop rendering to framebuffer object rsgClearAllRenderTargets(); //Bind a new fragment shader that declares the framebuffer object to be used as a texture rsgBindProgramFragment(gTextureProgramFragment); //Bind the framebuffer object to the fragment shader at slot 0 as a texture rsgBindTexture(gTextureProgramFragment, 0, gColorBuffer); //Draw a quad using the framebuffer object as the texture float startX = 10, startY = 10; float s = 256; rsgDrawQuadTexCoords(startX, startY, 0, 0, 1, startX, startY + s, 0, 0, 0, startX + s, startY + s, 0, 1, 0, startX + s, startY, 0, 1, 1); //Rebind the original fragment shader to render as normal rsgBindProgramFragment(gProgramFragment); //Render the main scene rsgDrawMesh(partMesh); return 1;}
- In the
FountainRS.java
file, modify theinit()
method to look like the following code. The modifications are commented:/* Add necessary members */private ScriptC_fountainfbo mScript;private Allocation mColorBuffer;private ProgramFragment mProgramFragment;private ProgramFragment mTextureProgramFragment;public void init(RenderScriptGL rs, Resources res) { mRS = rs; mRes = res; ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT); Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS); smb.addVertexAllocation(points.getAllocation()); smb.addIndexSetType(Mesh.Primitive.POINT); Mesh sm = smb.create(); mScript = new ScriptC_fountainfbo(mRS, mRes, R.raw.fountainfbo); mScript.set_partMesh(sm); mScript.bind_point(points); ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs); pfb.setVaryingColor(true); mProgramFragment = pfb.create(); mScript.set_gProgramFragment(mProgramFragment); /* Second fragment shader to use a texture (framebuffer object) to draw with */ pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); /* Set the fragment shader in the Renderscript runtime */ mTextureProgramFragment = pfb.create(); mScript.set_gTextureProgramFragment(mTextureProgramFragment); /* Create the allocation for the color buffer */ Type.Builder colorBuilder = new Type.Builder(mRS, Element.RGBA_8888(mRS)); colorBuilder.setX(256).setY(256); mColorBuffer = Allocation.createTyped(mRS, colorBuilder.create(), Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET); /* Set the allocation in the Renderscript runtime */ mScript.set_gColorBuffer(mColorBuffer); mRS.bindRootScript(mScript);}
Note: This sample doesn't use a depth buffer, but the following code shows you how to declare an example depth buffer if you need to use one for your application. The depth buffer must have the same dimensions as the color buffer:
Allocation mDepthBuffer;...Type.Builder b = new Type.Builder(mRS, Element.createPixel(mRS, DataType.UNSIGNED_16, DataKind.PIXEL_DEPTH));b.setX(256).setY(256);mDepthBuffer = Allocation.createTyped(mRS, b.create(),Allocation.USAGE_GRAPHICS_RENDER_TARGET);
- Run and use the sample. The smaller, white quad on the top-left corner is using the framebuffer object as a texture, which renders the same scene as the main rendering.
- android graphics
- android--graphics
- android graphics
- Android Graphics
- Android graphics
- android Graphics
- android.graphics
- android Graphics
- android.graphics(三)graphics
- android-android.graphics.Camera
- android graphics related modules
- Android Graphics System-1
- android.graphics.Camera解读
- android.graphics.Typeface实践
- android.graphics.Movie
- Android-----Graphics-----Xfermode
- android.graphics.Bitmap 一
- android.graphics.Bitmap 二
- 黑马程序员_Java反射机制
- 理解项目编辑器---part2:编辑事件
- 我的config 配置
- ORACLE-Kill 杀死正在执行的Oracle存储过程和死锁语句
- Jquery UI的日历控件datepicker限制日期
- android--graphics
- 皮肤保养牢记8件小事
- 关于虚析构函数的意义以及operator new与operator delete
- shell 重定向
- 探索ORACLE之RMAN_03一致性备份
- Linux 定时执行 PHP 文件
- linux下C语言多线程编程实例
- 枚举类型
- centOS root密码忘记怎么办?