• 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.validate();
39         mRS.nSimpleMeshBindVertex(mID, a.mID, slot);
40     }
41 
bindIndexAllocation(Allocation a)42     public void bindIndexAllocation(Allocation a) {
43         mRS.validate();
44         mRS.nSimpleMeshBindIndex(mID, a.mID);
45     }
46 
createVertexAllocation(int slot)47     public Allocation createVertexAllocation(int slot) {
48         mRS.validate();
49         return Allocation.createTyped(mRS, mVertexTypes[slot]);
50     }
51 
createIndexAllocation()52     public Allocation createIndexAllocation() {
53         mRS.validate();
54         return Allocation.createTyped(mRS, mIndexType);
55     }
56 
getVertexType(int slot)57     public Type getVertexType(int slot) {
58         return mVertexTypes[slot];
59     }
60 
getIndexType()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 
Builder(RenderScript rs)81         public Builder(RenderScript rs) {
82             mRS = rs;
83             mVertexTypeCount = 0;
84             mVertexTypes = new Entry[16];
85             mIndexType = new Entry();
86         }
87 
addVertexType(Type t)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 
addVertexType(Element e, int size)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 
setIndexType(Type t)113         public void setIndexType(Type t) {
114             mIndexType.t = t;
115             mIndexType.e = null;
116             mIndexType.size = 0;
117         }
118 
setIndexType(Element e, int size)119         public void setIndexType(Element e, int size) {
120             mIndexType.t = null;
121             mIndexType.e = e;
122             mIndexType.size = size;
123         }
124 
setPrimitive(Primitive p)125         public void setPrimitive(Primitive p) {
126             mPrimitive = p;
127         }
128 
129 
newType(Element e, int size)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 
internalCreate(RenderScript rs, Builder b)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 
create()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 
TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags)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 
makeSpace(int count)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 
latch()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 
addVertex(float x, float y)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 
addVertex(float x, float y, float z)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 
setTexture(float s, float t)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 
setNormal(float x, float y, float z)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 
setColor(float r, float g, float b, float a)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 
addTriangle(int idx1, int idx2, int idx3)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 
create()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