159206df88081556d0bf538234da0b455cc7bb095Romain Guy/*
259206df88081556d0bf538234da0b455cc7bb095Romain Guy * Copyright (C) 2009 The Android Open Source Project
359206df88081556d0bf538234da0b455cc7bb095Romain Guy *
459206df88081556d0bf538234da0b455cc7bb095Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
559206df88081556d0bf538234da0b455cc7bb095Romain Guy * you may not use this file except in compliance with the License.
659206df88081556d0bf538234da0b455cc7bb095Romain Guy * You may obtain a copy of the License at
759206df88081556d0bf538234da0b455cc7bb095Romain Guy *
859206df88081556d0bf538234da0b455cc7bb095Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
959206df88081556d0bf538234da0b455cc7bb095Romain Guy *
1059206df88081556d0bf538234da0b455cc7bb095Romain Guy * Unless required by applicable law or agreed to in writing, software
1159206df88081556d0bf538234da0b455cc7bb095Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
1259206df88081556d0bf538234da0b455cc7bb095Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1359206df88081556d0bf538234da0b455cc7bb095Romain Guy * See the License for the specific language governing permissions and
1459206df88081556d0bf538234da0b455cc7bb095Romain Guy * limitations under the License.
1559206df88081556d0bf538234da0b455cc7bb095Romain Guy */
1659206df88081556d0bf538234da0b455cc7bb095Romain Guy
1759206df88081556d0bf538234da0b455cc7bb095Romain Guypackage com.android.wallpaper.fall;
1859206df88081556d0bf538234da0b455cc7bb095Romain Guy
19c9e42c271d74990016bb2824ba72237f9c3529a3Mike Cleronimport android.os.Bundle;
2076faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchoukimport android.renderscript.*;
2159206df88081556d0bf538234da0b455cc7bb095Romain Guyimport static android.renderscript.Sampler.Value.LINEAR;
226a500a1d5e15bd5a563995f31d0796552cc13640Jason Samsimport static android.renderscript.Sampler.Value.CLAMP;
2359206df88081556d0bf538234da0b455cc7bb095Romain Guyimport static android.renderscript.ProgramStore.DepthFunc.*;
2459206df88081556d0bf538234da0b455cc7bb095Romain Guyimport static android.renderscript.ProgramStore.BlendDstFunc;
2559206df88081556d0bf538234da0b455cc7bb095Romain Guyimport static android.renderscript.ProgramStore.BlendSrcFunc;
2659206df88081556d0bf538234da0b455cc7bb095Romain Guyimport static android.renderscript.Element.*;
279d9a645b22a264e740b5a93ac1cddda594d36181Dianne Hackborn
284754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchoukimport android.util.Log;
294754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
309d9a645b22a264e740b5a93ac1cddda594d36181Dianne Hackbornimport android.app.WallpaperManager;
3159206df88081556d0bf538234da0b455cc7bb095Romain Guyimport android.graphics.BitmapFactory;
3259206df88081556d0bf538234da0b455cc7bb095Romain Guyimport android.graphics.Bitmap;
3359206df88081556d0bf538234da0b455cc7bb095Romain Guyimport static android.util.MathUtils.*;
3459206df88081556d0bf538234da0b455cc7bb095Romain Guy
3559206df88081556d0bf538234da0b455cc7bb095Romain Guyimport java.util.TimeZone;
3659206df88081556d0bf538234da0b455cc7bb095Romain Guy
3759206df88081556d0bf538234da0b455cc7bb095Romain Guyimport com.android.wallpaper.R;
3859206df88081556d0bf538234da0b455cc7bb095Romain Guyimport com.android.wallpaper.RenderScriptScene;
3959206df88081556d0bf538234da0b455cc7bb095Romain Guy
4059206df88081556d0bf538234da0b455cc7bb095Romain Guyclass FallRS extends RenderScriptScene {
4159206df88081556d0bf538234da0b455cc7bb095Romain Guy    private static final int MESH_RESOLUTION = 48;
4259206df88081556d0bf538234da0b455cc7bb095Romain Guy
4359206df88081556d0bf538234da0b455cc7bb095Romain Guy    private static final int RSID_STATE = 0;
446a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams    private static final int RSID_CONSTANTS = 1;
456a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams    private static final int RSID_DROP = 2;
4659206df88081556d0bf538234da0b455cc7bb095Romain Guy
47fc6bdef0134306ac062c0ff09fd0c61de34bb612Mike Cleron    private static final int TEXTURES_COUNT = 2;
4859206df88081556d0bf538234da0b455cc7bb095Romain Guy    private static final int RSID_TEXTURE_RIVERBED = 0;
4959206df88081556d0bf538234da0b455cc7bb095Romain Guy    private static final int RSID_TEXTURE_LEAVES = 1;
506a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams
5159206df88081556d0bf538234da0b455cc7bb095Romain Guy    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
5259206df88081556d0bf538234da0b455cc7bb095Romain Guy
5359206df88081556d0bf538234da0b455cc7bb095Romain Guy    @SuppressWarnings({"FieldCanBeLocal"})
5459206df88081556d0bf538234da0b455cc7bb095Romain Guy    private ProgramFragment mPfBackground;
5559206df88081556d0bf538234da0b455cc7bb095Romain Guy    @SuppressWarnings({"FieldCanBeLocal"})
5659206df88081556d0bf538234da0b455cc7bb095Romain Guy    private ProgramFragment mPfSky;
5759206df88081556d0bf538234da0b455cc7bb095Romain Guy    @SuppressWarnings({"FieldCanBeLocal"})
5859206df88081556d0bf538234da0b455cc7bb095Romain Guy    private ProgramStore mPfsBackground;
5959206df88081556d0bf538234da0b455cc7bb095Romain Guy    @SuppressWarnings({"FieldCanBeLocal"})
6059206df88081556d0bf538234da0b455cc7bb095Romain Guy    private ProgramStore mPfsLeaf;
6159206df88081556d0bf538234da0b455cc7bb095Romain Guy    @SuppressWarnings({"FieldCanBeLocal"})
6259206df88081556d0bf538234da0b455cc7bb095Romain Guy    private ProgramVertex mPvSky;
639a2bf356a59957a4bb8414744b913eb1dc3e9771Romain Guy    @SuppressWarnings({"FieldCanBeLocal"})
646a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams    private ProgramVertex mPvWater;
6576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk    private ProgramVertexFixedFunction.Constants mPvOrthoAlloc;
6659206df88081556d0bf538234da0b455cc7bb095Romain Guy    @SuppressWarnings({"FieldCanBeLocal"})
6759206df88081556d0bf538234da0b455cc7bb095Romain Guy    private Sampler mSampler;
6859206df88081556d0bf538234da0b455cc7bb095Romain Guy
6959206df88081556d0bf538234da0b455cc7bb095Romain Guy    private int mMeshWidth;
706a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams    private Allocation mUniformAlloc;
7159206df88081556d0bf538234da0b455cc7bb095Romain Guy
7259206df88081556d0bf538234da0b455cc7bb095Romain Guy    private int mMeshHeight;
7359206df88081556d0bf538234da0b455cc7bb095Romain Guy    @SuppressWarnings({"FieldCanBeLocal"})
74359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk    private Mesh mMesh;
752430b67ccf17b0528ce6a6d0ef4bdb2275ed2d73Jason Sams    private WorldState mWorldState;
7659206df88081556d0bf538234da0b455cc7bb095Romain Guy
775f5044f59065ac339b175bb8a47ea6be861f925cStephen Hines    private ScriptC_fall mScript;
784754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
794754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk    private ScriptField_Constants mConstants;
804754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
8159206df88081556d0bf538234da0b455cc7bb095Romain Guy    private float mGlHeight;
8259206df88081556d0bf538234da0b455cc7bb095Romain Guy
8359206df88081556d0bf538234da0b455cc7bb095Romain Guy    public FallRS(int width, int height) {
8459206df88081556d0bf538234da0b455cc7bb095Romain Guy        super(width, height);
8559206df88081556d0bf538234da0b455cc7bb095Romain Guy
8659206df88081556d0bf538234da0b455cc7bb095Romain Guy        mOptionsARGB.inScaled = false;
8759206df88081556d0bf538234da0b455cc7bb095Romain Guy        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
8859206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
8959206df88081556d0bf538234da0b455cc7bb095Romain Guy
9059206df88081556d0bf538234da0b455cc7bb095Romain Guy    @Override
91873e9934d83e0ddb1fb39d8a8bfe11b9e8175c5cJason Sams    public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
92873e9934d83e0ddb1fb39d8a8bfe11b9e8175c5cJason Sams        mWorldState.xOffset = xOffset;
934754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_xOffset(mWorldState.xOffset);
94873e9934d83e0ddb1fb39d8a8bfe11b9e8175c5cJason Sams    }
95b344cf4d5a49dd0f6615f982b6bc5adcf39b5eb6Jason Sams
96c9e42c271d74990016bb2824ba72237f9c3529a3Mike Cleron    @Override
97c9e42c271d74990016bb2824ba72237f9c3529a3Mike Cleron    public Bundle onCommand(String action, int x, int y, int z, Bundle extras,
98c9e42c271d74990016bb2824ba72237f9c3529a3Mike Cleron            boolean resultRequested) {
99843c77f4841670c95284c7243d61f5d77f6e5ff7Jeff Brown        if (WallpaperManager.COMMAND_TAP.equals(action)
100843c77f4841670c95284c7243d61f5d77f6e5ff7Jeff Brown                || WallpaperManager.COMMAND_SECONDARY_TAP.equals(action)
101843c77f4841670c95284c7243d61f5d77f6e5ff7Jeff Brown                || WallpaperManager.COMMAND_DROP.equals(action)) {
1029a2bf356a59957a4bb8414744b913eb1dc3e9771Romain Guy            addDrop(x + (mWorldState.rotate == 0 ? (mWorldState.width * mWorldState.xOffset) : 0), y);
103c9e42c271d74990016bb2824ba72237f9c3529a3Mike Cleron        }
104c9e42c271d74990016bb2824ba72237f9c3529a3Mike Cleron        return null;
105c9e42c271d74990016bb2824ba72237f9c3529a3Mike Cleron    }
1066a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams
10770ebeb824d61ccc8bbc10bf561a14afef019a409Mike Cleron    @Override
10870ebeb824d61ccc8bbc10bf561a14afef019a409Mike Cleron    public void start() {
10970ebeb824d61ccc8bbc10bf561a14afef019a409Mike Cleron        super.start();
11070ebeb824d61ccc8bbc10bf561a14afef019a409Mike Cleron        final WorldState worldState = mWorldState;
11170ebeb824d61ccc8bbc10bf561a14afef019a409Mike Cleron        final int width = worldState.width;
11270ebeb824d61ccc8bbc10bf561a14afef019a409Mike Cleron        final int x = width / 4 + (int)(Math.random() * (width / 2));
11370ebeb824d61ccc8bbc10bf561a14afef019a409Mike Cleron        final int y = worldState.height / 4 + (int)(Math.random() * (worldState.height / 2));
1149a2bf356a59957a4bb8414744b913eb1dc3e9771Romain Guy        addDrop(x + (mWorldState.rotate == 0 ? (width * worldState.xOffset) : 0), y);
11570ebeb824d61ccc8bbc10bf561a14afef019a409Mike Cleron    }
116873e9934d83e0ddb1fb39d8a8bfe11b9e8175c5cJason Sams
117873e9934d83e0ddb1fb39d8a8bfe11b9e8175c5cJason Sams    @Override
11859206df88081556d0bf538234da0b455cc7bb095Romain Guy    public void resize(int width, int height) {
11959206df88081556d0bf538234da0b455cc7bb095Romain Guy        super.resize(width, height);
12059206df88081556d0bf538234da0b455cc7bb095Romain Guy
12159206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.width = width;
12259206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.height = height;
123a6d4d985fd0d7d0d6c3b7e579b8f3157a13a8aecRomain Guy        mWorldState.rotate = width > height ? 1 : 0;
1244754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
1254754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_glWidth(mWorldState.width);
1264754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_glHeight(mWorldState.height);
1274754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_rotate(mWorldState.rotate);
1284754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
129791703ecfaecc7fee4c86a36f06634aa14bfde0cShih-wei Liao        mScript.invoke_initLeaves();
13059206df88081556d0bf538234da0b455cc7bb095Romain Guy
13176faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        Matrix4f proj = new Matrix4f();
13276faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        proj.loadProjectionNormalized(mWidth, mHeight);
13376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        mPvOrthoAlloc.setProjection(proj);
13459206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
13559206df88081556d0bf538234da0b455cc7bb095Romain Guy
13659206df88081556d0bf538234da0b455cc7bb095Romain Guy    @Override
13759206df88081556d0bf538234da0b455cc7bb095Romain Guy    protected ScriptC createScript() {
13876469b31f1bda22057330a0146d9296df92b9094Jason Sams        mScript = new ScriptC_fall(mRS, mResources, R.raw.fall);
1394754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
1406a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams        createMesh();
1416a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams        createState();
14259206df88081556d0bf538234da0b455cc7bb095Romain Guy        createProgramVertex();
14359206df88081556d0bf538234da0b455cc7bb095Romain Guy        createProgramFragmentStore();
14459206df88081556d0bf538234da0b455cc7bb095Romain Guy        createProgramFragment();
14559206df88081556d0bf538234da0b455cc7bb095Romain Guy        loadTextures();
14659206df88081556d0bf538234da0b455cc7bb095Romain Guy
1474754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.setTimeZone(TimeZone.getDefault().getID());
1484754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
149791703ecfaecc7fee4c86a36f06634aa14bfde0cShih-wei Liao        mScript.bind_g_Constants(mConstants);
1504754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
1514754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        return mScript;
15259206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
15359206df88081556d0bf538234da0b455cc7bb095Romain Guy
15459206df88081556d0bf538234da0b455cc7bb095Romain Guy    private void createMesh() {
155359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk        Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, 2, 0);
15659206df88081556d0bf538234da0b455cc7bb095Romain Guy
157a454eca5a443705380b1231527e103334b580594Romain Guy        final int width = mWidth > mHeight ? mHeight : mWidth;
158a454eca5a443705380b1231527e103334b580594Romain Guy        final int height = mWidth > mHeight ? mWidth : mHeight;
15959206df88081556d0bf538234da0b455cc7bb095Romain Guy
160a454eca5a443705380b1231527e103334b580594Romain Guy        int wResolution = MESH_RESOLUTION;
161a454eca5a443705380b1231527e103334b580594Romain Guy        int hResolution = (int) (MESH_RESOLUTION * height / (float) width);
16259206df88081556d0bf538234da0b455cc7bb095Romain Guy
16359206df88081556d0bf538234da0b455cc7bb095Romain Guy        mGlHeight = 2.0f * height / (float) width;
16459206df88081556d0bf538234da0b455cc7bb095Romain Guy
16559206df88081556d0bf538234da0b455cc7bb095Romain Guy        wResolution += 2;
16659206df88081556d0bf538234da0b455cc7bb095Romain Guy        hResolution += 2;
16759206df88081556d0bf538234da0b455cc7bb095Romain Guy
16859206df88081556d0bf538234da0b455cc7bb095Romain Guy        for (int y = 0; y <= hResolution; y++) {
1696a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams            final float yOffset = (((float)y / hResolution) * 2.f - 1.f) * height / width;
17059206df88081556d0bf538234da0b455cc7bb095Romain Guy            for (int x = 0; x <= wResolution; x++) {
1716a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams                tmb.addVertex(((float)x / wResolution) * 2.f - 1.f, yOffset);
17259206df88081556d0bf538234da0b455cc7bb095Romain Guy            }
17359206df88081556d0bf538234da0b455cc7bb095Romain Guy        }
17459206df88081556d0bf538234da0b455cc7bb095Romain Guy
17559206df88081556d0bf538234da0b455cc7bb095Romain Guy        for (int y = 0; y < hResolution; y++) {
17659206df88081556d0bf538234da0b455cc7bb095Romain Guy            final boolean shift = (y & 0x1) == 0;
17759206df88081556d0bf538234da0b455cc7bb095Romain Guy            final int yOffset = y * (wResolution + 1);
17859206df88081556d0bf538234da0b455cc7bb095Romain Guy            for (int x = 0; x < wResolution; x++) {
17959206df88081556d0bf538234da0b455cc7bb095Romain Guy                final int index = yOffset + x;
18059206df88081556d0bf538234da0b455cc7bb095Romain Guy                final int iWR1 = index + wResolution + 1;
18159206df88081556d0bf538234da0b455cc7bb095Romain Guy                if (shift) {
1822430b67ccf17b0528ce6a6d0ef4bdb2275ed2d73Jason Sams                    tmb.addTriangle(index, index + 1, iWR1);
1832430b67ccf17b0528ce6a6d0ef4bdb2275ed2d73Jason Sams                    tmb.addTriangle(index + 1, iWR1 + 1, iWR1);
18459206df88081556d0bf538234da0b455cc7bb095Romain Guy                } else {
1852430b67ccf17b0528ce6a6d0ef4bdb2275ed2d73Jason Sams                    tmb.addTriangle(index, iWR1 + 1, iWR1);
1862430b67ccf17b0528ce6a6d0ef4bdb2275ed2d73Jason Sams                    tmb.addTriangle(index, index + 1, iWR1 + 1);
18759206df88081556d0bf538234da0b455cc7bb095Romain Guy                }
18859206df88081556d0bf538234da0b455cc7bb095Romain Guy            }
18959206df88081556d0bf538234da0b455cc7bb095Romain Guy        }
19059206df88081556d0bf538234da0b455cc7bb095Romain Guy
191359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk        mMesh = tmb.create(true);
19259206df88081556d0bf538234da0b455cc7bb095Romain Guy
19359206df88081556d0bf538234da0b455cc7bb095Romain Guy        mMeshWidth = wResolution + 1;
19459206df88081556d0bf538234da0b455cc7bb095Romain Guy        mMeshHeight = hResolution + 1;
1954754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
1964754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_WaterMesh(mMesh);
19759206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
19859206df88081556d0bf538234da0b455cc7bb095Romain Guy
19959206df88081556d0bf538234da0b455cc7bb095Romain Guy    static class WorldState {
20059206df88081556d0bf538234da0b455cc7bb095Romain Guy        public int frameCount;
20159206df88081556d0bf538234da0b455cc7bb095Romain Guy        public int width;
20259206df88081556d0bf538234da0b455cc7bb095Romain Guy        public int height;
20359206df88081556d0bf538234da0b455cc7bb095Romain Guy        public int meshWidth;
20459206df88081556d0bf538234da0b455cc7bb095Romain Guy        public int meshHeight;
20559206df88081556d0bf538234da0b455cc7bb095Romain Guy        public int rippleIndex;
20659206df88081556d0bf538234da0b455cc7bb095Romain Guy        public float glWidth;
20759206df88081556d0bf538234da0b455cc7bb095Romain Guy        public float glHeight;
20859206df88081556d0bf538234da0b455cc7bb095Romain Guy        public float skySpeedX;
20959206df88081556d0bf538234da0b455cc7bb095Romain Guy        public float skySpeedY;
210f0bb95619b01499e991bee297745cad31c20b28eRomain Guy        public int rotate;
2112d42794e6237a56d2d7518a8b9dba27e3e818d31Romain Guy        public int isPreview;
212873e9934d83e0ddb1fb39d8a8bfe11b9e8175c5cJason Sams        public float xOffset;
21359206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
21459206df88081556d0bf538234da0b455cc7bb095Romain Guy
2156a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams    private void createState() {
21659206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState = new WorldState();
21759206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.width = mWidth;
21859206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.height = mHeight;
21959206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.meshWidth = mMeshWidth;
22059206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.meshHeight = mMeshHeight;
22159206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.rippleIndex = 0;
22259206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.glWidth = 2.0f;
22359206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.glHeight = mGlHeight;
22459206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.skySpeedX = random(-0.001f, 0.001f);
22559206df88081556d0bf538234da0b455cc7bb095Romain Guy        mWorldState.skySpeedY = random(0.00008f, 0.0002f);
226f0bb95619b01499e991bee297745cad31c20b28eRomain Guy        mWorldState.rotate = mWidth > mHeight ? 1 : 0;
2272d42794e6237a56d2d7518a8b9dba27e3e818d31Romain Guy        mWorldState.isPreview = isPreview() ? 1 : 0;
22859206df88081556d0bf538234da0b455cc7bb095Romain Guy
2294754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_glWidth(mWorldState.glWidth);
2304754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_glHeight(mWorldState.glHeight);
2314754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_meshWidth(mWorldState.meshWidth);
2324754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_meshHeight(mWorldState.meshHeight);
2334754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_xOffset(0);
2344754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_rotate(mWorldState.rotate);
23559206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
2366a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams
23759206df88081556d0bf538234da0b455cc7bb095Romain Guy    private void loadTextures() {
238c78002e81665739a29b2cb78b9e0db29e772da2dJason Sams        mScript.set_g_TLeaves(loadTextureARGB(R.drawable.leaves));
239c78002e81665739a29b2cb78b9e0db29e772da2dJason Sams        mScript.set_g_TRiverbed(loadTexture(R.drawable.pond));
24059206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
24159206df88081556d0bf538234da0b455cc7bb095Romain Guy
242c78002e81665739a29b2cb78b9e0db29e772da2dJason Sams    private Allocation loadTexture(int id) {
243bbcb547467bd09da372a15ac235e239c6557289bJason Sams        final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources, id);
24459206df88081556d0bf538234da0b455cc7bb095Romain Guy        return allocation;
24559206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
24659206df88081556d0bf538234da0b455cc7bb095Romain Guy
247c78002e81665739a29b2cb78b9e0db29e772da2dJason Sams    private Allocation loadTextureARGB(int id) {
24859206df88081556d0bf538234da0b455cc7bb095Romain Guy        Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
249bbcb547467bd09da372a15ac235e239c6557289bJason Sams        final Allocation allocation = Allocation.createFromBitmap(mRS, b);
25059206df88081556d0bf538234da0b455cc7bb095Romain Guy        return allocation;
25159206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
25259206df88081556d0bf538234da0b455cc7bb095Romain Guy
25359206df88081556d0bf538234da0b455cc7bb095Romain Guy    private void createProgramFragment() {
25459206df88081556d0bf538234da0b455cc7bb095Romain Guy        Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);
25576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        sampleBuilder.setMinification(LINEAR);
25676faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        sampleBuilder.setMagnification(LINEAR);
2576a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams        sampleBuilder.setWrapS(CLAMP);
2586a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams        sampleBuilder.setWrapT(CLAMP);
25959206df88081556d0bf538234da0b455cc7bb095Romain Guy        mSampler = sampleBuilder.create();
26059206df88081556d0bf538234da0b455cc7bb095Romain Guy
26176faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
26276faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
26376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
26459206df88081556d0bf538234da0b455cc7bb095Romain Guy        mPfBackground = builder.create();
26559206df88081556d0bf538234da0b455cc7bb095Romain Guy        mPfBackground.bindSampler(mSampler, 0);
26659206df88081556d0bf538234da0b455cc7bb095Romain Guy
2674754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_PFBackground(mPfBackground);
2684754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
26976faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder = new ProgramFragmentFixedFunction.Builder(mRS);
27076faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
27176faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
27259206df88081556d0bf538234da0b455cc7bb095Romain Guy        mPfSky = builder.create();
27359206df88081556d0bf538234da0b455cc7bb095Romain Guy        mPfSky.bindSampler(mSampler, 0);
2744754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
2754754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_PFSky(mPfSky);
27659206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
27759206df88081556d0bf538234da0b455cc7bb095Romain Guy
27859206df88081556d0bf538234da0b455cc7bb095Romain Guy    private void createProgramFragmentStore() {
27976faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
28059206df88081556d0bf538234da0b455cc7bb095Romain Guy        builder.setDepthFunc(ALWAYS);
28159206df88081556d0bf538234da0b455cc7bb095Romain Guy        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
28276faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder.setDitherEnabled(false);
28376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder.setDepthMaskEnabled(true);
28459206df88081556d0bf538234da0b455cc7bb095Romain Guy        mPfsBackground = builder.create();
28559206df88081556d0bf538234da0b455cc7bb095Romain Guy
28676faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder = new ProgramStore.Builder(mRS);
28759206df88081556d0bf538234da0b455cc7bb095Romain Guy        builder.setDepthFunc(ALWAYS);
28859206df88081556d0bf538234da0b455cc7bb095Romain Guy        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
28976faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder.setDitherEnabled(false);
29076faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder.setDepthMaskEnabled(true);
29159206df88081556d0bf538234da0b455cc7bb095Romain Guy        mPfsLeaf = builder.create();
2924754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
2934754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_PFSLeaf(mPfsLeaf);
2944754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_PFSBackground(mPfsBackground);
29559206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
29659206df88081556d0bf538234da0b455cc7bb095Romain Guy
29759206df88081556d0bf538234da0b455cc7bb095Romain Guy    private void createProgramVertex() {
29876faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(mRS);
29976faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        Matrix4f proj = new Matrix4f();
30076faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        proj.loadProjectionNormalized(mWidth, mHeight);
30176faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        mPvOrthoAlloc.setProjection(proj);
30259206df88081556d0bf538234da0b455cc7bb095Romain Guy
30376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk
30476faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ProgramVertexFixedFunction.Builder builder = new ProgramVertexFixedFunction.Builder(mRS);
30559206df88081556d0bf538234da0b455cc7bb095Romain Guy        mPvSky = builder.create();
30676faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ((ProgramVertexFixedFunction)mPvSky).bindConstants(mPvOrthoAlloc);
3076a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams
3084754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_PVSky(mPvSky);
3094754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
3104754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mConstants = new ScriptField_Constants(mRS, 1);
3114754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mUniformAlloc = mConstants.getAllocation();
3126a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams
31376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
3144ace270249d25302d027edd3a471aef94ab4e759Jason Sams
3154ace270249d25302d027edd3a471aef94ab4e759Jason Sams        String t = "\n" +
316a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk                "varying vec4 varColor;\n" +
3171462bbbccb3f4bd3a6f3b76e8caf5c8947a863bfAlex Sakhartchouk                "varying vec2 varTex0;\n" +
318a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk
3194ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "vec2 addDrop(vec4 d, vec2 pos, float dxMul) {\n" +
3204ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  vec2 ret = vec2(0.0, 0.0);\n" +
3214ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  vec2 delta = d.xy - pos;\n" +
3224ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  delta.x *= dxMul;\n" +
3234ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  float dist = length(delta);\n" +
3244ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  if (dist < d.w) { \n" +
3254ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "    float amp = d.z * dist;\n" +
3264ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "    amp /= d.w * d.w;\n" +
3274ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "    amp *= sin(d.w - dist);\n" +
3284ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "    ret = delta * amp;\n" +
3299a2bf356a59957a4bb8414744b913eb1dc3e9771Romain Guy                "  }\n" +
3304ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  return ret;\n" +
3314ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "}\n" +
3324ace270249d25302d027edd3a471aef94ab4e759Jason Sams
3334ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "void main() {\n" +
3344ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  vec2 pos = ATTRIB_position.xy;\n" +
3354ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);\n" +
3364ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  float dxMul = 1.0;\n" +
3374ace270249d25302d027edd3a471aef94ab4e759Jason Sams
3381462bbbccb3f4bd3a6f3b76e8caf5c8947a863bfAlex Sakhartchouk                "  varTex0 = vec2((pos.x + 1.0), (pos.y + 1.6666));\n" +
3399a2bf356a59957a4bb8414744b913eb1dc3e9771Romain Guy
3409a2bf356a59957a4bb8414744b913eb1dc3e9771Romain Guy                "  if (UNI_Rotate < 0.9) {\n" +
3414ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "    varTex0.xy *= vec2(0.25, 0.33);\n" +
3424ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "    varTex0.x += UNI_Offset.x * 0.5;\n" +
3439a2bf356a59957a4bb8414744b913eb1dc3e9771Romain Guy                "    pos.x += UNI_Offset.x * 2.0;\n" +
3444ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  } else {\n" +
3454ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "    varTex0.xy *= vec2(0.5, 0.3125);\n" +
3464ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "    dxMul = 2.5;\n" +
3479a2bf356a59957a4bb8414744b913eb1dc3e9771Romain Guy                "  }\n" +
3484ace270249d25302d027edd3a471aef94ab4e759Jason Sams
3494ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
3504ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  pos.xy += vec2(1.0, 1.0);\n" +
3514ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  pos.xy *= vec2(25.0, 42.0);\n" +
3524ace270249d25302d027edd3a471aef94ab4e759Jason Sams
3534ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varTex0.xy += addDrop(UNI_Drop01, pos, dxMul);\n" +
3544ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varTex0.xy += addDrop(UNI_Drop02, pos, dxMul);\n" +
3554ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varTex0.xy += addDrop(UNI_Drop03, pos, dxMul);\n" +
3564ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varTex0.xy += addDrop(UNI_Drop04, pos, dxMul);\n" +
3574ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varTex0.xy += addDrop(UNI_Drop05, pos, dxMul);\n" +
3584ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varTex0.xy += addDrop(UNI_Drop06, pos, dxMul);\n" +
3594ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varTex0.xy += addDrop(UNI_Drop07, pos, dxMul);\n" +
3604ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varTex0.xy += addDrop(UNI_Drop08, pos, dxMul);\n" +
3614ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varTex0.xy += addDrop(UNI_Drop09, pos, dxMul);\n" +
3624ace270249d25302d027edd3a471aef94ab4e759Jason Sams                "  varTex0.xy += addDrop(UNI_Drop10, pos, dxMul);\n" +
3639a2bf356a59957a4bb8414744b913eb1dc3e9771Romain Guy                "}\n";
3644754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
3656a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams        sb.setShader(t);
3666a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams        sb.addConstant(mUniformAlloc.getType());
367359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk        sb.addInput(mMesh.getVertexAllocation(0).getType().getElement());
3686a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams        mPvWater = sb.create();
369a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        mPvWater.bindConstants(mUniformAlloc, 0);
3706a500a1d5e15bd5a563995f31d0796552cc13640Jason Sams
3714754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        mScript.set_g_PVWater(mPvWater);
3724754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
37359206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
37459206df88081556d0bf538234da0b455cc7bb095Romain Guy
37559206df88081556d0bf538234da0b455cc7bb095Romain Guy    void addDrop(float x, float y) {
3764754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        int dropX = (int) ((x / mWidth) * mMeshWidth);
3774754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk        int dropY = (int) ((y / mHeight) * mMeshHeight);
3784754f87b228e0c2f9d4723e927dfc04a2b2401a1Alex Sakhartchouk
379843c77f4841670c95284c7243d61f5d77f6e5ff7Jeff Brown        mScript.invoke_addDrop(dropX, dropY);
38059206df88081556d0bf538234da0b455cc7bb095Romain Guy    }
381791703ecfaecc7fee4c86a36f06634aa14bfde0cShih-wei Liao}
382