blob: 810e4ff95738e5248236942d6267ada3fad3a274 [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 }
127
128 rsc->checkError("Mesh::uploadAll");
129}
130
131void Mesh::updateGLPrimitives()
132{
133 for(uint32_t i = 0; i < mPrimitivesCount; i ++) {
134 switch(mPrimitives[i]->mPrimitive) {
135 case RS_PRIMITIVE_POINT: mPrimitives[i]->mGLPrimitive = GL_POINTS; break;
136 case RS_PRIMITIVE_LINE: mPrimitives[i]->mGLPrimitive = GL_LINES; break;
137 case RS_PRIMITIVE_LINE_STRIP: mPrimitives[i]->mGLPrimitive = GL_LINE_STRIP; break;
138 case RS_PRIMITIVE_TRIANGLE: mPrimitives[i]->mGLPrimitive = GL_TRIANGLES; break;
139 case RS_PRIMITIVE_TRIANGLE_STRIP: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_STRIP; break;
140 case RS_PRIMITIVE_TRIANGLE_FAN: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_FAN; break;
141 }
142 }
Jason Samsa89371c2009-06-30 14:13:04 -0700143}
144
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700145void Mesh::serialize(OStream *stream) const
146{
147 // Need to identify ourselves
148 stream->addU32((uint32_t)getClassId());
149
150 String8 name(getName());
151 stream->addString(&name);
152
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700153 // Store number of vertex streams
154 stream->addU32(mVertexBufferCount);
155 for(uint32_t vCount = 0; vCount < mVertexBufferCount; vCount ++) {
156 mVertexBuffers[vCount]->serialize(stream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700157 }
158
159 stream->addU32(mPrimitivesCount);
160 // Store the primitives
161 for (uint32_t pCount = 0; pCount < mPrimitivesCount; pCount ++) {
162 Primitive_t * prim = mPrimitives[pCount];
163
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700164 stream->addU8((uint8_t)prim->mPrimitive);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700165
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700166 if(prim->mIndexBuffer.get()) {
167 stream->addU32(1);
168 prim->mIndexBuffer->serialize(stream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700169 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700170 else {
171 stream->addU32(0);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700172 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700173 }
174}
175
176Mesh *Mesh::createFromStream(Context *rsc, IStream *stream)
177{
178 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700179 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
180 if(classID != RS_A3D_CLASS_ID_MESH) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700181 LOGE("mesh loading skipped due to invalid class id");
182 return NULL;
183 }
184
185 Mesh * mesh = new Mesh(rsc);
186
187 String8 name;
188 stream->loadString(&name);
189 mesh->setName(name.string(), name.size());
190
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700191 mesh->mVertexBufferCount = stream->loadU32();
192 if(mesh->mVertexBufferCount) {
193 mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[mesh->mVertexBufferCount];
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700194
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700195 for(uint32_t vCount = 0; vCount < mesh->mVertexBufferCount; vCount ++) {
196 Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
197 mesh->mVertexBuffers[vCount].set(vertexAlloc);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700198 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700199 }
200
201 mesh->mPrimitivesCount = stream->loadU32();
202 if(mesh->mPrimitivesCount) {
203 mesh->mPrimitives = new Primitive_t *[mesh->mPrimitivesCount];
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700204
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700205 // load all primitives
206 for (uint32_t pCount = 0; pCount < mesh->mPrimitivesCount; pCount ++) {
207 Primitive_t * prim = new Primitive_t;
208 mesh->mPrimitives[pCount] = prim;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700209
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700210 prim->mPrimitive = (RsPrimitive)stream->loadU8();
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700211
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700212 // Check to see if the index buffer was stored
213 uint32_t isIndexPresent = stream->loadU32();
214 if(isIndexPresent) {
215 Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
216 prim->mIndexBuffer.set(indexAlloc);
217 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700218 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700219 }
220
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700221 mesh->updateGLPrimitives();
222 mesh->uploadAll(rsc);
223
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700224 return mesh;
225}
Jason Samsa89371c2009-06-30 14:13:04 -0700226
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700227void Mesh::computeBBox() {
228 float *posPtr = NULL;
229 uint32_t vectorSize = 0;
230 uint32_t stride = 0;
231 uint32_t numVerts = 0;
232 // First we need to find the position ptr and stride
233 for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
234 const Type *bufferType = mVertexBuffers[ct]->getType();
235 const Element *bufferElem = bufferType->getElement();
236
237 for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
238 if(strcmp(bufferElem->getFieldName(ct), "position") == 0) {
239 vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
240 stride = bufferElem->getSizeBytes() / sizeof(float);
241 uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
242 posPtr = (float*)((uint8_t*)mVertexBuffers[ct]->getPtr() + offset);
243 numVerts = bufferType->getDimX();
244 break;
245 }
246 }
247 if(posPtr) {
248 break;
249 }
250 }
251
252 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
253 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
254 if(!posPtr) {
255 LOGE("Unable to compute bounding box");
256 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
257 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
258 return;
259 }
260
261 for(uint32_t i = 0; i < numVerts; i ++) {
262 for(uint32_t v = 0; v < vectorSize; v ++) {
263 mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
264 mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
265 }
266 posPtr += stride;
267 }
268}
269
Jason Samsa89371c2009-06-30 14:13:04 -0700270
271MeshContext::MeshContext()
272{
273}
274
275MeshContext::~MeshContext()
276{
277}
278
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700279namespace android {
280namespace renderscript {
281
282RsMesh rsi_MeshCreate(Context *rsc, uint32_t vtxCount, uint32_t idxCount)
283{
284 Mesh *sm = new Mesh(rsc);
285 sm->incUserRef();
286
287 sm->mPrimitivesCount = idxCount;
288 sm->mPrimitives = new Mesh::Primitive_t *[sm->mPrimitivesCount];
289 for(uint32_t ct = 0; ct < idxCount; ct ++) {
290 sm->mPrimitives[ct] = new Mesh::Primitive_t;
291 }
292
293 sm->mVertexBufferCount = vtxCount;
294 sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount];
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700295
296 return sm;
297}
298
299void rsi_MeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot)
300{
301 Mesh *sm = static_cast<Mesh *>(mv);
302 rsAssert(slot < sm->mVertexBufferCount);
303
304 sm->mVertexBuffers[slot].set((Allocation *)va);
305}
306
307void rsi_MeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot)
308{
309 Mesh *sm = static_cast<Mesh *>(mv);
310 rsAssert(slot < sm->mPrimitivesCount);
311
312 sm->mPrimitives[slot]->mIndexBuffer.set((Allocation *)va);
313 sm->mPrimitives[slot]->mPrimitive = (RsPrimitive)primType;
314 sm->updateGLPrimitives();
315}
316
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700317void rsi_MeshGetVertexBufferCount(Context *rsc, RsMesh mv, int32_t *numVtx)
318{
319 Mesh *sm = static_cast<Mesh *>(mv);
320 *numVtx = sm->mVertexBufferCount;
321}
322
323void rsi_MeshGetIndexCount(Context *rsc, RsMesh mv, int32_t *numIdx)
324{
325 Mesh *sm = static_cast<Mesh *>(mv);
326 *numIdx = sm->mPrimitivesCount;
327}
328
329void rsi_MeshGetVertices(Context *rsc, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount)
330{
331 Mesh *sm = static_cast<Mesh *>(mv);
332 rsAssert(vtxDataCount == sm->mVertexBufferCount);
333
334 for(uint32_t ct = 0; ct < vtxDataCount; ct ++) {
335 vtxData[ct] = sm->mVertexBuffers[ct].get();
336 sm->mVertexBuffers[ct]->incUserRef();
337 }
338}
339
340void rsi_MeshGetIndices(Context *rsc, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount)
341{
342 Mesh *sm = static_cast<Mesh *>(mv);
343 rsAssert(idxDataCount == sm->mPrimitivesCount);
344
345 for(uint32_t ct = 0; ct < idxDataCount; ct ++) {
346 va[ct] = sm->mPrimitives[ct]->mIndexBuffer.get();
347 primType[ct] = sm->mPrimitives[ct]->mPrimitive;
348 if(sm->mPrimitives[ct]->mIndexBuffer.get()) {
349 sm->mPrimitives[ct]->mIndexBuffer->incUserRef();
350 }
351 }
352
353}
354
355
356
357
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700358}}