blob: f45074e23b248f40f50e9f26ebdd6652832c7b12 [file] [log] [blame]
Jason Sams1bada8c2009-08-09 17:01:55 -07001/*
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
17package android.renderscript;
18
19import android.util.Config;
20import android.util.Log;
21
22/**
23 * @hide
24 *
25 **/
26public 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
Jason Sams1bada8c2009-08-09 17:01:55 -070037 public void bindVertexAllocation(Allocation a, int slot) {
Jason Sams771bebb2009-12-07 12:40:12 -080038 mRS.validate();
Jason Sams1bada8c2009-08-09 17:01:55 -070039 mRS.nSimpleMeshBindVertex(mID, a.mID, slot);
40 }
41
42 public void bindIndexAllocation(Allocation a) {
Jason Sams771bebb2009-12-07 12:40:12 -080043 mRS.validate();
Jason Sams1bada8c2009-08-09 17:01:55 -070044 mRS.nSimpleMeshBindIndex(mID, a.mID);
45 }
46
47 public Allocation createVertexAllocation(int slot) {
Jason Sams771bebb2009-12-07 12:40:12 -080048 mRS.validate();
Jason Sams1bada8c2009-08-09 17:01:55 -070049 return Allocation.createTyped(mRS, mVertexTypes[slot]);
50 }
51
52 public Allocation createIndexAllocation() {
Jason Sams771bebb2009-12-07 12:40:12 -080053 mRS.validate();
Jason Sams1bada8c2009-08-09 17:01:55 -070054 return Allocation.createTyped(mRS, mIndexType);
55 }
56
Jason Sams2525a812009-09-03 15:43:13 -070057 public Type getVertexType(int slot) {
58 return mVertexTypes[slot];
59 }
60
61 public Type getIndexType() {
62 return mIndexType;
63 }
Jason Sams1bada8c2009-08-09 17:01:55 -070064
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 {
Jason Sams7f047782009-10-02 18:18:35 -070089 if (mVertexTypeCount >= mVertexTypes.length) {
Jason Sams1bada8c2009-08-09 17:01:55 -070090 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 {
Jason Sams7f047782009-10-02 18:18:35 -0700101 if (mVertexTypeCount >= mVertexTypes.length) {
Jason Sams1bada8c2009-08-09 17:01:55 -0700102 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;
Jason Sams7f047782009-10-02 18:18:35 -0700141 if (b.mIndexType.t != null) {
Jason Sams1bada8c2009-08-09 17:01:55 -0700142 indexID = b.mIndexType.t.mID;
Jason Sams7f047782009-10-02 18:18:35 -0700143 } else if (b.mIndexType.size != 0) {
Jason Sams1bada8c2009-08-09 17:01:55 -0700144 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++) {
Jason Sams7f047782009-10-02 18:18:35 -0700151 if (b.mVertexTypes[ct].t != null) {
Jason Sams1bada8c2009-08-09 17:01:55 -0700152 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() {
Jason Sams771bebb2009-12-07 12:40:12 -0800169 mRS.validate();
Jason Sams1bada8c2009-08-09 17:01:55 -0700170 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
Jason Sams07ae4062009-08-27 20:23:34 -0700181 public static class TriangleMeshBuilder {
182 float mVtxData[];
183 int mVtxCount;
Jason Sams768bc022009-09-21 19:41:04 -0700184 short mIndexData[];
Jason Sams07ae4062009-08-27 20:23:34 -0700185 int mIndexCount;
186 RenderScript mRS;
187 Element mElement;
188
Jason Sams7f047782009-10-02 18:18:35 -0700189 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;
Jason Sams07ae4062009-08-27 20:23:34 -0700198
Jason Sams7f047782009-10-02 18:18:35 -0700199 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) {
Jason Sams07ae4062009-08-27 20:23:34 -0700207 mRS = rs;
208 mVtxCount = 0;
209 mIndexCount = 0;
210 mVtxData = new float[128];
Jason Sams768bc022009-09-21 19:41:04 -0700211 mIndexData = new short[128];
Jason Sams07ae4062009-08-27 20:23:34 -0700212 mVtxSize = vtxSize;
Jason Sams7f047782009-10-02 18:18:35 -0700213 mFlags = flags;
Jason Sams07ae4062009-08-27 20:23:34 -0700214
Jason Sams7f047782009-10-02 18:18:35 -0700215 if (vtxSize < 2 || vtxSize > 3) {
Jason Sams07ae4062009-08-27 20:23:34 -0700216 throw new IllegalArgumentException("Vertex size out of range.");
217 }
218 }
219
220 private void makeSpace(int count) {
Jason Sams7f047782009-10-02 18:18:35 -0700221 if ((mVtxCount + count) >= mVtxData.length) {
Jason Sams07ae4062009-08-27 20:23:34 -0700222 float t[] = new float[mVtxData.length * 2];
223 System.arraycopy(mVtxData, 0, t, 0, mVtxData.length);
224 mVtxData = t;
225 }
226 }
227
Jason Sams7f047782009-10-02 18:18:35 -0700228 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 }
Jason Sams7299c832009-10-16 14:55:41 -0700236 if ((mFlags & TEXTURE_0) != 0) {
237 makeSpace(2);
238 mVtxData[mVtxCount++] = mS0;
239 mVtxData[mVtxCount++] = mT0;
240 }
Jason Sams7f047782009-10-02 18:18:35 -0700241 if ((mFlags & NORMAL) != 0) {
242 makeSpace(3);
243 mVtxData[mVtxCount++] = mNX;
244 mVtxData[mVtxCount++] = mNY;
245 mVtxData[mVtxCount++] = mNZ;
246 }
Jason Sams7f047782009-10-02 18:18:35 -0700247 }
248
249 public void addVertex(float x, float y) {
250 if (mVtxSize != 2) {
251 throw new IllegalStateException("add mistmatch with declared components.");
Jason Sams07ae4062009-08-27 20:23:34 -0700252 }
253 makeSpace(2);
254 mVtxData[mVtxCount++] = x;
255 mVtxData[mVtxCount++] = y;
Jason Sams7f047782009-10-02 18:18:35 -0700256 latch();
Jason Sams07ae4062009-08-27 20:23:34 -0700257 }
258
Jason Sams7f047782009-10-02 18:18:35 -0700259 public void addVertex(float x, float y, float z) {
260 if (mVtxSize != 3) {
261 throw new IllegalStateException("add mistmatch with declared components.");
Jason Sams07ae4062009-08-27 20:23:34 -0700262 }
263 makeSpace(3);
264 mVtxData[mVtxCount++] = x;
265 mVtxData[mVtxCount++] = y;
266 mVtxData[mVtxCount++] = z;
Jason Sams7f047782009-10-02 18:18:35 -0700267 latch();
Jason Sams07ae4062009-08-27 20:23:34 -0700268 }
269
Jason Sams7f047782009-10-02 18:18:35 -0700270 public void setTexture(float s, float t) {
271 if ((mFlags & TEXTURE_0) == 0) {
272 throw new IllegalStateException("add mistmatch with declared components.");
Jason Sams07ae4062009-08-27 20:23:34 -0700273 }
Jason Sams7f047782009-10-02 18:18:35 -0700274 mS0 = s;
275 mT0 = t;
Jason Sams07ae4062009-08-27 20:23:34 -0700276 }
277
Jason Sams7f047782009-10-02 18:18:35 -0700278 public void setNormal(float x, float y, float z) {
279 if ((mFlags & NORMAL) == 0) {
280 throw new IllegalStateException("add mistmatch with declared components.");
Jason Sams07ae4062009-08-27 20:23:34 -0700281 }
Jason Sams7f047782009-10-02 18:18:35 -0700282 mNX = x;
283 mNY = y;
284 mNZ = z;
Jason Sams07ae4062009-08-27 20:23:34 -0700285 }
286
Jason Sams7f047782009-10-02 18:18:35 -0700287 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.");
Jason Sams07ae4062009-08-27 20:23:34 -0700290 }
Jason Sams7f047782009-10-02 18:18:35 -0700291 mR = r;
292 mG = g;
293 mB = b;
294 mA = a;
Jason Sams07ae4062009-08-27 20:23:34 -0700295 }
296
297 public void addTriangle(int idx1, int idx2, int idx3) {
Jason Samsbd2197f2009-10-07 18:14:01 -0700298 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 }
Jason Sams7f047782009-10-02 18:18:35 -0700303 if ((mIndexCount + 3) >= mIndexData.length) {
Jason Sams768bc022009-09-21 19:41:04 -0700304 short t[] = new short[mIndexData.length * 2];
Jason Sams07ae4062009-08-27 20:23:34 -0700305 System.arraycopy(mIndexData, 0, t, 0, mIndexData.length);
306 mIndexData = t;
307 }
Jason Sams768bc022009-09-21 19:41:04 -0700308 mIndexData[mIndexCount++] = (short)idx1;
309 mIndexData[mIndexCount++] = (short)idx2;
310 mIndexData[mIndexCount++] = (short)idx3;
Jason Sams07ae4062009-08-27 20:23:34 -0700311 }
312
313 public SimpleMesh create() {
314 Element.Builder b = new Element.Builder(mRS);
315 int floatCount = mVtxSize;
Jason Sams7f047782009-10-02 18:18:35 -0700316 if (mVtxSize == 2) {
Jason Sams07ae4062009-08-27 20:23:34 -0700317 b.addFloatXY();
318 } else {
319 b.addFloatXYZ();
320 }
Jason Sams7f047782009-10-02 18:18:35 -0700321 if ((mFlags & COLOR) != 0) {
322 floatCount += 4;
323 b.addFloatRGBA();
324 }
325 if ((mFlags & TEXTURE_0) != 0) {
Jason Sams07ae4062009-08-27 20:23:34 -0700326 floatCount += 2;
327 b.addFloatST();
328 }
Jason Sams7f047782009-10-02 18:18:35 -0700329 if ((mFlags & NORMAL) != 0) {
Jason Sams07ae4062009-08-27 20:23:34 -0700330 floatCount += 3;
331 b.addFloatNorm();
332 }
333 mElement = b.create();
334
335 Builder smb = new Builder(mRS);
336 smb.addVertexType(mElement, mVtxCount / floatCount);
Jason Sams3c0dfba2009-09-27 17:50:38 -0700337 smb.setIndexType(Element.INDEX_16(mRS), mIndexCount);
Jason Sams07ae4062009-08-27 20:23:34 -0700338 smb.setPrimitive(Primitive.TRIANGLE);
339 SimpleMesh sm = smb.create();
340
341 Allocation vertexAlloc = sm.createVertexAllocation(0);
342 Allocation indexAlloc = sm.createIndexAllocation();
343 sm.bindVertexAllocation(vertexAlloc, 0);
344 sm.bindIndexAllocation(indexAlloc);
345
346 vertexAlloc.data(mVtxData);
347 vertexAlloc.uploadToBufferObject();
348
Jason Sams07ae4062009-08-27 20:23:34 -0700349 indexAlloc.data(mIndexData);
350 indexAlloc.uploadToBufferObject();
351
352 return sm;
353 }
354 }
Jason Sams1bada8c2009-08-09 17:01:55 -0700355}
356