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