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