Home | History | Annotate | Download | only in renderscript
      1 /*
      2  * Copyright (C) 2008 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.util.Config;
     20 import android.util.Log;
     21 
     22 /**
     23  * @hide
     24  *
     25  **/
     26 public class SimpleMesh extends BaseObj {
     27     Type[] mVertexTypes;
     28     Type mIndexType;
     29     //Type mBatcheType;
     30     Primitive mPrimitive;
     31 
     32     SimpleMesh(int id, RenderScript rs) {
     33         super(rs);
     34         mID = id;
     35     }
     36 
     37     public void bindVertexAllocation(Allocation a, int slot) {
     38         mRS.validate();
     39         mRS.nSimpleMeshBindVertex(mID, a.mID, slot);
     40     }
     41 
     42     public void bindIndexAllocation(Allocation a) {
     43         mRS.validate();
     44         mRS.nSimpleMeshBindIndex(mID, a.mID);
     45     }
     46 
     47     public Allocation createVertexAllocation(int slot) {
     48         mRS.validate();
     49         return Allocation.createTyped(mRS, mVertexTypes[slot]);
     50     }
     51 
     52     public Allocation createIndexAllocation() {
     53         mRS.validate();
     54         return Allocation.createTyped(mRS, mIndexType);
     55     }
     56 
     57     public Type getVertexType(int slot) {
     58         return mVertexTypes[slot];
     59     }
     60 
     61     public Type getIndexType() {
     62         return mIndexType;
     63     }
     64 
     65     public static class Builder {
     66         RenderScript mRS;
     67 
     68         class Entry {
     69             Type t;
     70             Element e;
     71             int size;
     72         }
     73 
     74         int mVertexTypeCount;
     75         Entry[] mVertexTypes;
     76         Entry mIndexType;
     77         //Entry mBatchType;
     78         Primitive mPrimitive;
     79 
     80 
     81         public Builder(RenderScript rs) {
     82             mRS = rs;
     83             mVertexTypeCount = 0;
     84             mVertexTypes = new Entry[16];
     85             mIndexType = new Entry();
     86         }
     87 
     88         public int addVertexType(Type t) throws IllegalStateException {
     89             if (mVertexTypeCount >= mVertexTypes.length) {
     90                 throw new IllegalStateException("Max vertex types exceeded.");
     91             }
     92 
     93             int addedIndex = mVertexTypeCount;
     94             mVertexTypes[mVertexTypeCount] = new Entry();
     95             mVertexTypes[mVertexTypeCount].t = t;
     96             mVertexTypeCount++;
     97             return addedIndex;
     98         }
     99 
    100         public int addVertexType(Element e, int size) throws IllegalStateException {
    101             if (mVertexTypeCount >= mVertexTypes.length) {
    102                 throw new IllegalStateException("Max vertex types exceeded.");
    103             }
    104 
    105             int addedIndex = mVertexTypeCount;
    106             mVertexTypes[mVertexTypeCount] = new Entry();
    107             mVertexTypes[mVertexTypeCount].e = e;
    108             mVertexTypes[mVertexTypeCount].size = size;
    109             mVertexTypeCount++;
    110             return addedIndex;
    111         }
    112 
    113         public void setIndexType(Type t) {
    114             mIndexType.t = t;
    115             mIndexType.e = null;
    116             mIndexType.size = 0;
    117         }
    118 
    119         public void setIndexType(Element e, int size) {
    120             mIndexType.t = null;
    121             mIndexType.e = e;
    122             mIndexType.size = size;
    123         }
    124 
    125         public void setPrimitive(Primitive p) {
    126             mPrimitive = p;
    127         }
    128 
    129 
    130         Type newType(Element e, int size) {
    131             Type.Builder tb = new Type.Builder(mRS, e);
    132             tb.add(Dimension.X, size);
    133             return tb.create();
    134         }
    135 
    136         static synchronized SimpleMesh internalCreate(RenderScript rs, Builder b) {
    137             Type[] toDestroy = new Type[18];
    138             int toDestroyCount = 0;
    139 
    140             int indexID = 0;
    141             if (b.mIndexType.t != null) {
    142                 indexID = b.mIndexType.t.mID;
    143             } else if (b.mIndexType.size != 0) {
    144                 b.mIndexType.t = b.newType(b.mIndexType.e, b.mIndexType.size);
    145                 indexID = b.mIndexType.t.mID;
    146                 toDestroy[toDestroyCount++] = b.mIndexType.t;
    147             }
    148 
    149             int[] IDs = new int[b.mVertexTypeCount];
    150             for(int ct=0; ct < b.mVertexTypeCount; ct++) {
    151                 if (b.mVertexTypes[ct].t != null) {
    152                     IDs[ct] = b.mVertexTypes[ct].t.mID;
    153                 } else {
    154                     b.mVertexTypes[ct].t = b.newType(b.mVertexTypes[ct].e, b.mVertexTypes[ct].size);
    155                     IDs[ct] = b.mVertexTypes[ct].t.mID;
    156                     toDestroy[toDestroyCount++] = b.mVertexTypes[ct].t;
    157                 }
    158             }
    159 
    160             int id = rs.nSimpleMeshCreate(0, indexID, IDs, b.mPrimitive.mID);
    161             for(int ct=0; ct < toDestroyCount; ct++) {
    162                 toDestroy[ct].destroy();
    163             }
    164 
    165             return new SimpleMesh(id, rs);
    166         }
    167 
    168         public SimpleMesh create() {
    169             mRS.validate();
    170             SimpleMesh sm = internalCreate(mRS, this);
    171             sm.mVertexTypes = new Type[mVertexTypeCount];
    172             for(int ct=0; ct < mVertexTypeCount; ct++) {
    173                 sm.mVertexTypes[ct] = mVertexTypes[ct].t;
    174             }
    175             sm.mIndexType = mIndexType.t;
    176             sm.mPrimitive = mPrimitive;
    177             return sm;
    178         }
    179     }
    180 
    181     public static class TriangleMeshBuilder {
    182         float mVtxData[];
    183         int mVtxCount;
    184         short mIndexData[];
    185         int mIndexCount;
    186         RenderScript mRS;
    187         Element mElement;
    188 
    189         float mNX = 0;
    190         float mNY = 0;
    191         float mNZ = -1;
    192         float mS0 = 0;
    193         float mT0 = 0;
    194         float mR = 1;
    195         float mG = 1;
    196         float mB = 1;
    197         float mA = 1;
    198 
    199         int mVtxSize;
    200         int mFlags;
    201 
    202         public static final int COLOR = 0x0001;
    203         public static final int NORMAL = 0x0002;
    204         public static final int TEXTURE_0 = 0x0100;
    205 
    206         public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) {
    207             mRS = rs;
    208             mVtxCount = 0;
    209             mIndexCount = 0;
    210             mVtxData = new float[128];
    211             mIndexData = new short[128];
    212             mVtxSize = vtxSize;
    213             mFlags = flags;
    214 
    215             if (vtxSize < 2 || vtxSize > 3) {
    216                 throw new IllegalArgumentException("Vertex size out of range.");
    217             }
    218         }
    219 
    220         private void makeSpace(int count) {
    221             if ((mVtxCount + count) >= mVtxData.length) {
    222                 float t[] = new float[mVtxData.length * 2];
    223                 System.arraycopy(mVtxData, 0, t, 0, mVtxData.length);
    224                 mVtxData = t;
    225             }
    226         }
    227 
    228         private void latch() {
    229             if ((mFlags & COLOR) != 0) {
    230                 makeSpace(4);
    231                 mVtxData[mVtxCount++] = mR;
    232                 mVtxData[mVtxCount++] = mG;
    233                 mVtxData[mVtxCount++] = mB;
    234                 mVtxData[mVtxCount++] = mA;
    235             }
    236             if ((mFlags & TEXTURE_0) != 0) {
    237                 makeSpace(2);
    238                 mVtxData[mVtxCount++] = mS0;
    239                 mVtxData[mVtxCount++] = mT0;
    240             }
    241             if ((mFlags & NORMAL) != 0) {
    242                 makeSpace(3);
    243                 mVtxData[mVtxCount++] = mNX;
    244                 mVtxData[mVtxCount++] = mNY;
    245                 mVtxData[mVtxCount++] = mNZ;
    246             }
    247         }
    248 
    249         public void addVertex(float x, float y) {
    250             if (mVtxSize != 2) {
    251                 throw new IllegalStateException("add mistmatch with declared components.");
    252             }
    253             makeSpace(2);
    254             mVtxData[mVtxCount++] = x;
    255             mVtxData[mVtxCount++] = y;
    256             latch();
    257         }
    258 
    259         public void addVertex(float x, float y, float z) {
    260             if (mVtxSize != 3) {
    261                 throw new IllegalStateException("add mistmatch with declared components.");
    262             }
    263             makeSpace(3);
    264             mVtxData[mVtxCount++] = x;
    265             mVtxData[mVtxCount++] = y;
    266             mVtxData[mVtxCount++] = z;
    267             latch();
    268         }
    269 
    270         public void setTexture(float s, float t) {
    271             if ((mFlags & TEXTURE_0) == 0) {
    272                 throw new IllegalStateException("add mistmatch with declared components.");
    273             }
    274             mS0 = s;
    275             mT0 = t;
    276         }
    277 
    278         public void setNormal(float x, float y, float z) {
    279             if ((mFlags & NORMAL) == 0) {
    280                 throw new IllegalStateException("add mistmatch with declared components.");
    281             }
    282             mNX = x;
    283             mNY = y;
    284             mNZ = z;
    285         }
    286 
    287         public void setColor(float r, float g, float b, float a) {
    288             if ((mFlags & COLOR) == 0) {
    289                 throw new IllegalStateException("add mistmatch with declared components.");
    290             }
    291             mR = r;
    292             mG = g;
    293             mB = b;
    294             mA = a;
    295         }
    296 
    297         public void addTriangle(int idx1, int idx2, int idx3) {
    298             if((idx1 >= mVtxCount) || (idx1 < 0) ||
    299                (idx2 >= mVtxCount) || (idx2 < 0) ||
    300                (idx3 >= mVtxCount) || (idx3 < 0)) {
    301                throw new IllegalStateException("Index provided greater than vertex count.");
    302             }
    303             if ((mIndexCount + 3) >= mIndexData.length) {
    304                 short t[] = new short[mIndexData.length * 2];
    305                 System.arraycopy(mIndexData, 0, t, 0, mIndexData.length);
    306                 mIndexData = t;
    307             }
    308             mIndexData[mIndexCount++] = (short)idx1;
    309             mIndexData[mIndexCount++] = (short)idx2;
    310             mIndexData[mIndexCount++] = (short)idx3;
    311         }
    312 
    313         public SimpleMesh create() {
    314             Element.Builder b = new Element.Builder(mRS);
    315             int floatCount = mVtxSize;
    316             b.add(Element.createAttrib(mRS,
    317                                        Element.DataType.FLOAT_32,
    318                                        Element.DataKind.POSITION,
    319                                        mVtxSize), "position");
    320             if ((mFlags & COLOR) != 0) {
    321                 floatCount += 4;
    322                 b.add(Element.createAttrib(mRS,
    323                                            Element.DataType.FLOAT_32,
    324                                            Element.DataKind.COLOR,
    325                                            4), "color");
    326             }
    327             if ((mFlags & TEXTURE_0) != 0) {
    328                 floatCount += 2;
    329                 b.add(Element.createAttrib(mRS,
    330                                            Element.DataType.FLOAT_32,
    331                                            Element.DataKind.TEXTURE,
    332                                            2), "texture");
    333             }
    334             if ((mFlags & NORMAL) != 0) {
    335                 floatCount += 3;
    336                 b.add(Element.createAttrib(mRS,
    337                                            Element.DataType.FLOAT_32,
    338                                            Element.DataKind.NORMAL,
    339                                            3), "normal");
    340             }
    341             mElement = b.create();
    342 
    343             Builder smb = new Builder(mRS);
    344             smb.addVertexType(mElement, mVtxCount / floatCount);
    345             smb.setIndexType(Element.createIndex(mRS), mIndexCount);
    346             smb.setPrimitive(Primitive.TRIANGLE);
    347             SimpleMesh sm = smb.create();
    348 
    349             Allocation vertexAlloc = sm.createVertexAllocation(0);
    350             Allocation indexAlloc = sm.createIndexAllocation();
    351             sm.bindVertexAllocation(vertexAlloc, 0);
    352             sm.bindIndexAllocation(indexAlloc);
    353 
    354             vertexAlloc.data(mVtxData);
    355             vertexAlloc.uploadToBufferObject();
    356 
    357             indexAlloc.data(mIndexData);
    358             indexAlloc.uploadToBufferObject();
    359 
    360             return sm;
    361         }
    362     }
    363 }
    364 
    365