这篇主要是关于Android RenderScript 的使用。

RenderScript简介:RenderScript是Android平台的一种类C脚本语言,Google虽然一直在之前的各个Android版本内置的动态墙纸中使用该技术实现3D图形特效,但一直未将其集成在公开发布的SDK中。至Android3.0版本开始,SDK中已将RenderScript技术集成了进来,开发者可在Eclipse下开发基于RenderScript的3D应用,并在Android3.0版本以上的平板电脑中运行。

SDK链接:http://developer.android.com/guide/topics/renderscript/index.html

要使用Renderscript渲染功能,需要实现的功能如下:

fall.rs实现RenderScript的代码,是水波纹效果实现的关键代码(但关于.rs文件的资料少之又少,希望今后会多起来)

FallRS.java .rs文件的辅助类,用以简化操作fall.rs文件
FallView.java 一个继承于RSSurfaceView的类,用于显示RenderScript的渲染或者用来处理用户的触摸等视图

Fall.java 这是一个Activity,Android 应用程序的界面类。

好了先来看fall.rs文件(中文是我加的注释):

// Copyright (C) 2009 The Android Open Source Project//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at////      http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//编译指示声明(#pragma version(1)),声明了要使用的Renderscript的版本(目前只能是1)#pragma version(1)//编译指示声明(#pragma rs java_package_name(package.name)),它声明了该Renderscript反射所对应的*.java类名#pragma rs java_package_name(com.harlan.waterscreen)#include "rs_graphics.rsh"#define LEAVES_TEXTURES_COUNT 8#define LEAF_SIZE 0.55f#define LEAVES_COUNT 14// Things we need to set from the applicationfloat g_glWidth;float g_glHeight;float g_meshWidth;float g_meshHeight;float g_xOffset;float g_rotate;//着色器处理程序类分为4类:ProgramFragment ProgramFragmentStore ProgramVertext Mesh//ProgramFragment对应片断处理程序,对光栅化的每一个片断做独立的处理,包括映射纹理点,混合,着色等。//ProgramFragmentStore主要负责一些跟片断处理相关的辅助功能,如设置混合模式等。//ProgramVertext对应顶点处理程序,对每一个顶点做独立的处理,包括视景投影变换,法线变换等。//Mesh又叫网格,是方便对一组顶点的处理的类。//以上四个类最终都会被调用setupGL或render这样方法,在这些方法中将用户的配置转换为OpenGL的具体操作序列。rs_program_vertex g_PVWater;rs_program_vertex g_PVSky;rs_program_fragment g_PFSky;rs_program_store g_PFSLeaf;rs_program_fragment g_PFBackground;rs_allocation g_TLeaves;rs_allocation g_TRiverbed;rs_mesh g_WaterMesh;//存储类,主要用来进行数据的存储以及和上层java的交换,包括Type,Element,Allocation。Element可以理解为一个结构体。//下面是一个element;Constants是对这个结构体的类型的命名,Constants_t 就是这个Constants。typedef struct Constants {    float4 Drop01;    float4 Drop02;    float4 Drop03;    float4 Drop04;    float4 Drop05;    float4 Drop06;    float4 Drop07;    float4 Drop08;    float4 Drop09;    float4 Drop10;    float4 Offset;    float Rotate;} Constants_t;//这是一个Constants_t的一个实例,是一个Allocation//在RenderScript运行之前,必要的Allocation要分配好,它们可能是定点坐标,可能是纹理,也可能是用户的数据Constants_t *g_Constants;rs_program_store g_PFSBackground;//float skyOffsetX;//float skyOffsetY;static float g_DT;static int64_t g_LastTime;typedef struct Drop {    float ampS;    float ampE;    float spread;    float x;    float y;} Drop_t;static Drop_t gDrops[10];static int gMaxDrops;typedef struct Leaves {    float x;    float y;    float scale;    float angle;    float spin;    float u1;    float u2;    float altitude;    float rippled;    float deltaX;    float deltaY;    int newLeaf;} Leaves_t;static Leaves_t gLeavesStore[LEAVES_COUNT];static Leaves_t* gLeaves[LEAVES_COUNT];static Leaves_t* gNextLeaves[LEAVES_COUNT];void initLeaves() {    Leaves_t *leaf = gLeavesStore;    // globals haven't been set at this point yet. We need to find the correct    // function index to call this, we can wait until reflection works    float width = 2; //g_glWidth;    float height = 3.333; //g_glHeight;    int i;    for (i = 0; i < LEAVES_COUNT; i ++) {        gLeaves[i] = leaf;        int sprite = rsRand(LEAVES_TEXTURES_COUNT);        leaf->x = rsRand(-width, width);        leaf->y = rsRand(-height * 0.5f, height * 0.5f);        leaf->scale = rsRand(0.4f, 0.5f);        leaf->angle = rsRand(0.0f, 360.0f);        leaf->spin = degrees(rsRand(-0.02f, 0.02f)) * 0.25f;        leaf->u1 = (float)sprite / (float) LEAVES_TEXTURES_COUNT;        leaf->u2 = (float)(sprite + 1) / (float) LEAVES_TEXTURES_COUNT;        leaf->altitude = -1.0f;        leaf->rippled = 1.0f;        leaf->deltaX = rsRand(-0.01f, 0.01f);        leaf->deltaY = -rsRand(0.036f, 0.044f);        leaf++;    }}//一个可选的init()方法,在root()方法调用之前做一些初始化工作,如初始化变量等。//这个函数运行一次,并且在Renderscript启动时,Renderscript中其他工作被执行之前,该方法会被自动的调用。void init() {    int ct;    gMaxDrops = 10;    for (ct=0; ct<gMaxDrops; ct++) {        gDrops[ct].ampS = 0;        gDrops[ct].ampE = 0;        gDrops[ct].spread = 1;    }    initLeaves();    g_LastTime = rsUptimeMillis();    g_DT = 0.1f;}static void updateDrop(int ct) {    gDrops[ct].spread += 30.f * g_DT;    gDrops[ct].ampE = gDrops[ct].ampS / gDrops[ct].spread;}static void drop(int x, int y, float s) {    int ct;    int iMin = 0;    float minAmp = 10000.f;    for (ct = 0; ct < gMaxDrops; ct++) {        if (gDrops[ct].ampE < minAmp) {            iMin = ct;            minAmp = gDrops[ct].ampE;        }    }    gDrops[iMin].ampS = s;    gDrops[iMin].spread = 0;    gDrops[iMin].x = x;    gDrops[iMin].y = g_meshHeight - y - 1;    updateDrop(iMin);}//绘制水波纹涟漪static void generateRipples() {    int ct;    for (ct = 0; ct < gMaxDrops; ct++) {        Drop_t * d = &gDrops[ct];        float *v = (float*)&g_Constants->Drop01;        v += ct*4;        *(v++) = d->x;        *(v++) = d->y;        *(v++) = d->ampE * 0.12f;        *(v++) = d->spread;    }    g_Constants->Offset.x = g_xOffset;    for (ct = 0; ct < gMaxDrops; ct++) {        updateDrop(ct);    }}//根据落叶位置绘制水波纹static void genLeafDrop(Leaves_t *leaf, float amp) {    float nx = (leaf->x + g_glWidth * 0.5f) / g_glWidth;    float ny = (leaf->y + g_glHeight * 0.5f) / g_glHeight;    drop(nx * g_meshWidth, g_meshHeight - ny * g_meshHeight, amp);}//绘制单片落叶static int drawLeaf(Leaves_t *leaf) {    float x = leaf->x;    float y = leaf->y;    float u1 = leaf->u1;    float u2 = leaf->u2;    float a = leaf->altitude;    float s = leaf->scale;    float r = leaf->angle;    float tz = 0.0f;    if (a > 0.0f) {        tz = -a;    }    rs_matrix4x4 matrix;    if (a > 0.0f) {        float alpha = 1.0f;        if (a >= 0.4f) alpha = 1.0f - (a - 0.4f) / 0.1f;        rsgProgramFragmentConstantColor(g_PFSky, 0.0f, 0.0f, 0.0f, alpha * 0.15f);        rsMatrixLoadIdentity(&matrix);        if (!g_rotate) {            rsMatrixTranslate(&matrix, x - g_xOffset * 2, y, 0);        } else {            rsMatrixTranslate(&matrix, x, y, 0);            rsMatrixRotate(&matrix, 90.0f, 0.0f, 0.0f, 1.0f);        }        float shadowOffet = a * 0.2f;        rsMatrixScale(&matrix, s, s, 1.0f);        rsMatrixRotate(&matrix, r, 0.0f, 0.0f, 1.0f);        rsgProgramVertexLoadModelMatrix(&matrix);        rsgDrawQuadTexCoords(-LEAF_SIZE, -LEAF_SIZE, 0, u1, 1.0f,                           LEAF_SIZE, -LEAF_SIZE, 0, u2, 1.0f,                           LEAF_SIZE,  LEAF_SIZE, 0, u2, 0.0f,                          -LEAF_SIZE,  LEAF_SIZE, 0, u1, 0.0f);        rsgProgramFragmentConstantColor(g_PFSky, 1.0f, 1.0f, 1.0f, alpha);    } else {        rsgProgramFragmentConstantColor(g_PFSky, 1.0f, 1.0f, 1.0f, 1.0f);    }    rsMatrixLoadIdentity(&matrix);    if (!g_rotate) {        rsMatrixTranslate(&matrix, x - g_xOffset * 2, y, tz);    } else {        rsMatrixTranslate(&matrix, x, y, tz);        rsMatrixRotate(&matrix, 90.0f, 0.0f, 0.0f, 1.0f);    }    rsMatrixScale(&matrix, s, s, 1.0f);    rsMatrixRotate(&matrix, r, 0.0f, 0.0f, 1.0f);    rsgProgramVertexLoadModelMatrix(&matrix);    rsgDrawQuadTexCoords(-LEAF_SIZE, -LEAF_SIZE, 0, u1, 1.0f,                       LEAF_SIZE, -LEAF_SIZE, 0, u2, 1.0f,                       LEAF_SIZE,  LEAF_SIZE, 0, u2, 0.0f,                      -LEAF_SIZE,  LEAF_SIZE, 0, u1, 0.0f);    float spin = leaf->spin;    if (a <= 0.0f) {        float rippled = leaf->rippled;        if (rippled < 0.0f) {            genLeafDrop(leaf, 1.5f);            //drop(((x + g_glWidth * 0.5f) / g_glWidth) * meshWidth,            //     meshHeight - ((y + g_glHeight * 0.5f) / g_glHeight) * meshHeight, 1);            spin *= 0.25f;            leaf->spin = spin;            leaf->rippled = 1.0f;        }        leaf->x = x + leaf->deltaX * g_DT;        leaf->y = y + leaf->deltaY * g_DT;        r += spin;        leaf->angle = r;    } else {        a -= 0.15f * g_DT;        leaf->altitude = a;        r += spin * 2.0f;        leaf->angle = r;    }    int newLeaf = 0;    if (-LEAF_SIZE * s + x > g_glWidth || LEAF_SIZE * s + x < -g_glWidth ||            LEAF_SIZE * s + y < -g_glHeight * 0.5f) {        int sprite = rsRand(LEAVES_TEXTURES_COUNT);        leaf->x = rsRand(-g_glWidth, g_glWidth);        leaf->y = rsRand(-g_glHeight * 0.5f, g_glHeight * 0.5f);        leaf->scale = rsRand(0.4f, 0.5f);        leaf->spin = degrees(rsRand(-0.02f, 0.02f)) * 0.35f;        leaf->u1 = sprite / (float) LEAVES_TEXTURES_COUNT;        leaf->u2 = (sprite + 1) / (float) LEAVES_TEXTURES_COUNT;        leaf->altitude = 0.7f;        leaf->rippled = -1.0f;        leaf->deltaX = rsRand(-0.01f, 0.01f);        leaf->deltaY = -rsRand(0.036f, 0.044f);        leaf->newLeaf = 1;        newLeaf = 1;    }    return newLeaf;}//绘制落叶static void drawLeaves() {    rsgBindProgramFragment(g_PFSky);    rsgBindProgramStore(g_PFSLeaf);    rsgBindProgramVertex(g_PVSky);    rsgBindTexture(g_PFSky, 0, g_TLeaves);    int newLeaves = 0;    int i = 0;    for ( ; i < LEAVES_COUNT; i += 1) {        if (drawLeaf(gLeaves[i])) {            newLeaves = 1;        }    }    if (newLeaves > 0) {        int index = 0;        // Copy all the old leaves to the beginning of gNextLeaves        for (i=0; i < LEAVES_COUNT; i++) {            if (gLeaves[i]->newLeaf == 0) {                gNextLeaves[index] = gLeaves[i];                index++;            }        }        // Now copy all the newly falling leaves to the end of gNextLeaves        for (i=0; i < LEAVES_COUNT; i++) {            if (gLeaves[i]->newLeaf > 0) {                gNextLeaves[index] = gLeaves[i];                gNextLeaves[index]->newLeaf = 0;                index++;            }        }        // And move everything in gNextLeaves back to gLeaves        for (i=0; i < LEAVES_COUNT; i++) {            gLeaves[i] = gNextLeaves[i];        }    }    rs_matrix4x4 matrix;    rsMatrixLoadIdentity(&matrix);    rsgProgramVertexLoadModelMatrix(&matrix);}//绘制水中的倒影static void drawRiverbed() {    rsgBindProgramFragment(g_PFBackground);    rsgBindProgramStore(g_PFSBackground);    rsgBindTexture(g_PFBackground, 0, g_TRiverbed);    rsgDrawMesh(g_WaterMesh);}//增加水滴的方法,该方法可以在java中被调用void addDrop(int x, int y) {    drop(x, y, 2);}//主函数,按指定频率反复调用int root(void) {    rsgClearColor(0.f, 0.f, 0.f, 1.f);    // Compute dt in seconds.    int64_t newTime = rsUptimeMillis();    g_DT = (newTime - g_LastTime) * 0.001f;    g_DT = min(g_DT, 0.2f);    g_LastTime = newTime;    g_Constants->Rotate = (float) g_rotate;    int ct;    int add = 0;    for (ct = 0; ct < gMaxDrops; ct++) {        if (gDrops[ct].ampE < 0.005f) {            add = 1;        }    }    if (add) {        int i = (int)rsRand(LEAVES_COUNT);        genLeafDrop(gLeaves[i], rsRand(0.3f) + 0.1f);    }    rsgBindProgramVertex(g_PVWater);    generateRipples();    rsgAllocationSyncAll(rsGetAllocation(g_Constants));    drawRiverbed();//程序中我们不需要绘制落叶,所以讲下面这行注释掉    //drawLeaves();//这个表示界面刷新的频率,50ms    return 50;}

