1a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk/*
2a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Copyright (C) 2011 The Android Open Source Project
3a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk *
4a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License");
5a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * you may not use this file except in compliance with the License.
6a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * You may obtain a copy of the License at
7a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk *
8a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk *      http://www.apache.org/licenses/LICENSE-2.0
9a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk *
10a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Unless required by applicable law or agreed to in writing, software
11a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS,
12a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * See the License for the specific language governing permissions and
14a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * limitations under the License.
15a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk */
16a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
17a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukpackage com.android.scenegraph;
18a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
1961440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchoukimport java.io.BufferedInputStream;
20e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport java.io.File;
2161440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchoukimport java.io.FileInputStream;
22e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport java.io.IOException;
23e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport java.io.InputStream;
24e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport java.io.Writer;
25a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.lang.Math;
26a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.ArrayList;
27a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.HashMap;
28a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.regex.Matcher;
29a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.regex.Pattern;
30a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
316f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchoukimport com.android.scenegraph.Camera;
32c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchoukimport com.android.scenegraph.FragmentShader;
336f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchoukimport com.android.scenegraph.MatrixTransform;
3461440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchoukimport com.android.scenegraph.Scene;
35c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchoukimport com.android.scenegraph.VertexShader;
366f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchoukimport com.android.testapp.R;
3761440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk
3861440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchoukimport android.content.res.Resources;
39e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport android.graphics.Bitmap;
40e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport android.graphics.BitmapFactory;
4161440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchoukimport android.os.AsyncTask;
42a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.*;
43a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.Allocation.MipmapControl;
4461440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchoukimport android.renderscript.Mesh;
4561440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchoukimport android.renderscript.RenderScriptGL;
46a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.util.Log;
4761440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchoukimport android.view.SurfaceHolder;
48a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
49a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk/**
50a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * @hide
51a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk */
52a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukpublic class SceneManager extends SceneGraphBase {
53a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
54e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk    HashMap<String, Allocation> mAllocationMap;
55e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk
56a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    ScriptC_render mRenderLoop;
574fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    ScriptC mCameraScript;
584fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    ScriptC mLightScript;
594fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    ScriptC mObjectParamsScript;
604fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    ScriptC mFragmentParamsScript;
614fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    ScriptC mVertexParamsScript;
624fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    ScriptC mCullScript;
63a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    ScriptC_transform mTransformScript;
64e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk    ScriptC_export mExportScript;
65a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
66a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    RenderScriptGL mRS;
67a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    Resources mRes;
68a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    Mesh mQuad;
69a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    int mWidth;
70a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    int mHeight;
71a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
7261440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk    Scene mActiveScene;
7361440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk    private static SceneManager sSceneManager;
7461440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk
75071e54d7a3b21ea5eeabff49ac979952b38c77a5Alex Sakhartchouk    private Allocation mDefault2D;
76071e54d7a3b21ea5eeabff49ac979952b38c77a5Alex Sakhartchouk    private Allocation mDefaultCube;
77e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
78c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    private FragmentShader mColor;
79c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    private FragmentShader mTexture;
80c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    private VertexShader mDefaultVertex;
81c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
82c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    private RenderState mDefaultState;
83d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk    private Transform mDefaultTransform;
84c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
85e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk    private static Allocation getDefault(boolean isCube) {
86e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        final int dimension = 4;
87e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        final int bytesPerPixel = 4;
88e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        int arraySize = dimension * dimension * bytesPerPixel;
89e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
90e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        RenderScriptGL rs = sSceneManager.mRS;
91e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        Type.Builder b = new Type.Builder(rs, Element.RGBA_8888(rs));
92e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        b.setX(dimension).setY(dimension);
93e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        if (isCube) {
94e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk            b.setFaces(true);
95e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk            arraySize *= 6;
96e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        }
97e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        Type bitmapType = b.create();
98e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
99e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        Allocation.MipmapControl mip = Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
100e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        int usage =  Allocation.USAGE_GRAPHICS_TEXTURE;
101e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        Allocation defaultImage = Allocation.createTyped(rs, bitmapType, mip, usage);
102e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
103e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        byte imageData[] = new byte[arraySize];
104e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        defaultImage.copyFrom(imageData);
105e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        return defaultImage;
106e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk    }
107e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
108e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk    static Allocation getDefaultTex2D() {
109e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        if (sSceneManager == null) {
110e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk            return null;
111e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        }
112c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (sSceneManager.mDefault2D == null) {
113c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            sSceneManager.mDefault2D = getDefault(false);
114c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
115071e54d7a3b21ea5eeabff49ac979952b38c77a5Alex Sakhartchouk        return sSceneManager.mDefault2D;
116e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk    }
117e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
118e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk    static Allocation getDefaultTexCube() {
119e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        if (sSceneManager == null) {
120e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk            return null;
121e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        }
122c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (sSceneManager.mDefaultCube == null) {
123c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            sSceneManager.mDefaultCube = getDefault(true);
124c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
125071e54d7a3b21ea5eeabff49ac979952b38c77a5Alex Sakhartchouk        return sSceneManager.mDefaultCube;
126e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk    }
127e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
128f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk    public static boolean isSDCardPath(String path) {
129f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        int sdCardIndex = path.indexOf("sdcard/");
130f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        // We are looking for /sdcard/ or sdcard/
131f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        if (sdCardIndex == 0 || sdCardIndex == 1) {
132f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk            return true;
133f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        }
134f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        sdCardIndex = path.indexOf("mnt/sdcard/");
135f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        if (sdCardIndex == 0 || sdCardIndex == 1) {
136f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk            return true;
137f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        }
138f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        return false;
139f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk    }
140f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk
141e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    static Bitmap loadBitmap(String name, Resources res) {
142e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        InputStream is = null;
143e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        boolean loadFromSD = isSDCardPath(name);
144e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        try {
145e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            if (!loadFromSD) {
146e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk                is = res.getAssets().open(name);
147e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            } else {
148e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk                File f = new File(name);
149e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk                is = new BufferedInputStream(new FileInputStream(f));
150e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            }
151e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        } catch (IOException e) {
152e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            Log.e("ImageLoaderTask", " Message: " + e.getMessage());
153e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            return null;
154e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        }
155e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk
156e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        Bitmap b = BitmapFactory.decodeStream(is);
157e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        try {
158e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            is.close();
159e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        } catch (IOException e) {
160e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            Log.e("ImageLoaderTask", " Message: " + e.getMessage());
161e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        }
162e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        return b;
163e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    }
164e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk
165d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk    static Allocation createFromBitmap(Bitmap b, RenderScriptGL rs, boolean isCube) {
166a9eb319965da1f2d59c06135d0d8d4631312bfffAlex Sakhartchouk        if (b == null) {
167a9eb319965da1f2d59c06135d0d8d4631312bfffAlex Sakhartchouk            return null;
168a9eb319965da1f2d59c06135d0d8d4631312bfffAlex Sakhartchouk        }
169d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        MipmapControl mip = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
170d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        int usage = Allocation.USAGE_GRAPHICS_TEXTURE;
171d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        if (isCube) {
172d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk            return Allocation.createCubemapFromBitmap(rs, b, mip, usage);
173d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        }
174d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        return Allocation.createFromBitmap(rs, b, mip, usage);
175d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk    }
176d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk
177d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk    public static Allocation loadCubemap(String name, RenderScriptGL rs, Resources res) {
178d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        return createFromBitmap(loadBitmap(name, res), rs, true);
179d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk    }
180d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk
181d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk    public static Allocation loadCubemap(int id, RenderScriptGL rs, Resources res) {
182d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        return createFromBitmap(BitmapFactory.decodeResource(res, id), rs, true);
183e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    }
184e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk
185e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    public static Allocation loadTexture2D(String name, RenderScriptGL rs, Resources res) {
186d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        return createFromBitmap(loadBitmap(name, res), rs, false);
187d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk    }
188d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk
189d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk    public static Allocation loadTexture2D(int id, RenderScriptGL rs, Resources res) {
190d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        return createFromBitmap(BitmapFactory.decodeResource(res, id), rs, false);
191e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    }
192e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk
193ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk    public static ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
194ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
195ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
196ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk        builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
197ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk        builder.setDitherEnabled(false);
198ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk        builder.setDepthMaskEnabled(false);
199ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk        return builder.create();
200ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk    }
201ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk
202ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk    static Allocation getStringAsAllocation(RenderScript rs, String str) {
203ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        if (str == null) {
204ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk            return null;
205ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        }
206ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        if (str.length() == 0) {
207ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk            return null;
208ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        }
209ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        byte[] allocArray = null;
210ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        byte[] nullChar = new byte[1];
211ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        nullChar[0] = 0;
212ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        try {
213ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk            allocArray = str.getBytes("UTF-8");
214ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk            Allocation alloc = Allocation.createSized(rs, Element.U8(rs),
215ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk                                                      allocArray.length + 1,
216ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk                                                      Allocation.USAGE_SCRIPT);
217ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk            alloc.copy1DRangeFrom(0, allocArray.length, allocArray);
218ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk            alloc.copy1DRangeFrom(allocArray.length, 1, nullChar);
219ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk            return alloc;
220ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        }
221ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        catch (Exception e) {
222ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk            throw new RSRuntimeException("Could not convert string to utf-8.");
223ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk        }
224ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk    }
225ee1031d1a280924bf9485b80638dc61d2812b12aAlex Sakhartchouk
226e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk    static Allocation getCachedAlloc(String str) {
227e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk        if (sSceneManager == null) {
228e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk            throw new RuntimeException("Scene manager not initialized");
229e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk        }
230e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk        return sSceneManager.mAllocationMap.get(str);
231e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk    }
232e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk
233e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk    static void cacheAlloc(String str, Allocation alloc) {
234e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk        if (sSceneManager == null) {
235e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk            throw new RuntimeException("Scene manager not initialized");
236e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk        }
237e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk        sSceneManager.mAllocationMap.put(str, alloc);
238e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk    }
239e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk
240a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public static class SceneLoadedCallback implements Runnable {
241d4cb9c587c23e3c24d928b0ac1a4de5679846f93Alex Sakhartchouk        public Scene mLoadedScene;
242d4cb9c587c23e3c24d928b0ac1a4de5679846f93Alex Sakhartchouk        public String mName;
243a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        public void run() {
244a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        }
245a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
246a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
24761440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk    public Scene getActiveScene() {
24861440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk        return mActiveScene;
24961440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk    }
25061440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk
25161440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk    public void setActiveScene(Scene s) {
25261440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk        mActiveScene = s;
2536f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk
254c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (mActiveScene == null) {
255c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            return;
256c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
257c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
2586f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk        // Do some sanity checking
2596f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk        if (mActiveScene.getCameras().size() == 0) {
2606f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk            Matrix4f camPos = new Matrix4f();
2616f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk            camPos.translate(0, 0, 10);
2626f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk            MatrixTransform cameraTransform = new MatrixTransform();
2636f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk            cameraTransform.setName("_DefaultCameraTransform");
2646f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk            cameraTransform.setMatrix(camPos);
2656f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk            mActiveScene.appendTransform(cameraTransform);
2666f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk            Camera cam = new Camera();
2676f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk            cam.setName("_DefaultCamera");
2686f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk            cam.setTransform(cameraTransform);
2696f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk            mActiveScene.appendCamera(cam);
2706f31c36a3dbe5e61644ec39c4fcad0284d50e4f1Alex Sakhartchouk        }
271c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
272c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        mActiveScene.appendShader(getDefaultVS());
273d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        mActiveScene.appendTransform(getDefaultTransform());
27461440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk    }
27561440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk
276e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk    static RenderScriptGL getRS() {
277e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        if (sSceneManager == null) {
278e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk            return null;
279e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        }
280e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        return sSceneManager.mRS;
281e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk    }
282e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk
283e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk    static Resources getRes() {
284e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        if (sSceneManager == null) {
285e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk            return null;
286e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        }
287e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        return sSceneManager.mRes;
288e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk    }
289e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk
290c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    // Provides the folowing inputs to fragment shader
291c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    // Assigned by default if nothing is present
292c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    // vec3 varWorldPos;
293c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    // vec3 varWorldNormal;
294c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    // vec2 varTex0;
295c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    public static VertexShader getDefaultVS() {
296c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (sSceneManager == null) {
297c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            return null;
298c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
299c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
300c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (sSceneManager.mDefaultVertex == null) {
301c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            RenderScriptGL rs = getRS();
302c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            Element.Builder b = new Element.Builder(rs);
303c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            b.add(Element.MATRIX_4X4(rs), "model");
304c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            Type.Builder objConstBuilder = new Type.Builder(rs, b.create());
305c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
306c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            b = new Element.Builder(rs);
307c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            b.add(Element.MATRIX_4X4(rs), "viewProj");
308c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            Type.Builder shaderConstBuilder = new Type.Builder(rs, b.create());
309c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
310c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            b = new Element.Builder(rs);
311c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            b.add(Element.F32_4(rs), "position");
312c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            b.add(Element.F32_2(rs), "texture0");
313c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            b.add(Element.F32_3(rs), "normal");
314c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            Element defaultIn = b.create();
315c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
316c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            final String code = "\n" +
317c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "varying vec3 varWorldPos;\n" +
318c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "varying vec3 varWorldNormal;\n" +
319c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "varying vec2 varTex0;\n" +
320c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "void main() {" +
321c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "   vec4 objPos = ATTRIB_position;\n" +
322c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "   vec4 worldPos = UNI_model * objPos;\n" +
323c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "   gl_Position = UNI_viewProj * worldPos;\n" +
324c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);\n" +
325c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "   vec3 worldNorm = model3 * ATTRIB_normal;\n" +
326c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "   varWorldPos = worldPos.xyz;\n" +
327c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "   varWorldNormal = worldNorm;\n" +
328c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "   varTex0 = ATTRIB_texture0;\n" +
329c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "}\n";
330c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
331c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            VertexShader.Builder sb = new VertexShader.Builder(rs);
332c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            sb.addInput(defaultIn);
333c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            sb.setObjectConst(objConstBuilder.setX(1).create());
334c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            sb.setShaderConst(shaderConstBuilder.setX(1).create());
335c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            sb.setShader(code);
336c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            sSceneManager.mDefaultVertex = sb.create();
337c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
338c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
339c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        return sSceneManager.mDefaultVertex;
340c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    }
341c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
342c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    public static FragmentShader getColorFS() {
343c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (sSceneManager == null) {
344c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            return null;
345c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
346c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (sSceneManager.mColor == null) {
347c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            RenderScriptGL rs = getRS();
348c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            Element.Builder b = new Element.Builder(rs);
349c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            b.add(Element.F32_4(rs), "color");
350c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            Type.Builder objConstBuilder = new Type.Builder(rs, b.create());
351c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
352c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            final String code = "\n" +
353c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "varying vec2 varTex0;\n" +
354c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "void main() {\n" +
35557fc7109e4e1ec0a32d1661779e8d7babab0279bAlex Sakhartchouk                "   lowp vec4 col = UNI_color;\n" +
356c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "   gl_FragColor = col;\n" +
357c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "}\n";
358c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            FragmentShader.Builder fb = new FragmentShader.Builder(rs);
359c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            fb.setShader(code);
360c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            fb.setObjectConst(objConstBuilder.create());
361c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            sSceneManager.mColor = fb.create();
362c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
363c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
364c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        return sSceneManager.mColor;
365c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    }
366c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
367c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    public static FragmentShader getTextureFS() {
368c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (sSceneManager == null) {
369c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            return null;
370c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
371c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (sSceneManager.mTexture == null) {
372c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            RenderScriptGL rs = getRS();
37357fc7109e4e1ec0a32d1661779e8d7babab0279bAlex Sakhartchouk
374c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            final String code = "\n" +
375c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "varying vec2 varTex0;\n" +
376c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "void main() {\n" +
377d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk                "   lowp vec4 col = texture2D(UNI_color, varTex0).rgba;\n" +
378c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "   gl_FragColor = col;\n" +
379c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                "}\n";
38057fc7109e4e1ec0a32d1661779e8d7babab0279bAlex Sakhartchouk
381c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            FragmentShader.Builder fb = new FragmentShader.Builder(rs);
382c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            fb.setShader(code);
383d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk            fb.addTexture(Program.TextureType.TEXTURE_2D, "color");
384c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            sSceneManager.mTexture = fb.create();
385d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk            sSceneManager.mTexture.mProgram.bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(rs), 0);
386c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
387c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
388c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        return sSceneManager.mTexture;
389c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    }
390c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
391c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    static RenderState getDefaultState() {
392c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (sSceneManager == null) {
393c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            return null;
394c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
395c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        if (sSceneManager.mDefaultState == null) {
396c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            sSceneManager.mDefaultState = new RenderState(getDefaultVS(), getColorFS(), null, null);
397d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk            sSceneManager.mDefaultState.setName("__DefaultState");
398c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
399c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        return sSceneManager.mDefaultState;
400c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk    }
401c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
402d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk    static Transform getDefaultTransform() {
403d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        if (sSceneManager == null) {
404d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk            return null;
405d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        }
406d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        if (sSceneManager.mDefaultTransform == null) {
407d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk            sSceneManager.mDefaultTransform = new MatrixTransform();
408d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk            sSceneManager.mDefaultTransform.setName("__DefaultTransform");
409d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        }
410d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        return sSceneManager.mDefaultTransform;
411d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk    }
412d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk
41361440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk    public static SceneManager getInstance() {
41461440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk        if (sSceneManager == null) {
41561440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk            sSceneManager = new SceneManager();
41661440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk        }
41761440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk        return sSceneManager;
41861440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk    }
41961440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk
42061440e8a8bc5d0d3c7edc66eccb609e5f07fea6eAlex Sakhartchouk    protected SceneManager() {
421a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
422a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
423a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public void loadModel(String name, SceneLoadedCallback cb) {
424a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        ColladaScene scene = new ColladaScene(name, cb);
425a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        scene.init(mRS, mRes);
426a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
427a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
428a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public Mesh getScreenAlignedQuad() {
429a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        if (mQuad != null) {
430a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk            return mQuad;
431a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        }
432a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
433a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
434a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk                                           3, Mesh.TriangleMeshBuilder.TEXTURE_0);
435a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
43657fc7109e4e1ec0a32d1661779e8d7babab0279bAlex Sakhartchouk        tmb.setTexture(0.0f, 1.0f).addVertex(-1.0f, 1.0f, 1.0f);
43757fc7109e4e1ec0a32d1661779e8d7babab0279bAlex Sakhartchouk        tmb.setTexture(0.0f, 0.0f).addVertex(-1.0f, -1.0f, 1.0f);
43857fc7109e4e1ec0a32d1661779e8d7babab0279bAlex Sakhartchouk        tmb.setTexture(1.0f, 0.0f).addVertex(1.0f, -1.0f, 1.0f);
43957fc7109e4e1ec0a32d1661779e8d7babab0279bAlex Sakhartchouk        tmb.setTexture(1.0f, 1.0f).addVertex(1.0f, 1.0f, 1.0f);
440a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
441a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.addTriangle(0, 1, 2);
442a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.addTriangle(2, 3, 0);
443a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
444a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mQuad = tmb.create(true);
445a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        return mQuad;
446a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
447a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
448f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk    public Renderable getRenderableQuad(String name, RenderState state) {
449f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        Renderable quad = new Renderable();
450f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        quad.setTransform(new MatrixTransform());
451f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        quad.setMesh(getScreenAlignedQuad());
452f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        quad.setName(name);
453f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        quad.setRenderState(state);
454f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        quad.setCullType(1);
455f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        return quad;
456f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk    }
457f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk
458a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public void initRS(RenderScriptGL rs, Resources res, int w, int h) {
459a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRS = rs;
460a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRes = res;
461e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk        mAllocationMap = new HashMap<String, Allocation>();
462e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk
463071e54d7a3b21ea5eeabff49ac979952b38c77a5Alex Sakhartchouk        mQuad = null;
464c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        mDefault2D = null;
465c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        mDefaultCube = null;
466c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        mDefaultVertex = null;
467c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        mColor = null;
468c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        mTexture = null;
469c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        mDefaultState = null;
470d2dc9838961f945c402e5d810bc715196240be6fAlex Sakhartchouk        mDefaultTransform = null;
471071e54d7a3b21ea5eeabff49ac979952b38c77a5Alex Sakhartchouk
472e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk        mExportScript = new ScriptC_export(rs, res, R.raw.export);
473e92c78ccd095ae1cb47198afb664f98571ce2148Alex Sakhartchouk
474a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mTransformScript = new ScriptC_transform(rs, res, R.raw.transform);
475a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mTransformScript.set_gTransformScript(mTransformScript);
476a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
477a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mCameraScript = new ScriptC_camera(rs, res, R.raw.camera);
478875a538d5db06e7e055401050e03b86bf8598536Alex Sakhartchouk        mLightScript = new ScriptC_light(rs, res, R.raw.light);
4794fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        mObjectParamsScript = new ScriptC_object_params(rs, res, R.raw.object_params);
4804fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        mFragmentParamsScript = new ScriptC_object_params(rs, res, R.raw.fragment_params);
4814fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        mVertexParamsScript = new ScriptC_object_params(rs, res, R.raw.vertex_params);
482ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk        mCullScript = new ScriptC_cull(rs, res, R.raw.cull);
483a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
484a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRenderLoop = new ScriptC_render(rs, res, R.raw.render);
485a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRenderLoop.set_gTransformScript(mTransformScript);
486a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRenderLoop.set_gCameraScript(mCameraScript);
487875a538d5db06e7e055401050e03b86bf8598536Alex Sakhartchouk        mRenderLoop.set_gLightScript(mLightScript);
4884fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        mRenderLoop.set_gObjectParamsScript(mObjectParamsScript);
4894fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        mRenderLoop.set_gFragmentParamsScript(mFragmentParamsScript);
4904fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        mRenderLoop.set_gVertexParamsScript(mVertexParamsScript);
491ce047cb47b761f00593f247a3901fe8155371d47Alex Sakhartchouk        mRenderLoop.set_gCullScript(mCullScript);
492a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
493be5bdeb9471c4a04905edd34e6d3560315293427Alex Sakhartchouk        mRenderLoop.set_gPFSBackground(ProgramStore.BLEND_NONE_DEPTH_TEST(mRS));
494a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
495a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
496a18d676edefbafc0b745ab98edab8f50b1c81c61Alex Sakhartchouk    public ScriptC getRenderLoop() {
497a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        return mRenderLoop;
498a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
499a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk}
500a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
501a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
502a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
503a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
504