diff options
author | David Li <davidxli@google.com> | 2011-03-01 16:54:04 -0800 |
---|---|---|
committer | David Li <davidxli@google.com> | 2011-03-08 17:41:29 -0800 |
commit | af94ceb5df8c7ee21d84a58caa5f632663d4e1b0 (patch) | |
tree | d4d71fbdd5d9119619d35a3a933f892a50124853 /opengl/libagl2/src/vertex.cpp | |
parent | b57af729808cc33f470afaf266b857a3e91ca3e7 (diff) | |
download | frameworks_base-af94ceb5df8c7ee21d84a58caa5f632663d4e1b0.zip frameworks_base-af94ceb5df8c7ee21d84a58caa5f632663d4e1b0.tar.gz frameworks_base-af94ceb5df8c7ee21d84a58caa5f632663d4e1b0.tar.bz2 |
Initial commit of libAgl2 using Pixelflinger2 in external/mesa3d
Somewhat functional, refer to README for details.
Need to enable Android.mk to build.
It builds libGLES_android.so, which needs to replace
the one in system/lib/egl built by libagl.
Change-Id: Iec3aaa8f3963a4185d81955cd24019eb0c4a5850
Signed-off-by: David Li <davidxli@google.com>
Diffstat (limited to 'opengl/libagl2/src/vertex.cpp')
-rw-r--r-- | opengl/libagl2/src/vertex.cpp | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/opengl/libagl2/src/vertex.cpp b/opengl/libagl2/src/vertex.cpp new file mode 100644 index 0000000..021b82b --- /dev/null +++ b/opengl/libagl2/src/vertex.cpp @@ -0,0 +1,373 @@ +#include "gles2context.h" + +//#undef LOGD +//#define LOGD(...) + +void GLES2Context::InitializeVertices() +{ + vert.vbos = std::map<GLuint, VBO *>(); // the entire struct has been zeroed in constructor + vert.free = 1; + vert.vbo = NULL; + vert.indices = NULL; + for (unsigned i = 0; i < GGL_MAXVERTEXATTRIBS; i++) + vert.defaultAttribs[i] = Vector4(0,0,0,1); +} + +void GLES2Context::UninitializeVertices() +{ + for (std::map<GLuint, VBO *>::iterator it = vert.vbos.begin(); it != vert.vbos.end(); it++) { + if (!it->second) + continue; + free(it->second->data); + free(it->second); + } +} + +static inline void FetchElement(const GLES2Context * ctx, const unsigned index, + const unsigned maxAttrib, VertexInput * elem) +{ + for (unsigned i = 0; i < maxAttrib; i++) { + { + unsigned size = 0; + if (ctx->vert.attribs[i].enabled) { + const char * ptr = (const char *)ctx->vert.attribs[i].ptr; + ptr += ctx->vert.attribs[i].stride * index; + memcpy(elem->attributes + i, ptr, ctx->vert.attribs[i].size * sizeof(float)); + size = ctx->vert.attribs[i].size; +// LOGD("agl2: FetchElement %d attribs size=%d %.2f,%.2f,%.2f,%.2f", i, size, elem->attributes[i].x, +// elem->attributes[i].y, elem->attributes[i].z, elem->attributes[i].w); + } else { +// LOGD("agl2: FetchElement %d default %.2f,%.2f,%.2f,%.2f", i, ctx->vert.defaultAttribs[i].x, +// ctx->vert.defaultAttribs[i].y, ctx->vert.defaultAttribs[i].z, ctx->vert.defaultAttribs[i].w); + } + + switch (size) { + case 0: // fall through + elem->attributes[i].x = ctx->vert.defaultAttribs[i].x; + case 1: // fall through + elem->attributes[i].y = ctx->vert.defaultAttribs[i].y; + case 2: // fall through + elem->attributes[i].z = ctx->vert.defaultAttribs[i].z; + case 3: // fall through + elem->attributes[i].w = ctx->vert.defaultAttribs[i].w; + case 4: + break; + default: + assert(0); + break; + } +// LOGD("agl2: FetchElement %d size=%d %.2f,%.2f,%.2f,%.2f", i, size, elem->attributes[i].x, +// elem->attributes[i].y, elem->attributes[i].z, elem->attributes[i].w); + } + } +} + +template<typename IndexT> static void DrawElementsTriangles(const GLES2Context * ctx, + const unsigned count, const IndexT * indices, const unsigned maxAttrib) +{ + VertexInput v[3]; + if (ctx->vert.indices) + indices = (IndexT *)((char *)ctx->vert.indices->data + (long)indices); + for (unsigned i = 0; i < count; i += 3) { + for (unsigned j = 0; j < 3; j++) + FetchElement(ctx, indices[i + j], maxAttrib, v + j); + ctx->iface->DrawTriangle(ctx->iface, v, v + 1, v + 2); + } +} + +static void DrawArraysTriangles(const GLES2Context * ctx, const unsigned first, + const unsigned count, const unsigned maxAttrib) +{ +// LOGD("agl: DrawArraysTriangles=%p", DrawArraysTriangles); + VertexInput v[3]; + for (unsigned i = 2; i < count; i+=3) { + // TODO: fix order + FetchElement(ctx, first + i - 2, maxAttrib, v + 0); + FetchElement(ctx, first + i - 1, maxAttrib, v + 1); + FetchElement(ctx, first + i - 0, maxAttrib, v + 2); + ctx->iface->DrawTriangle(ctx->iface, v + 0, v + 1, v + 2); + } +// LOGD("agl: DrawArraysTriangles end"); +} + +template<typename IndexT> static void DrawElementsTriangleStrip(const GLES2Context * ctx, + const unsigned count, const IndexT * indices, const unsigned maxAttrib) +{ + VertexInput v[3]; + if (ctx->vert.indices) + indices = (IndexT *)((char *)ctx->vert.indices->data + (long)indices); + +// LOGD("agl2: DrawElementsTriangleStrip"); +// for (unsigned i = 0; i < count; i++) +// LOGD("indices[%d] = %d", i, indices[i]); + + FetchElement(ctx, indices[0], maxAttrib, v + 0); + FetchElement(ctx, indices[1], maxAttrib, v + 1); + for (unsigned i = 2; i < count; i ++) { + FetchElement(ctx, indices[i], maxAttrib, v + i % 3); + ctx->iface->DrawTriangle(ctx->iface, v + (i - 2) % 3, v + (i - 1) % 3 , v + (i + 0) % 3); + } + +// for (unsigned i = 2; i < count; i++) { +// FetchElement(ctx, indices[i - 2], maxAttrib, v + 0); +// FetchElement(ctx, indices[i - 1], maxAttrib, v + 1); +// FetchElement(ctx, indices[i - 0], maxAttrib, v + 2); +// ctx->iface->DrawTriangle(ctx->iface, v + 0, v + 1, v + 2); +// } +} + +static void DrawArraysTriangleStrip(const GLES2Context * ctx, const unsigned first, + const unsigned count, const unsigned maxAttrib) +{ + VertexInput v[3]; + FetchElement(ctx, first, maxAttrib, v + 0); + FetchElement(ctx, first + 1, maxAttrib, v + 1); + for (unsigned i = 2; i < count; i++) { + // TODO: fix order + FetchElement(ctx, first + i, maxAttrib, v + i % 3); + ctx->iface->DrawTriangle(ctx->iface, v + (i - 2) % 3, v + (i - 1) % 3 , v + (i + 0) % 3); + } +} + +void glBindBuffer(GLenum target, GLuint buffer) +{ + GLES2_GET_CONST_CONTEXT(ctx); + VBO * vbo = NULL; + if (0 != buffer) { + std::map<GLuint, VBO *>::iterator it = ctx->vert.vbos.find(buffer); + if (it != ctx->vert.vbos.end()) { + vbo = it->second; + if (!vbo) + vbo = (VBO *)calloc(1, sizeof(VBO)); + it->second = vbo; + } else + assert(0); + } + if (GL_ARRAY_BUFFER == target) + ctx->vert.vbo = vbo; + else if (GL_ELEMENT_ARRAY_BUFFER == target) + ctx->vert.indices = vbo; + else + assert(0); + assert(vbo || buffer == 0); +// LOGD("\n*\n glBindBuffer 0x%.4X=%d ", target, buffer); +} + +void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) +{ + GLES2_GET_CONST_CONTEXT(ctx); + if (GL_ARRAY_BUFFER == target) { + assert(ctx->vert.vbo); + ctx->vert.vbo->data = realloc(ctx->vert.vbo->data, size); + ctx->vert.vbo->size = size; + ctx->vert.vbo->usage = usage; + if (data) + memcpy(ctx->vert.vbo->data, data, size); + } else if (GL_ELEMENT_ARRAY_BUFFER == target) { + assert(ctx->vert.indices); + ctx->vert.indices->data = realloc(ctx->vert.indices->data, size); + ctx->vert.indices->size = size; + ctx->vert.indices->usage = usage; + if (data) + memcpy(ctx->vert.indices->data, data, size); + } else + assert(0); +// LOGD("\n*\n glBufferData target=0x%.4X size=%u data=%p usage=0x%.4X \n", +// target, size, data, usage); +} + +void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) +{ + GLES2_GET_CONST_CONTEXT(ctx); + if (GL_ARRAY_BUFFER == target) + { + assert(ctx->vert.vbo); + assert(0 <= offset); + assert(0 <= size); + assert(offset + size <= ctx->vert.vbo->size); + memcpy((char *)ctx->vert.vbo->data + offset, data, size); + } + else + assert(0); +} + +void glDeleteBuffers(GLsizei n, const GLuint* buffers) +{ + GLES2_GET_CONST_CONTEXT(ctx); + for (unsigned i = 0; i < n; i++) { + std::map<GLuint, VBO*>::iterator it = ctx->vert.vbos.find(buffers[i]); + if (it == ctx->vert.vbos.end()) + continue; + ctx->vert.free = min(ctx->vert.free, buffers[i]); + if (it->second == ctx->vert.vbo) + ctx->vert.vbo = NULL; + else if (it->second == ctx->vert.indices) + ctx->vert.indices = NULL; + if (it->second) { + free(it->second->data); + free(it->second); + } + } +} + +void glDisableVertexAttribArray(GLuint index) +{ + GLES2_GET_CONST_CONTEXT(ctx); + assert(GGL_MAXVERTEXATTRIBS > index); + ctx->vert.attribs[index].enabled = false; +} + +void glDrawArrays(GLenum mode, GLint first, GLsizei count) +{ + GLES2_GET_CONST_CONTEXT(ctx); +// LOGD("agl2: glDrawArrays=%p", glDrawArrays); + assert(ctx->rasterizer.CurrentProgram); + assert(0 <= first); + int maxAttrib = -1; + ctx->iface->ShaderProgramGetiv(ctx->rasterizer.CurrentProgram, GL_ACTIVE_ATTRIBUTES, &maxAttrib); + assert(0 <= maxAttrib && GGL_MAXVERTEXATTRIBS >= maxAttrib); + switch (mode) { + case GL_TRIANGLE_STRIP: + DrawArraysTriangleStrip(ctx, first, count, maxAttrib); + break; + case GL_TRIANGLES: + DrawArraysTriangles(ctx, first, count, maxAttrib); + break; + default: + LOGE("agl2: glDrawArrays unsupported mode: 0x%.4X \n", mode); + assert(0); + break; + } +// LOGD("agl2: glDrawArrays end"); +} + +void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) +{ + GLES2_GET_CONST_CONTEXT(ctx); +// LOGD("agl2: glDrawElements=%p mode=0x%.4X count=%d type=0x%.4X indices=%p", +// glDrawElements, mode, count, type, indices); + if (!ctx->rasterizer.CurrentProgram) + return; + + int maxAttrib = -1; + ctx->iface->ShaderProgramGetiv(ctx->rasterizer.CurrentProgram, GL_ACTIVE_ATTRIBUTES, &maxAttrib); + assert(0 <= maxAttrib && GGL_MAXVERTEXATTRIBS >= maxAttrib); +// LOGD("agl2: glDrawElements mode=0x%.4X type=0x%.4X count=%d program=%p indices=%p \n", +// mode, type, count, ctx->rasterizer.CurrentProgram, indices); + switch (mode) { + case GL_TRIANGLES: + if (GL_UNSIGNED_SHORT == type) + DrawElementsTriangles<unsigned short>(ctx, count, (unsigned short *)indices, maxAttrib); + else + assert(0); + break; + case GL_TRIANGLE_STRIP: + if (GL_UNSIGNED_SHORT == type) + DrawElementsTriangleStrip<unsigned short>(ctx, count, (unsigned short *)indices, maxAttrib); + else + assert(0); + break; + default: + assert(0); + } +// LOGD("agl2: glDrawElements end"); +} + +void glEnableVertexAttribArray(GLuint index) +{ + GLES2_GET_CONST_CONTEXT(ctx); + ctx->vert.attribs[index].enabled = true; +// LOGD("agl2: glEnableVertexAttribArray %d \n", index); +} + +void glGenBuffers(GLsizei n, GLuint* buffers) +{ + GLES2_GET_CONST_CONTEXT(ctx); + for (unsigned i = 0; i < n; i++) { + buffers[i] = 0; + for (ctx->vert.free; ctx->vert.free < 0xffffffffu; ctx->vert.free++) { + if (ctx->vert.vbos.find(ctx->vert.free) == ctx->vert.vbos.end()) { + ctx->vert.vbos[ctx->vert.free] = NULL; + buffers[i] = ctx->vert.free; +// LOGD("glGenBuffers %d \n", buffers[i]); + ctx->vert.free++; + break; + } + } + assert(buffers[i]); + } +} + +void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, + GLsizei stride, const GLvoid* ptr) +{ + GLES2_GET_CONST_CONTEXT(ctx); + assert(GL_FLOAT == type); + assert(0 < size && 4 >= size); + ctx->vert.attribs[index].size = size; + ctx->vert.attribs[index].type = type; + ctx->vert.attribs[index].normalized = normalized; + if (0 == stride) + ctx->vert.attribs[index].stride = size * sizeof(float); + else if (stride > 0) + ctx->vert.attribs[index].stride = stride; + else + assert(0); +// LOGD("\n*\n*\n* agl2: glVertexAttribPointer program=%u index=%d size=%d stride=%d ptr=%p \n*\n*", +// unsigned(ctx->rasterizer.CurrentProgram) ^ 0x04dc18f9, index, size, stride, ptr); + if (ctx->vert.vbo) + ctx->vert.attribs[index].ptr = (char *)ctx->vert.vbo->data + (long)ptr; + else + ctx->vert.attribs[index].ptr = ptr; +// const float * attrib = (const float *)ctx->vert.attribs[index].ptr; +// for (unsigned i = 0; i < 3; i++) +// if (3 == size) +// LOGD("%.2f %.2f %.2f", attrib[i * 3 + 0], attrib[i * 3 + 1], attrib[i * 3 + 2]); +// else if (2 == size) +// LOGD("%.2f %.2f", attrib[i * 3 + 0], attrib[i * 3 + 1]); + +} + +void glVertexAttrib1f(GLuint indx, GLfloat x) +{ + glVertexAttrib4f(indx, x,0,0,1); +} + +void glVertexAttrib1fv(GLuint indx, const GLfloat* values) +{ + glVertexAttrib4f(indx, values[0],0,0,1); +} + +void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) +{ + glVertexAttrib4f(indx, x,y,0,1); +} + +void glVertexAttrib2fv(GLuint indx, const GLfloat* values) +{ + glVertexAttrib4f(indx, values[0],values[1],0,1); +} + +void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) +{ + glVertexAttrib4f(indx, x,y,z,1); +} + +void glVertexAttrib3fv(GLuint indx, const GLfloat* values) +{ + glVertexAttrib4f(indx, values[0],values[1],values[2],1); +} + +void glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + assert(GGL_MAXVERTEXATTRIBS > indx); + GLES2_GET_CONST_CONTEXT(ctx); +// LOGD("\n*\n*\n agl2: glVertexAttrib4f %d %.2f,%.2f,%.2f,%.2f \n*\n*", indx, x, y, z, w); + ctx->vert.defaultAttribs[indx] = Vector4(x,y,z,w); + assert(0); +} + +void glVertexAttrib4fv(GLuint indx, const GLfloat* values) +{ + glVertexAttrib4f(indx, values[0], values[1], values[2], values[3]); +} |