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