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         guard.open("destroy");
     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         long[] vtxIDs = new long[vtxCount];
    157         long[] idxIDs = new long[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             long[] vtx = new long[mVertexTypeCount];
    353             long[] idx = new long[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                 } else {
    368                     // Should never happen because the builder will always set one
    369                     throw new IllegalStateException("Builder corrupt, no valid element in entry.");
    370                 }
    371                 vertexBuffers[ct] = alloc;
    372                 vtx[ct] = alloc.getID(mRS);
    373             }
    374 
    375             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
    376                 Allocation alloc = null;
    377                 Entry entry = (Entry)mIndexTypes.elementAt(ct);
    378                 if (entry.t != null) {
    379                     alloc = Allocation.createTyped(mRS, entry.t, mUsage);
    380                 } else if(entry.e != null) {
    381                     alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
    382                 } else {
    383                     // Should never happen because the builder will always set one
    384                     throw new IllegalStateException("Builder corrupt, no valid element in entry.");
    385                 }
    386                 long allocID = (alloc == null) ? 0 : alloc.getID(mRS);
    387                 indexBuffers[ct] = alloc;
    388                 primitives[ct] = entry.prim;
    389 
    390                 idx[ct] = allocID;
    391                 prim[ct] = entry.prim.mID;
    392             }
    393 
    394             long id = mRS.nMeshCreate(vtx, idx, prim);
    395             Mesh newMesh = new Mesh(id, mRS);
    396             newMesh.mVertexBuffers = vertexBuffers;
    397             newMesh.mIndexBuffers = indexBuffers;
    398             newMesh.mPrimitives = primitives;
    399 
    400             return newMesh;
    401         }
    402     }
    403 
    404     /**
    405     * @deprecated in API 16
    406     * Mesh builder object. It starts empty and requires the user to
    407     * add all the vertex and index allocations that comprise the
    408     * mesh
    409     *
    410     */
    411     public static class AllocationBuilder {
    412         RenderScript mRS;
    413 
    414         class Entry {
    415             Allocation a;
    416             Primitive prim;
    417         }
    418 
    419         int mVertexTypeCount;
    420         Entry[] mVertexTypes;
    421 
    422         Vector mIndexTypes;
    423 
    424         /**
    425         * @deprecated in API 16
    426         **/
    427         public AllocationBuilder(RenderScript rs) {
    428             mRS = rs;
    429             mVertexTypeCount = 0;
    430             mVertexTypes = new Entry[16];
    431             mIndexTypes = new Vector();
    432         }
    433 
    434         /**
    435         * @deprecated in API 16
    436         * @return internal index of the last vertex buffer type added to
    437         *         builder
    438         **/
    439         public int getCurrentVertexTypeIndex() {
    440             return mVertexTypeCount - 1;
    441         }
    442 
    443         /**
    444         * @deprecated in API 16
    445         * @return internal index of the last index set added to the
    446         *         builder
    447         **/
    448         public int getCurrentIndexSetIndex() {
    449             return mIndexTypes.size() - 1;
    450         }
    451 
    452         /**
    453         * @deprecated in API 16
    454         * Adds an allocation containing vertex buffer data to the
    455         * builder
    456         *
    457         * @param a vertex data allocation
    458         *
    459         * @return this
    460         **/
    461         public AllocationBuilder addVertexAllocation(Allocation a) throws IllegalStateException {
    462             if (mVertexTypeCount >= mVertexTypes.length) {
    463                 throw new IllegalStateException("Max vertex types exceeded.");
    464             }
    465 
    466             mVertexTypes[mVertexTypeCount] = new Entry();
    467             mVertexTypes[mVertexTypeCount].a = a;
    468             mVertexTypeCount++;
    469             return this;
    470         }
    471 
    472         /**
    473         * @deprecated in API 16
    474         * Adds an allocation containing index buffer data and index type
    475         * to the builder
    476         *
    477         * @param a index set data allocation, could be null
    478         * @param p index set primitive type
    479         *
    480         * @return this
    481         **/
    482         public AllocationBuilder addIndexSetAllocation(Allocation a, Primitive p) {
    483             Entry indexType = new Entry();
    484             indexType.a = a;
    485             indexType.prim = p;
    486             mIndexTypes.addElement(indexType);
    487             return this;
    488         }
    489 
    490         /**
    491         * @deprecated in API 16
    492         * Adds an index set type to the builder
    493         *
    494         * @param p index set primitive type
    495         *
    496         * @return this
    497         **/
    498         public AllocationBuilder addIndexSetType(Primitive p) {
    499             Entry indexType = new Entry();
    500             indexType.a = null;
    501             indexType.prim = p;
    502             mIndexTypes.addElement(indexType);
    503             return this;
    504         }
    505 
    506         /**
    507         * @deprecated in API 16
    508         * Create a Mesh object from the current state of the builder
    509         *
    510         **/
    511         public Mesh create() {
    512             mRS.validate();
    513 
    514             long[] vtx = new long[mVertexTypeCount];
    515             long[] idx = new long[mIndexTypes.size()];
    516             int[] prim = new int[mIndexTypes.size()];
    517 
    518             Allocation[] indexBuffers = new Allocation[mIndexTypes.size()];
    519             Primitive[] primitives = new Primitive[mIndexTypes.size()];
    520             Allocation[] vertexBuffers = new Allocation[mVertexTypeCount];
    521 
    522             for(int ct = 0; ct < mVertexTypeCount; ct ++) {
    523                 Entry entry = mVertexTypes[ct];
    524                 vertexBuffers[ct] = entry.a;
    525                 vtx[ct] = entry.a.getID(mRS);
    526             }
    527 
    528             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
    529                 Entry entry = (Entry)mIndexTypes.elementAt(ct);
    530                 long allocID = (entry.a == null) ? 0 : entry.a.getID(mRS);
    531                 indexBuffers[ct] = entry.a;
    532                 primitives[ct] = entry.prim;
    533 
    534                 idx[ct] = allocID;
    535                 prim[ct] = entry.prim.mID;
    536             }
    537 
    538             long id = mRS.nMeshCreate(vtx, idx, prim);
    539             Mesh newMesh = new Mesh(id, mRS);
    540             newMesh.mVertexBuffers = vertexBuffers;
    541             newMesh.mIndexBuffers = indexBuffers;
    542             newMesh.mPrimitives = primitives;
    543 
    544             return newMesh;
    545         }
    546     }
    547 
    548     /**
    549     * @deprecated in API 16
    550     * Builder that allows creation of a mesh object point by point
    551     * and triangle by triangle
    552     *
    553     **/
    554     public static class TriangleMeshBuilder {
    555         float mVtxData[];
    556         int mVtxCount;
    557         int mMaxIndex;
    558         short mIndexData[];
    559         int mIndexCount;
    560         RenderScript mRS;
    561         Element mElement;
    562 
    563         float mNX = 0;
    564         float mNY = 0;
    565         float mNZ = -1;
    566         float mS0 = 0;
    567         float mT0 = 0;
    568         float mR = 1;
    569         float mG = 1;
    570         float mB = 1;
    571         float mA = 1;
    572 
    573         int mVtxSize;
    574         int mFlags;
    575 
    576         /**
    577         * @deprecated in API 16
    578         **/
    579         public static final int COLOR = 0x0001;
    580         /**
    581         * @deprecated in API 16
    582         **/
    583         public static final int NORMAL = 0x0002;
    584         /**
    585         * @deprecated in API 16
    586         **/
    587         public static final int TEXTURE_0 = 0x0100;
    588 
    589         /**
    590         * @deprecated in API 16
    591         * @param rs Context to which the mesh will belong.
    592         * @param vtxSize specifies whether the vertex is a float2 or
    593         *                float3
    594         * @param flags bitfield that is a combination of COLOR, NORMAL,
    595         *              and TEXTURE_0 that specifies what vertex data
    596         *              channels are present in the mesh
    597         *
    598         **/
    599         public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) {
    600             mRS = rs;
    601             mVtxCount = 0;
    602             mMaxIndex = 0;
    603             mIndexCount = 0;
    604             mVtxData = new float[128];
    605             mIndexData = new short[128];
    606             mVtxSize = vtxSize;
    607             mFlags = flags;
    608 
    609             if (vtxSize < 2 || vtxSize > 3) {
    610                 throw new IllegalArgumentException("Vertex size out of range.");
    611             }
    612         }
    613 
    614         private void makeSpace(int count) {
    615             if ((mVtxCount + count) >= mVtxData.length) {
    616                 float t[] = new float[mVtxData.length * 2];
    617                 System.arraycopy(mVtxData, 0, t, 0, mVtxData.length);
    618                 mVtxData = t;
    619             }
    620         }
    621 
    622         private void latch() {
    623             if ((mFlags & COLOR) != 0) {
    624                 makeSpace(4);
    625                 mVtxData[mVtxCount++] = mR;
    626                 mVtxData[mVtxCount++] = mG;
    627                 mVtxData[mVtxCount++] = mB;
    628                 mVtxData[mVtxCount++] = mA;
    629             }
    630             if ((mFlags & TEXTURE_0) != 0) {
    631                 makeSpace(2);
    632                 mVtxData[mVtxCount++] = mS0;
    633                 mVtxData[mVtxCount++] = mT0;
    634             }
    635             if ((mFlags & NORMAL) != 0) {
    636                 makeSpace(4);
    637                 mVtxData[mVtxCount++] = mNX;
    638                 mVtxData[mVtxCount++] = mNY;
    639                 mVtxData[mVtxCount++] = mNZ;
    640                 mVtxData[mVtxCount++] = 0.0f;
    641             }
    642             mMaxIndex ++;
    643         }
    644 
    645         /**
    646         * @deprecated in API 16
    647         * Adds a float2 vertex to the mesh
    648         *
    649         * @param x position x
    650         * @param y position y
    651         *
    652         * @return this
    653         *
    654         **/
    655         public TriangleMeshBuilder addVertex(float x, float y) {
    656             if (mVtxSize != 2) {
    657                 throw new IllegalStateException("add mistmatch with declared components.");
    658             }
    659             makeSpace(2);
    660             mVtxData[mVtxCount++] = x;
    661             mVtxData[mVtxCount++] = y;
    662             latch();
    663             return this;
    664         }
    665 
    666         /**
    667         * @deprecated in API 16
    668         * Adds a float3 vertex to the mesh
    669         *
    670         * @param x position x
    671         * @param y position y
    672         * @param z position z
    673         *
    674         * @return this
    675         *
    676         **/
    677         public TriangleMeshBuilder addVertex(float x, float y, float z) {
    678             if (mVtxSize != 3) {
    679                 throw new IllegalStateException("add mistmatch with declared components.");
    680             }
    681             makeSpace(4);
    682             mVtxData[mVtxCount++] = x;
    683             mVtxData[mVtxCount++] = y;
    684             mVtxData[mVtxCount++] = z;
    685             mVtxData[mVtxCount++] = 1.0f;
    686             latch();
    687             return this;
    688         }
    689 
    690         /**
    691         * @deprecated in API 16
    692         * Sets the texture coordinate for the vertices that are added after this method call.
    693         *
    694         * @param s texture coordinate s
    695         * @param t texture coordinate t
    696         *
    697         * @return this
    698         **/
    699         public TriangleMeshBuilder setTexture(float s, float t) {
    700             if ((mFlags & TEXTURE_0) == 0) {
    701                 throw new IllegalStateException("add mistmatch with declared components.");
    702             }
    703             mS0 = s;
    704             mT0 = t;
    705             return this;
    706         }
    707 
    708         /**
    709         * @deprecated in API 16
    710         * Sets the normal vector for the vertices that are added after this method call.
    711         *
    712         * @param x normal vector x
    713         * @param y normal vector y
    714         * @param z normal vector z
    715         *
    716         * @return this
    717         **/
    718         public TriangleMeshBuilder setNormal(float x, float y, float z) {
    719             if ((mFlags & NORMAL) == 0) {
    720                 throw new IllegalStateException("add mistmatch with declared components.");
    721             }
    722             mNX = x;
    723             mNY = y;
    724             mNZ = z;
    725             return this;
    726         }
    727 
    728         /**
    729         * @deprecated in API 16
    730         * Sets the color for the vertices that are added after this method call.
    731         *
    732         * @param r red component
    733         * @param g green component
    734         * @param b blue component
    735         * @param a alpha component
    736         *
    737         * @return this
    738         **/
    739         public TriangleMeshBuilder setColor(float r, float g, float b, float a) {
    740             if ((mFlags & COLOR) == 0) {
    741                 throw new IllegalStateException("add mistmatch with declared components.");
    742             }
    743             mR = r;
    744             mG = g;
    745             mB = b;
    746             mA = a;
    747             return this;
    748         }
    749 
    750         /**
    751         * @deprecated in API 16
    752         * Adds a new triangle to the mesh builder
    753         *
    754         * @param idx1 index of the first vertex in the triangle
    755         * @param idx2 index of the second vertex in the triangle
    756         * @param idx3 index of the third vertex in the triangle
    757         *
    758         * @return this
    759         **/
    760         public TriangleMeshBuilder addTriangle(int idx1, int idx2, int idx3) {
    761             if((idx1 >= mMaxIndex) || (idx1 < 0) ||
    762                (idx2 >= mMaxIndex) || (idx2 < 0) ||
    763                (idx3 >= mMaxIndex) || (idx3 < 0)) {
    764                throw new IllegalStateException("Index provided greater than vertex count.");
    765             }
    766             if ((mIndexCount + 3) >= mIndexData.length) {
    767                 short t[] = new short[mIndexData.length * 2];
    768                 System.arraycopy(mIndexData, 0, t, 0, mIndexData.length);
    769                 mIndexData = t;
    770             }
    771             mIndexData[mIndexCount++] = (short)idx1;
    772             mIndexData[mIndexCount++] = (short)idx2;
    773             mIndexData[mIndexCount++] = (short)idx3;
    774             return this;
    775         }
    776 
    777         /**
    778         * @deprecated in API 16
    779         * Creates the mesh object from the current state of the builder
    780         *
    781         * @param uploadToBufferObject specifies whether the vertex data
    782         *                             is to be uploaded into the buffer
    783         *                             object indicating that it's likely
    784         *                             not going to be modified and
    785         *                             rendered many times.
    786         *                             Alternatively, it indicates the
    787         *                             mesh data will be updated
    788         *                             frequently and remain in script
    789         *                             accessible memory
    790         *
    791         **/
    792         public Mesh create(boolean uploadToBufferObject) {
    793             Element.Builder b = new Element.Builder(mRS);
    794             b.add(Element.createVector(mRS,
    795                                        Element.DataType.FLOAT_32,
    796                                        mVtxSize), "position");
    797             if ((mFlags & COLOR) != 0) {
    798                 b.add(Element.F32_4(mRS), "color");
    799             }
    800             if ((mFlags & TEXTURE_0) != 0) {
    801                 b.add(Element.F32_2(mRS), "texture0");
    802             }
    803             if ((mFlags & NORMAL) != 0) {
    804                 b.add(Element.F32_3(mRS), "normal");
    805             }
    806             mElement = b.create();
    807 
    808             int usage = Allocation.USAGE_SCRIPT;
    809             if (uploadToBufferObject) {
    810                 usage |= Allocation.USAGE_GRAPHICS_VERTEX;
    811             }
    812 
    813             Builder smb = new Builder(mRS, usage);
    814             smb.addVertexType(mElement, mMaxIndex);
    815             smb.addIndexSetType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE);
    816 
    817             Mesh sm = smb.create();
    818 
    819             sm.getVertexAllocation(0).copy1DRangeFromUnchecked(0, mMaxIndex, mVtxData);
    820             if(uploadToBufferObject) {
    821                 sm.getVertexAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
    822             }
    823 
    824             sm.getIndexSetAllocation(0).copy1DRangeFromUnchecked(0, mIndexCount, mIndexData);
    825             if (uploadToBufferObject) {
    826                 sm.getIndexSetAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
    827             }
    828 
    829             return sm;
    830         }
    831     }
    832 }
    833 
    834