blob: fd604e5e99b5540271e48d259ad49d143e374d6b [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 Samsa89371c2009-06-30 14:13:04 -070036 mPrimitives = NULL;
Jason Samsa5597fc2009-07-08 18:01:53 -070037 mPrimitivesCount = 0;
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -070038 mVertexBuffers = NULL;
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -070039 mVertexBufferCount = 0;
Jason Samsa89371c2009-06-30 14:13:04 -070040}
41
42Mesh::~Mesh()
43{
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -070044 if(mVertexBuffers) {
45 delete[] mVertexBuffers;
46 }
47
48 if(mPrimitives) {
49 for(uint32_t i = 0; i < mPrimitivesCount; i ++) {
50 delete mPrimitives[i];
51 }
52 delete[] mPrimitives;
53 }
54}
55
56void Mesh::render(Context *rsc) const
57{
58 for(uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
59 renderPrimitive(rsc, ct);
60 }
61}
62
63void Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
64 if (primIndex >= mPrimitivesCount) {
65 LOGE("Invalid primitive index");
66 return;
67 }
68
69 Primitive_t *prim = mPrimitives[primIndex];
70
71 if (prim->mIndexBuffer.get()) {
72 renderPrimitiveRange(rsc, primIndex, 0, prim->mIndexBuffer->getType()->getDimX());
73 return;
74 }
75
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -070076 renderPrimitiveRange(rsc, primIndex, 0, mVertexBuffers[0]->getType()->getDimX());
77}
78
79void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const
80{
81 if (len < 1 || primIndex >= mPrimitivesCount) {
82 return;
83 }
84
85 rsc->checkError("Mesh::renderPrimitiveRange 1");
86 VertexArray va;
87 for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
88 mVertexBuffers[ct]->uploadCheck(rsc);
89 if (mVertexBuffers[ct]->getIsBufferObject()) {
90 va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID());
91 } else {
92 va.setActiveBuffer(mVertexBuffers[ct]->getPtr());
93 }
94 mVertexBuffers[ct]->getType()->enableGLVertexBuffer(&va);
95 }
96 va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
97
98 rsc->checkError("Mesh::renderPrimitiveRange 2");
99 Primitive_t *prim = mPrimitives[primIndex];
100 if (prim->mIndexBuffer.get()) {
101 prim->mIndexBuffer->uploadCheck(rsc);
102 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prim->mIndexBuffer->getBufferObjectID());
103 glDrawElements(prim->mGLPrimitive, len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2));
104 } else {
105 glDrawArrays(prim->mGLPrimitive, start, len);
106 }
107
108 rsc->checkError("Mesh::renderPrimitiveRange");
109}
110
111
112void Mesh::uploadAll(Context *rsc)
113{
114 for (uint32_t ct = 0; ct < mVertexBufferCount; ct ++) {
115 if (mVertexBuffers[ct].get()) {
116 mVertexBuffers[ct]->deferedUploadToBufferObject(rsc);
117 }
118 }
119
120 for (uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
121 if (mPrimitives[ct]->mIndexBuffer.get()) {
122 mPrimitives[ct]->mIndexBuffer->deferedUploadToBufferObject(rsc);
123 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700124 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700125}
126
127void Mesh::updateGLPrimitives()
128{
129 for(uint32_t i = 0; i < mPrimitivesCount; i ++) {
130 switch(mPrimitives[i]->mPrimitive) {
131 case RS_PRIMITIVE_POINT: mPrimitives[i]->mGLPrimitive = GL_POINTS; break;
132 case RS_PRIMITIVE_LINE: mPrimitives[i]->mGLPrimitive = GL_LINES; break;
133 case RS_PRIMITIVE_LINE_STRIP: mPrimitives[i]->mGLPrimitive = GL_LINE_STRIP; break;
134 case RS_PRIMITIVE_TRIANGLE: mPrimitives[i]->mGLPrimitive = GL_TRIANGLES; break;
135 case RS_PRIMITIVE_TRIANGLE_STRIP: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_STRIP; break;
136 case RS_PRIMITIVE_TRIANGLE_FAN: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_FAN; break;
137 }
138 }
Jason Samsa89371c2009-06-30 14:13:04 -0700139}
140
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700141void Mesh::serialize(OStream *stream) const
142{
143 // Need to identify ourselves
144 stream->addU32((uint32_t)getClassId());
145
146 String8 name(getName());
147 stream->addString(&name);
148
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700149 // Store number of vertex streams
150 stream->addU32(mVertexBufferCount);
151 for(uint32_t vCount = 0; vCount < mVertexBufferCount; vCount ++) {
152 mVertexBuffers[vCount]->serialize(stream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700153 }
154
155 stream->addU32(mPrimitivesCount);
156 // Store the primitives
157 for (uint32_t pCount = 0; pCount < mPrimitivesCount; pCount ++) {
158 Primitive_t * prim = mPrimitives[pCount];
159
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700160 stream->addU8((uint8_t)prim->mPrimitive);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700161
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700162 if(prim->mIndexBuffer.get()) {
163 stream->addU32(1);
164 prim->mIndexBuffer->serialize(stream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700165 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700166 else {
167 stream->addU32(0);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700168 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700169 }
170}
171
172Mesh *Mesh::createFromStream(Context *rsc, IStream *stream)
173{
174 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700175 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
176 if(classID != RS_A3D_CLASS_ID_MESH) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700177 LOGE("mesh loading skipped due to invalid class id");
178 return NULL;
179 }
180
181 Mesh * mesh = new Mesh(rsc);
182
183 String8 name;
184 stream->loadString(&name);
185 mesh->setName(name.string(), name.size());
186
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700187 mesh->mVertexBufferCount = stream->loadU32();
188 if(mesh->mVertexBufferCount) {
189 mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[mesh->mVertexBufferCount];
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700190
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700191 for(uint32_t vCount = 0; vCount < mesh->mVertexBufferCount; vCount ++) {
192 Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
193 mesh->mVertexBuffers[vCount].set(vertexAlloc);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700194 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700195 }
196
197 mesh->mPrimitivesCount = stream->loadU32();
198 if(mesh->mPrimitivesCount) {
199 mesh->mPrimitives = new Primitive_t *[mesh->mPrimitivesCount];
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700200
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700201 // load all primitives
202 for (uint32_t pCount = 0; pCount < mesh->mPrimitivesCount; pCount ++) {
203 Primitive_t * prim = new Primitive_t;
204 mesh->mPrimitives[pCount] = prim;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700205
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700206 prim->mPrimitive = (RsPrimitive)stream->loadU8();
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700207
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700208 // Check to see if the index buffer was stored
209 uint32_t isIndexPresent = stream->loadU32();
210 if(isIndexPresent) {
211 Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
212 prim->mIndexBuffer.set(indexAlloc);
213 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700214 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700215 }
216
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700217 mesh->updateGLPrimitives();
218 mesh->uploadAll(rsc);
219
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700220 return mesh;
221}
Jason Samsa89371c2009-06-30 14:13:04 -0700222
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700223void Mesh::computeBBox() {
224 float *posPtr = NULL;
225 uint32_t vectorSize = 0;
226 uint32_t stride = 0;
227 uint32_t numVerts = 0;
228 // First we need to find the position ptr and stride
229 for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
230 const Type *bufferType = mVertexBuffers[ct]->getType();
231 const Element *bufferElem = bufferType->getElement();
232
233 for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
234 if(strcmp(bufferElem->getFieldName(ct), "position") == 0) {
235 vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
236 stride = bufferElem->getSizeBytes() / sizeof(float);
237 uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
238 posPtr = (float*)((uint8_t*)mVertexBuffers[ct]->getPtr() + offset);
239 numVerts = bufferType->getDimX();
240 break;
241 }
242 }
243 if(posPtr) {
244 break;
245 }
246 }
247
248 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
249 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
250 if(!posPtr) {
251 LOGE("Unable to compute bounding box");
252 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
253 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
254 return;
255 }
256
257 for(uint32_t i = 0; i < numVerts; i ++) {
258 for(uint32_t v = 0; v < vectorSize; v ++) {
259 mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
260 mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
261 }
262 posPtr += stride;
263 }
264}
265
Jason Samsa89371c2009-06-30 14:13:04 -0700266
267MeshContext::MeshContext()
268{
269}
270
271MeshContext::~MeshContext()
272{
273}
274
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700275namespace android {
276namespace renderscript {
277
278RsMesh rsi_MeshCreate(Context *rsc, uint32_t vtxCount, uint32_t idxCount)
279{
280 Mesh *sm = new Mesh(rsc);
281 sm->incUserRef();
282
283 sm->mPrimitivesCount = idxCount;
284 sm->mPrimitives = new Mesh::Primitive_t *[sm->mPrimitivesCount];
285 for(uint32_t ct = 0; ct < idxCount; ct ++) {
286 sm->mPrimitives[ct] = new Mesh::Primitive_t;
287 }
288
289 sm->mVertexBufferCount = vtxCount;
290 sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount];
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700291
292 return sm;
293}
294
295void rsi_MeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot)
296{
297 Mesh *sm = static_cast<Mesh *>(mv);
298 rsAssert(slot < sm->mVertexBufferCount);
299
300 sm->mVertexBuffers[slot].set((Allocation *)va);
301}
302
303void rsi_MeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot)
304{
305 Mesh *sm = static_cast<Mesh *>(mv);
306 rsAssert(slot < sm->mPrimitivesCount);
307
308 sm->mPrimitives[slot]->mIndexBuffer.set((Allocation *)va);
309 sm->mPrimitives[slot]->mPrimitive = (RsPrimitive)primType;
310 sm->updateGLPrimitives();
311}
312
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700313}}
314
315void rsaMeshGetVertexBufferCount(RsContext con, RsMesh mv, int32_t *numVtx)
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700316{
317 Mesh *sm = static_cast<Mesh *>(mv);
318 *numVtx = sm->mVertexBufferCount;
319}
320
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700321void rsaMeshGetIndexCount(RsContext con, RsMesh mv, int32_t *numIdx)
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700322{
323 Mesh *sm = static_cast<Mesh *>(mv);
324 *numIdx = sm->mPrimitivesCount;
325}
326
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700327void rsaMeshGetVertices(RsContext con, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount)
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700328{
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
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700338void rsaMeshGetIndices(RsContext con, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount)
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700339{
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}