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