其实整个fall.rs源码我们就只改动了一行,注释掉了主函数中的drawLeaves(),这样,就没有落叶飘下了。

下面,是FallRS.java 文件。原来这几行报错:

import static android.util.MathUtils.*;import com.android.wallpaper.R;import com.android.wallpaper.RenderScriptScene;

So Easy,ctrl+O解决。顺便将这个工程里类似的错误都改下。

结果只报一个错,FallRS.java里面的random(float,float)方法没有定义。

那就加上一个random方法:百度android.util.MathUtils,得到其中的random方法,将其加到FallRS.java文件的末尾:

 public static float random(float howsmall, float howbig) {           if (howsmall >= howbig) return howsmall;           Random sRandom = new Random();          return sRandom.nextFloat() * (howbig - howsmall) + howsmall;      } 


此时,整个工程都没有错误了。

FallRS继承自RenderScriptScene,并覆写了其中两个方法:

 @Override    public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {        mWorldState.xOffset = xOffset;        mScript.set_g_xOffset(mWorldState.xOffset);    }    @Override    public Bundle onCommand(String action, int x, int y, int z, Bundle extras,            boolean resultRequested) {        if (WallpaperManager.COMMAND_TAP.equals(action)                || WallpaperManager.COMMAND_SECONDARY_TAP.equals(action)                || WallpaperManager.COMMAND_DROP.equals(action)) {            addDrop(x + (mWorldState.rotate == 0 ? (mWorldState.width * mWorldState.xOffset) : 0), y);        }        return null;    }

