blob: 8cf76e5f64a1fa493c629e6f64e4dc11a9a65d14 [file] [log] [blame]
Jason Sams7c878f32009-06-30 14:13:04 -07001/*
2 * Copyright (C) 2009 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
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070017#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Sams7c878f32009-06-30 14:13:04 -070018#include "rsContext.h"
19
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070020#include <GLES/gl.h>
21#include <GLES2/gl2.h>
22#include <GLES/glext.h>
23#else
24#include "rsContextHostStub.h"
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070025#endif
26
Jason Sams7c878f32009-06-30 14:13:04 -070027using namespace android;
28using namespace android::renderscript;
29
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080030Mesh::Mesh(Context *rsc) : ObjectBase(rsc) {
Jason Sams7c878f32009-06-30 14:13:04 -070031 mPrimitives = NULL;
Jason Sams64676f32009-07-08 18:01:53 -070032 mPrimitivesCount = 0;
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -070033 mVertexBuffers = NULL;
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -070034 mVertexBufferCount = 0;
Alex Sakhartchouka3b59602011-01-28 09:31:47 -080035
36#ifndef ANDROID_RS_BUILD_FOR_HOST
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -080037 mAttribs = NULL;
38 mAttribAllocationIndex = NULL;
39
40 mAttribCount = 0;
Alex Sakhartchouka3b59602011-01-28 09:31:47 -080041#endif
Jason Sams7c878f32009-06-30 14:13:04 -070042}
43
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080044Mesh::~Mesh() {
45 if (mVertexBuffers) {
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -070046 delete[] mVertexBuffers;
47 }
48
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080049 if (mPrimitives) {
50 for (uint32_t i = 0; i < mPrimitivesCount; i ++) {
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -070051 delete mPrimitives[i];
52 }
53 delete[] mPrimitives;
54 }
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -080055
Alex Sakhartchouka3b59602011-01-28 09:31:47 -080056#ifndef ANDROID_RS_BUILD_FOR_HOST
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080057 if (mAttribs) {
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -080058 delete[] mAttribs;
59 delete[] mAttribAllocationIndex;
60 }
Alex Sakhartchouka3b59602011-01-28 09:31:47 -080061#endif
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -080062}
63
Alex Sakhartchouka3b59602011-01-28 09:31:47 -080064void Mesh::serialize(OStream *stream) const {
65 // Need to identify ourselves
66 stream->addU32((uint32_t)getClassId());
67
68 String8 name(getName());
69 stream->addString(&name);
70
71 // Store number of vertex streams
72 stream->addU32(mVertexBufferCount);
73 for (uint32_t vCount = 0; vCount < mVertexBufferCount; vCount ++) {
74 mVertexBuffers[vCount]->serialize(stream);
75 }
76
77 stream->addU32(mPrimitivesCount);
78 // Store the primitives
79 for (uint32_t pCount = 0; pCount < mPrimitivesCount; pCount ++) {
80 Primitive_t * prim = mPrimitives[pCount];
81
82 stream->addU8((uint8_t)prim->mPrimitive);
83
84 if (prim->mIndexBuffer.get()) {
85 stream->addU32(1);
86 prim->mIndexBuffer->serialize(stream);
87 } else {
88 stream->addU32(0);
89 }
90 }
91}
92
93Mesh *Mesh::createFromStream(Context *rsc, IStream *stream) {
94 // First make sure we are reading the correct object
95 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
96 if (classID != RS_A3D_CLASS_ID_MESH) {
97 LOGE("mesh loading skipped due to invalid class id");
98 return NULL;
99 }
100
101 Mesh * mesh = new Mesh(rsc);
102
103 String8 name;
104 stream->loadString(&name);
105 mesh->setName(name.string(), name.size());
106
107 mesh->mVertexBufferCount = stream->loadU32();
108 if (mesh->mVertexBufferCount) {
109 mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[mesh->mVertexBufferCount];
110
111 for (uint32_t vCount = 0; vCount < mesh->mVertexBufferCount; vCount ++) {
112 Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
113 mesh->mVertexBuffers[vCount].set(vertexAlloc);
114 }
115 }
116
117 mesh->mPrimitivesCount = stream->loadU32();
118 if (mesh->mPrimitivesCount) {
119 mesh->mPrimitives = new Primitive_t *[mesh->mPrimitivesCount];
120
121 // load all primitives
122 for (uint32_t pCount = 0; pCount < mesh->mPrimitivesCount; pCount ++) {
123 Primitive_t * prim = new Primitive_t;
124 mesh->mPrimitives[pCount] = prim;
125
126 prim->mPrimitive = (RsPrimitive)stream->loadU8();
127
128 // Check to see if the index buffer was stored
129 uint32_t isIndexPresent = stream->loadU32();
130 if (isIndexPresent) {
131 Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
132 prim->mIndexBuffer.set(indexAlloc);
133 }
134 }
135 }
136
137#ifndef ANDROID_RS_BUILD_FOR_HOST
138 mesh->updateGLPrimitives();
139 mesh->initVertexAttribs();
140 mesh->uploadAll(rsc);
141#endif
142 return mesh;
143}
144
145#ifndef ANDROID_RS_BUILD_FOR_HOST
146
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800147bool Mesh::isValidGLComponent(const Element *elem, uint32_t fieldIdx) {
148 // Do not create attribs for padding
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800149 if (elem->getFieldName(fieldIdx)[0] == '#') {
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800150 return false;
151 }
152
153 // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
154 // Filter rs types accordingly
155 RsDataType dt = elem->getField(fieldIdx)->getComponent().getType();
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800156 if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800157 dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
158 dt != RS_TYPE_SIGNED_16) {
159 return false;
160 }
161
162 // Now make sure they are not arrays
163 uint32_t arraySize = elem->getFieldArraySize(fieldIdx);
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800164 if (arraySize != 1) {
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800165 return false;
166 }
167
168 return true;
169}
170
171void Mesh::initVertexAttribs() {
172 // Count the number of gl attrs to initialize
173 mAttribCount = 0;
174 for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
175 const Element *elem = mVertexBuffers[ct]->getType()->getElement();
176 for (uint32_t ct=0; ct < elem->getFieldCount(); ct++) {
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800177 if (isValidGLComponent(elem, ct)) {
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800178 mAttribCount ++;
179 }
180 }
181 }
182
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800183 if (mAttribs) {
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800184 delete [] mAttribs;
185 delete [] mAttribAllocationIndex;
186 mAttribs = NULL;
187 mAttribAllocationIndex = NULL;
188 }
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800189 if (!mAttribCount) {
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800190 return;
191 }
192
193 mAttribs = new VertexArray::Attrib[mAttribCount];
194 mAttribAllocationIndex = new uint32_t[mAttribCount];
195
196 uint32_t userNum = 0;
197 for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
198 const Element *elem = mVertexBuffers[ct]->getType()->getElement();
199 uint32_t stride = elem->getSizeBytes();
200 for (uint32_t fieldI=0; fieldI < elem->getFieldCount(); fieldI++) {
201 const Component &c = elem->getField(fieldI)->getComponent();
202
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800203 if (!isValidGLComponent(elem, fieldI)) {
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800204 continue;
205 }
206
207 mAttribs[userNum].size = c.getVectorSize();
208 mAttribs[userNum].offset = elem->getFieldOffsetBytes(fieldI);
209 mAttribs[userNum].type = c.getGLType();
210 mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
211 mAttribs[userNum].stride = stride;
212 String8 tmp(RS_SHADER_ATTR);
213 tmp.append(elem->getFieldName(fieldI));
214 mAttribs[userNum].name.setTo(tmp.string());
215
216 // Remember which allocation this attribute came from
217 mAttribAllocationIndex[userNum] = ct;
218 userNum ++;
219 }
220 }
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700221}
222
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800223void Mesh::render(Context *rsc) const {
224 for (uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700225 renderPrimitive(rsc, ct);
226 }
227}
228
229void Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
230 if (primIndex >= mPrimitivesCount) {
231 LOGE("Invalid primitive index");
232 return;
233 }
234
235 Primitive_t *prim = mPrimitives[primIndex];
236
237 if (prim->mIndexBuffer.get()) {
238 renderPrimitiveRange(rsc, primIndex, 0, prim->mIndexBuffer->getType()->getDimX());
239 return;
240 }
241
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700242 renderPrimitiveRange(rsc, primIndex, 0, mVertexBuffers[0]->getType()->getDimX());
243}
244
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800245void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800246 if (len < 1 || primIndex >= mPrimitivesCount || mAttribCount == 0) {
247 LOGE("Invalid mesh or parameters");
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700248 return;
249 }
250
251 rsc->checkError("Mesh::renderPrimitiveRange 1");
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700252 for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
253 mVertexBuffers[ct]->uploadCheck(rsc);
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700254 }
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800255 // update attributes with either buffer information or data ptr based on their current state
256 for (uint32_t ct=0; ct < mAttribCount; ct++) {
257 uint32_t allocIndex = mAttribAllocationIndex[ct];
258 Allocation *alloc = mVertexBuffers[allocIndex].get();
259 if (alloc->getIsBufferObject()) {
260 mAttribs[ct].buffer = alloc->getBufferObjectID();
261 mAttribs[ct].ptr = NULL;
262 } else {
263 mAttribs[ct].buffer = 0;
264 mAttribs[ct].ptr = (const uint8_t*)alloc->getPtr();
265 }
266 }
267
268 VertexArray va(mAttribs, mAttribCount);
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700269 va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
270
271 rsc->checkError("Mesh::renderPrimitiveRange 2");
272 Primitive_t *prim = mPrimitives[primIndex];
273 if (prim->mIndexBuffer.get()) {
274 prim->mIndexBuffer->uploadCheck(rsc);
275 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prim->mIndexBuffer->getBufferObjectID());
276 glDrawElements(prim->mGLPrimitive, len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2));
277 } else {
278 glDrawArrays(prim->mGLPrimitive, start, len);
279 }
280
281 rsc->checkError("Mesh::renderPrimitiveRange");
282}
283
284
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800285void Mesh::uploadAll(Context *rsc) {
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700286 for (uint32_t ct = 0; ct < mVertexBufferCount; ct ++) {
287 if (mVertexBuffers[ct].get()) {
288 mVertexBuffers[ct]->deferedUploadToBufferObject(rsc);
289 }
290 }
291
292 for (uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
293 if (mPrimitives[ct]->mIndexBuffer.get()) {
294 mPrimitives[ct]->mIndexBuffer->deferedUploadToBufferObject(rsc);
295 }
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700296 }
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700297}
298
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800299void Mesh::updateGLPrimitives() {
300 for (uint32_t i = 0; i < mPrimitivesCount; i ++) {
301 switch (mPrimitives[i]->mPrimitive) {
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700302 case RS_PRIMITIVE_POINT: mPrimitives[i]->mGLPrimitive = GL_POINTS; break;
303 case RS_PRIMITIVE_LINE: mPrimitives[i]->mGLPrimitive = GL_LINES; break;
304 case RS_PRIMITIVE_LINE_STRIP: mPrimitives[i]->mGLPrimitive = GL_LINE_STRIP; break;
305 case RS_PRIMITIVE_TRIANGLE: mPrimitives[i]->mGLPrimitive = GL_TRIANGLES; break;
306 case RS_PRIMITIVE_TRIANGLE_STRIP: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_STRIP; break;
307 case RS_PRIMITIVE_TRIANGLE_FAN: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_FAN; break;
308 }
309 }
Jason Sams7c878f32009-06-30 14:13:04 -0700310}
311
Alex Sakhartchouka80145d2010-08-13 14:32:23 -0700312void Mesh::computeBBox() {
313 float *posPtr = NULL;
314 uint32_t vectorSize = 0;
315 uint32_t stride = 0;
316 uint32_t numVerts = 0;
317 // First we need to find the position ptr and stride
318 for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
319 const Type *bufferType = mVertexBuffers[ct]->getType();
320 const Element *bufferElem = bufferType->getElement();
321
322 for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800323 if (strcmp(bufferElem->getFieldName(ct), "position") == 0) {
Alex Sakhartchouka80145d2010-08-13 14:32:23 -0700324 vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
325 stride = bufferElem->getSizeBytes() / sizeof(float);
326 uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
327 posPtr = (float*)((uint8_t*)mVertexBuffers[ct]->getPtr() + offset);
328 numVerts = bufferType->getDimX();
329 break;
330 }
331 }
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800332 if (posPtr) {
Alex Sakhartchouka80145d2010-08-13 14:32:23 -0700333 break;
334 }
335 }
336
337 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
338 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800339 if (!posPtr) {
Alex Sakhartchouka80145d2010-08-13 14:32:23 -0700340 LOGE("Unable to compute bounding box");
341 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
342 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
343 return;
344 }
345
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800346 for (uint32_t i = 0; i < numVerts; i ++) {
347 for (uint32_t v = 0; v < vectorSize; v ++) {
Alex Sakhartchouka80145d2010-08-13 14:32:23 -0700348 mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
349 mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
350 }
351 posPtr += stride;
352 }
353}
354
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700355namespace android {
356namespace renderscript {
357
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800358RsMesh rsi_MeshCreate(Context *rsc, uint32_t vtxCount, uint32_t idxCount) {
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700359 Mesh *sm = new Mesh(rsc);
360 sm->incUserRef();
361
362 sm->mPrimitivesCount = idxCount;
363 sm->mPrimitives = new Mesh::Primitive_t *[sm->mPrimitivesCount];
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800364 for (uint32_t ct = 0; ct < idxCount; ct ++) {
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700365 sm->mPrimitives[ct] = new Mesh::Primitive_t;
366 }
367
368 sm->mVertexBufferCount = vtxCount;
369 sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount];
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700370
371 return sm;
372}
373
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800374void rsi_MeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot) {
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700375 Mesh *sm = static_cast<Mesh *>(mv);
376 rsAssert(slot < sm->mVertexBufferCount);
377
378 sm->mVertexBuffers[slot].set((Allocation *)va);
379}
380
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800381void rsi_MeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot) {
Alex Sakhartchouk164aaed2010-07-01 16:14:06 -0700382 Mesh *sm = static_cast<Mesh *>(mv);
383 rsAssert(slot < sm->mPrimitivesCount);
384
385 sm->mPrimitives[slot]->mIndexBuffer.set((Allocation *)va);
386 sm->mPrimitives[slot]->mPrimitive = (RsPrimitive)primType;
387 sm->updateGLPrimitives();
388}
389
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800390void rsi_MeshInitVertexAttribs(Context *rsc, RsMesh mv) {
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800391 Mesh *sm = static_cast<Mesh *>(mv);
392 sm->initVertexAttribs();
393}
394
Alex Sakhartchouk581cc642010-10-27 14:10:07 -0700395}}
396
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800397void rsaMeshGetVertexBufferCount(RsContext con, RsMesh mv, int32_t *numVtx) {
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700398 Mesh *sm = static_cast<Mesh *>(mv);
399 *numVtx = sm->mVertexBufferCount;
400}
401
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800402void rsaMeshGetIndexCount(RsContext con, RsMesh mv, int32_t *numIdx) {
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700403 Mesh *sm = static_cast<Mesh *>(mv);
404 *numIdx = sm->mPrimitivesCount;
405}
406
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800407void rsaMeshGetVertices(RsContext con, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount) {
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700408 Mesh *sm = static_cast<Mesh *>(mv);
409 rsAssert(vtxDataCount == sm->mVertexBufferCount);
410
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800411 for (uint32_t ct = 0; ct < vtxDataCount; ct ++) {
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700412 vtxData[ct] = sm->mVertexBuffers[ct].get();
413 sm->mVertexBuffers[ct]->incUserRef();
414 }
415}
416
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800417void rsaMeshGetIndices(RsContext con, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount) {
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700418 Mesh *sm = static_cast<Mesh *>(mv);
419 rsAssert(idxDataCount == sm->mPrimitivesCount);
420
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800421 for (uint32_t ct = 0; ct < idxDataCount; ct ++) {
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700422 va[ct] = sm->mPrimitives[ct]->mIndexBuffer.get();
423 primType[ct] = sm->mPrimitives[ct]->mPrimitive;
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800424 if (sm->mPrimitives[ct]->mIndexBuffer.get()) {
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700425 sm->mPrimitives[ct]->mIndexBuffer->incUserRef();
426 }
427 }
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700428}
Alex Sakhartchouka3b59602011-01-28 09:31:47 -0800429
430#endif