`

【翻译】(79)Renderscript之图形

 
阅读更多

【翻译】(79)Renderscript之图形

 

see

http://developer.android.com/guide/topics/renderscript/graphics.html

 

原文见

http://developer.android.com/guide/topics/renderscript/graphics.html

 

-------------------------------

 

Graphics

 

Renderscript之图形

 

-------------------------------

 

In this document

 

目录

 

* Creating a Graphics Renderscript 创建一个图形Renderscript

* Creating the Renderscript file 创建Renderscript文件

* Creating the Renderscript entry point class 创建Renderscript入口点类

* Creating the view class 创建视图类

* Creating the activity class 创建活动类

* Drawing 绘画

* Simple drawing 简单绘画

* Drawing with a mesh 用网格绘画

* Shaders 着色器

* Shader bindings 着色器绑定

* Defining a sampler 定义采样器

* Rendering to a Framebuffer Object 渲染到一个帧缓冲对象

 

Related Samples 

 

相关示例

 

* Balls 球

* Fountain 喷泉

* FountainFbo 喷泉帧缓冲对象(注:Fbo是Framebuffer Object的缩写)

* Hello World 你好世界

* Misc Samples 杂项(注:miscellaneous)示例

 

-------------------------------

 

Renderscript provides a number of graphics APIs for rendering, both at the Android framework level as well as at the Renderscript runtime 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 let you draw the actual meshes to render your scene. You need to be familiar with both APIs to appropriately render graphics on an Android-powered device.

 

Renderscript提供一些用于渲染的图形API,在Android框架层也在Renderscript运行时层。例如,Android框架API让你创建网格和定义着色器以定制图形渲染管线。原生Renderscript图形API让你绘画实际网格以渲染你的场景。你需要熟悉两套API以正确地在基于Android的设备上渲染图形。

 

-------------------------------

 

Creating a Graphics Renderscript

 

创建一个图形Renderscript

 

Renderscript applications require various layers of code, so it is useful to create the following files to help keep your application organized:

 

Renderscript应用程序需要各种代码层,所以创建以下文件以帮助维持你的应用程序被组织好是有用的。

 

The Renderscript .rs file

 

Renderscript的.rs文件

 

This file contains the logic to do the graphics rendering.

 

此文件包含执行图形渲染的逻辑。

 

The Renderscript entry point .java class

 

Renderscript入口点.java类

 

This class allows the view class to interact with the code defined in the .rs file. This class contains a Renderscript object (instance of ScriptC_renderscript_file), which allows your Android framework code to call the Renderscript code. In general, this class does much of the setup for Renderscript such as shader and mesh building and memory allocation and binding. The SDK samples follow the convention of naming this file ActivityRS.java, where Activity is the name of your main activity class.

 

此类允许视图类与定义在.rs文件中的代码交互。此类包含一个Renderscript对象(ScriptC_renderscript_file的实例),它允许你的Android框架代码调用Renderscript代码。通常,此类为Renderscript执行很多配置诸如着色器与网格的构建和内存的分配与绑定。SDK示例遵循命名这个文件为ActivityRS.java的约定,其中Activity(注:指ActivityRS.java中的Activity)是你的主活动类的名称。

 

The view .java class

 

视图的.java类

 

This class extends RSSurfaceView or RSTextureView to provide a surface to render on. A RSSurfaceView consumes a whole window, but a RSTextureView allows you to draw Renderscript graphics inside of a view and add it to a ViewGroup alongside other views. In this class, you create a RenderScriptGL context object with a call to RSSurfaceView.createRenderscriptGL() or RSTextureView.createRenderscriptGL(). The RenderScriptGL context object contains information about the current rendering state of Renderscript such as the vertex and fragment shaders. You pass this context object to the Renderscript entry point class, so that class can modify the rendering context if needed and bind the Renderscript code to the context. Once bound, the view class can use the Renderscript code to display graphics. The view class should also implement callbacks for events inherited from View, such as onTouchEvent() and onKeyDown() if you want to detect these types of user interactions. The SDK samples follow the convention of naming this file ActivityView.java, where Activity is the name of your main activity class

 

这个类扩展自RSSurfaceView或RSTextureView以提供一个所渲染在的表面。RSSurfaceView消耗整个窗口,但RSTextureView允许你在一个视图内渲染Renderscript图形并且添加它到一个ViewGroup在其它视图旁边。在这个类中,你使用一个对RSSurfaceView.createRenderscriptGL()或RSTextureView.createRenderscriptGL()的调用来创建一个RenderScriptGL上下文对象。RenderScriptGL上下文对象包含关于Renderscript的当前渲染状态的信息,诸如顶点和片断(注:fragment也可以翻译为片段,为了区别这里翻译为片断)着色器。你传递这个上下文对象给Renderscript入口点类,所以如果需要的话那个类可以修改渲染上下文并绑定Renderscript代码到上下文。一旦被绑定,视图类可以使用Renderscript代码来显示图形。该视图类还应该为继承自View的事件实现回调,诸如onTouchEvent()和onKeyDown(),如果你想检测这些用户交互的类型。SDK示例遵循命名这个文件为ActivityView.java的约定,这里Activity(注:指ActivityView.java中的Activity)是你的主活动类的名称。

 

The activity .java class

 

活动的.java类

 

This class is the main activity class and sets your RSSurfaceView as the main content view for this activity or uses the RSTextureView alongside other views.

 

这个类是主活动类并设置你的RSSurfaceView作为这个活动的主内容视图或在其它视图旁边使用RSTextureView。

 

Figure 1 describes how these classes interact with one another in a graphics Renderscript:

 

图1描述在一个图形Renderscript中这些类如何相互交互:

 

-------------------------------

 

(图略:

1. Android框架(左图)

活动 

 

--o(连线,圆圈) 

 

RSSurfaceView或RsTextureView

        (包含)RenderscriptGL上下文

 

--(连线,圆圈)

 

bindRootScript()

 

--(连线,圆圈,至“Renderscript对象”)

 

Renderscript入口点

(包含)Renderscript对象

--(连线,圆圈,至“图形Renderscript”)

 

2. Renderscript运行时层(右图)

 

图形Renderscript(.rs)

 

-->

 

Renderscript图形引擎

 

 

Figure 1. Graphics Renderscript overview

 

图1. 图形Renderscript概览

 

-------------------------------

 

The following sections describe how to create an application that uses a graphics Renderscript by using the Renderscript Fountain sample that is provided in the SDK as a guide (some code has been modified from its original form for simplicity).

 

以下章节通过使用在SDK中提供的作为指引的Renderscript喷泉示例来描述如何创建一个使用图形Renderscript的应用程序(出于简化,一些代码已经修改自它原来的形式)。

 

Creating the Renderscript file

 

创建Renderscript文件

 

Your Renderscript code resides in .rs and .rsh (headers) files in the <project_root>/src/ directory. This code contains the logic to render your graphics and declares all other necessary items such as variables, structs, and pointers. Every graphics .rs file generally contains the following items:

 

你的Renderscript代码位于<project_root>/src/目录中的.rs和.rsh(头文件)文件里。这个代码包含用于渲染你的图形的逻辑并且声明其它所有必需的条目诸如变量、struct、和指针。每个图形.rs文件通常包含以下条目:

 

* A pragma declaration (#pragma rs java_package_name(package.name)) that declares the package name of the .java reflection of this Renderscript.

 

* 一个pragma声明(#pragma rs java_package_name(package.name)),它声明这个Renderscript的.java反射的包名。

 

* A pragma declaration (#pragma version(1)) that declares the version of Renderscript that you are using (1 is the only value for now).

 

* 一个pragma声明(#pragma version(1)),它声明你正在使用的Renderscript版本(目前1是唯一的值)。

 

* A #include "rs_graphics.rsh" declaration.

 

* 一个#include "rs_graphics.rsh"声明。

 

* A root() function. This is the main worker function for your Renderscript and calls Renderscript graphics functions to render scenes. This function is called every time a frame refresh occurs, which is specified as its return value. A 0 (zero) 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.

 

* 一个root()函数。它是你的Renderscript的主工作者函数并且调用Renderscript图形函数来渲染场景。每当一个帧刷新发生时此函数被调用,它(注:指帧刷新)被指定作为它的返回值。指定一个0(零)为返回值表示仅当你正在渲染的场景的一个属性改变时才渲染帧。一个非零正整数指示每毫秒的帧刷新率。

 

-------------------------------

 

Note: 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 20, the Renderscript runtime renders the wallpaper at 50fps if it has just enough or more resources to do so. It renders as fast as it can if not enough resources are available.

 

注意:Renderscript运行时尽它最大努力以指定的速率(注:频率,帧率)刷新帧。例如,如果你正在创建一个动态壁纸和设置返回值为20,那么Renderscript运行时以50fps(注:frames per second,帧率)渲染壁纸,如果它正好拥有足够或更多的资源来做这件事。它尽它可能地渲染,如果没有足够资源是可用的。

 

-------------------------------

 

For more information on using the Renderscript graphics functions, see the Drawing section.

 

想获得关于使用Renderscript图形函数的更多信息,请参见绘画章节。

 

* An init() function. This allows you to do initialization of your Renderscript before the root() function runs, such as assigning values to variables. This function runs once and is called automatically when the Renderscript starts, before anything else in your Renderscript. Creating this function is optional.

 

* 一个init()函数。它允许你在root()函数运行前执行你的Renderscript的初始化,诸如赋值给变量。这个函数运行一次并且在Renderscript开始时你的Renderscript中其它任何事情执行之前被自动地调用。创建此函数是可选的。

 

* Any variables, pointers, and structures that you wish to use in your Renderscript code (can be declared in .rsh files if desired)

 

* 任何你希望在你的Renderscript代码中使用的变量、指针和结构体(可以被声明在.rsh文件如果它们是所期望的)

 

The following code shows how the fountain.rs file is implemented:

 

以下代码展示fountain.rs文件是如何被实现的:

 

-------------------------------

 

#pragma version(1)

 

// Tell which java package name the reflected files should belong to

// 告诉反射文件应该属于哪个java包名

#pragma rs java_package_name(com.example.android.rs.fountain)

 

//declare shader binding

//声明着色器绑定

#pragma stateFragment(parent)

 

// header with graphics APIs, must include explicitly

// 带图形API的头文件,必须显式地包含

#include "rs_graphics.rsh"

 

static int newPart = 0;

 

// the mesh to render

// 要渲染的网格

rs_mesh partMesh;

 

// the point representing where a particle is rendered

// 代表一个粒子被渲染在哪里的点

typedef struct __attribute__((packed, aligned(4))) Point {

    float2 delta;

    float2 position;

    uchar4 color;

} Point_t;

Point_t *point;

 

// main worker function that renders particles onto the screen

// 主工作者函数,它渲染粒子到屏幕上

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++;

    }

 

    rsgDrawMesh(partMesh);

    return 1;

}

 

// adds particles to the screen to render

// 添加粒子到屏幕以渲染

static float4 partColor[10];

void addParticles(int rate, float x, float y, int index, bool newColor)

{

    if (newColor) {

        partColor[index].x = rsRand(0.5f, 1.0f);

        partColor[index].y = rsRand(1.0f);

        partColor[index].z = rsRand(1.0f);

    }

    float rMax = ((float)rate) * 0.02f;

    int size = rsAllocationGetDimX(rsGetAllocation(point));

    uchar4 c = rsPackColorTo8888(partColor[index]);

 

    Point_t * np = &point[newPart];

    float2 p = {x, y};

    while (rate--) {

        float angle = rsRand(3.14f * 2.f);

        float len = rsRand(rMax);

        np->delta.x = len * sin(angle);

        np->delta.y = len * cos(angle);

        np->position = p;

        np->color = c;

        newPart++;

        np++;

        if (newPart >= size) {

            newPart = 0;

            np = &point[newPart];

        }

    }

}

 

-------------------------------

 

Creating the Renderscript entry point class

 

创建Renderscript入口点类

 

When you create a Renderscript (.rs) file, it is helpful to create a corresponding Android framework class that is an entry point into the .rs file. The most important thing this class does is receive a RenderScriptGL rendering context object from the view class and binds the actual Renderscript code to the rendering context. This notifies your view class of the code that it needs to render graphics.

 

当你创建一个Renderscript(.rs)文件时,创建一个相应的Android框架类是有用的,它是进入.rs文件的一个入口点。此类做的最重要事情是从视图类中接收一个RenderscriptGL渲染上下文对象并且绑定实际的Renderscript代码到渲染上下文。它通知你的视图类它需要用来渲染图形的代码。

 

In addition, this class should contain all of the things needed to set up Renderscript. Some important things that you need to do in this class are:

 

另外,此类应该包含用来设置Renderscript需要的所有东西。在这个类中你需要做的一些重要事情有:

 

* Create a Renderscript object ScriptC_rs_filename. The Renderscript object is attached to the Renderscript bytecode, which is platform-independent and gets compiled on the device when the Renderscript application runs. The bytecode is referenced as a raw resource and is passed into the constructor for the Renderscript object. For example, this is how the Fountain sample creates the Renderscript object:

 

* 创建一个Renderscript对象ScriptC_rs_filename。Renderscript对象被依附到Renderscript字节码,它是平台独立的并且当Renderscript应用程序运行时在设备上被编译。字节码被引用作为一个原始资源并且被传递进Renderscript对象的构造函数。例如,这是喷泉示例如何创建Renderscript对象:

 

-------------------------------

 

  RenderScriptGL rs;  //obtained from the view class 从视图类中取出

  Resources res;      //obtained from the view class 从视图类中取出

  ...

  ScriptC_fountain mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);

 

-------------------------------

 

* Allocate any necessary memory and bind it to your Renderscript code via the Renderscript object.

 

* 分配任意必需的内存并且通过Renderscript对象绑定它到你的Renderscript代码。

 

* Build any necessary meshes and bind them to the Renderscript code via the Renderscript object.

 

* 构建任意必需的网格并且通过Renderscript对象绑定它们到Renderscript代码。

 

* Create any necessary programs and bind them to the Renderscript code via the Renderscript object.

 

* 创建任意必需的程序并且通过Renderscript对象绑定它们到Renderscript代码。

 

The following code shows how the FountainRS class is implemented:

 

以下代码展示FountainRS类是如何被实现的:

 

-------------------------------

 

package com.example.android.rs.fountain;

 

import android.content.res.Resources;

import android.renderscript.*;

import android.util.Log;

 

public class FountainRS {

    public static final int PART_COUNT = 50000;

 

    public FountainRS() {

    }

 

    /**

     * This provides us with the Renderscript context and resources

     * that allow us to create the Renderscript object

     * 它提供我们Renderscript上下文和资源,它们允许我们创建Renderscript对象

     */

    private Resources mRes;

    private RenderScriptGL mRS;

 

    // Renderscript object

    // Renderscript对象

    private ScriptC_fountain mScript;

 

    // Called by the view class to initialize the Renderscript context and renderer

    // 被视图类调用以初始化Renderscript上下文和渲染器

    public void init(RenderScriptGL rs, Resources res) {

        mRS = rs;

        mRes = res;

 

        /**

         * Create a shader and bind to the Renderscript context

         * 创建一个着色器并绑定到Renderscript上下文

         */

        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);

        pfb.setVaryingColor(true);

        rs.bindProgramFragment(pfb.create());

 

        /**

         * Allocate memory for the particles to render and create the mesh to draw

         * 为粒子分配内存以渲染和创建要绘画的网格

         */

        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();

 

       /**

        * Create and bind the Renderscript object to the Renderscript context

        * 创建和绑定Renderscript对象到Renderscript上下文

        */

        mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);

        mScript.set_partMesh(sm);

        mScript.bind_point(points);

        mRS.bindRootScript(mScript);

    }

 

    boolean holdingColor[] = new boolean[10];

 

    /**

     * Calls Renderscript functions (invoke_addParticles)

     * via the Renderscript object to add particles to render

     * based on where a user touches the screen.

     * 通过Renderscript对象调用Renderscript函数(invoke_addParticles)

     * 来添加要渲染的粒子,基于用户在哪里触碰屏幕。

     */

    public void newTouchPosition(float x, float y, float pressure, int id) {

        if (id >= holdingColor.length) {

            return;

        }

        int rate = (int)(pressure * pressure * 500.f);

        if (rate > 500) {

            rate = 500;

        }

        if (rate > 0) {

            mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);

            holdingColor[id] = true;

        } else {

            holdingColor[id] = false;

        }

 

    }

}

 

-------------------------------

 

Creating the view class

 

创建视图类

 

To display graphics, you need a view to render on. Create a class that extends RSSurfaceView or RSTextureView. This class allows you to create a RenderScriptGL context object by calling and pass it to the Rendscript entry point class to bind the two. Once bound, the content is aware of the code that it needs to use to render graphics with. If your Renderscript code depends on any type of information that the view is aware of, such as touches from the user, you can also use this class to relay that information to the Renderscript entry point class. The following code shows how the FountainView class is implemented:

 

为了显示图形,你需要一个视图来渲染。创建一个扩展自RSSurfaceView或RSTextureView的类。这个类允许你通过调用创建一个RenderScriptGL上下文对象,并且传递它给Rendscript入口点类以绑定两者。一旦被绑定,上下文知道了它需要用来渲染图形的代码。如果你的Renderscript代码依赖于视图知道的任意类型的信息,诸如来自用户的触碰,你还可以使用此类来中转那些信息给Renderscript入口点类。以下代码展示FountainView类是如何被实现的:

 

-------------------------------

 

package com.example.android.rs.fountain;

 

import android.renderscript.RSTextureView;

import android.renderscript.RenderScriptGL;

import android.content.Context;

import android.view.MotionEvent;

 

public class FountainView extends RSTextureView {

 

    public FountainView(Context context) {

        super(context);

    }

    // Renderscript context

    // Renderscript上下文

    private RenderScriptGL mRS;

    // Renderscript entry point object that calls Renderscript code

    // 调用Renderscript代码的Renderscript入口点对象

    private FountainRS mRender;

 

    /**

     * Create Renderscript context and initialize Renderscript entry point

     * 创建Renderscript上下文并初始化Renderscript入口点

     */

    @Override

    protected void onAttachedToWindow() {

        super.onAttachedToWindow();

        android.util.Log.e("rs", "onAttachedToWindow");

        if (mRS == null) {

            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();

            mRS = createRenderScriptGL(sc);

            mRender = new FountainRS();

            mRender.init(mRS, getResources());

        }

    }

 

    @Override

    protected void onDetachedFromWindow() {

        super.onDetachedFromWindow();

        android.util.Log.e("rs", "onDetachedFromWindow");

        if (mRS != null) {

            mRS = null;

            destroyRenderScriptGL();

        }

    }

 

 

    /**

     * Use callbacks to relay data to Renderscript entry point class

     * 使用活动来中转数据给Renderscript入口点类

     */

    @Override

    public boolean onTouchEvent(MotionEvent ev)

    {

        int act = ev.getActionMasked();

        if (act == ev.ACTION_UP) {

            mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));

            return false;

        } else if (act == MotionEvent.ACTION_POINTER_UP) {

            // only one pointer going up, we can get the index like this

            // 只有一个指针(注:鼠标)弹起,我们可以想这样获取该索引

            int pointerIndex = ev.getActionIndex();

            int pointerId = ev.getPointerId(pointerIndex);

            mRender.newTouchPosition(0, 0, 0, pointerId);

        }

        int count = ev.getHistorySize();

        int pcount = ev.getPointerCount();

 

        for (int p=0; p < pcount; p++) {

            int id = ev.getPointerId(p);

            mRender.newTouchPosition(ev.getX(p),

                                     ev.getY(p),

                                     ev.getPressure(p),

                                     id);

 

            for (int i=0; i < count; i++) {

                mRender.newTouchPosition(ev.getHistoricalX(p, i),

                                         ev.getHistoricalY(p, i),

                                         ev.getHistoricalPressure(p, i),

                                         id);

            }

        }

        return true;

    }

}

 

-------------------------------

 

Creating the activity class

 

创建活动类

 

Applications that use Renderscript still behave like normal Android applications, so you need an activity class that handles activity lifecycle callback events appropriately. The activity class also sets your RSSurfaceView view class to be the main content view of the activity or uses your RSTextureView in a ViewGroup alongside other views.

 

使用Renderscript的应用程序仍然像正常Android应用程序那样行为,所以你需要一个正确地处理活动生命周期回调事件的活动类。该活动类还设置你的RSSurfaceView视图类作为活动的主内容视图或在一个ViewGroup中在其它视图旁使用你的RSTextureView。

 

The following code shows how the Fountain sample declares its activity class:

 

以下代码展示喷泉示例如何声明它的活动类:

 

-------------------------------

 

package com.example.android.rs.fountain;

 

import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

 

public class Fountain extends Activity {

 

    private static final String LOG_TAG = "libRS_jni";

    private static final boolean DEBUG  = false;

    private static final boolean LOG_ENABLED = false;

 

    private FountainView mView;

 

    @Override

    public void onCreate(Bundle icicle) {

        super.onCreate(icicle);

 

        // Create our Preview view and set it as 

        // the content of our activity

        // 创建我们的预览视图并设置它作为

        // 我们的活动的内容

        mView = new FountainView(this);

        setContentView(mView);

    }

 

    @Override

    protected void onResume() {

        Log.e("rs", "onResume");

 

        // Ideally a game should implement onResume() and onPause()

        // to take appropriate action when the activity looses focus

        // 理论上一个游戏应该实现onResume()和onPause()

        // 来采取正确的动作,当活动失去焦点时

        super.onResume();

        mView.resume();

    }

 

    @Override

    protected void onPause() {

        Log.e("rs", "onPause");

 

        // Ideally a game should implement onResume() and onPause()

        // to take appropriate action when the activity looses focus

        // 理论上一个游戏应该实现onResume()和onPause()

        // 来采取正确的动作,当活动失去焦点时

        super.onPause();

        mView.pause();

 

    }

 

    static void log(String message) {

        if (LOG_ENABLED) {

            Log.v(LOG_TAG, message);

        }

    }

}

 

-------------------------------

 

Now that you have an idea of what is involved in a Renderscript graphics application, you can start building your own. It might be easiest to begin with one of the Renderscript samples as a starting point if this is your first time using Renderscript.

 

现在你知道在Renderscript图形应用程序涉及什么,你可以开始构建你自己的应用程序。从一个Renderscript示例开始作为起点可能是最简单的,如果这是你第一次使用Renderscript。

 

-------------------------------

 

Drawing

 

绘画

 

The following sections describe how to use the graphics functions to draw with Renderscript.

 

以下章节描述如何使用图形函数以使用Renderscript绘画。

 

Simple drawing

 

简单绘画

 

The native Renderscript APIs provide a few convenient functions to easily draw a polygon or text to the screen. You call these in your root() function to have them render to the RSSurfaceView or RSTextureView. These functions are available for simple drawing and should not be used for complex graphics rendering:

 

原生Renderscript的API提供一些便利函数以简单地绘画一个多边形或文本到屏幕。你在你的root()函数中调用这些函数以让它们渲染到RSSurfaceView或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.

 

* rsgDrawRect():设置一个网格并绘画一个矩形到屏幕。它使用矩形的左上角顶点和右下角顶点来绘画。

 

* rsgDrawQuad(): Sets up a mesh and draws a quadrilateral to the screen.

 

* rsgDrawQuad():设置一个网格并绘画一个四边形到屏幕。

 

* rsgDrawQuadTexCoords(): Sets up a mesh and draws a quadrilateral to the screen using the provided coordinates of a texture.

 

* rsgDrawQuadTexCoords():设置一个网格并绘画一个四边形到屏幕,使用提供的纹理坐标。

 

* rsgDrawText(): Draws specified text to the screen. Use rsgFontColor() to set the color of the text.

 

* rsgDrawText():绘画指定文本到屏幕。使用rsgFontColor()来设置文本颜色。

 

Drawing with a mesh

 

用网格绘画

 

When you want to render complex scenes to the screen, instantiate a Mesh and draw it with rsgDrawMesh(). A Mesh is a collection of allocations that represent vertex data (positions, normals, texture coordinates) and index data that provides information on how to draw triangles and lines with the provided vertex data. You can build a Mesh in three different ways:

 

当你想渲染一些复杂场景到屏幕,实例化一个Mesh(注:网格)并用rsgDrawMesh()绘画它。一个Mesh是一些分配的一个集合,它代表顶点数据(位置、法线、纹理坐标)以及提供关于如何使用提供的顶点数据绘画三角形和线的信息的索引数据。你可以用三种不同的方式构建一个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.

 

* 用Mesh.TriangleMeshBuilder类构建网格,它允许你指定每个你想绘画的每个矩形的一组顶点和索引。

 

* Build the mesh using an Allocation or a set of Allocations with the Mesh.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.

 

* 使用带Mesh.AllocationBuilder类的一个Allocation或一组Allocation来构建网格。这种方法允许你用已经存储在内存中的顶点构建一个网格,它允许你在Renderscript或Android框架代码中指定顶点。

 

* 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 with Mesh.AllocationBuilder. You can specify the types that you want and this mesh builder automatically creates the memory allocations for you.

 

* 使用Mesh.Builder类构建网格。你应该使用这个便利方法,当你知道你想使用来构建你的网格的数据类型,但不想想使用Mesh.AllocationBuilder那样作出分离的内存分配的时候。你可以指定你想要的类型,而这个网格构建器自动地为你创建内存分配。

 

To create a mesh using the 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 addTriangle() draws the triangle with vertex 0, 1, and 2 (the vertices are drawn counter-clockwise).

 

为了使用Mesh.TriangleMeshBuilder创建一个网格,你需要提供给它一组顶点和组成三角形的顶点的索引。例如,以下代码指定三个顶点,它们被添加到一个内部数组,根据它们被添加的次序被索引。对addTriangle()的调用使用顶点0,1或2绘画三角形(顶点被逆时针地绘画)(注:这里的“逆时针”可能是用来表示这个三角形的法线方向是哪边)。

 

-------------------------------

 

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);

 

-------------------------------

 

To draw a mesh using the Mesh.AllocationBuilder, you need to supply it with one or more allocations that contain the vertex data:

 

为了使用Mesh.AllocationBuilder绘画一个网格,你需要提供给它一个或多个包含顶点数据的分配:

 

-------------------------------

 

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:

 

在你的Renderscript代码中,绘画构建的网格到屏幕:

 

-------------------------------

 

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.

          //指定一个非0正整数以指定帧刷新。

          //0表示刷新帧仅当网格改变时。

}

 

-------------------------------

 

-------------------------------

 

Programs

 

程序

 

You can attach four program objects to the RenderScriptGL context to customize the rendering pipeline. For example, you can create vertex and fragment shaders in GLSL or build a raster program object that controls culling. The four programs mirror a traditional graphical rendering pipeline:

 

你可以依附四个程序对象到RenderScriptGL上下文以定制渲染管线。例如,你可以用GLSL(注:GLSL,OpenGL Shading Language,OpenGL着色语言,也被称为GLslang,一种以C语言为基础的高阶着色语言)创建顶点和片断着色器或构建一个控制剔除(注:参考wiki的Viewing frustum)的光栅程序对象。这四个程序映射一条传统的图形渲染管线:

 

-------------------------------

 

* Android Object Type Renderscript Native Type Description

 

* Android对象类型 Renderscript原生类型 描述

 

* ProgramVertex rs_program_vertex

 

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:

 

Renderscript顶点程序,也被称为顶点着色器,它描述图形管线中负责用一种用户定义的方式操纵几何数据的阶段。通过提供带以下数据的Renderscript来构造该对象:

 

* An Element describing its varying inputs or attributes

 

* 一个描述其正在改变的输入或属性的Element。

 

* GLSL shader string that defines the body of the program

 

* 定义程序主体的GLSL着色器字符串

 

* a Type that describes the layout of an Allocation containing constant or uniform inputs

 

* 一个描述一个Allocation的布局的Type,包含常量或统一的输入。

 

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.

 

一旦该程序被创建,请通过调用bindProgramVertex()绑定它到RenderScriptGL图形上下文。然后它被用于所有随后的绘画调用,直至你绑定一个新的程序。如果该程序拥有常量输入,那么用户需要绑定一个包含那些输入的分配。该分配的类型必须匹配在创建期间提供的分配类型(注:待考)。

 

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.

 

然后Renderscript运行时做所有必需的探索以发送那些常量到图形硬件。对着色器的变化的输入,诸如位置、法线和纹理坐标在输入Element和正在被绘画的网格对象之间通过名称被匹配。签名不必是准确的或按任意严格的次序。只要在着色器中输入名称匹配一个通道名称和网格上可用的大小,Renderscript运行时处理两者的连接。不像OpenGL那样,没有必要链接顶点和片断程序。

 

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 the struct to the hardware when necessary. To update shader constants, you change the values in the Allocation and notify the Renderscript code of the change.

 

绑定着色器常量到该程序,声明一个struct包含你的Renderscript代码中必需的着色器常量。这个struct被生成进一个反射类,你可以使用它作为程序的创建期间的一个常量输入元素。它是创建这个struct的一个实例作为一个分配的一种简单方式。然后,你将绑定这个Allocation到程序,并且在必要时Renderscript运行时把包含在struct中的数据发送到硬件。为了更新着色器常量,你改变Allocation中的值并且把改变通知给Renderscript代码。

 

The ProgramVertexFixedFunction.Builder class also lets you build a simple vertex shader without writing GLSL code.

 

ProgramVertexFixedFunction.Builder类还让你在不写入GLSL代码的情况下构建一个简单顶点着色器。

 

* ProgramFragment rs_program_fragment

 

The 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.

 

Renderscript片断程序,也被称为一个片断着色器,是负责以一种用户定义的方式操纵像素数据。它从一个GLSL着色器字符串中被构造,它包含程序体,纹理输入,和一个描述程序使用的常量的Type对象。像顶点程序那样,当一个带有常量输入值的Allocation被绑定到着色器时,它的值被自动地发送到图形程序。注意Allocation内的值不被显式地跟踪。如果它们在两次绘画调用之间使用相同的程序对象来改变,请通过调用rsgAllocationSyncAll()把那个改变通知给运行时,那样它可以发送新的值给硬件。顶点和片断程序之间的通信内部地在GLSL代码中被处理。例如,如果片断程序正在期待一个被称为varTex0的变化输入,那么在程序顶点内的GLSL代码必须提供它。

 

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 the struct to the hardware when necessary. To update shader constants, you change the values in the Allocation and notify the Renderscript code of the change.

 

为了绑定着色器构造到程序,声明一个包含你的Renderscript代码中必要着色器常量的struct。这个struct被生成进一个你可以使用的反射类作为程序创建期间的一个常量输入元素。这是一种简单的方式以创建这个struct的一个实例作为一个分配。然后,你将绑定这个Allocation到该程序,而在必要时Renderscript运行时把包含在struct中的数据发送到硬件。为了更新着色器常量,你改变Allocation中的值并且把改变通知给Renderscript代码。

 

The ProgramFragmentFixedFunction.Builder class also lets you build a simple fragment shader without writing GLSL code.

 

ProgramFragmentFixedFunction.Builder还让你在不写GLSL代码的情况下构建一个简单的片断着色器。

 

* ProgramStore rs_program_store

 

The 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.

 

Renderscript存储程序包含一组参数,它们控制图形硬件如何写入到帧对象。它可以被用于使能和屏蔽深度写入和测试,配置不同的混合模式以获得像透明的效果,并且为颜色成分(注:分量)定义写入遮罩。

 

* ProgramRaster rs_program_raster

 

The 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.

 

Renderscript光栅程序主要用于指定点精灵是否被使能和控制剔除模式。默认背面(注:被遮挡的面,背割面,后端面)被剔除。

 

-------------------------------

 

The following example defines a vertex shader in GLSL and binds it to a Renderscript context object:

 

以下示例用GLSL定义一个顶点着色器并且绑定它到一个Renderscript上下文对象:

 

-------------------------------

 

    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.

 

RsRenderStatesRS示例拥有关于如何在不写GLSL的情况下创建一个着色器的许多例子。

 

Program bindings

 

程序绑定

 

You can also declare four pragmas that control default program bindings to the RenderScriptGL context when the script is executing:

 

你还可以声明四个pragma,它们控制对RenderScriptGL上下文的默认程序绑定,当脚本正在执行时:

 

* stateVertex

* stateFragment

* stateRaster

* stateStore

 

The possible values for each pragma are parent or default. Using default binds the shaders to the graphical context with the system defaults.

 

每个pragma的可能值是parent或default的。使用default会使用系统默认值绑定着色器到图形上下文。

 

Using parent 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 RenderScriptGL bind methods.

 

使用parent则以与它在调用方脚本中被绑定的相同方式来绑定着色器。如果它是根脚本,那么父级状态从RenderScriptGL绑定方法设置的绑定点处取得。

 

For example, you can define this at the top of your graphics Renderscript code to have the vertex and store programs inherent the bind properties from their parent scripts:

 

例如,你可以在你的图形Renderscript代码的顶部定义它,以让顶点和存储程序从它们的父级脚本中继承(注:inherent可能是inherit的笔误)绑定属性:

 

-------------------------------

 

#pragma stateVertex(parent)

#pragma stateStore(parent)

 

-------------------------------

 

Defining a sampler

 

定义一个采样器

 

A Sampler object defines how data is extracted from textures. Samplers are bound to a ProgramFragment 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 Renderscript 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.

 

一个采样器对象定义数据如何从纹理中被分离。采样器被绑定到该纹理旁边的一个ProgramFragment,它们控制该纹理的采样。这些对象被用于指定这些东西作为边缘钳位(注:边缘夹紧,夹边。在OpenGL中GL_CLAMP表示超出纹理坐标的区域使用边界颜色代替)行为,是否使用mip-map(注:一种三维贴图渲染技术),以及所需要的各向异性(注:因方向不同而变化的特性。这里应该是指OpenGL中纹理表面反射光的各向异性)数量。可能有一些情况,硬件并不支持期望的采样器行为。在这些情况下,Renderscript运行时尝试提供最接近的可能近似值。例如,用户请求16x(注:“16倍”?)的各向异性,但只被设置为8x,因为它是硬件上可用的最佳值。

 

The RsRenderStatesRS sample has many examples on how to create a sampler and bind it to a Fragment program.

 

RsRenderStatesRS示例拥有许多关于如何创建一个采样器和绑定它到一个Fragment程序(注:片断着色器程序?)的例子。

 

-------------------------------

 

Rendering to a Framebuffer Object

 

渲染到一个帧缓冲对象

 

Framebuffer objects allow you to render offscreen instead of in the default onscreen framebuffer. This approach might be useful for situations where you need to post-process a texture before rendering it to the screen, or when you want to composite two scenes in one such as rendering a rear-view mirror of a car. There are two buffers associated with a framebuffer object: a color buffer and a depth buffer. The color buffer (required) contains the actual pixel data of the scene that you are rendering, and the depth buffer (optional) contains the values necessary to figure out what vertices are drawn depending on their z-values.

 

帧缓冲对象允许你离屏地渲染而非在默认的屏幕上帧缓冲中渲染。这种方法对于这些情况可能有用,你需要后期处理一个纹理,在渲染它到屏幕上之前,或者当你想合成两个场景为一个,诸如渲染一辆汽车的后视镜。有两个缓冲与一个帧缓冲对象关联:一个颜色缓冲和一个深度缓冲。颜色缓冲(必需的)包含你正在渲染的屏幕的实际像素数据,而深度缓冲(可选的)包含必需的值以计算出哪些顶点被绘画,依赖于它们的z值。

 

In general, you need to do the following to render to a framebuffer object:

 

通常,你需要做以下工作以渲染到一个帧缓冲对象:

 

* Create Allocation objects for the color buffer and depth buffer (if needed). Specify the USAGE_GRAPHICS_RENDER_TARGET usage attribute for these allocations to notify the Renderscript runtime to use these allocations for the framebuffer object. For the color buffer allocation, you most likely need to declare the USAGE_GRAPHICS_TEXTURE usage attribute to use the color buffer as a texture, which is the most common use of the framebuffer object.

 

* 创建用于颜色缓冲和深度缓冲的Allocation对象(如果需要的话)。为这些分配指定USAGE_GRAPHICS_RENDER_TARGET的用法属性以通知Renderscript运行时以为该帧缓冲对象使用这些分配。对于颜色缓冲分配,你最有可能需要声明USAGE_GRAPHICS_TEXTURE的用法属性以使用颜色缓冲作为一个纹理,它是帧缓冲最一般的使用。

 

* Tell the Renderscript runtime to render to the framebuffer object instead of the default framebuffer by calling rsgBindColorTarget() and passing it the color buffer allocation. If applicable, call rsgBindDepthTarget() passing in the depth buffer allocation as well.

 

* 告诉Renderscript运行时以渲染到帧缓冲对象而非默认帧缓冲,通过调用rsgBindColorTarget()并传给它颜色缓冲分配。如果可应用的话,还要调用rsgBindDepthTarget()以传递进深度缓冲分配。

 

* Render your scene normally with the rsgDraw functions. The scene will be rendered into the color buffer instead of the default onscreen framebuffer.

 

* 正常地用rsgDraw函数渲染你的场景。场景将被渲染进颜色缓冲而非默认的屏幕上帧缓冲。

 

* When done, tell the Renderscript runtime stop rendering to the color buffer and back to the default framebuffer by calling rsgClearAllRenderTargets().

 

* 当完成时,告诉Renderscript运行时停止渲染到颜色缓冲并通过调用rsgClearAllRenderTargets()返回到(注:渲染回到)默认帧缓冲。

 

* Create a fragment shader and bind a the color buffer to it as a texture.

 

* 创建一个片断着色器并且绑定一个颜色缓冲到它作为一个纹理。

 

* Render your scene to the default framebuffer. The texture will be used according to the way you setup your fragment shader.

 

* 渲染你的场景到默认的帧缓冲。将依照你配置你的片断着色器的方式来使用纹理。

 

The following example shows you how to render to a framebuffer object by modifying the Fountain Renderscript sample. The end result is the FountainFBO sample. The modifications render the exact same scene into a framebuffer object as it does the default framebuffer. The framebuffer object is then rendered into the default framebuffer in a small area at the top left corner of the screen.

 

以下示例向你展示如何通过修改喷泉Renderscript示例来渲染一个帧缓冲对象。最后的结构是FountainFBO示例。修改版把与渲染进默认帧缓冲的完全相同的场景渲染进一个帧缓冲对象。然后帧缓冲对象被渲染进屏幕左上角的一个小区域中的默认帧缓冲。

 

1. 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.

 

修改fountain.rs并添加以下全局变量。它创建set方法,当这个文件被反射进一个.java文件,允许你在你的Android框架代码中分配内存并绑定它到Renderscript运行时。

 

-------------------------------

 

//allocation for color buffer

//用于颜色缓冲的分配

rs_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;

 

-------------------------------

 

2. Modify the root function of fountain.rs to look like the following code. The modifications are commented:

 

2. 把fountain.rs的root函数修改到看起来像以下代码。修改部分被注释:

 

-------------------------------

 

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

    //告诉Renderscript运行时渲染帧缓冲对象

    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

    //当完成时,告诉Renderscript运行时停止渲染到帧缓冲对象

    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

    //在槽0上绑定帧缓冲对象到帧着色器作为一个纹理

    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;

}

 

-------------------------------

 

3. In the FountainRS.java file, modify the init() method to look like the following code. The modifications are commented:

 

3. 在FountainRS.java文件中,把init()方法修改到看起来像以下代码。修改部分被注释:

 

-------------------------------

 

/* 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 */

    /* 在Renderscript运行时中设置片断着色器 */

    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 */

    /* 在Renderscript运行时中设置分配 */

    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);

 

-------------------------------

 

4. 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.

 

4. 运行并使用该示例。较小的,在左上角的白色四边形正在使用帧缓冲对象作为一个纹理,它渲染相同的场景作为主要渲染。

 

Except as noted, this content is licensed under Apache 2.0. For details and restrictions, see the Content License.

 

除特别说明外,本文在Apache 2.0下许可。细节和限制请参考内容许可证。

 

Android 4.0 r1 - 02 Apr 2012 19:36

 

-------------------------------

 

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

 

此页部分内容,是基于Android开源项目所创建和共享的工作,并且根据知识共享2.5署名许可证描述的条款来使用的修改版。

 

(本人翻译质量欠佳,请以官方最新内容为准,或者参考其它翻译版本:

* ソフトウェア技術ドキュメントを勝手に翻訳

http://www.techdoctranslator.com/android

* Ley's Blog

http://leybreeze.com/blog/

* 农民伯伯

http://www.cnblogs.com/over140/

* Android中文翻译组

http://androidbox.sinaapp.com/


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics