blob: 8e43f2425cfbd2808ea97d4d979753f3b6d2ef0b [file] [log] [blame]
Jason Samsa89371c2009-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 Sakhartchoukfb6b6142010-05-21 12:53:13 -070017#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Samsa89371c2009-06-30 14:13:04 -070018#include "rsContext.h"
19
Alex Sakhartchoukfb6b6142010-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"
25
26#include <OpenGL/gl.h>
27#include <OpenGl/glext.h>
28#endif
29
30
Jason Samsa89371c2009-06-30 14:13:04 -070031using namespace android;
32using namespace android::renderscript;
33
Jason Samse514b452009-09-25 14:51:22 -070034Mesh::Mesh(Context *rsc) : ObjectBase(rsc)
Jason Samsa89371c2009-06-30 14:13:04 -070035{
Jason Samsf2649a92009-09-25 16:37:33 -070036 mAllocFile = __FILE__;
37 mAllocLine = __LINE__;
Jason Samsa89371c2009-06-30 14:13:04 -070038 mPrimitives = NULL;
Jason Samsa5597fc2009-07-08 18:01:53 -070039 mPrimitivesCount = 0;
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -070040 mVertexBuffers = NULL;
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -070041 mVertexBufferCount = 0;
Jason Samsa89371c2009-06-30 14:13:04 -070042}
43
44Mesh::~Mesh()
45{
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -070046 if(mVertexBuffers) {
47 delete[] mVertexBuffers;
48 }
49
50 if(mPrimitives) {
51 for(uint32_t i = 0; i < mPrimitivesCount; i ++) {
52 delete mPrimitives[i];
53 }
54 delete[] mPrimitives;
55 }
56}
57
58void Mesh::render(Context *rsc) const
59{
60 for(uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
61 renderPrimitive(rsc, ct);
62 }
63}
64
65void Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
66 if (primIndex >= mPrimitivesCount) {
67 LOGE("Invalid primitive index");
68 return;
69 }
70
71 Primitive_t *prim = mPrimitives[primIndex];
72
73 if (prim->mIndexBuffer.get()) {
74 renderPrimitiveRange(rsc, primIndex, 0, prim->mIndexBuffer->getType()->getDimX());
75 return;
76 }
77
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -070078 renderPrimitiveRange(rsc, primIndex, 0, mVertexBuffers[0]->getType()->getDimX());
79}
80
81void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const
82{
83 if (len < 1 || primIndex >= mPrimitivesCount) {
84 return;
85 }
86
87 rsc->checkError("Mesh::renderPrimitiveRange 1");
88 VertexArray va;
89 for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
90 mVertexBuffers[ct]->uploadCheck(rsc);
91 if (mVertexBuffers[ct]->getIsBufferObject()) {
92 va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID());
93 } else {
94 va.setActiveBuffer(mVertexBuffers[ct]->getPtr());
95 }
96 mVertexBuffers[ct]->getType()->enableGLVertexBuffer(&va);
97 }
98 va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
99
100 rsc->checkError("Mesh::renderPrimitiveRange 2");
101 Primitive_t *prim = mPrimitives[primIndex];
102 if (prim->mIndexBuffer.get()) {
103 prim->mIndexBuffer->uploadCheck(rsc);
104 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prim->mIndexBuffer->getBufferObjectID());
105 glDrawElements(prim->mGLPrimitive, len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2));
106 } else {
107 glDrawArrays(prim->mGLPrimitive, start, len);
108 }
109
110 rsc->checkError("Mesh::renderPrimitiveRange");
111}
112
113
114void Mesh::uploadAll(Context *rsc)
115{
116 for (uint32_t ct = 0; ct < mVertexBufferCount; ct ++) {
117 if (mVertexBuffers[ct].get()) {
118 mVertexBuffers[ct]->deferedUploadToBufferObject(rsc);
119 }
120 }
121
122 for (uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
123 if (mPrimitives[ct]->mIndexBuffer.get()) {
124 mPrimitives[ct]->mIndexBuffer->deferedUploadToBufferObject(rsc);
125 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700126 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700127}
128
129void Mesh::updateGLPrimitives()
130{
131 for(uint32_t i = 0; i < mPrimitivesCount; i ++) {
132 switch(mPrimitives[i]->mPrimitive) {
133 case RS_PRIMITIVE_POINT: mPrimitives[i]->mGLPrimitive = GL_POINTS; break;
134 case RS_PRIMITIVE_LINE: mPrimitives[i]->mGLPrimitive = GL_LINES; break;
135 case RS_PRIMITIVE_LINE_STRIP: mPrimitives[i]->mGLPrimitive = GL_LINE_STRIP; break;
136 case RS_PRIMITIVE_TRIANGLE: mPrimitives[i]->mGLPrimitive = GL_TRIANGLES; break;
137 case RS_PRIMITIVE_TRIANGLE_STRIP: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_STRIP; break;
138 case RS_PRIMITIVE_TRIANGLE_FAN: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_FAN; break;
139 }
140 }
Jason Samsa89371c2009-06-30 14:13:04 -0700141}
142
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700143void Mesh::serialize(OStream *stream) const
144{
145 // Need to identify ourselves
146 stream->addU32((uint32_t)getClassId());
147
148 String8 name(getName());
149 stream->addString(&name);
150
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700151 // Store number of vertex streams
152 stream->addU32(mVertexBufferCount);
153 for(uint32_t vCount = 0; vCount < mVertexBufferCount; vCount ++) {
154 mVertexBuffers[vCount]->serialize(stream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700155 }
156
157 stream->addU32(mPrimitivesCount);
158 // Store the primitives
159 for (uint32_t pCount = 0; pCount < mPrimitivesCount; pCount ++) {
160 Primitive_t * prim = mPrimitives[pCount];
161
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700162 stream->addU8((uint8_t)prim->mPrimitive);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700163
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700164 if(prim->mIndexBuffer.get()) {
165 stream->addU32(1);
166 prim->mIndexBuffer->serialize(stream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700167 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700168 else {
169 stream->addU32(0);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700170 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700171 }
172}
173
174Mesh *Mesh::createFromStream(Context *rsc, IStream *stream)
175{
176 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700177 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
178 if(classID != RS_A3D_CLASS_ID_MESH) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700179 LOGE("mesh loading skipped due to invalid class id");
180 return NULL;
181 }
182
183 Mesh * mesh = new Mesh(rsc);
184
185 String8 name;
186 stream->loadString(&name);
187 mesh->setName(name.string(), name.size());
188
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700189 mesh->mVertexBufferCount = stream->loadU32();
190 if(mesh->mVertexBufferCount) {
191 mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[mesh->mVertexBufferCount];
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700192
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700193 for(uint32_t vCount = 0; vCount < mesh->mVertexBufferCount; vCount ++) {
194 Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
195 mesh->mVertexBuffers[vCount].set(vertexAlloc);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700196 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700197 }
198
199 mesh->mPrimitivesCount = stream->loadU32();
200 if(mesh->mPrimitivesCount) {
201 mesh->mPrimitives = new Primitive_t *[mesh->mPrimitivesCount];
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700202
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700203 // load all primitives
204 for (uint32_t pCount = 0; pCount < mesh->mPrimitivesCount; pCount ++) {
205 Primitive_t * prim = new Primitive_t;
206 mesh->mPrimitives[pCount] = prim;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700207
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700208 prim->mPrimitive = (RsPrimitive)stream->loadU8();
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700209
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700210 // Check to see if the index buffer was stored
211 uint32_t isIndexPresent = stream->loadU32();
212 if(isIndexPresent) {
213 Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
214 prim->mIndexBuffer.set(indexAlloc);
215 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700216 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700217 }
218
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700219 mesh->updateGLPrimitives();
220 mesh->uploadAll(rsc);
221
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700222 return mesh;
223}
Jason Samsa89371c2009-06-30 14:13:04 -0700224
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700225void Mesh::computeBBox() {
226 float *posPtr = NULL;
227 uint32_t vectorSize = 0;
228 uint32_t stride = 0;
229 uint32_t numVerts = 0;
230 // First we need to find the position ptr and stride
231 for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
232 const Type *bufferType = mVertexBuffers[ct]->getType();
233 const Element *bufferElem = bufferType->getElement();
234
235 for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
236 if(strcmp(bufferElem->getFieldName(ct), "position") == 0) {
237 vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
238 stride = bufferElem->getSizeBytes() / sizeof(float);
239 uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
240 posPtr = (float*)((uint8_t*)mVertexBuffers[ct]->getPtr() + offset);
241 numVerts = bufferType->getDimX();
242 break;
243 }
244 }
245 if(posPtr) {
246 break;
247 }
248 }
249
250 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
251 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
252 if(!posPtr) {
253 LOGE("Unable to compute bounding box");
254 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
255 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
256 return;
257 }
258
259 for(uint32_t i = 0; i < numVerts; i ++) {
260 for(uint32_t v = 0; v < vectorSize; v ++) {
261 mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
262 mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
263 }
264 posPtr += stride;
265 }
266}
267
Jason Samsa89371c2009-06-30 14:13:04 -0700268
269MeshContext::MeshContext()
270{
271}
272
273MeshContext::~MeshContext()
274{
275}
276
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700277namespace android {
278namespace renderscript {
279
280RsMesh rsi_MeshCreate(Context *rsc, uint32_t vtxCount, uint32_t idxCount)
281{
282 Mesh *sm = new Mesh(rsc);
283 sm->incUserRef();
284
285 sm->mPrimitivesCount = idxCount;
286 sm->mPrimitives = new Mesh::Primitive_t *[sm->mPrimitivesCount];
287 for(uint32_t ct = 0; ct < idxCount; ct ++) {
288 sm->mPrimitives[ct] = new Mesh::Primitive_t;
289 }
290
291 sm->mVertexBufferCount = vtxCount;
292 sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount];
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700293
294 return sm;
295}
296
297void rsi_MeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot)
298{
299 Mesh *sm = static_cast<Mesh *>(mv);
300 rsAssert(slot < sm->mVertexBufferCount);
301
302 sm->mVertexBuffers[slot].set((Allocation *)va);
303}
304
305void rsi_MeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot)
306{
307 Mesh *sm = static_cast<Mesh *>(mv);
308 rsAssert(slot < sm->mPrimitivesCount);
309
310 sm->mPrimitives[slot]->mIndexBuffer.set((Allocation *)va);
311 sm->mPrimitives[slot]->mPrimitive = (RsPrimitive)primType;
312 sm->updateGLPrimitives();
313}
314
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700315void rsi_MeshGetVertexBufferCount(Context *rsc, RsMesh mv, int32_t *numVtx)
316{
317 Mesh *sm = static_cast<Mesh *>(mv);
318 *numVtx = sm->mVertexBufferCount;
319}
320
321void rsi_MeshGetIndexCount(Context *rsc, RsMesh mv, int32_t *numIdx)
322{
323 Mesh *sm = static_cast<Mesh *>(mv);
324 *numIdx = sm->mPrimitivesCount;
325}
326
327void rsi_MeshGetVertices(Context *rsc, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount)
328{
329 Mesh *sm = static_cast<Mesh *>(mv);
330 rsAssert(vtxDataCount == sm->mVertexBufferCount);
331
332 for(uint32_t ct = 0; ct < vtxDataCount; ct ++) {
333 vtxData[ct] = sm->mVertexBuffers[ct].get();
334 sm->mVertexBuffers[ct]->incUserRef();
335 }
336}
337
338void rsi_MeshGetIndices(Context *rsc, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount)
339{
340 Mesh *sm = static_cast<Mesh *>(mv);
341 rsAssert(idxDataCount == sm->mPrimitivesCount);
342
343 for(uint32_t ct = 0; ct < idxDataCount; ct ++) {
344 va[ct] = sm->mPrimitives[ct]->mIndexBuffer.get();
345 primType[ct] = sm->mPrimitives[ct]->mPrimitive;
346 if(sm->mPrimitives[ct]->mIndexBuffer.get()) {
347 sm->mPrimitives[ct]->mIndexBuffer->incUserRef();
348 }
349 }
350
351}
352
353
354
355
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700356}}