Home | History | Annotate | Download | only in renderscript
      1 /*
      2  * Copyright (C) 2008-2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.renderscript;
     18 
     19 import java.util.Vector;
     20 
     21 /**
     22  * @hide
     23  * @deprecated in API 16
     24  * <p>This class is a container for geometric data displayed with
     25  * RenderScript. Internally, a mesh is a collection of allocations that
     26  * represent vertex data (positions, normals, texture
     27  * coordinates) and index data such as triangles and lines. </p>
     28  * <p>
     29  * Vertex data could either be interleaved within one
     30  * allocation that is provided separately, as multiple allocation
     31  * objects, or done as a combination of both. When a
     32  * vertex channel name matches an input in the vertex program,
     33  * RenderScript automatically connects the two together.
     34  * </p>
     35  * <p>
     36  *  Parts of the mesh can be rendered with either explicit
     37  *  index sets or primitive types.
     38  * </p>
     39  **/
     40 public class Mesh extends BaseObj {
     41 
     42     /**
     43     * @deprecated in API 16
     44     * Describes the way mesh vertex data is interpreted when rendering
     45     *
     46     **/
     47     public enum Primitive {
     48         /**
     49         * @deprecated in API 16
     50         * Vertex data will be rendered as a series of points
     51         */
     52         POINT (0),
     53         /**
     54         * @deprecated in API 16
     55         * Vertex pairs will be rendered as lines
     56         */
     57         LINE (1),
     58         /**
     59         * @deprecated in API 16
     60         * Vertex data will be rendered as a connected line strip
     61         */
     62         LINE_STRIP (2),
     63         /**
     64         * @deprecated in API 16
     65         * Vertices will be rendered as individual triangles
     66         */
     67         TRIANGLE (3),
     68         /**
     69         * @deprecated in API 16
     70         * Vertices will be rendered as a connected triangle strip
     71         * defined by the first three vertices with each additional
     72         * triangle defined by a new vertex
     73         */
     74         TRIANGLE_STRIP (4),
     75         /**
     76         * @deprecated in API 16
     77         * Vertices will be rendered as a sequence of triangles that all
     78         * share first vertex as the origin
     79         */
     80         TRIANGLE_FAN (5);
     81 
     82         int mID;
     83         Primitive(int id) {
     84             mID = id;
     85         }
     86     }
     87 
     88     Allocation[] mVertexBuffers;
     89     Allocation[] mIndexBuffers;
     90     Primitive[] mPrimitives;
     91 
     92     Mesh(long id, RenderScript rs) {
     93         super(id, rs);
     94     }
     95 
     96     /**
     97     * @deprecated in API 16
     98     * @return number of allocations containing vertex data
     99     *
    100     **/
    101     public int getVertexAllocationCount() {
    102         if(mVertexBuffers == null) {
    103             return 0;
    104         }
    105         return mVertexBuffers.length;
    106     }
    107     /**
    108     * @deprecated in API 16
    109     * @param slot index in the list of allocations to return
    110     * @return vertex data allocation at the given index
    111     *
    112     **/
    113     public Allocation getVertexAllocation(int slot) {
    114         return mVertexBuffers[slot];
    115     }
    116 
    117     /**
    118     * @deprecated in API 16
    119     * @return number of primitives or index sets in the mesh
    120     *
    121     **/
    122     public int getPrimitiveCount() {
    123         if(mIndexBuffers == null) {
    124             return 0;
    125         }
    126         return mIndexBuffers.length;
    127     }
    128 
    129     /**
    130     * @deprecated in API 16
    131     * @param slot locaton within the list of index set allocation
    132     * @return allocation containing primtive index data or null if
    133     *         the index data is not specified explicitly
    134     *
    135     **/
    136     public Allocation getIndexSetAllocation(int slot) {
    137         return mIndexBuffers[slot];
    138     }
    139     /**
    140     * @deprecated in API 16
    141     * @param slot locaiton within the list of index set primitives
    142     * @return index set primitive type
    143     *
    144     **/
    145     public Primitive getPrimitive(int slot) {
    146         return mPrimitives[slot];
    147     }
    148 
    149     @Override
    150     void updateFromNative() {
    151         super.updateFromNative();
    152         int vtxCount = mRS.nMeshGetVertexBufferCount(getID(mRS));
    153         int idxCount = mRS.nMeshGetIndexCount(getID(mRS));
    154 
    155         long[] vtxIDs = new long[vtxCount];
    156         long[] idxIDs = new long[idxCount];
    157         int[] primitives = new int[idxCount];
    158 
    159         mRS.nMeshGetVertices(getID(mRS), vtxIDs, vtxCount);
    160         mRS.nMeshGetIndices(getID(mRS), idxIDs, primitives, idxCount);
    161 
    162         mVertexBuffers = new Allocation[vtxCount];
    163         mIndexBuffers = new Allocation[idxCount];
    164         mPrimitives = new Primitive[idxCount];
    165 
    166         for(int i = 0; i < vtxCount; i ++) {
    167             if(vtxIDs[i] != 0) {
    168                 mVertexBuffers[i] = new Allocation(vtxIDs[i], mRS, null, Allocation.USAGE_SCRIPT);
    169                 mVertexBuffers[i].updateFromNative();
    170             }
    171         }
    172 
    173         for(int i = 0; i < idxCount; i ++) {
    174             if(idxIDs[i] != 0) {
    175                 mIndexBuffers[i] = new Allocation(idxIDs[i], mRS, null, Allocation.USAGE_SCRIPT);
    176                 mIndexBuffers[i].updateFromNative();
    177             }
    178             mPrimitives[i] = Primitive.values()[primitives[i]];
    179         }
    180     }
    181 
    182     /**
    183     * @deprecated in API 16
    184     * Mesh builder object. It starts empty and requires you to
    185     * add the types necessary to create vertex and index
    186     * allocations.
    187     *
    188     */
    189     public static class Builder {
    190         RenderScript mRS;
    191         int mUsage;
    192 
    193         class Entry {
    194             Type t;
    195             Element e;
    196             int size;
    197             Primitive prim;
    198             int usage;
    199         }
    200 
    201         int mVertexTypeCount;
    202         Entry[] mVertexTypes;
    203         Vector mIndexTypes;
    204 
    205         /**
    206         * @deprecated in API 16
    207         * Creates builder object
    208         * @param rs Context to which the mesh will belong.
    209         * @param usage specifies how the mesh allocations are to be
    210         *              handled, whether they need to be uploaded to a
    211         *              buffer on the gpu, maintain a cpu copy, etc
    212         */
    213         public Builder(RenderScript rs, int usage) {
    214             mRS = rs;
    215             mUsage = usage;
    216             mVertexTypeCount = 0;
    217             mVertexTypes = new Entry[16];
    218             mIndexTypes = new Vector();
    219         }
    220 
    221         /**
    222         * @deprecated in API 16
    223         * @return internal index of the last vertex buffer type added to
    224         *         builder
    225         **/
    226         public int getCurrentVertexTypeIndex() {
    227             return mVertexTypeCount - 1;
    228         }
    229 
    230         /**
    231         * @deprecated in API 16
    232         * @return internal index of the last index set added to the
    233         *         builder
    234         **/
    235         public int getCurrentIndexSetIndex() {
    236             return mIndexTypes.size() - 1;
    237         }
    238 
    239         /**
    240         * @deprecated in API 16
    241         * Adds a vertex data type to the builder object
    242         *
    243         * @param t type of the vertex data allocation to be created
    244         *
    245         * @return this
    246         **/
    247         public Builder addVertexType(Type t) throws IllegalStateException {
    248             if (mVertexTypeCount >= mVertexTypes.length) {
    249                 throw new IllegalStateException("Max vertex types exceeded.");
    250             }
    251 
    252             mVertexTypes[mVertexTypeCount] = new Entry();
    253             mVertexTypes[mVertexTypeCount].t = t;
    254             mVertexTypes[mVertexTypeCount].e = null;
    255             mVertexTypeCount++;
    256             return this;
    257         }
    258 
    259         /**
    260         * @deprecated in API 16
    261         * Adds a vertex data type to the builder object
    262         *
    263         * @param e element describing the vertex data layout
    264         * @param size number of elements in the buffer
    265         *
    266         * @return this
    267         **/
    268         public Builder addVertexType(Element e, int size) throws IllegalStateException {
    269             if (mVertexTypeCount >= mVertexTypes.length) {
    270                 throw new IllegalStateException("Max vertex types exceeded.");
    271             }
    272 
    273             mVertexTypes[mVertexTypeCount] = new Entry();
    274             mVertexTypes[mVertexTypeCount].t = null;
    275             mVertexTypes[mVertexTypeCount].e = e;
    276             mVertexTypes[mVertexTypeCount].size = size;
    277             mVertexTypeCount++;
    278             return this;
    279         }
    280 
    281         /**
    282         * @deprecated in API 16
    283         * Adds an index set data type to the builder object
    284         *
    285         * @param t type of the index set data, could be null
    286         * @param p primitive type
    287         *
    288         * @return this
    289         **/
    290         public Builder addIndexSetType(Type t, Primitive p) {
    291             Entry indexType = new Entry();
    292             indexType.t = t;
    293             indexType.e = null;
    294             indexType.size = 0;
    295             indexType.prim = p;
    296             mIndexTypes.addElement(indexType);
    297             return this;
    298         }
    299 
    300         /**
    301         * @deprecated in API 16
    302         * Adds an index set primitive type to the builder object
    303         *
    304         * @param p primitive type
    305         *
    306         * @return this
    307         **/
    308         public Builder addIndexSetType(Primitive p) {
    309             Entry indexType = new Entry();
    310             indexType.t = null;
    311             indexType.e = null;
    312             indexType.size = 0;
    313             indexType.prim = p;
    314             mIndexTypes.addElement(indexType);
    315             return this;
    316         }
    317 
    318         /**
    319         * @deprecated in API 16
    320         * Adds an index set data type to the builder object
    321         *
    322         * @param e element describing the index set data layout
    323         * @param size number of elements in the buffer
    324         * @param p primitive type
    325         *
    326         * @return this
    327         **/
    328         public Builder addIndexSetType(Element e, int size, Primitive p) {
    329             Entry indexType = new Entry();
    330             indexType.t = null;
    331             indexType.e = e;
    332             indexType.size = size;
    333             indexType.prim = p;
    334             mIndexTypes.addElement(indexType);
    335             return this;
    336         }
    337 
    338         Type newType(Element e, int size) {
    339             Type.Builder tb = new Type.Builder(mRS, e);
    340             tb.setX(size);
    341             return tb.create();
    342         }
    343 
    344         /**
    345         * @deprecated in API 16
    346         * Create a Mesh object from the current state of the builder
    347         *
    348         **/
    349         public Mesh create() {
    350             mRS.validate();
    351             long[] vtx = new long[mVertexTypeCount];
    352             long[] idx = new long[mIndexTypes.size()];
    353             int[] prim = new int[mIndexTypes.size()];
    354 
    355             Allocation[] vertexBuffers = new Allocation[mVertexTypeCount];
    356             Allocation[] indexBuffers = new Allocation[mIndexTypes.size()];
    357             Primitive[] primitives = new Primitive[mIndexTypes.size()];
    358 
    359             for(int ct = 0; ct < mVertexTypeCount; ct ++) {
    360                 Allocation alloc = null;
    361                 Entry entry = mVertexTypes[ct];
    362                 if (entry.t != null) {
    363                     alloc = Allocation.createTyped(mRS, entry.t, mUsage);
    364                 } else if(entry.e != null) {
    365                     alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
    366                 }
    367                 vertexBuffers[ct] = alloc;
    368                 vtx[ct] = alloc.getID(mRS);
    369             }
    370 
    371             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
    372                 Allocation alloc = null;
    373                 Entry entry = (Entry)mIndexTypes.elementAt(ct);
    374                 if (entry.t != null) {
    375                     alloc = Allocation.createTyped(mRS, entry.t, mUsage);
    376                 } else if(entry.e != null) {
    377                     alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
    378                 }
    379                 long allocID = (alloc == null) ? 0 : alloc.getID(mRS);
    380                 indexBuffers[ct] = alloc;
    381                 primitives[ct] = entry.prim;
    382 
    383                 idx[ct] = allocID;
    384                 prim[ct] = entry.prim.mID;
    385             }
    386 
    387             long id = mRS.nMeshCreate(vtx, idx, prim);
    388             Mesh newMesh = new Mesh(id, mRS);
    389             newMesh.mVertexBuffers = vertexBuffers;
    390             newMesh.mIndexBuffers = indexBuffers;
    391             newMesh.mPrimitives = primitives;
    392 
    393             return newMesh;
    394         }
    395     }
    396 
    397     /**
    398     * @deprecated in API 16
    399     * Mesh builder object. It starts empty and requires the user to
    400     * add all the vertex and index allocations that comprise the
    401     * mesh
    402     *
    403     */
    404     public static class AllocationBuilder {
    405         RenderScript mRS;
    406 
    407         class Entry {
    408             Allocation a;
    409             Primitive prim;
    410         }
    411 
    412         int mVertexTypeCount;
    413         Entry[] mVertexTypes;
    414 
    415         Vector mIndexTypes;
    416 
    417         /**
    418         * @deprecated in API 16
    419         **/
    420         public AllocationBuilder(RenderScript rs) {
    421             mRS = rs;
    422             mVertexTypeCount = 0;
    423             mVertexTypes = new Entry[16];
    424             mIndexTypes = new Vector();
    425         }
    426 
    427         /**
    428         * @deprecated in API 16
    429         * @return internal index of the last vertex buffer type added to
    430         *         builder
    431         **/
    432         public int getCurrentVertexTypeIndex() {
    433             return mVertexTypeCount - 1;
    434         }
    435 
    436         /**
    437         * @deprecated in API 16
    438         * @return internal index of the last index set added to the
    439         *         builder
    440         **/
    441         public int getCurrentIndexSetIndex() {
    442             return mIndexTypes.size() - 1;
    443         }
    444 
    445         /**
    446         * @deprecated in API 16
    447         * Adds an allocation containing vertex buffer data to the
    448         * builder
    449         *
    450         * @param a vertex data allocation
    451         *
    452         * @return this
    453         **/
    454         public AllocationBuilder addVertexAllocation(Allocation a) throws IllegalStateException {
    455             if (mVertexTypeCount >= mVertexTypes.length) {
    456                 throw new IllegalStateException("Max vertex types exceeded.");
    457             }
    458 
    459             mVertexTypes[mVertexTypeCount] = new Entry();
    460             mVertexTypes[mVertexTypeCount].a = a;
    461             mVertexTypeCount++;
    462             return this;
    463         }
    464 
    465         /**
    466         * @deprecated in API 16
    467         * Adds an allocation containing index buffer data and index type
    468         * to the builder
    469         *
    470         * @param a index set data allocation, could be null
    471         * @param p index set primitive type
    472         *
    473         * @return this
    474         **/
    475         public AllocationBuilder addIndexSetAllocation(Allocation a, Primitive p) {
    476             Entry indexType = new Entry();
    477             indexType.a = a;
    478             indexType.prim = p;
    479             mIndexTypes.addElement(indexType);
    480             return this;
    481         }
    482 
    483         /**
    484         * @deprecated in API 16
    485         * Adds an index set type to the builder
    486         *
    487         * @param p index set primitive type
    488         *
    489         * @return this
    490         **/
    491         public AllocationBuilder addIndexSetType(Primitive p) {
    492             Entry indexType = new Entry();
    493             indexType.a = null;
    494             indexType.prim = p;
    495             mIndexTypes.addElement(indexType);
    496             return this;
    497         }
    498 
    499         /**
    500         * @deprecated in API 16
    501         * Create a Mesh object from the current state of the builder
    502         *
    503         **/
    504         public Mesh create() {
    505             mRS.validate();
    506 
    507             long[] vtx = new long[mVertexTypeCount];
    508             long[] idx = new long[mIndexTypes.size()];
    509             int[] prim = new int[mIndexTypes.size()];
    510 
    511             Allocation[] indexBuffers = new Allocation[mIndexTypes.size()];
    512             Primitive[] primitives = new Primitive[mIndexTypes.size()];
    513             Allocation[] vertexBuffers = new Allocation[mVertexTypeCount];
    514 
    515             for(int ct = 0; ct < mVertexTypeCount; ct ++) {
    516                 Entry entry = mVertexTypes[ct];
    517                 vertexBuffers[ct] = entry.a;
    518                 vtx[ct] = entry.a.getID(mRS);
    519             }
    520 
    521             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
    522                 Entry entry = (Entry)mIndexTypes.elementAt(ct);
    523                 long allocID = (entry.a == null) ? 0 : entry.a.getID(mRS);
    524                 indexBuffers[ct] = entry.a;
    525                 primitives[ct] = entry.prim;
    526 
    527                 idx[ct] = allocID;
    528                 prim[ct] = entry.prim.mID;
    529             }
    530 
    531             long id = mRS.nMeshCreate(vtx, idx, prim);
    532             Mesh newMesh = new Mesh(id, mRS);
    533             newMesh.mVertexBuffers = vertexBuffers;
    534             newMesh.mIndexBuffers = indexBuffers;
    535             newMesh.mPrimitives = primitives;
    536 
    537             return newMesh;
    538         }
    539     }
    540 
    541     /**
    542     * @deprecated in API 16
    543     * Builder that allows creation of a mesh object point by point
    544     * and triangle by triangle
    545     *
    546     **/
    547     public static class TriangleMeshBuilder {
    548         float mVtxData[];
    549         int mVtxCount;
    550         int mMaxIndex;
    551         short mIndexData[];
    552         int mIndexCount;
    553         RenderScript mRS;
    554         Element mElement;
    555 
    556         float mNX = 0;
    557         float mNY = 0;
    558         float mNZ = -1;
    559         float mS0 = 0;
    560         float mT0 = 0;
    561         float mR = 1;
    562         float mG = 1;
    563         float mB = 1;
    564         float mA = 1;
    565 
    566         int mVtxSize;
    567         int mFlags;
    568 
    569         /**
    570         * @deprecated in API 16
    571         **/
    572         public static final int COLOR = 0x0001;
    573         /**
    574         * @deprecated in API 16
    575         **/
    576         public static final int NORMAL = 0x0002;
    577         /**
    578         * @deprecated in API 16
    579         **/
    580         public static final int TEXTURE_0 = 0x0100;
    581 
    582         /**
    583         * @deprecated in API 16
    584         * @param rs Context to which the mesh will belong.
    585         * @param vtxSize specifies whether the vertex is a float2 or
    586         *                float3
    587         * @param flags bitfield that is a combination of COLOR, NORMAL,
    588         *              and TEXTURE_0 that specifies what vertex data
    589         *              channels are present in the mesh
    590         *
    591         **/
    592         public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) {
    593             mRS = rs;
    594             mVtxCount = 0;
    595             mMaxIndex = 0;
    596             mIndexCount = 0;
    597             mVtxData = new float[128];
    598             mIndexData = new short[128];
    599             mVtxSize = vtxSize;
    600             mFlags = flags;
    601 
    602             if (vtxSize < 2 || vtxSize > 3) {
    603                 throw new IllegalArgumentException("Vertex size out of range.");
    604             }
    605         }
    606 
    607         private void makeSpace(int count) {
    608             if ((mVtxCount + count) >= mVtxData.length) {
    609                 float t[] = new float[mVtxData.length * 2];
    610                 System.arraycopy(mVtxData, 0, t, 0, mVtxData.length);
    611                 mVtxData = t;
    612             }
    613         }
    614 
    615         private void latch() {
    616             if ((mFlags & COLOR) != 0) {
    617                 makeSpace(4);
    618                 mVtxData[mVtxCount++] = mR;
    619                 mVtxData[mVtxCount++] = mG;
    620                 mVtxData[mVtxCount++] = mB;
    621                 mVtxData[mVtxCount++] = mA;
    622             }
    623             if ((mFlags & TEXTURE_0) != 0) {
    624                 makeSpace(2);
    625                 mVtxData[mVtxCount++] = mS0;
    626                 mVtxData[mVtxCount++] = mT0;
    627             }
    628             if ((mFlags & NORMAL) != 0) {
    629                 makeSpace(4);
    630                 mVtxData[mVtxCount++] = mNX;
    631                 mVtxData[mVtxCount++] = mNY;
    632                 mVtxData[mVtxCount++] = mNZ;
    633                 mVtxData[mVtxCount++] = 0.0f;
    634             }
    635             mMaxIndex ++;
    636         }
    637 
    638         /**
    639         * @deprecated in API 16
    640         * Adds a float2 vertex to the mesh
    641         *
    642         * @param x position x
    643         * @param y position y
    644         *
    645         * @return this
    646         *
    647         **/
    648         public TriangleMeshBuilder addVertex(float x, float y) {
    649             if (mVtxSize != 2) {
    650                 throw new IllegalStateException("add mistmatch with declared components.");
    651             }
    652             makeSpace(2);
    653             mVtxData[mVtxCount++] = x;
    654             mVtxData[mVtxCount++] = y;
    655             latch();
    656             return this;
    657         }
    658 
    659         /**
    660         * @deprecated in API 16
    661         * Adds a float3 vertex to the mesh
    662         *
    663         * @param x position x
    664         * @param y position y
    665         * @param z position z
    666         *
    667         * @return this
    668         *
    669         **/
    670         public TriangleMeshBuilder addVertex(float x, float y, float z) {
    671             if (mVtxSize != 3) {
    672                 throw new IllegalStateException("add mistmatch with declared components.");
    673             }
    674             makeSpace(4);
    675             mVtxData[mVtxCount++] = x;
    676             mVtxData[mVtxCount++] = y;
    677             mVtxData[mVtxCount++] = z;
    678             mVtxData[mVtxCount++] = 1.0f;
    679             latch();
    680             return this;
    681         }
    682 
    683         /**
    684         * @deprecated in API 16
    685         * Sets the texture coordinate for the vertices that are added after this method call.
    686         *
    687         * @param s texture coordinate s
    688         * @param t texture coordinate t
    689         *
    690         * @return this
    691         **/
    692         public TriangleMeshBuilder setTexture(float s, float t) {
    693             if ((mFlags & TEXTURE_0) == 0) {
    694                 throw new IllegalStateException("add mistmatch with declared components.");
    695             }
    696             mS0 = s;
    697             mT0 = t;
    698             return this;
    699         }
    700 
    701         /**
    702         * @deprecated in API 16
    703         * Sets the normal vector for the vertices that are added after this method call.
    704         *
    705         * @param x normal vector x
    706         * @param y normal vector y
    707         * @param z normal vector z
    708         *
    709         * @return this
    710         **/
    711         public TriangleMeshBuilder setNormal(float x, float y, float z) {
    712             if ((mFlags & NORMAL) == 0) {
    713                 throw new IllegalStateException("add mistmatch with declared components.");
    714             }
    715             mNX = x;
    716             mNY = y;
    717             mNZ = z;
    718             return this;
    719         }
    720 
    721         /**
    722         * @deprecated in API 16
    723         * Sets the color for the vertices that are added after this method call.
    724         *
    725         * @param r red component
    726         * @param g green component
    727         * @param b blue component
    728         * @param a alpha component
    729         *
    730         * @return this
    731         **/
    732         public TriangleMeshBuilder setColor(float r, float g, float b, float a) {
    733             if ((mFlags & COLOR) == 0) {
    734                 throw new IllegalStateException("add mistmatch with declared components.");
    735             }
    736             mR = r;
    737             mG = g;
    738             mB = b;
    739             mA = a;
    740             return this;
    741         }
    742 
    743         /**
    744         * @deprecated in API 16
    745         * Adds a new triangle to the mesh builder
    746         *
    747         * @param idx1 index of the first vertex in the triangle
    748         * @param idx2 index of the second vertex in the triangle
    749         * @param idx3 index of the third vertex in the triangle
    750         *
    751         * @return this
    752         **/
    753         public TriangleMeshBuilder addTriangle(int idx1, int idx2, int idx3) {
    754             if((idx1 >= mMaxIndex) || (idx1 < 0) ||
    755                (idx2 >= mMaxIndex) || (idx2 < 0) ||
    756                (idx3 >= mMaxIndex) || (idx3 < 0)) {
    757                throw new IllegalStateException("Index provided greater than vertex count.");
    758             }
    759             if ((mIndexCount + 3) >= mIndexData.length) {
    760                 short t[] = new short[mIndexData.length * 2];
    761                 System.arraycopy(mIndexData, 0, t, 0, mIndexData.length);
    762                 mIndexData = t;
    763             }
    764             mIndexData[mIndexCount++] = (short)idx1;
    765             mIndexData[mIndexCount++] = (short)idx2;
    766             mIndexData[mIndexCount++] = (short)idx3;
    767             return this;
    768         }
    769 
    770         /**
    771         * @deprecated in API 16
    772         * Creates the mesh object from the current state of the builder
    773         *
    774         * @param uploadToBufferObject specifies whether the vertex data
    775         *                             is to be uploaded into the buffer
    776         *                             object indicating that it's likely
    777         *                             not going to be modified and
    778         *                             rendered many times.
    779         *                             Alternatively, it indicates the
    780         *                             mesh data will be updated
    781         *                             frequently and remain in script
    782         *                             accessible memory
    783         *
    784         **/
    785         public Mesh create(boolean uploadToBufferObject) {
    786             Element.Builder b = new Element.Builder(mRS);
    787             b.add(Element.createVector(mRS,
    788                                        Element.DataType.FLOAT_32,
    789                                        mVtxSize), "position");
    790             if ((mFlags & COLOR) != 0) {
    791                 b.add(Element.F32_4(mRS), "color");
    792             }
    793             if ((mFlags & TEXTURE_0) != 0) {
    794                 b.add(Element.F32_2(mRS), "texture0");
    795             }
    796             if ((mFlags & NORMAL) != 0) {
    797                 b.add(Element.F32_3(mRS), "normal");
    798             }
    799             mElement = b.create();
    800 
    801             int usage = Allocation.USAGE_SCRIPT;
    802             if (uploadToBufferObject) {
    803                 usage |= Allocation.USAGE_GRAPHICS_VERTEX;
    804             }
    805 
    806             Builder smb = new Builder(mRS, usage);
    807             smb.addVertexType(mElement, mMaxIndex);
    808             smb.addIndexSetType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE);
    809 
    810             Mesh sm = smb.create();
    811 
    812             sm.getVertexAllocation(0).copy1DRangeFromUnchecked(0, mMaxIndex, mVtxData);
    813             if(uploadToBufferObject) {
    814                 if (uploadToBufferObject) {
    815                     sm.getVertexAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
    816                 }
    817             }
    818 
    819             sm.getIndexSetAllocation(0).copy1DRangeFromUnchecked(0, mIndexCount, mIndexData);
    820             if (uploadToBufferObject) {
    821                 sm.getIndexSetAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
    822             }
    823 
    824             return sm;
    825         }
    826     }
    827 }
    828 
    829