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