1e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy/*
2e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy * Copyright (C) 2009 The Android Open Source Project
3e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy *
4e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy * you may not use this file except in compliance with the License.
6e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy * You may obtain a copy of the License at
7e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy *
8e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy *
10e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy * Unless required by applicable law or agreed to in writing, software
11e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy * See the License for the specific language governing permissions and
14e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy * limitations under the License.
15e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy */
16e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
17e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guypackage com.android.wallpaper.galaxy;
18e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
1976faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchoukimport android.renderscript.*;
2076faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchoukimport android.renderscript.Mesh.Primitive;
21e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guyimport static android.renderscript.ProgramStore.DepthFunc.*;
22e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guyimport static android.renderscript.ProgramStore.BlendDstFunc;
23e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guyimport static android.renderscript.ProgramStore.BlendSrcFunc;
24e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guyimport static android.renderscript.Element.*;
25fd1b3b35498508878dc41f22a270df95db316e4bRomain Guyimport android.graphics.Bitmap;
26fd1b3b35498508878dc41f22a270df95db316e4bRomain Guyimport android.graphics.BitmapFactory;
27e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
28e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guyimport java.util.TimeZone;
29e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
30e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guyimport com.android.wallpaper.R;
3144da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guyimport com.android.wallpaper.RenderScriptScene;
32e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
3344da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guyclass GalaxyRS extends RenderScriptScene {
34e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    private static final int PARTICLES_COUNT = 12000;
35fd1b3b35498508878dc41f22a270df95db316e4bRomain Guy    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
3676faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk    private ProgramVertexFixedFunction.Constants mPvOrthoAlloc;
3776faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk    private ProgramVertexFixedFunction.Constants mPvProjectionAlloc;
38a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk    private ScriptField_VpConsts mPvStarAlloc;
39359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk    private Mesh mParticlesMesh;
405f5044f59065ac339b175bb8a47ea6be861f925cStephen Hines    private ScriptC_galaxy mScript;
41e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
4244da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy    GalaxyRS(int width, int height) {
4344da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy        super(width, height);
44fd1b3b35498508878dc41f22a270df95db316e4bRomain Guy
45fd1b3b35498508878dc41f22a270df95db316e4bRomain Guy        mOptionsARGB.inScaled = false;
46fd1b3b35498508878dc41f22a270df95db316e4bRomain Guy        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
47e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    }
48e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
4944da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy    @Override
5044da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy    protected ScriptC createScript() {
5176469b31f1bda22057330a0146d9296df92b9094Jason Sams        mScript = new ScriptC_galaxy(mRS, mResources, R.raw.galaxy);
5289f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gIsPreview(isPreview() ? 1 : 0);
5389f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        if (isPreview()) {
5489f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams            mScript.set_gXOffset(0.5f);
5589f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        }
5689f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams
5789f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams
5889f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        createParticlesMesh();
59e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy        createProgramVertex();
605d43b50fb2a88c6166a7c3b25c4d39d7522cd308Jason Sams        createProgramRaster();
61e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy        createProgramFragmentStore();
62e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy        createProgramFragment();
63e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy        loadTextures();
64e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
6589f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.setTimeZone(TimeZone.getDefault().getID());
6689f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        return mScript;
67e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    }
68e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
69e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    private void createParticlesMesh() {
7089f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        ScriptField_Particle p = new ScriptField_Particle(mRS, PARTICLES_COUNT);
71e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
72359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk        final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS);
7376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        meshBuilder.addVertexAllocation(p.getAllocation());
7476faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        final int vertexSlot = meshBuilder.getCurrentVertexTypeIndex();
7576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        meshBuilder.addIndexSetType(Primitive.POINT);
76e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy        mParticlesMesh = meshBuilder.create();
77e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
7889f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gParticlesMesh(mParticlesMesh);
7989f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.bind_Particles(p);
80e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    }
81e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
82a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk    private Matrix4f getProjectionNormalized(int w, int h) {
83a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        // range -1,1 in the narrow axis at z = 0.
84a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        Matrix4f m1 = new Matrix4f();
85a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        Matrix4f m2 = new Matrix4f();
86a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk
87a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        if(w > h) {
88a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk            float aspect = ((float)w) / h;
89a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk            m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
90a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        } else {
91a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk            float aspect = ((float)h) / w;
92a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk            m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
93a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        }
94a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk
95a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        m2.loadRotate(180, 0, 1, 0);
96a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        m1.loadMultiply(m1, m2);
97a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk
98a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        m2.loadScale(-2, 2, 1);
99a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        m1.loadMultiply(m1, m2);
100a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk
101a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        m2.loadTranslate(0, 0, 2);
102a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        m1.loadMultiply(m1, m2);
103a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        return m1;
104a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk    }
105a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk
106a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk    private void updateProjectionMatrices() {
10776faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        Matrix4f proj = new Matrix4f();
10876faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        proj.loadOrthoWindow(mWidth, mHeight);
10976faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        mPvOrthoAlloc.setProjection(proj);
110a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk
111a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        Matrix4f projNorm = getProjectionNormalized(mWidth, mHeight);
112a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
113a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        i.Proj = projNorm;
114a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        i.MVP = projNorm;
115a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        mPvStarAlloc.set(i, 0, true);
11676faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        mPvProjectionAlloc.setProjection(projNorm);
117a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk    }
118a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk
11944da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy    @Override
12044da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy    public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
12189f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gXOffset(xOffset);
1229e6f2347087ab40539b4c4b76f4b050f02184436Romain Guy    }
1239e6f2347087ab40539b4c4b76f4b050f02184436Romain Guy
12444da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy    @Override
12544da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy    public void resize(int width, int height) {
12644da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy        super.resize(width, height);
1279e6f2347087ab40539b4c4b76f4b050f02184436Romain Guy
128a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        updateProjectionMatrices();
129e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    }
130e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
131e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    private void loadTextures() {
13289f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gTSpace(loadTexture(R.drawable.space));
13389f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gTLight1(loadTexture(R.drawable.light1));
13489f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gTFlares(loadTextureARGB(R.drawable.flares));
135e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    }
136e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
13789f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams    private Allocation loadTexture(int id) {
13836fec1d691a2db23a0a4b110b4db6c5742b29968Jason Sams        final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources, id,
13936fec1d691a2db23a0a4b110b4db6c5742b29968Jason Sams                                           Allocation.MipmapControl.MIPMAP_NONE,
14036fec1d691a2db23a0a4b110b4db6c5742b29968Jason Sams                                           Allocation.USAGE_GRAPHICS_TEXTURE);
141e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy        return allocation;
142e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    }
143e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
144fd1b3b35498508878dc41f22a270df95db316e4bRomain Guy    // TODO: Fix Allocation.createFromBitmapResource() to do this when RGBA_8888 is specified
14589f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams    private Allocation loadTextureARGB(int id) {
146fd1b3b35498508878dc41f22a270df95db316e4bRomain Guy        Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
14736fec1d691a2db23a0a4b110b4db6c5742b29968Jason Sams        final Allocation allocation = Allocation.createFromBitmap(mRS, b,
14836fec1d691a2db23a0a4b110b4db6c5742b29968Jason Sams                                           Allocation.MipmapControl.MIPMAP_NONE,
14936fec1d691a2db23a0a4b110b4db6c5742b29968Jason Sams                                           Allocation.USAGE_GRAPHICS_TEXTURE);
150fd1b3b35498508878dc41f22a270df95db316e4bRomain Guy        return allocation;
151fd1b3b35498508878dc41f22a270df95db316e4bRomain Guy    }
152fd1b3b35498508878dc41f22a270df95db316e4bRomain Guy
153e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    private void createProgramFragment() {
15476faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
15576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
15676faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk                           ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
15789f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        ProgramFragment pfb = builder.create();
15889f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        pfb.bindSampler(Sampler.WRAP_NEAREST(mRS), 0);
15989f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gPFBackground(pfb);
160909dff3d19912a810aa1b51a4fac514a41cf139eRomain Guy
16176faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder = new ProgramFragmentFixedFunction.Builder(mRS);
162909dff3d19912a810aa1b51a4fac514a41cf139eRomain Guy        builder.setPointSpriteTexCoordinateReplacement(true);
16376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
16476faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
1655dde25d38dd72a709c7e7e6c9dd7975d39bd8b0aJason Sams        builder.setVaryingColor(true);
16689f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        ProgramFragment pfs = builder.create();
16789f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        pfs.bindSampler(Sampler.WRAP_LINEAR(mRS), 0);
16889f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gPFStars(pfs);
169e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    }
170e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
171e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    private void createProgramFragmentStore() {
17276faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
173e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
17476469b31f1bda22057330a0146d9296df92b9094Jason Sams        mRS.bindProgramStore(builder.create());
17516b673ef8cf81f7518a3313cf90a4e1c7b080cfeJason Sams
176909dff3d19912a810aa1b51a4fac514a41cf139eRomain Guy        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
17789f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gPSLights(builder.create());
178e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    }
179e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
180e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    private void createProgramVertex() {
18176faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(mRS);
182e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy
18376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ProgramVertexFixedFunction.Builder builder = new ProgramVertexFixedFunction.Builder(mRS);
18489f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        ProgramVertex pvbo = builder.create();
18576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ((ProgramVertexFixedFunction)pvbo).bindConstants(mPvOrthoAlloc);
18676469b31f1bda22057330a0146d9296df92b9094Jason Sams        mRS.bindProgramVertex(pvbo);
1875d43b50fb2a88c6166a7c3b25c4d39d7522cd308Jason Sams
188a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        mPvStarAlloc = new ScriptField_VpConsts(mRS, 1);
189a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        mScript.bind_vpConstants(mPvStarAlloc);
19076faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        mPvProjectionAlloc = new ProgramVertexFixedFunction.Constants(mRS);
191a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        updateProjectionMatrices();
192909dff3d19912a810aa1b51a4fac514a41cf139eRomain Guy
19376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        builder = new ProgramVertexFixedFunction.Builder(mRS);
19489f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        ProgramVertex pvbp = builder.create();
19576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ((ProgramVertexFixedFunction)pvbp).bindConstants(mPvProjectionAlloc);
19689f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gPVBkProj(pvbp);
19740cc801af8128aa88b229a64baae7f6f69c770ddJason Sams
19876faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
199a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        String t =  "varying vec4 varColor;\n" +
2001462bbbccb3f4bd3a6f3b76e8caf5c8947a863bfAlex Sakhartchouk                    "varying vec2 varTex0;\n" +
201a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk                    "void main() {\n" +
202757dedabc226071faee893bba718add2990353baRomain Guy                    "  float dist = ATTRIB_position.y;\n" +
203757dedabc226071faee893bba718add2990353baRomain Guy                    "  float angle = ATTRIB_position.x;\n" +
204757dedabc226071faee893bba718add2990353baRomain Guy                    "  float x = dist * sin(angle);\n" +
205757dedabc226071faee893bba718add2990353baRomain Guy                    "  float y = dist * cos(angle) * 0.892;\n" +
206757dedabc226071faee893bba718add2990353baRomain Guy                    "  float p = dist * 5.5;\n" +
207757dedabc226071faee893bba718add2990353baRomain Guy                    "  float s = cos(p);\n" +
208757dedabc226071faee893bba718add2990353baRomain Guy                    "  float t = sin(p);\n" +
209757dedabc226071faee893bba718add2990353baRomain Guy                    "  vec4 pos;\n" +
210757dedabc226071faee893bba718add2990353baRomain Guy                    "  pos.x = t * x + s * y;\n" +
211757dedabc226071faee893bba718add2990353baRomain Guy                    "  pos.y = s * x - t * y;\n" +
212757dedabc226071faee893bba718add2990353baRomain Guy                    "  pos.z = ATTRIB_position.z;\n" +
213757dedabc226071faee893bba718add2990353baRomain Guy                    "  pos.w = 1.0;\n" +
214757dedabc226071faee893bba718add2990353baRomain Guy                    "  gl_Position = UNI_MVP * pos;\n" +
215757dedabc226071faee893bba718add2990353baRomain Guy                    "  gl_PointSize = ATTRIB_color.a * 10.0;\n" +
216757dedabc226071faee893bba718add2990353baRomain Guy                    "  varColor.rgb = ATTRIB_color.rgb;\n" +
217757dedabc226071faee893bba718add2990353baRomain Guy                    "  varColor.a = 1.0;\n" +
218757dedabc226071faee893bba718add2990353baRomain Guy                    "}\n";
21940cc801af8128aa88b229a64baae7f6f69c770ddJason Sams        sb.setShader(t);
220359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk        sb.addInput(mParticlesMesh.getVertexAllocation(0).getType().getElement());
221a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        sb.addConstant(mPvStarAlloc.getType());
22289f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        ProgramVertex pvs = sb.create();
223a459fdb58267ada5d7f49929c53ba1af2be08c2dAlex Sakhartchouk        pvs.bindConstants(mPvStarAlloc.getAllocation(), 0);
22489f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        mScript.set_gPVStars(pvs);
225e04d27e0532ed819f7bc790917ff7f24c4338b6fRomain Guy    }
2265d43b50fb2a88c6166a7c3b25c4d39d7522cd308Jason Sams
2275d43b50fb2a88c6166a7c3b25c4d39d7522cd308Jason Sams    private void createProgramRaster() {
2281ba864e729a2e6a55a6ffc1d5b67a0574faf92fbAlex Sakhartchouk        ProgramRaster.Builder b = new ProgramRaster.Builder(mRS);
22976faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk        b.setPointSpriteEnabled(true);
23089f5dba9390df29e8887049ca1c9f9afcc747da5Jason Sams        ProgramRaster pr = b.create();
23176469b31f1bda22057330a0146d9296df92b9094Jason Sams        mRS.bindProgramRaster(pr);
2325d43b50fb2a88c6166a7c3b25c4d39d7522cd308Jason Sams    }
2335d43b50fb2a88c6166a7c3b25c4d39d7522cd308Jason Sams
234909dff3d19912a810aa1b51a4fac514a41cf139eRomain Guy}
235