blob: 5eb4b800c705dcebaa28477be350940835da552c [file] [log] [blame]
Jason Sams1bada8c2009-08-09 17:01:55 -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 Sams1bada8c2009-08-09 17:01:55 -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"
25
26#include <OpenGL/gl.h>
27#include <OpenGl/glext.h>
28#endif
29
Jason Sams1bada8c2009-08-09 17:01:55 -070030using namespace android;
31using namespace android::renderscript;
32
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070033
34
Jason Sams1bada8c2009-08-09 17:01:55 -070035
Jason Samsa9e7a052009-09-25 14:51:22 -070036SimpleMesh::SimpleMesh(Context *rsc) : ObjectBase(rsc)
Jason Sams1bada8c2009-08-09 17:01:55 -070037{
Jason Sams61f08d62009-09-25 16:37:33 -070038 mAllocFile = __FILE__;
39 mAllocLine = __LINE__;
Jason Sams1bada8c2009-08-09 17:01:55 -070040}
41
42SimpleMesh::~SimpleMesh()
43{
Jason Sams61f08d62009-09-25 16:37:33 -070044 delete[] mVertexTypes;
45 delete[] mVertexBuffers;
Jason Sams1bada8c2009-08-09 17:01:55 -070046}
47
Jason Samsbb51c402009-11-25 13:22:07 -080048void SimpleMesh::render(Context *rsc) const
Jason Sams1bada8c2009-08-09 17:01:55 -070049{
50 if (mPrimitiveType.get()) {
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -070051 LOGE("Rendering primitive");
Jason Samsbb51c402009-11-25 13:22:07 -080052 renderRange(rsc, 0, mPrimitiveType->getDimX());
Jason Sams1bada8c2009-08-09 17:01:55 -070053 return;
54 }
55
56 if (mIndexType.get()) {
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -070057 LOGE("Rendering index");
Jason Samsbb51c402009-11-25 13:22:07 -080058 renderRange(rsc, 0, mIndexType->getDimX());
Jason Sams1bada8c2009-08-09 17:01:55 -070059 return;
60 }
61
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -070062 LOGE("Rendering non-indexed");
Jason Samsbb51c402009-11-25 13:22:07 -080063 renderRange(rsc, 0, mVertexTypes[0]->getDimX());
Jason Sams1bada8c2009-08-09 17:01:55 -070064}
65
Jason Samsbb51c402009-11-25 13:22:07 -080066void SimpleMesh::renderRange(Context *rsc, uint32_t start, uint32_t len) const
Jason Sams1bada8c2009-08-09 17:01:55 -070067{
68 if (len < 1) {
69 return;
70 }
71
Jason Samsa09a6e12010-01-06 11:57:52 -080072 rsc->checkError("SimpleMesh::renderRange 1");
Jason Samsbb51c402009-11-25 13:22:07 -080073 VertexArray va;
Jason Sams8cb39de2010-06-01 15:47:01 -070074 for (uint32_t ct=0; ct < mVertexTypeCount; ct++) {
75 mVertexBuffers[ct]->uploadCheck(rsc);
76 va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID());
77 mVertexTypes[ct]->enableGLVertexBuffer(&va);
Jason Sams1bada8c2009-08-09 17:01:55 -070078 }
Jason Sams8cb39de2010-06-01 15:47:01 -070079 va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
Jason Sams1bada8c2009-08-09 17:01:55 -070080
Jason Samsa09a6e12010-01-06 11:57:52 -080081 rsc->checkError("SimpleMesh::renderRange 2");
Jason Sams1bada8c2009-08-09 17:01:55 -070082 if (mIndexType.get()) {
Jason Sams3b7d39b2009-12-14 12:57:40 -080083 mIndexBuffer->uploadCheck(rsc);
Jason Sams1bada8c2009-08-09 17:01:55 -070084 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->getBufferObjectID());
Jason Sams07ae4062009-08-27 20:23:34 -070085 glDrawElements(mGLPrimitive, len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2));
Jason Sams1bada8c2009-08-09 17:01:55 -070086 } else {
87 glDrawArrays(mGLPrimitive, start, len);
88 }
Jason Sams718cd1f2009-12-23 14:35:29 -080089
90 rsc->checkError("SimpleMesh::renderRange");
Jason Sams1bada8c2009-08-09 17:01:55 -070091}
92
Jason Samsbb51c402009-11-25 13:22:07 -080093void SimpleMesh::uploadAll(Context *rsc)
Jason Sams6b9dec02009-09-23 16:38:37 -070094{
95 for (uint32_t ct=0; ct < mVertexTypeCount; ct++) {
96 if (mVertexBuffers[ct].get()) {
Jason Sams3b7d39b2009-12-14 12:57:40 -080097 mVertexBuffers[ct]->deferedUploadToBufferObject(rsc);
Jason Sams6b9dec02009-09-23 16:38:37 -070098 }
99 }
100 if (mIndexBuffer.get()) {
Jason Sams3b7d39b2009-12-14 12:57:40 -0800101 mIndexBuffer->deferedUploadToBufferObject(rsc);
Jason Sams6b9dec02009-09-23 16:38:37 -0700102 }
103 if (mPrimitiveBuffer.get()) {
Jason Sams3b7d39b2009-12-14 12:57:40 -0800104 mPrimitiveBuffer->deferedUploadToBufferObject(rsc);
Jason Sams6b9dec02009-09-23 16:38:37 -0700105 }
Jason Sams718cd1f2009-12-23 14:35:29 -0800106 rsc->checkError("SimpleMesh::uploadAll");
Jason Sams6b9dec02009-09-23 16:38:37 -0700107}
Jason Sams1bada8c2009-08-09 17:01:55 -0700108
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700109void SimpleMesh::updateGLPrimitive()
110{
111 switch(mPrimitive) {
112 case RS_PRIMITIVE_POINT: mGLPrimitive = GL_POINTS; break;
113 case RS_PRIMITIVE_LINE: mGLPrimitive = GL_LINES; break;
114 case RS_PRIMITIVE_LINE_STRIP: mGLPrimitive = GL_LINE_STRIP; break;
115 case RS_PRIMITIVE_TRIANGLE: mGLPrimitive = GL_TRIANGLES; break;
116 case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitive = GL_TRIANGLE_STRIP; break;
117 case RS_PRIMITIVE_TRIANGLE_FAN: mGLPrimitive = GL_TRIANGLE_FAN; break;
118 }
119}
120
121void SimpleMesh::serialize(OStream *stream) const
122{
123 // Need to identify ourselves
124 stream->addU32((uint32_t)getClassId());
125
126 String8 name(getName());
127 stream->addString(&name);
128
129 // Add primitive type
130 stream->addU8((uint8_t)mPrimitive);
131
132 // And now serialize the allocations
133 mIndexBuffer->serialize(stream);
134
135 // We need to indicate if the primitive buffer is present
136 if(mPrimitiveBuffer.get() != NULL) {
137 // Write if the primitive buffer is present
138 stream->addU32(1);
139 mPrimitiveBuffer->serialize(stream);
140 }
141 else {
142 // No buffer present, will need this when we read
143 stream->addU32(0);
144 }
145
146 // Store number of vertex streams
147 stream->addU32(mVertexTypeCount);
148 for(uint32_t vCount = 0; vCount < mVertexTypeCount; vCount ++) {
149 mVertexBuffers[vCount]->serialize(stream);
150 }
151}
152
153SimpleMesh *SimpleMesh::createFromStream(Context *rsc, IStream *stream)
154{
155 // First make sure we are reading the correct object
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700156 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
157 if(classID != RS_A3D_CLASS_ID_SIMPLE_MESH) {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700158 LOGE("simple mesh loading skipped due to invalid class id");
159 return NULL;
160 }
161
162 SimpleMesh * mesh = new SimpleMesh(rsc);
163
164 String8 name;
165 stream->loadString(&name);
166 mesh->setName(name.string(), name.size());
167
168 mesh->mPrimitive = (RsPrimitive)stream->loadU8();
169 mesh->updateGLPrimitive();
170
171 Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
172 const Type *indexType = indexAlloc->getType();
173 mesh->mIndexBuffer.set(indexAlloc);
174 mesh->mIndexType.set(indexType);
175
176 bool isPrimitivePresent = stream->loadU32() != 0;
177 if(isPrimitivePresent) {
178 mesh->mPrimitiveBuffer.set(Allocation::createFromStream(rsc, stream));
179 mesh->mPrimitiveType.set(mesh->mPrimitiveBuffer->getType());
180 }
181
182 mesh->mVertexTypeCount = stream->loadU32();
183 if(mesh->mVertexTypeCount) {
184 mesh->mVertexTypes = new ObjectBaseRef<const Type>[mesh->mVertexTypeCount];
185 mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[mesh->mVertexTypeCount];
186
187 for(uint32_t vCount = 0; vCount < mesh->mVertexTypeCount; vCount ++) {
188 Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
189 const Type *vertexType = vertexAlloc->getType();
190 mesh->mVertexBuffers[vCount].set(vertexAlloc);
191 mesh->mVertexTypes[vCount].set(vertexType);
192 }
193 }
194
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700195 LOGE("Triangles: %u", indexType->getDimX()/3);
196 uint16_t *indices = (uint16_t*)indexAlloc->getPtr();
197 for(uint32_t i = 0; i < indexType->getDimX(); i += 3) {
198 LOGE("T: %.2u %.2u %2.u", indices[i], indices[i+1], indices[i+2]);
199 }
200
201 uint32_t numVerts = mesh->mVertexTypes[0]->getDimX();
202 LOGE("Vertices: %u", numVerts);
203 float *verts = (float*)mesh->mVertexBuffers[0]->getPtr();
204
205 for(uint32_t i = 0; i < numVerts; i ++) {
206
207 LOGE("Vpnt: %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f", verts[8*i], verts[8*i+1], verts[8*i+2],
208 verts[8*i+3], verts[8*i+4], verts[8*i+5],
209 verts[8*i+6], verts[8*i+7] );
210 }
211
212 mesh->uploadAll(rsc);
213
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700214 return mesh;
215}
216
Jason Sams1bada8c2009-08-09 17:01:55 -0700217
218SimpleMeshContext::SimpleMeshContext()
219{
220}
221
222SimpleMeshContext::~SimpleMeshContext()
223{
224}
225
226
227namespace android {
228namespace renderscript {
229
230
231RsSimpleMesh rsi_SimpleMeshCreate(Context *rsc, RsType prim, RsType idx, RsType *vtx, uint32_t vtxCount, uint32_t primType)
232{
Jason Samsa9e7a052009-09-25 14:51:22 -0700233 SimpleMesh *sm = new SimpleMesh(rsc);
Jason Sams07ae4062009-08-27 20:23:34 -0700234 sm->incUserRef();
Jason Sams1bada8c2009-08-09 17:01:55 -0700235
236 sm->mIndexType.set((const Type *)idx);
237 sm->mPrimitiveType.set((const Type *)prim);
238
239 sm->mVertexTypeCount = vtxCount;
240 sm->mVertexTypes = new ObjectBaseRef<const Type>[vtxCount];
241 sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount];
242 for (uint32_t ct=0; ct < vtxCount; ct++) {
243 sm->mVertexTypes[ct].set((const Type *)vtx[ct]);
244 }
245
246 sm->mPrimitive = (RsPrimitive)primType;
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700247 sm->updateGLPrimitive();
Jason Sams1bada8c2009-08-09 17:01:55 -0700248 return sm;
249}
250
251void rsi_SimpleMeshBindVertex(Context *rsc, RsSimpleMesh mv, RsAllocation va, uint32_t slot)
252{
253 SimpleMesh *sm = static_cast<SimpleMesh *>(mv);
254 rsAssert(slot < sm->mVertexTypeCount);
255
256 sm->mVertexBuffers[slot].set((Allocation *)va);
257}
258
259void rsi_SimpleMeshBindIndex(Context *rsc, RsSimpleMesh mv, RsAllocation va)
260{
261 SimpleMesh *sm = static_cast<SimpleMesh *>(mv);
262 sm->mIndexBuffer.set((Allocation *)va);
263}
264
265void rsi_SimpleMeshBindPrimitive(Context *rsc, RsSimpleMesh mv, RsAllocation va)
266{
267 SimpleMesh *sm = static_cast<SimpleMesh *>(mv);
268 sm->mPrimitiveBuffer.set((Allocation *)va);
269}
270
Jason Sams1bada8c2009-08-09 17:01:55 -0700271
272
273
274}}
275