• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "gles2context.h"
2 
3 //#undef LOGD
4 //#define LOGD(...)
5 
InitializeVertices()6 void GLES2Context::InitializeVertices()
7 {
8    vert.vbos = std::map<GLuint, VBO *>(); // the entire struct has been zeroed in constructor
9    vert.free = 1;
10    vert.vbo = NULL;
11    vert.indices = NULL;
12    for (unsigned i = 0; i < GGL_MAXVERTEXATTRIBS; i++)
13       vert.defaultAttribs[i] = Vector4(0,0,0,1);
14 }
15 
UninitializeVertices()16 void GLES2Context::UninitializeVertices()
17 {
18    for (std::map<GLuint, VBO *>::iterator it = vert.vbos.begin(); it != vert.vbos.end(); it++) {
19       if (!it->second)
20          continue;
21       free(it->second->data);
22       free(it->second);
23    }
24 }
25 
FetchElement(const GLES2Context * ctx,const unsigned index,const unsigned maxAttrib,VertexInput * elem)26 static inline void FetchElement(const GLES2Context * ctx, const unsigned index,
27                                 const unsigned maxAttrib, VertexInput * elem)
28 {
29    for (unsigned i = 0; i < maxAttrib; i++) {
30       {
31          unsigned size = 0;
32          if (ctx->vert.attribs[i].enabled) {
33             const char * ptr = (const char *)ctx->vert.attribs[i].ptr;
34             ptr += ctx->vert.attribs[i].stride * index;
35             memcpy(elem->attributes + i, ptr, ctx->vert.attribs[i].size * sizeof(float));
36             size = ctx->vert.attribs[i].size;
37 //            LOGD("agl2: FetchElement %d attribs size=%d %.2f,%.2f,%.2f,%.2f", i, size, elem->attributes[i].x,
38 //                 elem->attributes[i].y, elem->attributes[i].z, elem->attributes[i].w);
39          } else {
40 //            LOGD("agl2: FetchElement %d default %.2f,%.2f,%.2f,%.2f", i, ctx->vert.defaultAttribs[i].x,
41 //                 ctx->vert.defaultAttribs[i].y, ctx->vert.defaultAttribs[i].z, ctx->vert.defaultAttribs[i].w);
42          }
43 
44          switch (size) {
45          case 0: // fall through
46             elem->attributes[i].x = ctx->vert.defaultAttribs[i].x;
47          case 1: // fall through
48             elem->attributes[i].y = ctx->vert.defaultAttribs[i].y;
49          case 2: // fall through
50             elem->attributes[i].z = ctx->vert.defaultAttribs[i].z;
51          case 3: // fall through
52             elem->attributes[i].w = ctx->vert.defaultAttribs[i].w;
53          case 4:
54             break;
55          default:
56             assert(0);
57             break;
58          }
59 //         LOGD("agl2: FetchElement %d size=%d %.2f,%.2f,%.2f,%.2f", i, size, elem->attributes[i].x,
60 //              elem->attributes[i].y, elem->attributes[i].z, elem->attributes[i].w);
61       }
62    }
63 }
64 
DrawElementsTriangles(const GLES2Context * ctx,const unsigned count,const IndexT * indices,const unsigned maxAttrib)65 template<typename IndexT> static void DrawElementsTriangles(const GLES2Context * ctx,
66       const unsigned count, const IndexT * indices, const unsigned maxAttrib)
67 {
68    VertexInput v[3];
69    if (ctx->vert.indices)
70       indices = (IndexT *)((char *)ctx->vert.indices->data + (long)indices);
71    for (unsigned i = 0; i < count; i += 3) {
72       for (unsigned j = 0; j < 3; j++)
73          FetchElement(ctx, indices[i + j], maxAttrib, v + j);
74       ctx->iface->DrawTriangle(ctx->iface, v, v + 1, v + 2);
75    }
76 }
77 
DrawArraysTriangles(const GLES2Context * ctx,const unsigned first,const unsigned count,const unsigned maxAttrib)78 static void DrawArraysTriangles(const GLES2Context * ctx, const unsigned first,
79                                 const unsigned count, const unsigned maxAttrib)
80 {
81 //   LOGD("agl: DrawArraysTriangles=%p", DrawArraysTriangles);
82    VertexInput v[3];
83    for (unsigned i = 2; i < count; i+=3) {
84       // TODO: fix order
85       FetchElement(ctx, first + i - 2, maxAttrib, v + 0);
86       FetchElement(ctx, first + i - 1, maxAttrib, v + 1);
87       FetchElement(ctx, first + i - 0, maxAttrib, v + 2);
88       ctx->iface->DrawTriangle(ctx->iface, v + 0, v + 1, v + 2);
89    }
90 //   LOGD("agl: DrawArraysTriangles end");
91 }
92 
DrawElementsTriangleStrip(const GLES2Context * ctx,const unsigned count,const IndexT * indices,const unsigned maxAttrib)93 template<typename IndexT> static void DrawElementsTriangleStrip(const GLES2Context * ctx,
94       const unsigned count, const IndexT * indices, const unsigned maxAttrib)
95 {
96    VertexInput v[3];
97    if (ctx->vert.indices)
98       indices = (IndexT *)((char *)ctx->vert.indices->data + (long)indices);
99 
100 //   LOGD("agl2: DrawElementsTriangleStrip");
101 //   for (unsigned i = 0; i < count; i++)
102 //      LOGD("indices[%d] = %d", i, indices[i]);
103 
104    FetchElement(ctx, indices[0], maxAttrib, v + 0);
105    FetchElement(ctx, indices[1], maxAttrib, v + 1);
106    for (unsigned i = 2; i < count; i ++) {
107       FetchElement(ctx, indices[i], maxAttrib, v + i % 3);
108       ctx->iface->DrawTriangle(ctx->iface, v + (i - 2) % 3, v + (i - 1) % 3 , v + (i + 0) % 3);
109    }
110 
111 //   for (unsigned i = 2; i < count; i++) {
112 //      FetchElement(ctx, indices[i - 2], maxAttrib, v + 0);
113 //      FetchElement(ctx, indices[i - 1], maxAttrib, v + 1);
114 //      FetchElement(ctx, indices[i - 0], maxAttrib, v + 2);
115 //      ctx->iface->DrawTriangle(ctx->iface, v + 0, v + 1, v + 2);
116 //   }
117 }
118 
DrawArraysTriangleStrip(const GLES2Context * ctx,const unsigned first,const unsigned count,const unsigned maxAttrib)119 static void DrawArraysTriangleStrip(const GLES2Context * ctx, const unsigned first,
120                                     const unsigned count, const unsigned maxAttrib)
121 {
122    VertexInput v[3];
123    FetchElement(ctx, first, maxAttrib, v + 0);
124    FetchElement(ctx, first + 1, maxAttrib, v + 1);
125    for (unsigned i = 2; i < count; i++) {
126       // TODO: fix order
127       FetchElement(ctx, first + i, maxAttrib, v + i % 3);
128       ctx->iface->DrawTriangle(ctx->iface, v + (i - 2) % 3, v + (i - 1) % 3 , v + (i + 0) % 3);
129    }
130 }
131 
glBindBuffer(GLenum target,GLuint buffer)132 void glBindBuffer(GLenum target, GLuint buffer)
133 {
134    GLES2_GET_CONST_CONTEXT(ctx);
135    VBO * vbo = NULL;
136    if (0 != buffer) {
137       std::map<GLuint, VBO *>::iterator it = ctx->vert.vbos.find(buffer);
138       if (it != ctx->vert.vbos.end()) {
139          vbo = it->second;
140          if (!vbo)
141             vbo = (VBO *)calloc(1, sizeof(VBO));
142          it->second = vbo;
143       } else
144          assert(0);
145    }
146    if (GL_ARRAY_BUFFER == target)
147       ctx->vert.vbo = vbo;
148    else if (GL_ELEMENT_ARRAY_BUFFER == target)
149       ctx->vert.indices = vbo;
150    else
151       assert(0);
152    assert(vbo || buffer == 0);
153 //   LOGD("\n*\n glBindBuffer 0x%.4X=%d ", target, buffer);
154 }
155 
glBufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)156 void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
157 {
158    GLES2_GET_CONST_CONTEXT(ctx);
159    if (GL_ARRAY_BUFFER == target) {
160       assert(ctx->vert.vbo);
161       ctx->vert.vbo->data = realloc(ctx->vert.vbo->data, size);
162       ctx->vert.vbo->size = size;
163       ctx->vert.vbo->usage = usage;
164       if (data)
165          memcpy(ctx->vert.vbo->data, data, size);
166    } else if (GL_ELEMENT_ARRAY_BUFFER == target) {
167       assert(ctx->vert.indices);
168       ctx->vert.indices->data = realloc(ctx->vert.indices->data, size);
169       ctx->vert.indices->size = size;
170       ctx->vert.indices->usage = usage;
171       if (data)
172          memcpy(ctx->vert.indices->data, data, size);
173    } else
174       assert(0);
175 //   LOGD("\n*\n glBufferData target=0x%.4X size=%u data=%p usage=0x%.4X \n",
176 //        target, size, data, usage);
177 }
178 
glBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)179 void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
180 {
181    GLES2_GET_CONST_CONTEXT(ctx);
182    if (GL_ARRAY_BUFFER == target)
183    {
184       assert(ctx->vert.vbo);
185       assert(0 <= offset);
186       assert(0 <= size);
187       assert(offset + size <= ctx->vert.vbo->size);
188       memcpy((char *)ctx->vert.vbo->data + offset, data, size);
189    }
190    else
191       assert(0);
192 }
193 
glDeleteBuffers(GLsizei n,const GLuint * buffers)194 void glDeleteBuffers(GLsizei n, const GLuint* buffers)
195 {
196    GLES2_GET_CONST_CONTEXT(ctx);
197    for (unsigned i = 0; i < n; i++) {
198       std::map<GLuint, VBO*>::iterator it = ctx->vert.vbos.find(buffers[i]);
199       if (it == ctx->vert.vbos.end())
200          continue;
201       ctx->vert.free = min(ctx->vert.free, buffers[i]);
202       if (it->second == ctx->vert.vbo)
203          ctx->vert.vbo = NULL;
204       else if (it->second == ctx->vert.indices)
205          ctx->vert.indices = NULL;
206       if (it->second) {
207          free(it->second->data);
208          free(it->second);
209       }
210    }
211 }
212 
glDisableVertexAttribArray(GLuint index)213 void glDisableVertexAttribArray(GLuint index)
214 {
215    GLES2_GET_CONST_CONTEXT(ctx);
216    assert(GGL_MAXVERTEXATTRIBS > index);
217    ctx->vert.attribs[index].enabled = false;
218 }
219 
glDrawArrays(GLenum mode,GLint first,GLsizei count)220 void glDrawArrays(GLenum mode, GLint first, GLsizei count)
221 {
222    GLES2_GET_CONST_CONTEXT(ctx);
223 //   LOGD("agl2: glDrawArrays=%p", glDrawArrays);
224    assert(ctx->rasterizer.CurrentProgram);
225    assert(0 <= first);
226    int maxAttrib = -1;
227    ctx->iface->ShaderProgramGetiv(ctx->rasterizer.CurrentProgram, GL_ACTIVE_ATTRIBUTES, &maxAttrib);
228    assert(0 <= maxAttrib && GGL_MAXVERTEXATTRIBS >= maxAttrib);
229    switch (mode) {
230    case GL_TRIANGLE_STRIP:
231       DrawArraysTriangleStrip(ctx, first, count, maxAttrib);
232       break;
233    case GL_TRIANGLES:
234       DrawArraysTriangles(ctx, first, count, maxAttrib);
235       break;
236    default:
237       LOGE("agl2: glDrawArrays unsupported mode: 0x%.4X \n", mode);
238       assert(0);
239       break;
240    }
241 //   LOGD("agl2: glDrawArrays end");
242 }
243 
glDrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)244 void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
245 {
246    GLES2_GET_CONST_CONTEXT(ctx);
247 //   LOGD("agl2: glDrawElements=%p mode=0x%.4X count=%d type=0x%.4X indices=%p",
248 //        glDrawElements, mode, count, type, indices);
249    if (!ctx->rasterizer.CurrentProgram)
250       return;
251 
252    int maxAttrib = -1;
253    ctx->iface->ShaderProgramGetiv(ctx->rasterizer.CurrentProgram, GL_ACTIVE_ATTRIBUTES, &maxAttrib);
254    assert(0 <= maxAttrib && GGL_MAXVERTEXATTRIBS >= maxAttrib);
255 //   LOGD("agl2: glDrawElements mode=0x%.4X type=0x%.4X count=%d program=%p indices=%p \n",
256 //        mode, type, count, ctx->rasterizer.CurrentProgram, indices);
257    switch (mode) {
258    case GL_TRIANGLES:
259       if (GL_UNSIGNED_SHORT == type)
260          DrawElementsTriangles<unsigned short>(ctx, count, (unsigned short *)indices, maxAttrib);
261       else
262          assert(0);
263       break;
264    case GL_TRIANGLE_STRIP:
265       if (GL_UNSIGNED_SHORT == type)
266          DrawElementsTriangleStrip<unsigned short>(ctx, count, (unsigned short *)indices, maxAttrib);
267       else
268          assert(0);
269       break;
270    default:
271       assert(0);
272    }
273 //   LOGD("agl2: glDrawElements end");
274 }
275 
glEnableVertexAttribArray(GLuint index)276 void glEnableVertexAttribArray(GLuint index)
277 {
278    GLES2_GET_CONST_CONTEXT(ctx);
279    ctx->vert.attribs[index].enabled = true;
280 //   LOGD("agl2: glEnableVertexAttribArray %d \n", index);
281 }
282 
glGenBuffers(GLsizei n,GLuint * buffers)283 void glGenBuffers(GLsizei n, GLuint* buffers)
284 {
285    GLES2_GET_CONST_CONTEXT(ctx);
286    for (unsigned i = 0; i < n; i++) {
287       buffers[i] = 0;
288       for (ctx->vert.free; ctx->vert.free < 0xffffffffu; ctx->vert.free++) {
289          if (ctx->vert.vbos.find(ctx->vert.free) == ctx->vert.vbos.end()) {
290             ctx->vert.vbos[ctx->vert.free] = NULL;
291             buffers[i] = ctx->vert.free;
292 //            LOGD("glGenBuffers %d \n", buffers[i]);
293             ctx->vert.free++;
294             break;
295          }
296       }
297       assert(buffers[i]);
298    }
299 }
300 
glVertexAttribPointer(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)301 void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
302                            GLsizei stride, const GLvoid* ptr)
303 {
304    GLES2_GET_CONST_CONTEXT(ctx);
305    assert(GL_FLOAT == type);
306    assert(0 < size && 4 >= size);
307    ctx->vert.attribs[index].size = size;
308    ctx->vert.attribs[index].type = type;
309    ctx->vert.attribs[index].normalized = normalized;
310    if (0 == stride)
311       ctx->vert.attribs[index].stride = size * sizeof(float);
312    else if (stride > 0)
313       ctx->vert.attribs[index].stride = stride;
314    else
315       assert(0);
316 //   LOGD("\n*\n*\n* agl2: glVertexAttribPointer program=%u index=%d size=%d stride=%d ptr=%p \n*\n*",
317 //        unsigned(ctx->rasterizer.CurrentProgram) ^ 0x04dc18f9, index, size, stride, ptr);
318    if (ctx->vert.vbo)
319       ctx->vert.attribs[index].ptr = (char *)ctx->vert.vbo->data + (long)ptr;
320    else
321       ctx->vert.attribs[index].ptr = ptr;
322 //   const float * attrib = (const float *)ctx->vert.attribs[index].ptr;
323 //   for (unsigned i = 0; i < 3; i++)
324 //      if (3 == size)
325 //         LOGD("%.2f %.2f %.2f", attrib[i * 3 + 0], attrib[i * 3 + 1], attrib[i * 3 + 2]);
326 //      else if (2 == size)
327 //         LOGD("%.2f %.2f", attrib[i * 3 + 0], attrib[i * 3 + 1]);
328 
329 }
330 
glVertexAttrib1f(GLuint indx,GLfloat x)331 void glVertexAttrib1f(GLuint indx, GLfloat x)
332 {
333    glVertexAttrib4f(indx, x,0,0,1);
334 }
335 
glVertexAttrib1fv(GLuint indx,const GLfloat * values)336 void glVertexAttrib1fv(GLuint indx, const GLfloat* values)
337 {
338    glVertexAttrib4f(indx, values[0],0,0,1);
339 }
340 
glVertexAttrib2f(GLuint indx,GLfloat x,GLfloat y)341 void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
342 {
343    glVertexAttrib4f(indx, x,y,0,1);
344 }
345 
glVertexAttrib2fv(GLuint indx,const GLfloat * values)346 void glVertexAttrib2fv(GLuint indx, const GLfloat* values)
347 {
348    glVertexAttrib4f(indx, values[0],values[1],0,1);
349 }
350 
glVertexAttrib3f(GLuint indx,GLfloat x,GLfloat y,GLfloat z)351 void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
352 {
353    glVertexAttrib4f(indx, x,y,z,1);
354 }
355 
glVertexAttrib3fv(GLuint indx,const GLfloat * values)356 void glVertexAttrib3fv(GLuint indx, const GLfloat* values)
357 {
358    glVertexAttrib4f(indx, values[0],values[1],values[2],1);
359 }
360 
glVertexAttrib4f(GLuint indx,GLfloat x,GLfloat y,GLfloat z,GLfloat w)361 void glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
362 {
363    assert(GGL_MAXVERTEXATTRIBS > indx);
364    GLES2_GET_CONST_CONTEXT(ctx);
365 //   LOGD("\n*\n*\n agl2: glVertexAttrib4f %d %.2f,%.2f,%.2f,%.2f \n*\n*", indx, x, y, z, w);
366    ctx->vert.defaultAttribs[indx] = Vector4(x,y,z,w);
367    assert(0);
368 }
369 
glVertexAttrib4fv(GLuint indx,const GLfloat * values)370 void glVertexAttrib4fv(GLuint indx, const GLfloat* values)
371 {
372    glVertexAttrib4f(indx, values[0], values[1], values[2], values[3]);
373 }
374