blob: 64bb71b68c679fba279db62efcc778004928f120 [file] [log] [blame]
Jason Samsd19f10d2009-05-22 14:03:28 -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
17#include "rsContext.h"
18
19using namespace android;
20using namespace android::renderscript;
21
22#include <GLES/gl.h>
23#include <GLES/glext.h>
24
Jason Samsd19f10d2009-05-22 14:03:28 -070025TriangleMesh::TriangleMesh()
26{
27 mVertexElement = NULL;
28 mIndexElement = NULL;
29 mVertexData = NULL;
30 mIndexData = NULL;
31 mTriangleCount = 0;
32 mVertexDataSize = 0;
33 mIndexDataSize = 0;
34
35 mBufferObjects[0] = 0;
36 mBufferObjects[1] = 0;
37
38 mOffsetCoord = 0;
39 mOffsetTex = 0;
40 mOffsetNorm = 0;
41
42 mSizeCoord = 0;
43 mSizeTex = 0;
44 mSizeNorm = 0;
45
46}
47
48TriangleMesh::~TriangleMesh()
49{
50 free(mVertexData);
51 free(mIndexData);
52}
53
54
55
56TriangleMeshContext::TriangleMeshContext()
57{
58 clear();
59}
60
61TriangleMeshContext::~TriangleMeshContext()
62{
63}
64
65void TriangleMeshContext::clear()
66{
67 mVertexElement = NULL;
68 mVertexSizeBits = 0;
69 mIndexElement = NULL;
70 mIndexSizeBits = 0;
71 mTriangleCount = 0;
72 mVertexData.clear();
73 mIndexData.clear();
74}
75
76void TriangleMesh::analyzeElement()
77{
78 for (uint32_t ct=0; ct < mVertexElement->getComponentCount(); ct++) {
79 const Component *c = mVertexElement->getComponent(ct);
80
81 if (c->getKind() == Component::X) {
82 rsAssert(mSizeCoord == 0);
83 mSizeCoord = 1;
84 mOffsetCoord = ct;
85 }
86 if (c->getKind() == Component::Y) {
87 rsAssert(mSizeCoord == 1);
88 mSizeCoord = 2;
89 }
90 if (c->getKind() == Component::Z) {
91 rsAssert(mSizeCoord == 2);
92 mSizeCoord = 3;
93 }
94 if (c->getKind() == Component::W) {
95 rsAssert(mSizeCoord == 4);
96 mSizeCoord = 4;
97 }
98
99 if (c->getKind() == Component::NX) {
100 rsAssert(mSizeNorm == 0);
101 mSizeNorm = 1;
102 mOffsetNorm = ct;
103 }
104 if (c->getKind() == Component::NY) {
105 rsAssert(mSizeNorm == 1);
106 mSizeNorm = 2;
107 }
108 if (c->getKind() == Component::NZ) {
109 rsAssert(mSizeNorm == 2);
110 mSizeNorm = 3;
111 }
112
113 if (c->getKind() == Component::S) {
114 rsAssert(mSizeTex == 0);
115 mSizeTex = 1;
116 mOffsetTex = ct;
117 }
118 if (c->getKind() == Component::T) {
119 rsAssert(mSizeTex == 1);
120 mSizeTex = 2;
121 }
122 }
Jason Samsf29ca502009-06-23 12:22:47 -0700123 LOGV("TriangleMesh %i,%i %i,%i %i,%i", mSizeCoord, mOffsetCoord, mSizeNorm, mOffsetNorm, mSizeTex, mOffsetTex);
Jason Samsd19f10d2009-05-22 14:03:28 -0700124
125}
126
127
128namespace android {
129namespace renderscript {
130
131void rsi_TriangleMeshBegin(Context *rsc, RsElement vertex, RsElement index)
132{
Jason Samsd19f10d2009-05-22 14:03:28 -0700133 TriangleMeshContext *tmc = &rsc->mStateTriangleMesh;
134
135 tmc->clear();
136 tmc->mVertexElement = static_cast<Element *>(vertex);
137 tmc->mVertexSizeBits = tmc->mVertexElement->getSizeBits();
138 tmc->mIndexElement = static_cast<Element *>(index);
139 tmc->mIndexSizeBits = tmc->mIndexElement->getSizeBits();
140
Jason Samsd19f10d2009-05-22 14:03:28 -0700141 assert(!(tmc->mVertexSizeBits & 0x7));
142 assert(!(tmc->mIndexSizeBits & 0x7));
143}
144
145void rsi_TriangleMeshAddVertex(Context *rsc, const void *data)
146{
147 TriangleMeshContext *tmc = &rsc->mStateTriangleMesh;
148
149 // todo: Make this efficient.
150 for (uint32_t ct = 0; (ct * 8) < tmc->mVertexSizeBits; ct++) {
151 tmc->mVertexData.add(static_cast<const uint8_t *>(data) [ct]);
152 }
153}
154
155void rsi_TriangleMeshAddTriangle(Context *rsc, uint32_t idx1, uint32_t idx2, uint32_t idx3)
156{
157 TriangleMeshContext *tmc = &rsc->mStateTriangleMesh;
158
159 // todo: Make this efficient.
160 switch(tmc->mIndexSizeBits) {
161 case 16:
162 tmc->mIndexData.add(idx1);
163 tmc->mIndexData.add(idx2);
164 tmc->mIndexData.add(idx3);
165 break;
166 default:
167 assert(0);
168 }
169
170 tmc->mTriangleCount++;
171}
172
173RsTriangleMesh rsi_TriangleMeshCreate(Context *rsc)
174{
175 TriangleMeshContext *tmc = &rsc->mStateTriangleMesh;
176
177 TriangleMesh * tm = new TriangleMesh();
178 if (!tm) {
179 LOGE("rsTriangleMeshCreate: Error OUT OF MEMORY");
180 // error
181 return 0;
182 }
183
184 tm->mTriangleCount = tmc->mTriangleCount;
185 tm->mIndexDataSize = tmc->mIndexData.size() * tmc->mIndexSizeBits >> 3;
186 tm->mVertexDataSize = tmc->mVertexData.size();
187 tm->mIndexElement = tmc->mIndexElement;
188 tm->mVertexElement = tmc->mVertexElement;
189
190 tm->mIndexData = malloc(tm->mIndexDataSize);
191 tm->mVertexData = malloc(tm->mVertexDataSize);
192 if (!tm->mIndexData || !tm->mVertexData) {
193 LOGE("rsTriangleMeshCreate: Error OUT OF MEMORY");
194 delete tm;
195 return 0;
196 }
197
Jason Samsd19f10d2009-05-22 14:03:28 -0700198 memcpy(tm->mVertexData, tmc->mVertexData.array(), tm->mVertexDataSize);
199 memcpy(tm->mIndexData, tmc->mIndexData.array(), tm->mIndexDataSize);
200 tm->analyzeElement();
201
Jason Sams07ae4062009-08-27 20:23:34 -0700202 tm->incUserRef();
Jason Samsd19f10d2009-05-22 14:03:28 -0700203 return tm;
204}
205
206void rsi_TriangleMeshDestroy(Context *rsc, RsTriangleMesh vtm)
207{
208 TriangleMeshContext *tmc = &rsc->mStateTriangleMesh;
209 TriangleMesh * tm = static_cast<TriangleMesh *>(vtm);
210
211 free(tm->mIndexData);
212 free(tm->mVertexData);
213 delete tm;
214}
215
216
217
218void rsi_TriangleMeshRenderRange(Context *rsc, RsTriangleMesh vtm, uint32_t first, uint32_t count)
219{
220 TriangleMesh * tm = static_cast<TriangleMesh *>(vtm);
221
222 rsc->setupCheck();
223
Jason Samsd19f10d2009-05-22 14:03:28 -0700224 if (!tm->mBufferObjects[0]) {
225 glGenBuffers(2, &tm->mBufferObjects[0]);
226
227 glBindBuffer(GL_ARRAY_BUFFER, tm->mBufferObjects[0]);
228 glBufferData(GL_ARRAY_BUFFER, tm->mVertexDataSize, tm->mVertexData, GL_STATIC_DRAW);
229 glBindBuffer(GL_ARRAY_BUFFER, 0);
230
231 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
232 glBufferData(GL_ELEMENT_ARRAY_BUFFER, tm->mIndexDataSize, tm->mIndexData, GL_STATIC_DRAW);
233 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
234 }
235
Jason Samsd19f10d2009-05-22 14:03:28 -0700236 if (first >= tm->mTriangleCount) {
237 return;
238 }
239 if (count >= (tm->mTriangleCount - first)) {
240 count = tm->mTriangleCount - first;
241 }
242 if (!count) {
243 return;
244 }
245
246 const float *f = (const float *)tm->mVertexData;
247
Jason Samsd19f10d2009-05-22 14:03:28 -0700248 glBindBuffer(GL_ARRAY_BUFFER, tm->mBufferObjects[0]);
249 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
250
251 glEnableClientState(GL_VERTEX_ARRAY);
Jason Sams25ffcdc2009-08-20 16:10:36 -0700252 glVertexPointer(tm->mSizeCoord,
253 GL_FLOAT,
254 tm->mVertexElement->getSizeBytes(),
Jason Samsd19f10d2009-05-22 14:03:28 -0700255 (void *)tm->mVertexElement->getComponentOffsetBytes(tm->mOffsetCoord));
256
257 if (tm->mSizeTex) {
258 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
Jason Sams25ffcdc2009-08-20 16:10:36 -0700259 glTexCoordPointer(tm->mSizeTex,
260 GL_FLOAT,
261 tm->mVertexElement->getSizeBytes(),
Jason Samsd19f10d2009-05-22 14:03:28 -0700262 (void *)tm->mVertexElement->getComponentOffsetBytes(tm->mOffsetTex));
263 } else {
264 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
265 }
266
267 if (tm->mSizeNorm) {
268 glEnableClientState(GL_NORMAL_ARRAY);
Jason Sams25ffcdc2009-08-20 16:10:36 -0700269 glNormalPointer(GL_FLOAT,
270 tm->mVertexElement->getSizeBytes(),
Jason Samsd19f10d2009-05-22 14:03:28 -0700271 (void *)tm->mVertexElement->getComponentOffsetBytes(tm->mOffsetNorm));
272 } else {
273 glDisableClientState(GL_NORMAL_ARRAY);
274 }
275
276 glDrawElements(GL_TRIANGLES, count * 3, GL_UNSIGNED_SHORT, (GLvoid *)(first * 3 * 2));
277
Jason Samsd19f10d2009-05-22 14:03:28 -0700278 glBindBuffer(GL_ARRAY_BUFFER, 0);
279 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
280}
281
282void rsi_TriangleMeshRender(Context *rsc, RsTriangleMesh vtm)
283{
284 rsi_TriangleMeshRenderRange(rsc, vtm, 0, 0xffffff);
285}
286
287}}