显然,onCommand方法告诉我们,源码只有在壁纸状态上才调用addDrop方法,而我们是要使其在activity中便能生效。

为了直观,将父类的成员直接写到FallRS里。FallRS不再继承RenderScriptScene类。

修改后的FallRS代码(中文是我加的注释)

/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.harlan.waterscreen;import static android.renderscript.ProgramStore.DepthFunc.ALWAYS;import static android.renderscript.Sampler.Value.CLAMP;import static android.renderscript.Sampler.Value.LINEAR;import java.util.Random;import java.util.TimeZone;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.renderscript.Allocation;import android.renderscript.Matrix4f;import android.renderscript.Mesh;import android.renderscript.ProgramFragment;import android.renderscript.ProgramFragmentFixedFunction;import android.renderscript.ProgramStore;import android.renderscript.ProgramStore.BlendDstFunc;import android.renderscript.ProgramStore.BlendSrcFunc;import android.renderscript.ProgramVertex;import android.renderscript.ProgramVertexFixedFunction;import android.renderscript.RenderScriptGL;import android.renderscript.Sampler;import com.android.wallpaper.fall.ScriptC_fall;import com.android.wallpaper.fall.ScriptField_Constants;//class FallRS extends RenderScriptScene {class FallRS{    private static final int MESH_RESOLUTION = 48;    private static final int RSID_STATE = 0;    private static final int RSID_CONSTANTS = 1;    private static final int RSID_DROP = 2;    private static final int TEXTURES_COUNT = 2;    private static final int RSID_TEXTURE_RIVERBED = 0;    private static final int RSID_TEXTURE_LEAVES = 1;    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();    @SuppressWarnings({"FieldCanBeLocal"})    private ProgramFragment mPfBackground;    @SuppressWarnings({"FieldCanBeLocal"})    private ProgramFragment mPfSky;    @SuppressWarnings({"FieldCanBeLocal"})    private ProgramStore mPfsBackground;    @SuppressWarnings({"FieldCanBeLocal"})    private ProgramStore mPfsLeaf;    @SuppressWarnings({"FieldCanBeLocal"})    private ProgramVertex mPvSky;    @SuppressWarnings({"FieldCanBeLocal"})    private ProgramVertex mPvWater;    private ProgramVertexFixedFunction.Constants mPvOrthoAlloc;    @SuppressWarnings({"FieldCanBeLocal"})    private Sampler mSampler;    private int mMeshWidth;    private Allocation mUniformAlloc;    private int mMeshHeight;    @SuppressWarnings({"FieldCanBeLocal"})    private Mesh mMesh;    private WorldState mWorldState;    private ScriptC_fall mScript;    private ScriptField_Constants mConstants;    private float mGlHeight;        /*******add by harlan****************/    protected int mWidth;    protected int mHeight;    protected boolean mPreview;    protected Resources mResources;    protected RenderScriptGL mRS;//    protected ScriptC mScript;    /**************************************/    public FallRS(int width, int height) {//        super(width, height);        mWidth = width;        mHeight = height;        mOptionsARGB.inScaled = false;        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;    }//    @Override//    public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {//        mWorldState.xOffset = xOffset;//        mScript.set_g_xOffset(mWorldState.xOffset);//    }////    @Override//    public Bundle onCommand(String action, int x, int y, int z, Bundle extras,//            boolean resultRequested) {//        if (WallpaperManager.COMMAND_TAP.equals(action)//                || WallpaperManager.COMMAND_SECONDARY_TAP.equals(action)//                || WallpaperManager.COMMAND_DROP.equals(action)) {//            addDrop(x + (mWorldState.rotate == 0 ? (mWorldState.width * mWorldState.xOffset) : 0), y);//        }//        return null;//    }    /**     * 绑定脚本     * <功能详细描述>     * @see [类、类#方法、类#成员]     *///    @Override    public void start() {//        super.start();        mRS.bindRootScript(mScript);                final WorldState worldState = mWorldState;        final int width = worldState.width;        final int x = width / 4 + (int)(Math.random() * (width / 2));        final int y = worldState.height / 4 + (int)(Math.random() * (worldState.height / 2));        addDrop(x + (mWorldState.rotate == 0 ? (width * worldState.xOffset) : 0), y);    }//    @Override    public void resize(int width, int height) {//        super.resize(width, height);        mWidth = width;        mHeight = height;        mWorldState.width = width;        mWorldState.height = height;        mWorldState.rotate = width > height ? 1 : 0;        mScript.set_g_glWidth(mWorldState.width);        mScript.set_g_glHeight(mWorldState.height);        mScript.set_g_rotate(mWorldState.rotate);        mScript.invoke_initLeaves();        Matrix4f proj = new Matrix4f();        proj.loadProjectionNormalized(mWidth, mHeight);        mPvOrthoAlloc.setProjection(proj);    }    /**     *生成脚本文件,并做一系列的初始化工作     * <功能详细描述>     * @return     * @see [类、类#方法、类#成员]     *///    @Override//    protected ScriptC createScript() {    protected ScriptC_fall createScript() {        mScript = new ScriptC_fall(mRS, mResources, R.raw.fall);        createMesh();        createState();        createProgramVertex();        createProgramFragmentStore();        createProgramFragment();        loadTextures();        mScript.setTimeZone(TimeZone.getDefault().getID());        mScript.bind_g_Constants(mConstants);        return mScript;    }    private void createMesh() {        Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, 2, 0);        final int width = mWidth > mHeight ? mHeight : mWidth;        final int height = mWidth > mHeight ? mWidth : mHeight;        int wResolution = MESH_RESOLUTION;        int hResolution = (int) (MESH_RESOLUTION * height / (float) width);        mGlHeight = 2.0f * height / (float) width;        wResolution += 2;        hResolution += 2;        for (int y = 0; y <= hResolution; y++) {            final float yOffset = (((float)y / hResolution) * 2.f - 1.f) * height / width;            for (int x = 0; x <= wResolution; x++) {                tmb.addVertex(((float)x / wResolution) * 2.f - 1.f, yOffset);            }        }        for (int y = 0; y < hResolution; y++) {            final boolean shift = (y & 0x1) == 0;            final int yOffset = y * (wResolution + 1);            for (int x = 0; x < wResolution; x++) {                final int index = yOffset + x;                final int iWR1 = index + wResolution + 1;                if (shift) {                    tmb.addTriangle(index, index + 1, iWR1);                    tmb.addTriangle(index + 1, iWR1 + 1, iWR1);                } else {                    tmb.addTriangle(index, iWR1 + 1, iWR1);                    tmb.addTriangle(index, index + 1, iWR1 + 1);                }            }        }        mMesh = tmb.create(true);        mMeshWidth = wResolution + 1;        mMeshHeight = hResolution + 1;        mScript.set_g_WaterMesh(mMesh);    }    static class WorldState {        public int frameCount;        public int width;        public int height;        public int meshWidth;        public int meshHeight;        public int rippleIndex;        public float glWidth;        public float glHeight;        public float skySpeedX;        public float skySpeedY;        public int rotate;        public int isPreview;        public float xOffset;    }    private void createState() {        mWorldState = new WorldState();        mWorldState.width = mWidth;        mWorldState.height = mHeight;        mWorldState.meshWidth = mMeshWidth;        mWorldState.meshHeight = mMeshHeight;        mWorldState.rippleIndex = 0;        mWorldState.glWidth = 2.0f;        mWorldState.glHeight = mGlHeight;        mWorldState.skySpeedX = random(-0.001f, 0.001f);        mWorldState.skySpeedY = random(0.00008f, 0.0002f);        mWorldState.rotate = mWidth > mHeight ? 1 : 0;//        mWorldState.isPreview = isPreview() ? 1 : 0;        mScript.set_g_glWidth(mWorldState.glWidth);        mScript.set_g_glHeight(mWorldState.glHeight);        mScript.set_g_meshWidth(mWorldState.meshWidth);        mScript.set_g_meshHeight(mWorldState.meshHeight);        mScript.set_g_xOffset(0);        mScript.set_g_rotate(mWorldState.rotate);    }    private void loadTextures() {        mScript.set_g_TLeaves(loadTextureARGB(R.drawable.leaves));        mScript.set_g_TRiverbed(loadTexture(R.drawable.pond));    }    private Allocation loadTexture(int id) {        final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources, id);        return allocation;    }    private Allocation loadTextureARGB(int id) {        Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);        final Allocation allocation = Allocation.createFromBitmap(mRS, b);        return allocation;    }    private void createProgramFragment() {        Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);        sampleBuilder.setMinification(LINEAR);        sampleBuilder.setMagnification(LINEAR);        sampleBuilder.setWrapS(CLAMP);        sampleBuilder.setWrapT(CLAMP);        mSampler = sampleBuilder.create();        ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);        builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);        mPfBackground = builder.create();        mPfBackground.bindSampler(mSampler, 0);        mScript.set_g_PFBackground(mPfBackground);        builder = new ProgramFragmentFixedFunction.Builder(mRS);        builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);        mPfSky = builder.create();        mPfSky.bindSampler(mSampler, 0);        mScript.set_g_PFSky(mPfSky);    }    private void createProgramFragmentStore() {        ProgramStore.Builder builder = new ProgramStore.Builder(mRS);        builder.setDepthFunc(ALWAYS);        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);        builder.setDitherEnabled(false);        builder.setDepthMaskEnabled(true);        mPfsBackground = builder.create();        builder = new ProgramStore.Builder(mRS);        builder.setDepthFunc(ALWAYS);        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);        builder.setDitherEnabled(false);        builder.setDepthMaskEnabled(true);        mPfsLeaf = builder.create();        mScript.set_g_PFSLeaf(mPfsLeaf);        mScript.set_g_PFSBackground(mPfsBackground);    }    private void createProgramVertex() {        mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(mRS);        Matrix4f proj = new Matrix4f();        proj.loadProjectionNormalized(mWidth, mHeight);        mPvOrthoAlloc.setProjection(proj);        ProgramVertexFixedFunction.Builder builder = new ProgramVertexFixedFunction.Builder(mRS);        mPvSky = builder.create();        ((ProgramVertexFixedFunction)mPvSky).bindConstants(mPvOrthoAlloc);        mScript.set_g_PVSky(mPvSky);        mConstants = new ScriptField_Constants(mRS, 1);        mUniformAlloc = mConstants.getAllocation();        ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);        String t = "\n" +                "varying vec4 varColor;\n" +                "varying vec2 varTex0;\n" +                "vec2 addDrop(vec4 d, vec2 pos, float dxMul) {\n" +                "  vec2 ret = vec2(0.0, 0.0);\n" +                "  vec2 delta = d.xy - pos;\n" +                "  delta.x *= dxMul;\n" +                "  float dist = length(delta);\n" +                "  if (dist < d.w) { \n" +                "    float amp = d.z * dist;\n" +                "    amp /= d.w * d.w;\n" +                "    amp *= sin(d.w - dist);\n" +                "    ret = delta * amp;\n" +                "  }\n" +                "  return ret;\n" +                "}\n" +                "void main() {\n" +                "  vec2 pos = ATTRIB_position.xy;\n" +                "  gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);\n" +                "  float dxMul = 1.0;\n" +                "  varTex0 = vec2((pos.x + 1.0), (pos.y + 1.6666));\n" +                "  if (UNI_Rotate < 0.9) {\n" +                "    varTex0.xy *= vec2(0.25, 0.33);\n" +                "    varTex0.x += UNI_Offset.x * 0.5;\n" +                "    pos.x += UNI_Offset.x * 2.0;\n" +                "  } else {\n" +                "    varTex0.xy *= vec2(0.5, 0.3125);\n" +                "    dxMul = 2.5;\n" +                "  }\n" +                "  varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +                "  pos.xy += vec2(1.0, 1.0);\n" +                "  pos.xy *= vec2(25.0, 42.0);\n" +                "  varTex0.xy += addDrop(UNI_Drop01, pos, dxMul);\n" +                "  varTex0.xy += addDrop(UNI_Drop02, pos, dxMul);\n" +                "  varTex0.xy += addDrop(UNI_Drop03, pos, dxMul);\n" +                "  varTex0.xy += addDrop(UNI_Drop04, pos, dxMul);\n" +                "  varTex0.xy += addDrop(UNI_Drop05, pos, dxMul);\n" +                "  varTex0.xy += addDrop(UNI_Drop06, pos, dxMul);\n" +                "  varTex0.xy += addDrop(UNI_Drop07, pos, dxMul);\n" +                "  varTex0.xy += addDrop(UNI_Drop08, pos, dxMul);\n" +                "  varTex0.xy += addDrop(UNI_Drop09, pos, dxMul);\n" +                "  varTex0.xy += addDrop(UNI_Drop10, pos, dxMul);\n" +                "}\n";        sb.setShader(t);        sb.addConstant(mUniformAlloc.getType());        sb.addInput(mMesh.getVertexAllocation(0).getType().getElement());        mPvWater = sb.create();        mPvWater.bindConstants(mUniformAlloc, 0);        mScript.set_g_PVWater(mPvWater);    }    /**     * 根据传入的坐标生成水波纹特效     * <功能详细描述>     * @param x     * @param y     * @see [类、类#方法、类#成员]     */    void addDrop(float x, float y) {        int dropX = (int) ((x / mWidth) * mMeshWidth);        int dropY = (int) ((y / mHeight) * mMeshHeight);        mScript.invoke_addDrop(dropX, dropY);    }        /*******add by harlan************************/    public static float random(float howsmall, float howbig) {           if (howsmall >= howbig) return howsmall;           Random sRandom = new Random();          return sRandom.nextFloat() * (howbig - howsmall) + howsmall;      }         public void init(RenderScriptGL rs, Resources res, boolean isPreview) {        mRS = rs;        mResources = res;        mPreview = isPreview;        mScript = createScript();    }        public void stop() {        mRS.bindRootScript(null);    }    /****************************************************/}




好了,至此,RenderScript准备工作完毕,下面就是修改FallView.java文件,以及在activity中加载FallView。


更多相关文章

  1. Android学习三UI之Layout
  2. [置顶] Android(安卓)调用js,传对象到js里面使用addJavascriptInt
  3. Android(安卓)Studio 使用Gradle引入第三方库文件的总结
  4. Android中AsyncTask的简单用法
  5. 我的Android进阶之旅------>Android中解析XML 技术详解---->SAX
  6. 浅谈Java中Collections.sort对List排序的两种方法
  7. NPM 和webpack 的基础使用
  8. Python list sort方法的具体使用
  9. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程

随机推荐

  1. Andorid 文件浏览器简易实现
  2. 系统启动之一
  3. 【报错问题】 - React native Android(安
  4. 直接从数据库里修改桌面图标
  5. 自定义时间控件
  6. 详解Android 扫描条形码(Zxing插件)
  7. Android -联系人列表
  8. 解决gradle DSL method not found: andro
  9. android主界面tab切换方式
  10. 阿里 Andfix 介绍及原理解析