From 69137dfa78d42bca56ca36a113270bac1624175e Mon Sep 17 00:00:00 2001 From: lubomyr Date: Fri, 24 Feb 2017 21:27:22 +0200 Subject: [PATCH] gl4es updated, added latest changes by ptitSeb --- project/jni/gl4es/README.md | 12 +- project/jni/gl4es/src/config.h | 5 +- project/jni/gl4es/src/gl/buffers.c | 17 +- project/jni/gl4es/src/gl/const.h | 2 + project/jni/gl4es/src/gl/debug.c | 24 ++ project/jni/gl4es/src/gl/getter.c | 38 ++- project/jni/gl4es/src/gl/gl.c | 189 +++++++++------ project/jni/gl4es/src/gl/gl.h | 15 +- project/jni/gl4es/src/gl/hint.c | 5 +- project/jni/gl4es/src/gl/init.c | 1 + project/jni/gl4es/src/gl/init.h | 1 + project/jni/gl4es/src/gl/light.c | 336 ++++++++++++++------------- project/jni/gl4es/src/gl/line.c | 9 + project/jni/gl4es/src/gl/list.c | 72 ++++-- project/jni/gl4es/src/gl/list.h | 31 ++- project/jni/gl4es/src/gl/loader.c | 5 +- project/jni/gl4es/src/gl/matrix.c | 50 ++-- project/jni/gl4es/src/gl/matvec.c | 6 +- project/jni/gl4es/src/gl/queries.c | 27 ++- project/jni/gl4es/src/gl/raster.c | 66 +++--- project/jni/gl4es/src/gl/render.c | 29 +++ project/jni/gl4es/src/gl/stack.c | 28 ++- project/jni/gl4es/src/gl/state.h | 2 + project/jni/gl4es/src/gl/texgen.c | 50 +++- project/jni/gl4es/src/gl/texture.c | 106 +++++---- project/jni/gl4es/src/gl/wrap/gl.c | 32 +-- project/jni/gl4es/src/gl/wrap/gles.h | 2 +- project/jni/gl4es/src/glx/glx.c | 4 +- project/jni/gl4es/src/glx/hardext.c | 4 +- 29 files changed, 732 insertions(+), 436 deletions(-) diff --git a/project/jni/gl4es/README.md b/project/jni/gl4es/README.md index 558d3235e..cf6f33e6f 100755 --- a/project/jni/gl4es/README.md +++ b/project/jni/gl4es/README.md @@ -227,14 +227,24 @@ Initial Hardware test ##### LIBGL_NOVAOCACHE VAO Caching - * 0 : Default, tr to cache vao to avoid memcpy in render list + * 0 : Default, try to cache vao to avoid memcpy in render list * 1 : Don't cache VAO +##### LIBGL_VABGRA +Vertex Array BGRA extension + * 0 : Default, GL_ARB_vertex_array_bgra not exposed (still emulated) + * 1 : Extension exposed may be faster in some cases (Arx Libertatis mainly) + ---- Version history ---- +##### Current version + * Added some optimisations for sequencial glBegin/glEnd blocks + * Fixed many issue with Lights introduced with 0.9.4 + * Fixed Android build introduced with 0.9.4 + ##### 0.9.4 * Fixed some extended functions (like glBlendFuncSeparate) not working inside list (fixing some issues with Batch mode) * Added back GL_TEXTURE_RECTANGLE_ARB handling (and using npot texture, even limited, if available) diff --git a/project/jni/gl4es/src/config.h b/project/jni/gl4es/src/config.h index 2abfe86c5..9699f502a 100755 --- a/project/jni/gl4es/src/config.h +++ b/project/jni/gl4es/src/config.h @@ -141,6 +141,9 @@ // MultiDrawArrays #define skip_glMultiDrawArrays #define skip_glMultiDrawElements +// this is to avoid a warning. I don't Push those anyway +#define direct_glMultiDrawArrays +#define direct_glMultiDrawElements // don't compile these into display lists #define direct_glColorPointer @@ -148,7 +151,7 @@ #define direct_glDisableClientState #define direct_glEdgeFlagPointer #define direct_glEnableClientState -#define direct_glClientActiveTexture +//#define direct_glClientActiveTexture // will use it in Batch mode #define direct_glFeedbackBuffer #define direct_glGenLists #define direct_glIndexPointer diff --git a/project/jni/gl4es/src/gl/buffers.c b/project/jni/gl4es/src/gl/buffers.c index 2ece32c9c..159f8b47f 100755 --- a/project/jni/gl4es/src/gl/buffers.c +++ b/project/jni/gl4es/src/gl/buffers.c @@ -69,9 +69,8 @@ void gl4es_glGenBuffers(GLsizei n, GLuint * buffers) { void gl4es_glBindBuffer(GLenum target, GLuint buffer) { //printf("glBindBuffer(%s, %u)\n", PrintEnum(target), buffer); - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) flush(); - } khint_t k; int ret; @@ -162,9 +161,8 @@ void gl4es_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, cons void gl4es_glDeleteBuffers(GLsizei n, const GLuint * buffers) { //printf("glDeleteBuffers(%i, %p)\n", n, buffers); - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) flush(); - } VaoSharedClear(glstate->vao); khash_t(buff) *list = glstate->buffers; @@ -272,6 +270,10 @@ void *gl4es_glMapBuffer(GLenum target, GLenum access) { GLboolean gl4es_glUnmapBuffer(GLenum target) { //printf("glUnmapBuffer(%s)\n", PrintEnum(target)); + if(glstate->list.compiling) {errorShim(GL_INVALID_OPERATION); return GL_FALSE;} + if(glstate->list.active) + flush(); + if (!buffer_target(target)) { errorShim(GL_INVALID_ENUM); return GL_FALSE; @@ -368,9 +370,8 @@ void gl4es_glGenVertexArrays(GLsizei n, GLuint *arrays) { } void gl4es_glBindVertexArray(GLuint array) { //printf("glBindVertexArray(%u)\n", array); - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) flush(); - } khint_t k; int ret; @@ -412,9 +413,9 @@ void gl4es_glBindVertexArray(GLuint array) { } void gl4es_glDeleteVertexArrays(GLsizei n, const GLuint *arrays) { //printf("glDeleteVertexArrays(%i, %p)\n", n, arrays); - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) flush(); - } + khash_t(glvao) *list = glstate->vaos; if (list) { khint_t k; diff --git a/project/jni/gl4es/src/gl/const.h b/project/jni/gl4es/src/gl/const.h index 7514cfc7d..b70e5fb53 100755 --- a/project/jni/gl4es/src/gl/const.h +++ b/project/jni/gl4es/src/gl/const.h @@ -2,6 +2,8 @@ #define GL_QUAD_STRIP 8 #define GL_POLYGON 9 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C /* texture mapping */ #define GL_TEXTURE_ENV 0x2300 #define GL_TEXTURE_ENV_MODE 0x2200 diff --git a/project/jni/gl4es/src/gl/debug.c b/project/jni/gl4es/src/gl/debug.c index 0a7cb4692..165d6643a 100755 --- a/project/jni/gl4es/src/gl/debug.c +++ b/project/jni/gl4es/src/gl/debug.c @@ -135,6 +135,30 @@ const char* PrintEnum(GLenum what) { p(GL_PROJECTION); p(GL_MODELVIEW); p(GL_TEXTURE); + // blend + p(GL_SRC_ALPHA); + p(GL_DST_ALPHA); + p(GL_ONE_MINUS_SRC_ALPHA); + p(GL_ONE_MINUS_DST_ALPHA); + // lights + p(GL_LIGHT0); + p(GL_LIGHT1); + p(GL_LIGHT2); + p(GL_LIGHT3); + p(GL_LIGHT4); + p(GL_LIGHT5); + p(GL_LIGHT6); + p(GL_LIGHT7); + p(GL_AMBIENT); + p(GL_DIFFUSE); + p(GL_SPECULAR); + p(GL_POSITION); + p(GL_SPOT_DIRECTION); + p(GL_SPOT_EXPONENT); + p(GL_SPOT_CUTOFF); + p(GL_CONSTANT_ATTENUATION); + p(GL_LINEAR_ATTENUATION); + p(GL_QUADRATIC_ATTENUATION); default: sprintf(fallback, "0x%04X", what); } diff --git a/project/jni/gl4es/src/gl/getter.c b/project/jni/gl4es/src/gl/getter.c index e417a3375..3854e9332 100755 --- a/project/jni/gl4es/src/gl/getter.c +++ b/project/jni/gl4es/src/gl/getter.c @@ -100,10 +100,11 @@ const GLubyte *gl4es_glGetString(GLenum name) { "GL_EXT_texture_object " "GL_EXT_polygon_offset " "GL_GL4ES_hint " - "GL_ARB_vertex_array_bgra " "GL_ARB_texture_rectangle " // "GL_EXT_blend_logic_op " ); + if(globals4es.vabgra) + strcat(extensions, "GL_ARB_vertex_array_bgra "); if(globals4es.npot>=1) strcat(extensions, "GL_APPLE_texture_2D_limited_npot "); if(globals4es.npot>=2) @@ -160,6 +161,12 @@ void gl4es_glGetIntegerv(GLenum pname, GLint *params) { if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush(); noerrorShim(); switch (pname) { + case GL_MAJOR_VERSION: + *params = 1; + break; + case GL_MINOR_VERSION: + *params = 5; + break; case GL_MAX_ELEMENTS_INDICES: *params = 1024; break; @@ -348,6 +355,12 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) { if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush(); noerrorShim(); switch (pname) { + case GL_MAJOR_VERSION: + *params = 1; + break; + case GL_MINOR_VERSION: + *params = 5; + break; case GL_MAX_ELEMENTS_INDICES: *params = 1024; break; @@ -520,40 +533,41 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) { void glGetFloatv(GLenum pname, GLfloat *params) AliasExport("gl4es_glGetFloatv"); void gl4es_glGetLightfv(GLenum light, GLenum pname, GLfloat * params) { - if(light<0 || light>=hardext.maxlights) { + const int nl = light-GL_LIGHT0; + if(nl<0 || nl>=hardext.maxlights) { errorShim(GL_INVALID_ENUM); return; } switch(pname) { case GL_AMBIENT: - memcpy(params, glstate->light.lights[light].ambient, 4*sizeof(GLfloat)); + memcpy(params, glstate->light.lights[nl].ambient, 4*sizeof(GLfloat)); break; case GL_DIFFUSE: - memcpy(params, glstate->light.lights[light].diffuse, 4*sizeof(GLfloat)); + memcpy(params, glstate->light.lights[nl].diffuse, 4*sizeof(GLfloat)); break; case GL_SPECULAR: - memcpy(params, glstate->light.lights[light].specular, 4*sizeof(GLfloat)); + memcpy(params, glstate->light.lights[nl].specular, 4*sizeof(GLfloat)); break; case GL_POSITION: - memcpy(params, glstate->light.lights[light].position, 4*sizeof(GLfloat)); + memcpy(params, glstate->light.lights[nl].position, 4*sizeof(GLfloat)); break; case GL_SPOT_DIRECTION: - memcpy(params, glstate->light.lights[light].spotDirection, 3*sizeof(GLfloat)); + memcpy(params, glstate->light.lights[nl].spotDirection, 3*sizeof(GLfloat)); break; case GL_SPOT_EXPONENT: - params[0] = glstate->light.lights[light].spotExponent; + params[0] = glstate->light.lights[nl].spotExponent; break; case GL_SPOT_CUTOFF: - params[0] = glstate->light.lights[light].spotCutoff; + params[0] = glstate->light.lights[nl].spotCutoff; break; case GL_CONSTANT_ATTENUATION: - params[0] = glstate->light.lights[light].constantAttenuation; + params[0] = glstate->light.lights[nl].constantAttenuation; break; case GL_LINEAR_ATTENUATION: - params[0] = glstate->light.lights[light].linearAttenuation; + params[0] = glstate->light.lights[nl].linearAttenuation; break; case GL_QUADRATIC_ATTENUATION: - params[0] = glstate->light.lights[light].quadraticAttenuation; + params[0] = glstate->light.lights[nl].quadraticAttenuation; break; default: errorShim(GL_INVALID_ENUM); diff --git a/project/jni/gl4es/src/gl/gl.c b/project/jni/gl4es/src/gl/gl.c index 90780e7ad..00f09dab1 100755 --- a/project/jni/gl4es/src/gl/gl.c +++ b/project/jni/gl4es/src/gl/gl.c @@ -20,7 +20,7 @@ void* NewGLState(void* shared_glstate) { memset(glstate, 0, sizeof(glstate_t)); memcpy(glstate->color, white, sizeof(GLfloat)*4); glstate->last_error = GL_NO_ERROR; - glstate->normal[3] = 1.0f; // default normal is 0/0/1 + glstate->normal[2] = 1.0f; // default normal is 0/0/1 glstate->matrix_mode = GL_MODELVIEW; // add default VBO @@ -348,8 +348,9 @@ void gl4es_glDisable(GLenum cap) { void glDisable(GLenum cap) AliasExport("gl4es_glDisable"); void gl4es_glEnableClientState(GLenum cap) { + ERROR_IN_BEGIN // should flush for now... to be optimized later! - if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) + if (glstate->list.active && !glstate->list.compiling) flush(); LOAD_GLES(glEnableClientState); proxy_glEnable(cap, true, gles_glEnableClientState); @@ -357,8 +358,9 @@ void gl4es_glEnableClientState(GLenum cap) { void glEnableClientState(GLenum cap) AliasExport("gl4es_glEnableClientState"); void gl4es_glDisableClientState(GLenum cap) { + ERROR_IN_BEGIN // should flush for now... to be optimized later! - if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) + if (glstate->list.active && !glstate->list.compiling) flush(); LOAD_GLES(glDisableClientState); proxy_glEnable(cap, false, gles_glDisableClientState); @@ -372,8 +374,10 @@ void glDisableClientState(GLenum cap) AliasExport("gl4es_glDisableClientState"); case what: return glstate->vao->where GLboolean gl4es_glIsEnabled(GLenum cap) { + if(glstate->list.begin) {errorShim(GL_INVALID_OPERATION); return GL_FALSE;} + if(glstate->list.compiling) {errorShim(GL_INVALID_OPERATION); return GL_FALSE;} // should flush for now... to be optimized later! - if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) + if (glstate->list.active) flush(); LOAD_GLES(glIsEnabled); noerrorShim(); @@ -552,7 +556,7 @@ static inline bool should_intercept_render(GLenum mode) { return ( (glstate->vao->vertex_array && ! valid_vertex_type(glstate->vao->pointers.vertex.type)) || (mode == GL_LINES && glstate->enable.line_stipple) || - /*(mode == GL_QUADS) ||*/ (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) + /*(mode == GL_QUADS) ||*/ (glstate->list.active) ); } @@ -560,6 +564,8 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid //printf("glDrawElements(%s, %d, %s, %p), vtx=%p map=%p\n", PrintEnum(mode), count, PrintEnum(type), indices, (glstate->vao->vertex)?glstate->vao->vertex->data:NULL, (glstate->vao->elements)?glstate->vao->elements->data:NULL); // TODO: split for count > 65535? // special check for QUADS and TRIANGLES that need multiple of 4 or 3 vertex... + if(glstate->list.active && !glstate->list.compiling && glstate->gl_batch) + flush(); if (mode == GL_QUADS) while(count%4) count--; else if (mode == GL_TRIANGLES) while(count%3) count--; @@ -580,7 +586,7 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count); else sindices = (glstate->vao->elements)?(glstate->vao->elements->data + (uintptr_t)indices):(GLvoid*)indices; - bool compiling = (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)); + bool compiling = (glstate->list.active); if (compiling) { renderlist_t *list = NULL; @@ -721,6 +727,8 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) AliasExport("gl4es_glDrawElements"); void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) { + if(glstate->list.active && !glstate->list.compiling && glstate->gl_batch) + flush(); // special check for QUADS and TRIANGLES that need multiple of 4 or 3 vertex... if (mode == GL_QUADS) while(count%4) count--; else if (mode == GL_TRIANGLES) while(count%3) count--; @@ -754,7 +762,7 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) { LOAD_GLES(glDisableClientState); LOAD_GLES(glMultiTexCoord4f); - if (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) { + if (glstate->list.active) { NewStage(glstate->list.active, STAGE_DRAW); glstate->list.active = arrays_to_renderlist(glstate->list.active, mode, first, count+first); glstate->list.active = extend_renderlist(glstate->list.active); @@ -1019,9 +1027,12 @@ void glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) A // immediate mode functions void gl4es_glBegin(GLenum mode) { + glstate->list.begin = 1; + glstate->list.pending = 0; if (!glstate->list.active) glstate->list.active = alloc_renderlist(); - NewStage(glstate->list.active, STAGE_DRAW); + // small optim... continue a render command if possible + NewDrawStage(glstate->list.active, mode); glstate->list.active->mode = mode; glstate->list.active->mode_init = mode; noerrorShim(); // TODO, check Enum validity @@ -1030,19 +1041,24 @@ void glBegin(GLenum mode) AliasExport("gl4es_glBegin"); void gl4es_glEnd() { if (!glstate->list.active) return; + glstate->list.begin = 0; // check if TEXTUREx is activate and no TexCoord (or texgen), in that case, create a dummy one base on glstate->.. for (int a=0; aenable.texture[a] && ((glstate->list.active->tex[a]==0) && !(glstate->enable.texgen_s[a] || glstate->texture.pscoordreplace[a]))) rlMultiTexCoord4f(glstate->list.active, GL_TEXTURE0+a, glstate->texcoord[a][0], glstate->texcoord[a][1], glstate->texcoord[a][2], glstate->texcoord[a][3]); // render if we're not in a display list - if (!(glstate->list.compiling || glstate->gl_batch)) { + if (!(glstate->list.compiling || glstate->gl_batch) && (!(globals4es.mergelist) || (glstate->polygon_mode==GL_LINE))) { renderlist_t *mylist = glstate->list.active; glstate->list.active = NULL; mylist = end_renderlist(mylist); draw_renderlist(mylist); free_renderlist(mylist); } else { - glstate->list.active = extend_renderlist(glstate->list.active); + if(!(glstate->list.compiling || glstate->gl_batch)) { + glstate->list.pending = 1; + NewStage(glstate->list.active, STAGE_POSTDRAW); + } + else glstate->list.active = extend_renderlist(glstate->list.active); } noerrorShim(); } @@ -1051,12 +1067,16 @@ void glEnd() AliasExport("gl4es_glEnd"); void gl4es_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) { if (glstate->list.active) { if (glstate->list.active->stage != STAGE_DRAW) { - if (glstate->list.active->stage != STAGE_DRAW) { - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - glstate->list.active->lastNormal[0] = nx; glstate->list.active->lastNormal[1] = ny; glstate->list.active->lastNormal[2] = nz; - } - PUSH_IF_COMPILING(glNormal3f); + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + glstate->list.active->lastNormal[0] = nx; glstate->list.active->lastNormal[1] = ny; glstate->list.active->lastNormal[2] = nz; + } else if (glstate->list.pending && glstate->list.active->stage==STAGE_POSTDRAW) { + glstate->list.active->post_normals[0] = nx; glstate->list.active->post_normals[1] = ny; + glstate->list.active->post_normals[2] = nz; + glstate->list.active->post_normal = 1; + return; } + + PUSH_IF_COMPILING(glNormal3f); } else { rlNormal3f(glstate->list.active, nx, ny, nz); glstate->list.active->lastNormal[0] = nx; glstate->list.active->lastNormal[1] = ny; glstate->list.active->lastNormal[2] = nz; @@ -1085,13 +1105,23 @@ void glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) AliasExport("gl4es_g void gl4es_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { if (glstate->list.active) { if (glstate->list.active->stage != STAGE_DRAW) { - glstate->list.active->lastColors[0] = red; glstate->list.active->lastColors[1] = green; - glstate->list.active->lastColors[2] = blue; glstate->list.active->lastColors[3] = alpha; - glstate->list.active->lastColorsSet = 1; + if (glstate->list.compiling || glstate->gl_batch || glstate->list.active->stagelist.active->lastColors[0] = red; glstate->list.active->lastColors[1] = green; + glstate->list.active->lastColors[2] = blue; glstate->list.active->lastColors[3] = alpha; + glstate->list.active->lastColorsSet = 1; + PUSH_IF_COMPILING(glColor4f); + } + else if (glstate->list.pending && glstate->list.active->stage==STAGE_POSTDRAW) { + glstate->list.active->post_colors[0] = red; glstate->list.active->post_colors[1] = green; + glstate->list.active->post_colors[2] = blue; glstate->list.active->post_colors[3] = alpha; + glstate->list.active->post_color = 1; + return; + } PUSH_IF_COMPILING(glColor4f); + } else { + rlColor4f(glstate->list.active, red, green, blue, alpha); + noerrorShim(); } - rlColor4f(glstate->list.active, red, green, blue, alpha); - noerrorShim(); } #ifndef USE_ES2 else { @@ -1108,9 +1138,14 @@ void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) AliasExp void gl4es_glSecondaryColor3f(GLfloat r, GLfloat g, GLfloat b) { if (glstate->list.active) { - rlSecondary3f(glstate->list.active, r, g, b); - glstate->list.active->lastSecondaryColors[0] = r; glstate->list.active->lastSecondaryColors[1] = g; - glstate->list.active->lastSecondaryColors[2] = b; + if(glstate->list.pending) + flush(); + else + { + rlSecondary3f(glstate->list.active, r, g, b); + glstate->list.active->lastSecondaryColors[0] = r; glstate->list.active->lastSecondaryColors[1] = g; + glstate->list.active->lastSecondaryColors[2] = b; + } noerrorShim(); } else { noerrorShim(); @@ -1124,7 +1159,10 @@ void glSecondaryColor3f(GLfloat r, GLfloat g, GLfloat b) AliasExport("gl4es_glSe void gl4es_glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { if (glstate->list.active) { - rlTexCoord4f(glstate->list.active, s, t, r, q); + if(glstate->list.pending) + flush(); + else + rlMultiTexCoord4f(glstate->list.active, GL_TEXTURE0, s, t, r, q); } noerrorShim(); glstate->texcoord[0][0] = s; glstate->texcoord[0][1] = t; @@ -1135,7 +1173,10 @@ void glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) AliasExport("gl4es void gl4es_glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { // TODO, error if target is unsuported texture.... if (glstate->list.active) { - rlMultiTexCoord4f(glstate->list.active, target, s, t, r, q); + if(glstate->list.pending) + flush(); + else + rlMultiTexCoord4f(glstate->list.active, target, s, t, r, q); } noerrorShim(); glstate->texcoord[target-GL_TEXTURE0][0] = s; glstate->texcoord[target-GL_TEXTURE0][1] = t; @@ -1298,7 +1339,7 @@ void glEndList() AliasExport("gl4es_glEndList"); renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a); void gl4es_glCallList(GLuint list) { noerrorShim(); - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + if (glstate->list.active) { glstate->list.active = append_calllist(glstate->list.active, gl4es_glGetList(list)); return; } @@ -1310,7 +1351,7 @@ void gl4es_glCallList(GLuint list) { void glCallList(GLuint list) AliasExport("gl4es_glCallList"); void glPushCall(void *call) { - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + if (glstate->list.active) { NewStage(glstate->list.active, STAGE_GLCALL); rlPushCall(glstate->list.active, call); } @@ -1390,16 +1431,19 @@ GLboolean gl4es_glIsList(GLuint list) { GLboolean glIsList(GLuint list) AliasExport("gl4es_glIsList"); void gl4es_glPolygonMode(GLenum face, GLenum mode) { + ERROR_IN_BEGIN noerrorShim(); if (face != GL_FRONT_AND_BACK) errorShim(GL_INVALID_ENUM); if (face == GL_BACK) return; //TODO, handle face enum for polygon mode != GL_FILL - if ((glstate->list.compiling || glstate->gl_batch) && (glstate->list.active)) { - NewStage(glstate->list.active, STAGE_POLYGON); - glstate->list.active->polygon_mode = mode; - return; - } + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_POLYGON); + glstate->list.active->polygon_mode = mode; + return; + } + else flush(); switch(mode) { case GL_LINE: case GL_POINT: @@ -1455,17 +1499,17 @@ void glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) AliasExport("gl4es_gl void glBlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) AliasExport("gl4es_glBlendEquationSeparate"); void gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor) { - if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) { - if ((glstate->statebatch.blendfunc_s == sfactor) && (glstate->statebatch.blendfunc_d == dfactor)) - return; // nothing to do... - if (!glstate->statebatch.blendfunc_s) { - glstate->statebatch.blendfunc_s = sfactor; - glstate->statebatch.blendfunc_d = dfactor; - } else { - flush(); - } - } - PUSH_IF_COMPILING(glBlendFunc); + if (glstate->list.active) + if (!glstate->list.compiling && glstate->gl_batch) { + if ((glstate->statebatch.blendfunc_s == sfactor) && (glstate->statebatch.blendfunc_d == dfactor)) + return; // nothing to do... + if (!glstate->statebatch.blendfunc_s) { + glstate->statebatch.blendfunc_s = sfactor; + glstate->statebatch.blendfunc_d = dfactor; + } + } + + PUSH_IF_COMPILING(glBlendFunc) LOAD_GLES(glBlendFunc); LOAD_GLES_OES(glBlendFuncSeparate); errorGL(); @@ -1549,6 +1593,7 @@ void flush() { if (mylist) { GLuint old = glstate->gl_batch; glstate->list.active = NULL; + glstate->list.pending = 0; glstate->gl_batch = 0; mylist = end_renderlist(mylist); draw_renderlist(mylist); @@ -1571,12 +1616,8 @@ extern void BlitEmulatedPixmap(); void gl4es_glFlush() { LOAD_GLES(glFlush); - if (glstate->list.active && !glstate->gl_batch) { - errorShim(GL_INVALID_OPERATION); - return; - } - - if (glstate->gl_batch) flush(); + if (glstate->gl_batch || glstate->list.pending) flush(); + PUSH_IF_COMPILING(glFlush); gles_glFlush(); errorGL(); @@ -1591,11 +1632,8 @@ void glFlush() AliasExport("gl4es_glFlush"); void gl4es_glFinish() { LOAD_GLES(glFinish); - if (glstate->list.active && !glstate->gl_batch) { - errorShim(GL_INVALID_OPERATION); - return; - } - if (glstate->gl_batch) flush(); + if (glstate->gl_batch || glstate->list.pending) flush(); + PUSH_IF_COMPILING(glFinish); gles_glFinish(); errorGL(); @@ -1603,17 +1641,16 @@ void gl4es_glFinish() { void glFinish() AliasExport("gl4es_glFinish"); void gl4es_glFogfv(GLenum pname, const GLfloat* params) { - LOAD_GLES(glFogfv); - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - if (pname == GL_FOG_COLOR) { - NewStage(glstate->list.active, STAGE_FOG); - rlFogOp(glstate->list.active, 1, params); - return; - } - } - PUSH_IF_COMPILING(glFogfv); - + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_FOG); + rlFogOp(glstate->list.active, pname, params); + return; + } + else flush(); + + LOAD_GLES(glFogfv); gles_glFogfv(pname, params); } void glFogfv(GLenum pname, const GLfloat* params) AliasExport("gl4es_glFogfv"); @@ -1659,16 +1696,18 @@ void gl4es_glPointParameterf(GLenum pname, GLfloat param) { void gl4es_glPointParameterfv(GLenum pname, const GLfloat * params) { - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - if (pname == GL_POINT_DISTANCE_ATTENUATION) { - NewStage(glstate->list.active, STAGE_POINTPARAM); - rlPointParamOp(glstate->list.active, 1, params); - return; - } else { - gl4es_glPointParameterf(pname, params[0]); - return; - } - } + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + if (pname == GL_POINT_DISTANCE_ATTENUATION) { + NewStage(glstate->list.active, STAGE_POINTPARAM); + rlPointParamOp(glstate->list.active, 1, params); + return; + } else { + gl4es_glPointParameterf(pname, params[0]); + return; + } + } else flush(); + LOAD_GLES(glPointParameterfv); gles_glPointParameterfv(pname, params); @@ -1680,6 +1719,7 @@ void glPointParameterfv(GLenum pname, const GLfloat * params) AliasExport("gl4es void gl4es_glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount) { LOAD_GLES_EXT(glMultiDrawArrays); + if(glstate->list.pending) flush(); if((!gles_glMultiDrawArrays) || should_intercept_render(mode) || (mode==GL_QUADS) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) || (glstate->render_mode == GL_SELECT) || ((glstate->polygon_mode == GL_LINE) || (glstate->polygon_mode == GL_POINT)) ) { @@ -1702,6 +1742,7 @@ void glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GL void gl4es_glMultiDrawElements( GLenum mode, GLsizei *count, GLenum type, const void * const *indices, GLsizei primcount) { LOAD_GLES_EXT(glMultiDrawElements); + if(glstate->list.pending) flush(); if((!gles_glMultiDrawElements) || should_intercept_render(mode) || (mode==GL_QUADS) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) || (glstate->render_mode == GL_SELECT) || ((glstate->polygon_mode == GL_LINE) || (glstate->polygon_mode == GL_POINT)) || (type != GL_UNSIGNED_SHORT) ) { diff --git a/project/jni/gl4es/src/gl/gl.h b/project/jni/gl4es/src/gl/gl.h index 04da0ef92..b588e0bcd 100755 --- a/project/jni/gl4es/src/gl/gl.h +++ b/project/jni/gl4es/src/gl/gl.h @@ -190,11 +190,14 @@ packed_call_t* glCopyPackedCall(const packed_call_t *packed); } #define PUSH_IF_COMPILING_EXT(nam, ...) \ - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { \ - NewStage(glstate->list.active, STAGE_GLCALL); \ - push_##nam(__VA_ARGS__); \ - noerrorShim(); \ - return (nam##_RETURN)0; \ + if (glstate->list.active) { \ + if (!glstate->list.pending) { \ + NewStage(glstate->list.active, STAGE_GLCALL); \ + push_##nam(__VA_ARGS__); \ + noerrorShim(); \ + return (nam##_RETURN)0; \ + } \ + else if(glstate->list.pending) flush(); \ } //printf("list:%i, " #nam "\n", state.list.name); @@ -203,6 +206,8 @@ const char* PrintEnum(GLenum what); #define PUSH_IF_COMPILING(name) PUSH_IF_COMPILING_EXT(name, name##_ARG_NAMES) +#define ERROR_IN_BEGIN if(glstate->list.begin) {errorShim(GL_INVALID_OPERATION); return;} + static const GLsizei gl_sizeof(GLenum type) { // types switch (type) { diff --git a/project/jni/gl4es/src/gl/hint.c b/project/jni/gl4es/src/gl/hint.c index 47c40ffc5..253833bef 100755 --- a/project/jni/gl4es/src/gl/hint.c +++ b/project/jni/gl4es/src/gl/hint.c @@ -3,7 +3,10 @@ #include "init.h" void gl4es_glHint(GLenum pname, GLenum mode) { - if(glstate->gl_batch) flush(); + + if (glstate->gl_batch || glstate->list.pending) + flush(); + LOAD_GLES(glHint); noerrorShim(); switch(pname) { diff --git a/project/jni/gl4es/src/gl/init.c b/project/jni/gl4es/src/gl/init.c index 5e399f10e..732a4e632 100755 --- a/project/jni/gl4es/src/gl/init.c +++ b/project/jni/gl4es/src/gl/init.c @@ -221,6 +221,7 @@ void initialize_gl4es() { env(LIBGL_BLENDCOLOR, globals4es.blendcolor, "Export a (faked) glBlendColor"); env(LIBGL_NOERROR, globals4es.noerror, "glGetError() always return GL_NOERROR"); env(LIBGL_SILENTSTUB, globals4es.silentstub, "Stub/non present functions are not printed"); + env(LIBGL_VABGRA, globals4es.vabgra, "Export GL_ARB_vertex_array_bgra extension"); char *env_version = getenv("LIBGL_VERSION"); if (env_version) { diff --git a/project/jni/gl4es/src/gl/init.h b/project/jni/gl4es/src/gl/init.h index dc3dd3219..5ee201397 100755 --- a/project/jni/gl4es/src/gl/init.h +++ b/project/jni/gl4es/src/gl/init.h @@ -34,6 +34,7 @@ typedef struct _globals4es { int silentstub; int glx_surface_srgb; int nodownsampling; + int vabgra; #ifdef PANDORA float gamma; #endif diff --git a/project/jni/gl4es/src/gl/light.c b/project/jni/gl4es/src/gl/light.c index 375b67f5c..72dbc139b 100755 --- a/project/jni/gl4es/src/gl/light.c +++ b/project/jni/gl4es/src/gl/light.c @@ -3,15 +3,16 @@ #include "matrix.h" #include "matvec.h" -#ifndef USE_ES2 void gl4es_glLightModelf(GLenum pname, GLfloat param) { //printf("%sglLightModelf(%04X, %.2f)\n", (state.list.compiling)?"list":"", pname, param); - if (glstate->list.compiling && glstate->list.active) { - GLfloat dummy[4]; - dummy[0]=param; - gl4es_glLightModelfv(pname, dummy); - return; - } + ERROR_IN_BEGIN + if(glstate->list.active) + if ((glstate->list.compiling || glstate->gl_batch)) { + GLfloat dummy[4]; + dummy[0]=param; + gl4es_glLightModelfv(pname, dummy); + return; + } else flush(); switch (pname) { case GL_LIGHT_MODEL_TWO_SIDE: errorGL(); @@ -28,16 +29,18 @@ void gl4es_glLightModelf(GLenum pname, GLfloat param) { void gl4es_glLightModelfv(GLenum pname, const GLfloat* params) { //printf("%sglLightModelfv(%04X, [%.2f, %.2f, %.2f, %.2f])\n", (state.list.compiling)?"list":"", pname, params[0], params[1], params[2], params[3]); - if (glstate->list.compiling && glstate->list.active) { - NewStage(glstate->list.active, STAGE_LIGHTMODEL); -/* if (glstate->list.active->lightmodel) - glstate->list.active = extend_renderlist(glstate->list.active);*/ - glstate->list.active->lightmodelparam = pname; - glstate->list.active->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat)); - memcpy(glstate->list.active->lightmodel, params, 4*sizeof(GLfloat)); - noerrorShim(); - return; - } + ERROR_IN_BEGIN + if(glstate->list.active) + if ((glstate->list.compiling || glstate->gl_batch)) { + NewStage(glstate->list.active, STAGE_LIGHTMODEL); + /* if (glstate->list.active->lightmodel) + glstate->list.active = extend_renderlist(glstate->list.active);*/ + glstate->list.active->lightmodelparam = pname; + glstate->list.active->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat)); + memcpy(glstate->list.active->lightmodel, params, 4*sizeof(GLfloat)); + noerrorShim(); + return; + } else flush(); switch (pname) { case GL_LIGHT_MODEL_AMBIENT: if(memcmp(glstate->light.ambient, params, 4*sizeof(GLfloat))==0) { @@ -64,93 +67,97 @@ void gl4es_glLightModelfv(GLenum pname, const GLfloat* params) { } void gl4es_glLightfv(GLenum light, GLenum pname, const GLfloat* params) { -//printf("%sglLightfv(%04X, %04X, %p=[%.2f, %.2f, %.2f, %.2f])\n", (glstate->list.compiling)?"list":"", light, pname, params, (params)?params[0]:0.0f, (params)?params[1]:0.0f, (params)?params[2]:0.0f, (params)?params[3]:0.0f); - if(light<0 || light>=hardext.maxlights) { +//printf("%sglLightfv(%s, %s, %p=[%.2f, %.2f, %.2f, %.2f])\n", (glstate->list.compiling)?"list":"", PrintEnum(light), PrintEnum(pname), params, (params)?params[0]:0.0f, (params)?params[1]:0.0f, (params)?params[2]:0.0f, (params)?params[3]:0.0f); + const int nl = light-GL_LIGHT0; + if(nl<0 || nl>=hardext.maxlights) { errorShim(GL_INVALID_ENUM); return; } - if (glstate->list.compiling && glstate->list.active) { - NewStage(glstate->list.active, STAGE_LIGHT); - rlLightfv(glstate->list.active, light, pname, params); - noerrorShim(); - return; - } + ERROR_IN_BEGIN + if(glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_LIGHT); + rlLightfv(glstate->list.active, light, pname, params); + noerrorShim(); + return; + } else flush(); + GLfloat tmp[4]; noerrorShim(); switch(pname) { case GL_AMBIENT: - if(memcmp(glstate->light.lights[light].ambient, params, 4*sizeof(GLfloat))==0) + if(memcmp(glstate->light.lights[nl].ambient, params, 4*sizeof(GLfloat))==0) return; - memcpy(glstate->light.lights[light].ambient, params, 4*sizeof(GLfloat)); + memcpy(glstate->light.lights[nl].ambient, params, 4*sizeof(GLfloat)); break; case GL_DIFFUSE: - if(memcmp(glstate->light.lights[light].diffuse, params, 4*sizeof(GLfloat))) + if(memcmp(glstate->light.lights[nl].diffuse, params, 4*sizeof(GLfloat))==0) return; - memcpy(glstate->light.lights[light].diffuse, params, 4*sizeof(GLfloat)); + memcpy(glstate->light.lights[nl].diffuse, params, 4*sizeof(GLfloat)); break; case GL_SPECULAR: - if(memcmp(glstate->light.lights[light].specular, params, 4*sizeof(GLfloat))) + if(memcmp(glstate->light.lights[nl].specular, params, 4*sizeof(GLfloat))==0) return; - memcpy(glstate->light.lights[light].specular, params, 4*sizeof(GLfloat)); + memcpy(glstate->light.lights[nl].specular, params, 4*sizeof(GLfloat)); break; case GL_POSITION: vector_matrix(params, getMVMat(), tmp); - if(memcmp(glstate->light.lights[light].position, tmp, 4*sizeof(GLfloat))) + if(memcmp(glstate->light.lights[nl].position, tmp, 4*sizeof(GLfloat))==0) return; - memcpy(glstate->light.lights[light].position, tmp, 4*sizeof(GLfloat)); + memcpy(glstate->light.lights[nl].position, tmp, 4*sizeof(GLfloat)); break; case GL_SPOT_DIRECTION: memcpy(tmp, params, 3*sizeof(GLfloat)); tmp[3] = 0.0f; vector_matrix(tmp, getMVMat(), tmp); - if(memcmp(glstate->light.lights[light].spotDirection, tmp, 4*sizeof(GLfloat))) + if(memcmp(glstate->light.lights[nl].spotDirection, tmp, 4*sizeof(GLfloat))==0) return; - memcpy(glstate->light.lights[light].spotDirection, tmp, 4*sizeof(GLfloat)); + memcpy(glstate->light.lights[nl].spotDirection, tmp, 4*sizeof(GLfloat)); break; case GL_SPOT_EXPONENT: if(params[0]<0 || params[0]>128) { errorShim(GL_INVALID_VALUE); return; } - if(glstate->light.lights[light].spotExponent == params[0]) + if(glstate->light.lights[nl].spotExponent == params[0]) return; - glstate->light.lights[light].spotExponent = params[0]; + glstate->light.lights[nl].spotExponent = params[0]; break; case GL_SPOT_CUTOFF: if(params[0]<0 || (params[0]>90 && params[0]!=180)) { errorShim(GL_INVALID_VALUE); return; } - if(glstate->light.lights[light].spotCutoff == params[0]) + if(glstate->light.lights[nl].spotCutoff == params[0]) return; - glstate->light.lights[light].spotCutoff = params[0]; + glstate->light.lights[nl].spotCutoff = params[0]; break; case GL_CONSTANT_ATTENUATION: if(params[0]<0) { errorShim(GL_INVALID_VALUE); return; } - if(glstate->light.lights[light].constantAttenuation == params[0]) + if(glstate->light.lights[nl].constantAttenuation == params[0]) return; - glstate->light.lights[light].constantAttenuation = params[0]; + glstate->light.lights[nl].constantAttenuation = params[0]; break; case GL_LINEAR_ATTENUATION: if(params[0]<0) { errorShim(GL_INVALID_VALUE); return; } - if(glstate->light.lights[light].linearAttenuation == params[0]) + if(glstate->light.lights[nl].linearAttenuation == params[0]) return; - glstate->light.lights[light].linearAttenuation = params[0]; + glstate->light.lights[nl].linearAttenuation = params[0]; break; case GL_QUADRATIC_ATTENUATION: if(params[0]<0) { errorShim(GL_INVALID_VALUE); return; } - if(glstate->light.lights[light].quadraticAttenuation == params[0]) + if(glstate->light.lights[nl].quadraticAttenuation == params[0]) return; - glstate->light.lights[light].quadraticAttenuation = params[0]; + glstate->light.lights[nl].quadraticAttenuation = params[0]; break; } LOAD_GLES(glLightfv); @@ -166,135 +173,143 @@ void gl4es_glLightf(GLenum light, GLenum pname, const GLfloat params) { } void gl4es_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - //TODO: Materialfv can be done per vertex, how to handle that ?! - //NewStage(glstate->list.active, STAGE_MATERIAL); - rlMaterialfv(glstate->list.active, face, pname, params); - noerrorShim(); - } else { - if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) { - errorShim(GL_INVALID_ENUM); - return; - } - switch(pname) { - case GL_AMBIENT: - if(face==GL_FRONT_AND_BACK || face==GL_FRONT) - memcpy(glstate->material.front.ambient, params, 4*sizeof(GLfloat)); - if(face==GL_FRONT_AND_BACK || face==GL_BACK) - memcpy(glstate->material.back.ambient, params, 4*sizeof(GLfloat)); - break; - case GL_DIFFUSE: - if(face==GL_FRONT_AND_BACK || face==GL_FRONT) - memcpy(glstate->material.front.diffuse, params, 4*sizeof(GLfloat)); - if(face==GL_FRONT_AND_BACK || face==GL_BACK) - memcpy(glstate->material.back.diffuse, params, 4*sizeof(GLfloat)); - break; - case GL_SPECULAR: - if(face==GL_FRONT_AND_BACK || face==GL_FRONT) - memcpy(glstate->material.front.specular, params, 4*sizeof(GLfloat)); - if(face==GL_FRONT_AND_BACK || face==GL_BACK) - memcpy(glstate->material.back.specular, params, 4*sizeof(GLfloat)); - break; - case GL_EMISSION: - if(face==GL_FRONT_AND_BACK || face==GL_FRONT) - memcpy(glstate->material.front.emission, params, 4*sizeof(GLfloat)); - if(face==GL_FRONT_AND_BACK || face==GL_BACK) - memcpy(glstate->material.back.emission, params, 4*sizeof(GLfloat)); - break; - case GL_AMBIENT_AND_DIFFUSE: - if(face==GL_FRONT_AND_BACK || face==GL_FRONT) { - memcpy(glstate->material.front.ambient, params, 4*sizeof(GLfloat)); - memcpy(glstate->material.front.diffuse, params, 4*sizeof(GLfloat)); - } - if(face==GL_FRONT_AND_BACK || face==GL_BACK) { - memcpy(glstate->material.back.ambient, params, 4*sizeof(GLfloat)); - memcpy(glstate->material.back.diffuse, params, 4*sizeof(GLfloat)); - } - break; - case GL_SHININESS: - if(face==GL_FRONT_AND_BACK || face==GL_FRONT) - glstate->material.front.shininess = *params; - if(face==GL_FRONT_AND_BACK || face==GL_BACK) - glstate->material.back.shininess = *params; - break; - case GL_COLOR_INDEXES: - if(face==GL_FRONT_AND_BACK || face==GL_FRONT) { - glstate->material.front.indexes[0] = params[0]; - glstate->material.front.indexes[1] = params[1]; - glstate->material.front.indexes[2] = params[2]; - } - if(face==GL_FRONT_AND_BACK || face==GL_BACK) { - glstate->material.back.indexes[0] = params[0]; - glstate->material.back.indexes[1] = params[1]; - glstate->material.back.indexes[2] = params[2]; - } - break; - - } - - LOAD_GLES(glMaterialfv); - if(face==GL_BACK) { // lets ignore GL_BACK in GLES 1.1 + ERROR_IN_BEGIN // that not true, but don't know how to handle it + if(glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + //TODO: Materialfv can be done per vertex, how to handle that ?! + //NewStage(glstate->list.active, STAGE_MATERIAL); + rlMaterialfv(glstate->list.active, face, pname, params); noerrorShim(); return; - } - gles_glMaterialfv(GL_FRONT_AND_BACK, pname, params); - errorGL(); + } else flush(); + + if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) { + errorShim(GL_INVALID_ENUM); + return; } + switch(pname) { + case GL_AMBIENT: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + memcpy(glstate->material.front.ambient, params, 4*sizeof(GLfloat)); + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + memcpy(glstate->material.back.ambient, params, 4*sizeof(GLfloat)); + break; + case GL_DIFFUSE: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + memcpy(glstate->material.front.diffuse, params, 4*sizeof(GLfloat)); + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + memcpy(glstate->material.back.diffuse, params, 4*sizeof(GLfloat)); + break; + case GL_SPECULAR: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + memcpy(glstate->material.front.specular, params, 4*sizeof(GLfloat)); + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + memcpy(glstate->material.back.specular, params, 4*sizeof(GLfloat)); + break; + case GL_EMISSION: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + memcpy(glstate->material.front.emission, params, 4*sizeof(GLfloat)); + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + memcpy(glstate->material.back.emission, params, 4*sizeof(GLfloat)); + break; + case GL_AMBIENT_AND_DIFFUSE: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) { + memcpy(glstate->material.front.ambient, params, 4*sizeof(GLfloat)); + memcpy(glstate->material.front.diffuse, params, 4*sizeof(GLfloat)); + } + if(face==GL_FRONT_AND_BACK || face==GL_BACK) { + memcpy(glstate->material.back.ambient, params, 4*sizeof(GLfloat)); + memcpy(glstate->material.back.diffuse, params, 4*sizeof(GLfloat)); + } + break; + case GL_SHININESS: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + glstate->material.front.shininess = *params; + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + glstate->material.back.shininess = *params; + break; + case GL_COLOR_INDEXES: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) { + glstate->material.front.indexes[0] = params[0]; + glstate->material.front.indexes[1] = params[1]; + glstate->material.front.indexes[2] = params[2]; + } + if(face==GL_FRONT_AND_BACK || face==GL_BACK) { + glstate->material.back.indexes[0] = params[0]; + glstate->material.back.indexes[1] = params[1]; + glstate->material.back.indexes[2] = params[2]; + } + break; + } + + if(face==GL_BACK) { // lets ignore GL_BACK in GLES 1.1 + noerrorShim(); + return; + } + LOAD_GLES(glMaterialfv); + gles_glMaterialfv(GL_FRONT_AND_BACK, pname, params); + errorGL(); } void gl4es_glMaterialf(GLenum face, GLenum pname, const GLfloat param) { - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - GLfloat params[4]; - memset(params, 0, 4*sizeof(GLfloat)); - params[0] = param; - NewStage(glstate->list.active, STAGE_MATERIAL); - rlMaterialfv(glstate->list.active, face, pname, params); - noerrorShim(); - } else { - if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) { - errorShim(GL_INVALID_ENUM); - return; - } - if(pname!=GL_SHININESS) { - errorShim(GL_INVALID_ENUM); - return; - } - if(face==GL_FRONT_AND_BACK || face==GL_FRONT) - glstate->material.front.shininess = param; - if(face==GL_FRONT_AND_BACK || face==GL_BACK) - glstate->material.back.shininess = param; - - LOAD_GLES(glMaterialf); - if(face==GL_BACK) { // lets ignore GL_BACK in GLES 1.1 + ERROR_IN_BEGIN + if(glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + GLfloat params[4]; + memset(params, 0, 4*sizeof(GLfloat)); + params[0] = param; + NewStage(glstate->list.active, STAGE_MATERIAL); + rlMaterialfv(glstate->list.active, face, pname, params); noerrorShim(); return; - } - gles_glMaterialf(GL_FRONT_AND_BACK, pname, param); - errorGL(); + } else flush(); + + if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) { + errorShim(GL_INVALID_ENUM); + return; } + if(pname!=GL_SHININESS) { + errorShim(GL_INVALID_ENUM); + return; + } + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + glstate->material.front.shininess = param; + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + glstate->material.back.shininess = param; + + LOAD_GLES(glMaterialf); + if(face==GL_BACK) { // lets ignore GL_BACK in GLES 1.1 + noerrorShim(); + return; + } + gles_glMaterialf(GL_FRONT_AND_BACK, pname, param); + errorGL(); } void gl4es_glColorMaterial(GLenum face, GLenum mode) { - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - NewStage(glstate->list.active, STAGE_COLOR_MATERIAL); - glstate->list.active->colormat_face = face; - glstate->list.active->colormat_mode = mode; - noerrorShim(); - } else { - if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) { - errorShim(GL_INVALID_ENUM); + ERROR_IN_BEGIN + if(glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_COLOR_MATERIAL); + glstate->list.active->colormat_face = face; + glstate->list.active->colormat_mode = mode; + noerrorShim(); return; - } - if(mode!=GL_EMISSION && mode!=GL_AMBIENT && mode!=GL_DIFFUSE && mode!=GL_SPECULAR && mode!=GL_AMBIENT_AND_DIFFUSE) { - errorShim(GL_INVALID_ENUM); - return; - } - if(face==GL_FRONT_AND_BACK || face==GL_FRONT) - glstate->material.front.colormat = mode; - if(face==GL_FRONT_AND_BACK || face==GL_BACK) - glstate->material.back.colormat = mode; - noerrorShim(); + } else flush(); + + if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) { + errorShim(GL_INVALID_ENUM); + return; } + if(mode!=GL_EMISSION && mode!=GL_AMBIENT && mode!=GL_DIFFUSE && mode!=GL_SPECULAR && mode!=GL_AMBIENT_AND_DIFFUSE) { + errorShim(GL_INVALID_ENUM); + return; + } + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + glstate->material.front.colormat = mode; + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + glstate->material.back.colormat = mode; + noerrorShim(); } void glLightModelf(GLenum pname, GLfloat param) AliasExport("gl4es_glLightModelf"); @@ -304,4 +319,3 @@ void glLightf(GLenum light, GLenum pname, const GLfloat params) AliasExport("gl4 void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) AliasExport("gl4es_glMaterialfv"); void glMaterialf(GLenum face, GLenum pname, const GLfloat param) AliasExport("gl4es_glMaterialf"); void glColorMaterial(GLenum face, GLenum mode) AliasExport("gl4es_glColorMaterial"); -#endif diff --git a/project/jni/gl4es/src/gl/line.c b/project/jni/gl4es/src/gl/line.c index 47a5a4ace..a6bc7c10a 100755 --- a/project/jni/gl4es/src/gl/line.c +++ b/project/jni/gl4es/src/gl/line.c @@ -6,6 +6,15 @@ GLubyte *stippleData = NULL; GLuint stippleTexture = 0; void gl4es_glLineStipple(GLuint factor, GLushort pattern) { + if(glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_LINESTIPPLE); + glstate->list.active->linestipple_op = 1; + glstate->list.active->linestipple_factor = factor; + glstate->list.active->linestipple_pattern = pattern; + return; + } else if(glstate->list.pending) flush(); + stippleFactor = factor; stipplePattern = pattern; if (stippleData != NULL) { diff --git a/project/jni/gl4es/src/gl/list.c b/project/jni/gl4es/src/gl/list.c index 37553a737..00e4d15ce 100755 --- a/project/jni/gl4es/src/gl/list.c +++ b/project/jni/gl4es/src/gl/list.c @@ -103,6 +103,8 @@ bool islistscompatible_renderlist(renderlist_t *a, renderlist_t *b) { if (a_mode != b_mode) return false; } + if(!a->open || !b->open) + return false; /* if ((a->indices==NULL) != (b->indices==NULL)) return false;*/ if (a->polygon_mode != b->polygon_mode) @@ -126,6 +128,8 @@ bool islistscompatible_renderlist(renderlist_t *a, renderlist_t *b) { // polygon mode if(a->polygon_mode!=b->polygon_mode) return false; + if(a->post_color || b->post_color || a->post_normal || b->post_normal) + return false; // Check the size of a list, if it"s too big, don't merge... if ((a->len+b->len)>30000) @@ -684,7 +688,7 @@ void adjust_renderlist(renderlist_t *list) { list->open = false; for (int a=0; aenable.texture[a]); - gltexture_t *bound = glstate->texture.bound[a][itarget]; + gltexture_t *bound = (itarget>=0)?glstate->texture.bound[a][itarget]:NULL; // in case of Texture bounding inside a list if (list->set_texture && (list->tmu == a)) bound = gl4es_getTexture(list->target_texture, list->texture); @@ -727,6 +731,29 @@ renderlist_t* end_renderlist(renderlist_t *list) { return list; } +renderlist_t* recycle_renderlist(renderlist_t *list) { + if(isempty_renderlist(list)) { + renderlist_t* old=list; + list = list->prev; + old->prev = NULL; + list->next = NULL; + free_renderlist(old); + } + // check if pending color... + if (list->post_color) { + list->post_color = 0; + rlColor4f(list, list->post_colors[0], list->post_colors[1], list->post_colors[2], list->post_colors[3]); + } + if (list->post_normal) { + list->post_normal = 0; + rlNormal3f(list, list->post_normals[0], list->post_normals[1], list->post_normals[2]); + } + // All done + list->stage=STAGE_DRAW; + + return list; +} + void draw_renderlist(renderlist_t *list) { if (!list) return; // go to 1st... @@ -767,13 +794,17 @@ void draw_renderlist(renderlist_t *list) { glPackedCall(cl->calls[i]); } } - if (list->fog_op) { - switch (list->fog_op) { - case 1: // GL_FOG_COLOR - gl4es_glFogfv(GL_FOG_COLOR, list->fog_val); - break; + if(list->render_op) { + switch(list->render_op) { + case 1: gl4es_glInitNames(); break; + case 2: gl4es_glPopName(); break; + case 3: gl4es_glPushName(list->render_arg); break; + case 4: gl4es_glLoadName(list->render_arg); break; } } + if (list->fog_op) { + gl4es_glFogfv(GL_FOG_COLOR, list->fog_val); + } if (list->pointparam_op) { switch (list->pointparam_op) { case 1: // GL_POINT_DISTANCE_ATTENUATION @@ -845,6 +876,10 @@ void draw_renderlist(renderlist_t *list) { if (list->lightmodel) { gl4es_glLightModelfv(list->lightmodelparam, list->lightmodel); } + + if (list->linestipple_op) { + gl4es_glLineStipple(list->linestipple_factor, list->linestipple_pattern); + } if (list->texenv) { khash_t(texenv) *tgn = list->texenv; @@ -1207,6 +1242,8 @@ void draw_renderlist(renderlist_t *list) { gl4es_glPopAttrib(); } #endif + if(list->post_color) gl4es_glColor4fv(list->post_colors); + if(list->post_normal) gl4es_glNormal3fv(list->post_normals); } while ((list = list->next)); gl4es_glPopClientAttrib(); } @@ -1386,21 +1423,6 @@ void rlTexGenfv(renderlist_t *list, GLenum coord, GLenum pname, const GLfloat * memcpy(m->color, params, 4*sizeof(GLfloat)); } -void rlTexCoord4f(renderlist_t *list, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { - if (list->tex[0] == NULL) { - list->tex[0] = alloc_sublist(4, list->cap); - // catch up - GLfloat *tex = list->tex[0]; - if (list->len) for (int i = 0; i < list->len; i++) { - memcpy(tex, glstate->texcoord[0], sizeof(GLfloat) * 4); - tex += 4; - } - } - GLfloat *tex = glstate->texcoord[0]; - tex[0] = s; tex[1] = t; - tex[2] = r; tex[3] = q; -} - void rlMultiTexCoord4f(renderlist_t *list, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { const int tmu = target - GL_TEXTURE0; if (list->tex[tmu] == NULL) { @@ -1436,11 +1458,13 @@ void rlRasterOp(renderlist_t *list, int op, GLfloat x, GLfloat y, GLfloat z) { } void rlFogOp(renderlist_t *list, int op, const GLfloat* v) { + int n = 1; + if (op==GL_FOG_COLOR) n = 4; list->fog_op = op; list->fog_val[0] = v[0]; - list->fog_val[1] = v[1]; - list->fog_val[2] = v[2]; - list->fog_val[3] = v[3]; + if (n>1) list->fog_val[1] = v[1]; + if (n>2) list->fog_val[2] = v[2]; + if (n>3) list->fog_val[3] = v[3]; } void rlPointParamOp(renderlist_t *list, int op, const GLfloat* v) { diff --git a/project/jni/gl4es/src/gl/list.h b/project/jni/gl4es/src/gl/list.h index ddfdc8318..ead2930cd 100755 --- a/project/jni/gl4es/src/gl/list.h +++ b/project/jni/gl4es/src/gl/list.h @@ -9,6 +9,7 @@ typedef enum { STAGE_POP, STAGE_CALLLIST, STAGE_GLCALL, + STAGE_RENDER, STAGE_FOG, STAGE_POINTPARAM, STAGE_MATRIX, @@ -19,19 +20,22 @@ typedef enum { STAGE_COLOR_MATERIAL, STAGE_LIGHT, STAGE_LIGHTMODEL, + STAGE_LINESTIPPLE, STAGE_TEXENV, STAGE_TEXGEN, STAGE_POLYGON, STAGE_DRAW, + STAGE_POSTDRAW, STAGE_LAST } liststage_t; -static int StageExclusive[STAGE_LAST] = { +static int StageExclusive[] = { 0, // STAGE_NONE 1, // STAGE_PUSH 1, // STAGE_POP 1, // STAGE_CALLLIST 0, // STAGE_GLCALL + 1, // STAGE_RENDER 1, // STAGE_FOG 1, // STAGE_POINTPARAM 1, // STAGE_MATRIX @@ -42,10 +46,13 @@ static int StageExclusive[STAGE_LAST] = { 1, // STAGE_COLOR_MATERIAL 0, // STAGE_LIGHT 1, // STAGE_LIGTMODEL + 1, // STAGE_LINESTIPPLE 0, // STAGE_TEXENV 0, // STAGE_TEXGEN 1, // STAGE_POLYGON - 1 // STAGE_DRAW + 1, // STAGE_DRAW + 1, // STAGE_POSTDRAW (used for "pending", i.e. post glEnd(), in case a similar glBegin occurs) + 0 // STAGE_LAST }; typedef struct { @@ -133,6 +140,9 @@ typedef struct _renderlist_t { GLbitfield pushattribute; GLboolean popattribute; + int render_op; + GLuint render_arg; + int raster_op; GLfloat raster_xyz[3]; @@ -144,6 +154,14 @@ typedef struct _renderlist_t { int pointparam_op; GLfloat pointparam_val[4]; + + int linestipple_op; + GLuint linestipple_factor, linestipple_pattern; + + int post_color; + GLfloat post_colors[4]; + int post_normal; + GLfloat post_normals[3]; khash_t(material) *material; GLenum colormat_face; @@ -167,6 +185,13 @@ typedef struct _renderlist_t { #define DEFAULT_CALL_LIST_CAPACITY 20 #define DEFAULT_RENDER_LIST_CAPACITY 64 +renderlist_t* recycle_renderlist(renderlist_t* list); +#define NewDrawStage(l, m) if(globals4es.mergelist \ + && ((l->prev && isempty_renderlist(l) && l->prev->open && l->prev->mode==mode && l->prev->mode_init==mode) \ + || (l->stage==STAGE_POSTDRAW && l->open && l->mode==mode && l->mode_init==mode)) && \ + mode!=GL_POLYGON && mode!=GL_LINE_STRIP && mode!=GL_LINE_LOOP && \ + mode!=GL_TRIANGLE_FAN && mode!=GL_TRIANGLE_STRIP && mode!=GL_QUAD_STRIP) \ + l=recycle_renderlist(l); else NewStage(l, STAGE_DRAW) #define NewStage(l, s) if (l->stage+StageExclusive[l->stage] > s) {l = extend_renderlist(l);} l->stage = s renderlist_t* GetFirst(renderlist_t* list); @@ -176,6 +201,7 @@ renderlist_t *extend_renderlist(renderlist_t *list); void free_renderlist(renderlist_t *list); void draw_renderlist(renderlist_t *list); renderlist_t* end_renderlist(renderlist_t *list); +bool isempty_renderlist(renderlist_t *list); void rlActiveTexture(renderlist_t *list, GLenum texture ); void rlBindTexture(renderlist_t *list, GLenum target, GLuint texture); @@ -187,7 +213,6 @@ void rlTexEnvfv(renderlist_t *list, GLenum target, GLenum pname, const GLfloat * void rlTexEnviv(renderlist_t *list, GLenum target, GLenum pname, const GLint * params); void rlNormal3f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z) FASTMATH; void rlPushCall(renderlist_t *list, packed_call_t *data); -void rlTexCoord4f(renderlist_t *list, GLfloat s, GLfloat t, GLfloat r, GLfloat q) FASTMATH; void rlMultiTexCoord4f(renderlist_t *list, GLenum texture, GLfloat s, GLfloat t, GLfloat r, GLfloat q) FASTMATH; void rlVertex4f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z, GLfloat w) FASTMATH; void rlSecondary3f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b) FASTMATH; diff --git a/project/jni/gl4es/src/gl/loader.c b/project/jni/gl4es/src/gl/loader.c index ab28abea7..738ed442b 100755 --- a/project/jni/gl4es/src/gl/loader.c +++ b/project/jni/gl4es/src/gl/loader.c @@ -1,5 +1,6 @@ #include "loader.h" #include "logs.h" +#include "init.h" #include void *gles = NULL, *egl = NULL, *bcm_host = NULL, *vcos = NULL; @@ -48,7 +49,7 @@ void *open_lib(const char **names, const char *override) { if (override) { if ((lib = dlopen(override, flags))) { strncpy(path_name, override, PATH_MAX); - LOGD("LIBGL:loaded: %s\n", path_name); + if(!globals4es.nobanner) LOGD("LIBGL:loaded: %s\n", path_name); return lib; } else { LOGE("LIBGL_GLES override failed: %s\n", dlerror()); @@ -59,7 +60,7 @@ void *open_lib(const char **names, const char *override) { for (int e = 0; lib_ext[e]; e++) { snprintf(path_name, PATH_MAX, "%s%s.%s", path_prefix[p], names[i], lib_ext[e]); if ((lib = dlopen(path_name, flags))) { - LOGD("LIBGL:loaded: %s\n", path_name); + if(!globals4es.nobanner) LOGD("LIBGL:loaded: %s\n", path_name); return lib; } } diff --git a/project/jni/gl4es/src/gl/matrix.c b/project/jni/gl4es/src/gl/matrix.c index 10eaa7319..8ef889d5f 100755 --- a/project/jni/gl4es/src/gl/matrix.c +++ b/project/jni/gl4es/src/gl/matrix.c @@ -154,11 +154,14 @@ DBG(printf("glLoadMatrix(%f, %f, %f, %f, %f, %f, %f...), list=%p\n", m[0], m[1], LOAD_GLES(glLoadMatrixf); LOAD_GLES(glLoadIdentity); - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - NewStage(glstate->list.active, STAGE_MATRIX); - glstate->list.active->matrix_op = 1; - memcpy(glstate->list.active->matrix_val, m, 16*sizeof(GLfloat)); - return; + if (glstate->list.active) { + if(glstate->list.pending) flush(); + else { + NewStage(glstate->list.active, STAGE_MATRIX); + glstate->list.active->matrix_op = 1; + memcpy(glstate->list.active->matrix_val, m, 16*sizeof(GLfloat)); + return; + } } memcpy(update_current_mat(), m, 16*sizeof(GLfloat)); const int id = update_current_identity(0); @@ -171,17 +174,20 @@ void gl4es_glMultMatrixf(const GLfloat * m) { DBG(printf("glMultMatrix(%f, %f, %f, %f, %f, %f, %f...), list=%p\n", m[0], m[1], m[2], m[3], m[4], m[5], m[6], glstate->list.active);) LOAD_GLES(glLoadMatrixf); LOAD_GLES(glLoadIdentity); - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - if(glstate->list.active->stage == STAGE_MATRIX) { - // multiply the matrix mith the current one.... - matrix_mul(glstate->list.active->matrix_val, m, glstate->list.active->matrix_val); + if (glstate->list.active) { + if(glstate->list.pending) flush(); + else { + if(glstate->list.active->stage == STAGE_MATRIX) { + // multiply the matrix mith the current one.... + matrix_mul(glstate->list.active->matrix_val, m, glstate->list.active->matrix_val); + return; + } + NewStage(glstate->list.active, STAGE_MATRIX); + glstate->list.active->matrix_op = 2; + memcpy(glstate->list.active->matrix_val, m, 16*sizeof(GLfloat)); return; } - NewStage(glstate->list.active, STAGE_MATRIX); - glstate->list.active->matrix_op = 2; - memcpy(glstate->list.active->matrix_val, m, 16*sizeof(GLfloat)); - return; - } + } GLfloat *current_mat = update_current_mat(); matrix_mul(current_mat, m, current_mat); const int id = update_current_identity(0); @@ -193,13 +199,15 @@ DBG(printf("glMultMatrix(%f, %f, %f, %f, %f, %f, %f...), list=%p\n", m[0], m[1], void gl4es_glLoadIdentity() { DBG(printf("glLoadIdentity(), list=%p\n", glstate->list.active);) LOAD_GLES(glLoadIdentity); - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - NewStage(glstate->list.active, STAGE_MATRIX); - glstate->list.active->matrix_op = 1; - set_identity(glstate->list.active->matrix_val); - return; - } - + if (glstate->list.active) { + if(glstate->list.pending) flush(); + else { + NewStage(glstate->list.active, STAGE_MATRIX); + glstate->list.active->matrix_op = 1; + set_identity(glstate->list.active->matrix_val); + return; + } + } set_identity(update_current_mat()); update_current_identity(1); if(send_to_hardware()) gles_glLoadIdentity(); diff --git a/project/jni/gl4es/src/gl/matvec.c b/project/jni/gl4es/src/gl/matvec.c index be3b9efc0..dda872204 100755 --- a/project/jni/gl4es/src/gl/matvec.c +++ b/project/jni/gl4es/src/gl/matvec.c @@ -82,9 +82,9 @@ void vector3_matrix(const float *a, const float *b, float *c) { const float* b4=b+12; asm volatile ( //"vld1.f32 {q0}, [%1] \n" // %q0 = a(0..2) - "vld1.32 {d4}, [%1] \n" - "flds s10, [%1, #8] \n" - "vsub.f32 s11, s11, s11 \n" + "vld1.32 {d0}, [%1] \n" + "flds s2, [%1, #8] \n" + "vsub.f32 s3, s3, s3 \n" "vld1.f32 {q1}, [%2] \n" // %q1 = b(0..3) "vmul.f32 q1, q1, d0[0] \n" // %q1 = b(0..3)*a[0] "vld1.f32 {q2}, [%3] \n" // %q2 = b(4..7) diff --git a/project/jni/gl4es/src/gl/queries.c b/project/jni/gl4es/src/gl/queries.c index bd59dc499..b23478220 100755 --- a/project/jni/gl4es/src/gl/queries.c +++ b/project/jni/gl4es/src/gl/queries.c @@ -4,6 +4,8 @@ static GLuint lastquery = 0; static glquery_t *active_samples_passed = 0; void gl4es_glGenQueries(GLsizei n, GLuint * ids) { + if (glstate->gl_batch || glstate->list.pending) + flush(); noerrorShim(); if (n<1) { errorShim(GL_INVALID_VALUE); @@ -15,6 +17,8 @@ void gl4es_glGenQueries(GLsizei n, GLuint * ids) { } GLboolean gl4es_glIsQuery(GLuint id) { + if(glstate->list.compiling) {errorShim(GL_INVALID_OPERATION); return GL_FALSE;} + if(glstate->list.active) flush(); khash_t(queries) *list = glstate->queries; khint_t k; noerrorShim(); @@ -28,6 +32,8 @@ GLboolean gl4es_glIsQuery(GLuint id) { } void gl4es_glDeleteQueries(GLsizei n, const GLuint* ids) { + if (glstate->gl_batch || glstate->list.pending) + flush(); khash_t(queries) *list = glstate->queries; if (list) { khint_t k; @@ -54,9 +60,9 @@ void gl4es_glBeginQuery(GLenum target, GLuint id) { errorShim(GL_INVALID_ENUM); return; } - if (glstate->gl_batch) { - flush(); - } + if (glstate->gl_batch || glstate->list.pending) + flush(); + khint_t k; int ret; glquery_t *query; @@ -89,9 +95,9 @@ void gl4es_glEndQuery(GLenum target) { errorShim(GL_INVALID_OPERATION); return; } - if (glstate->gl_batch) { - flush(); - } + if (glstate->gl_batch || glstate->list.pending) + flush(); + active_samples_passed = NULL; noerrorShim(); } @@ -101,6 +107,9 @@ void gl4es_glGetQueryiv(GLenum target, GLenum pname, GLint* params) { errorShim(GL_INVALID_ENUM); return; } + if (glstate->gl_batch || glstate->list.pending) + flush(); + noerrorShim(); switch (pname) { case GL_CURRENT_QUERY: @@ -117,6 +126,9 @@ void gl4es_glGetQueryiv(GLenum target, GLenum pname, GLint* params) { void gl4es_glGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) { khint_t k; int ret; + if (glstate->gl_batch || glstate->list.pending) + flush(); + glquery_t *query = NULL; khash_t(queries) *list = glstate->queries; if (! list) { @@ -150,6 +162,9 @@ void gl4es_glGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) { void gl4es_glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) { khint_t k; int ret; + if (glstate->gl_batch || glstate->list.pending) + flush(); + glquery_t *query = NULL; khash_t(queries) *list = glstate->queries; if (! list) { diff --git a/project/jni/gl4es/src/gl/raster.c b/project/jni/gl4es/src/gl/raster.c index 01fcf5573..99dd80c70 100755 --- a/project/jni/gl4es/src/gl/raster.c +++ b/project/jni/gl4es/src/gl/raster.c @@ -17,12 +17,14 @@ void matrix_transpose(const GLfloat *a, GLfloat *b); void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c); void gl4es_glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - NewStage(glstate->list.active, STAGE_RASTER); - rlRasterOp(glstate->list.active, 1, x, y, z); - noerrorShim(); - return; - } + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_RASTER); + rlRasterOp(glstate->list.active, 1, x, y, z); + noerrorShim(); + return; + } else flush(); + // Transform xyz coordinates with current modelview and projection matrix... GLfloat glmatrix[16], projection[16], modelview[16]; GLfloat t[4], transl[4] = {x, y, z, 1.0f}; @@ -41,12 +43,14 @@ void gl4es_glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { } void gl4es_glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) { - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - NewStage(glstate->list.active, STAGE_RASTER); - rlRasterOp(glstate->list.active, 2, x, y, z); - noerrorShim(); - return; - } + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_RASTER); + rlRasterOp(glstate->list.active, 2, x, y, z); + noerrorShim(); + return; + } else flush(); + glstate->raster.rPos.x = x; glstate->raster.rPos.y = y; glstate->raster.rPos.z = z; @@ -76,24 +80,28 @@ void popViewport() { void gl4es_glPixelZoom(GLfloat xfactor, GLfloat yfactor) { - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - NewStage(glstate->list.active, STAGE_RASTER); - rlRasterOp(glstate->list.active, 3, xfactor, yfactor, 0.0f); - noerrorShim(); - return; - } + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_RASTER); + rlRasterOp(glstate->list.active, 3, xfactor, yfactor, 0.0f); + noerrorShim(); + return; + } else flush(); + glstate->raster.raster_zoomx = xfactor; glstate->raster.raster_zoomy = yfactor; //printf("LIBGL: glPixelZoom(%f, %f)\n", xfactor, yfactor); } void gl4es_glPixelTransferf(GLenum pname, GLfloat param) { - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - NewStage(glstate->list.active, STAGE_RASTER); - rlRasterOp(glstate->list.active, pname|0x10000, param, 0.0f, 0.0f); - noerrorShim(); - return; - } + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_RASTER); + rlRasterOp(glstate->list.active, pname|0x10000, param, 0.0f, 0.0f); + noerrorShim(); + return; + } else flush(); + //printf("LIBGL: glPixelTransferf(%04x, %f)\n", pname, param); switch(pname) { case GL_RED_SCALE: @@ -229,7 +237,7 @@ void gl4es_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, // TODO: negative width/height mirrors bitmap? noerrorShim(); if ((!width && !height) || (bitmap==0)) { - if (glstate->list.compiling || glstate->gl_batch) { + if (glstate->list.active) { if (glstate->list.active->raster) glstate->list.active = extend_renderlist(glstate->list.active); // already a raster in the list, create a new one rasterlist_t *r = glstate->list.active->raster = (rasterlist_t*)malloc(sizeof(rasterlist_t)); @@ -288,7 +296,7 @@ void gl4es_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, rasterlist_t rast; rasterlist_t *r; - if (glstate->list.compiling || glstate->gl_batch) { + if (glstate->list.active) { NewStage(glstate->list.active, STAGE_RASTER); r = glstate->list.active->raster = (rasterlist_t*)malloc(sizeof(rasterlist_t)); r->shared = (int*)malloc(sizeof(int)); @@ -307,7 +315,7 @@ void gl4es_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, r->zoomx = glstate->raster.raster_zoomx; r->zoomy = glstate->raster.raster_zoomy; LOAD_GLES(glDeleteTextures); - if (!(glstate->list.compiling || glstate->gl_batch)) { + if (!(glstate->list.active)) { render_raster_list(r); gles_glDeleteTextures(1, &r->texture); r->texture = 0; @@ -371,7 +379,7 @@ void gl4es_glDrawPixels(GLsizei width, GLsizei height, GLenum format, static rasterlist_t rast = {.texture=0, .shared=NULL}; rasterlist_t *r; - if (glstate->list.compiling || globals4es.batch) { + if (glstate->list.active) { NewStage(glstate->list.active, STAGE_RASTER); rasterlist_t *r = glstate->list.active->raster = (rasterlist_t*)malloc(sizeof(rasterlist_t)); r->shared = (int*)malloc(sizeof(int)); @@ -391,7 +399,7 @@ void gl4es_glDrawPixels(GLsizei width, GLsizei height, GLenum format, r->bitmap = false; r->zoomx = glstate->raster.raster_zoomx; r->zoomy = glstate->raster.raster_zoomy; - if (!(glstate->list.compiling || glstate->gl_batch)) { + if (!(glstate->list.active)) { render_raster_list(r); /* gles_glDeleteTextures(1, &r->texture); r->texture = 0;*/ diff --git a/project/jni/gl4es/src/gl/render.c b/project/jni/gl4es/src/gl/render.c index 2c960087d..2ab7a114b 100755 --- a/project/jni/gl4es/src/gl/render.c +++ b/project/jni/gl4es/src/gl/render.c @@ -37,6 +37,9 @@ void push_hit() { GLint gl4es_glRenderMode(GLenum mode) { + if(glstate->list.compiling) {errorShim(GL_INVALID_OPERATION); return 0;} + if(glstate->list.active) flush(); + int ret = 0; if ((mode==GL_SELECT) || (mode==GL_RENDER)) { // missing GL_FEEDBACK noerrorShim(); @@ -77,6 +80,12 @@ GLint gl4es_glRenderMode(GLenum mode) { } void gl4es_glInitNames() { + if(glstate->list.active) { + NewStage(glstate->list.active, STAGE_RENDER); + glstate->list.active->render_op = 1; + return; + } + //TODO list stuffs if (glstate->namestack.names == 0) { glstate->namestack.names = (GLuint*)malloc(1024*sizeof(GLuint)); } @@ -85,6 +94,11 @@ void gl4es_glInitNames() { } void gl4es_glPopName() { + if(glstate->list.active) { + NewStage(glstate->list.active, STAGE_RENDER); + glstate->list.active->render_op = 2; + return; + } noerrorShim(); if (glstate->render_mode != GL_SELECT) return; @@ -96,6 +110,12 @@ void gl4es_glPopName() { } void gl4es_glPushName(GLuint name) { + if(glstate->list.active) { + NewStage(glstate->list.active, STAGE_RENDER); + glstate->list.active->render_op = 3; + glstate->list.active->render_arg = name; + return; + } noerrorShim(); if (glstate->render_mode != GL_SELECT) return; @@ -108,6 +128,12 @@ void gl4es_glPushName(GLuint name) { } void gl4es_glLoadName(GLuint name) { + if(glstate->list.active) { + NewStage(glstate->list.active, STAGE_RENDER); + glstate->list.active->render_op = 4; + glstate->list.active->render_arg = name; + return; + } noerrorShim(); if (glstate->render_mode != GL_SELECT) return; @@ -120,6 +146,9 @@ void gl4es_glLoadName(GLuint name) { } void gl4es_glSelectBuffer(GLsizei size, GLuint *buffer) { + if (glstate->gl_batch || glstate->list.pending) + flush(); + noerrorShim(); glstate->selectbuf.buffer = buffer; glstate->selectbuf.size = size; diff --git a/project/jni/gl4es/src/gl/stack.c b/project/jni/gl4es/src/gl/stack.c index 76bc7c8d3..5c66a62e8 100755 --- a/project/jni/gl4es/src/gl/stack.c +++ b/project/jni/gl4es/src/gl/stack.c @@ -5,11 +5,13 @@ void gl4es_glPushAttrib(GLbitfield mask) { //printf("glPushAttrib(0x%04X)\n", mask); noerrorShim(); - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - NewStage(glstate->list.active, STAGE_PUSH); - glstate->list.active->pushattribute = mask; - return; - } + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_PUSH); + glstate->list.active->pushattribute = mask; + return; + } else flush(); + if (glstate->stack == NULL) { glstate->stack = (glstack_t *)malloc(STACK_SIZE * sizeof(glstack_t)); glstate->stack->len = 0; @@ -281,7 +283,7 @@ void gl4es_glPushAttrib(GLbitfield mask) { void gl4es_glPushClientAttrib(GLbitfield mask) { noerrorShim(); GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; } @@ -339,11 +341,13 @@ void gl4es_glPushClientAttrib(GLbitfield mask) { void gl4es_glPopAttrib() { //printf("glPopAttrib()\n"); noerrorShim(); - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - NewStage(glstate->list.active, STAGE_POP); - glstate->list.active->popattribute = true; - return; - } + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_POP); + glstate->list.active->popattribute = true; + return; + } else flush(); + if (glstate->stack == NULL || glstate->stack->len == 0) { errorShim(GL_STACK_UNDERFLOW); return; @@ -620,7 +624,7 @@ void gl4es_glPopAttrib() { void gl4es_glPopClientAttrib() { noerrorShim(); GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; } diff --git a/project/jni/gl4es/src/gl/state.h b/project/jni/gl4es/src/gl/state.h index 9eed4e6a9..9c3a638dd 100755 --- a/project/jni/gl4es/src/gl/state.h +++ b/project/jni/gl4es/src/gl/state.h @@ -62,6 +62,8 @@ typedef struct { typedef struct { renderlist_t *active; GLboolean compiling; + GLboolean pending; + GLboolean begin; GLboolean locked; GLuint base; GLuint name; diff --git a/project/jni/gl4es/src/gl/texgen.c b/project/jni/gl4es/src/gl/texgen.c index d71ca7670..691145517 100755 --- a/project/jni/gl4es/src/gl/texgen.c +++ b/project/jni/gl4es/src/gl/texgen.c @@ -23,12 +23,14 @@ void gl4es_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { */ //printf("glTexGenf(%s, %s, %s/%f), texture=%i\n", PrintEnum(coord), PrintEnum(pname), PrintEnum(param[0]), param[0], glstate->texture.active); - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - NewStage(glstate->list.active, STAGE_TEXGEN); - rlTexGenfv(glstate->list.active, coord, pname, param); - noerrorShim(); - return; - } + ERROR_IN_BEGIN + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_TEXGEN); + rlTexGenfv(glstate->list.active, coord, pname, param); + noerrorShim(); + return; + } else flush(); // pname is in: GL_TEXTURE_GEN_MODE, GL_OBJECT_PLANE, GL_EYE_PLANE noerrorShim(); @@ -84,7 +86,8 @@ void gl4es_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { } } void gl4es_glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) { - if (glstate->gl_batch) flush(); + if (glstate->gl_batch || glstate->list.pending) + flush(); noerrorShim(); switch(pname) { case GL_TEXTURE_GEN_MODE: @@ -224,7 +227,26 @@ void eye_loop(const GLfloat *verts, const GLfloat *param, GLfloat *out, GLint co matrix_vector(ModelviewMatrix, verts+k*4, tmp); out[k*4]=dot4(plane, tmp); } +} +void eye_loop_dual(const GLfloat *verts, const GLfloat *param1, const GLfloat* param2, GLfloat *out, GLint count, GLushort *indices) { + // based on https://www.opengl.org/wiki/Mathematics_of_glTexGen + // First get the ModelviewMatrix + GLfloat ModelviewMatrix[16], InvModelview[16]; + glGetFloatv(GL_MODELVIEW_MATRIX, InvModelview); + // column major -> row major + matrix_transpose(InvModelview, ModelviewMatrix); + // And get the inverse + matrix_inverse(ModelviewMatrix, InvModelview); + GLfloat plane1[4], plane2[4], tmp[4]; + vector_matrix(param1, InvModelview, plane1); + vector_matrix(param2, InvModelview, plane2); + for (int i=0; ienable.texgen_s[texture]) - tex_coord_loop(verts, norm, (*coords), (indices)?ilen:count, glstate->texgen[texture].S, glstate->texgen[texture].S_O, glstate->texgen[texture].S_E, indices); - if (glstate->enable.texgen_t[texture]) - tex_coord_loop(verts, norm, (*coords)+1, (indices)?ilen:count, glstate->texgen[texture].T, glstate->texgen[texture].T_O, glstate->texgen[texture].T_E, indices); + if ( (glstate->enable.texgen_s[texture] && glstate->texgen[texture].S==GL_EYE_LINEAR) + && (glstate->enable.texgen_t[texture] && glstate->texgen[texture].T==GL_EYE_LINEAR) ) + { + eye_loop_dual(verts, glstate->texgen[texture].S_E, glstate->texgen[texture].T_E, (*coords), (indices)?ilen:count, indices); + } else { + if (glstate->enable.texgen_s[texture]) + tex_coord_loop(verts, norm, (*coords), (indices)?ilen:count, glstate->texgen[texture].S, glstate->texgen[texture].S_O, glstate->texgen[texture].S_E, indices); + if (glstate->enable.texgen_t[texture]) + tex_coord_loop(verts, norm, (*coords)+1, (indices)?ilen:count, glstate->texgen[texture].T, glstate->texgen[texture].T_O, glstate->texgen[texture].T_E, indices); + } if (glstate->enable.texgen_r[texture]) tex_coord_loop(verts, norm, (*coords)+2, (indices)?ilen:count, glstate->texgen[texture].R, glstate->texgen[texture].R_O, glstate->texgen[texture].R_E, indices); else diff --git a/project/jni/gl4es/src/gl/texture.c b/project/jni/gl4es/src/gl/texture.c index e3806b486..30802f8bc 100755 --- a/project/jni/gl4es/src/gl/texture.c +++ b/project/jni/gl4es/src/gl/texture.c @@ -167,6 +167,10 @@ void internal2format_type(GLenum internalformat, GLenum *format, GLenum *type) *format = GL_RGBA; *type = GL_UNSIGNED_BYTE; break; + case GL_BGRA: + *format = GL_BGRA; + *type = GL_UNSIGNED_BYTE; + break; case GL_DEPTH_COMPONENT: *format = GL_DEPTH_COMPONENT; *type = GL_UNSIGNED_SHORT; @@ -229,6 +233,12 @@ static void *swizzle_texture(GLsizei width, GLsizei height, dest_format = GL_RGBA; *format = GL_RGBA; break; + case GL_BGRA: + if(hardext.bgra8888 && ((*type)==GL_UNSIGNED_BYTE)) { + dest_format = GL_BGRA; + *format = GL_BGRA; + } else convert = true; + break; default: convert = true; break; @@ -336,7 +346,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height, return (void *)data; } -GLenum swizzle_internalformat(GLenum *internalformat) { +GLenum swizzle_internalformat(GLenum *internalformat, GLenum format) { GLenum ret = *internalformat; GLenum sret; switch(*internalformat) { @@ -372,13 +382,16 @@ GLenum swizzle_internalformat(GLenum *internalformat) { break; case GL_RGBA: case GL_RGBA8: - case GL_BGRA: case GL_RGBA16: case GL_RGBA16F: case GL_RGBA32F: case GL_RGB10_A2: case 4: - ret = GL_RGBA; sret = GL_RGBA; + if(format==GL_BGRA && hardext.bgra8888) { + ret = GL_BGRA; sret = GL_BGRA; + } else { + ret = GL_RGBA; sret = GL_RGBA; + } break; case GL_ALPHA8: case GL_ALPHA: @@ -431,6 +444,15 @@ GLenum swizzle_internalformat(GLenum *internalformat) { ret = GL_COMPRESSED_RGBA; sret = GL_RGBA; break; + case GL_BGRA: + if(hardext.bgra8888) { + ret = GL_BGRA; + sret = GL_BGRA; + } else { + ret = GL_RGBA; + sret = GL_RGBA; + } + break; default: ret = GL_RGBA; sret = GL_RGBA; @@ -531,7 +553,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *data) { - //printf("glTexImage2D on target=%s with unpack_row_length(%i), size(%i,%i) and skip(%i,%i), format(internal)=%s(%s), type=%s, data=%08x, level=%i (mipmap_need=%i, mipmap_auto=%i) => texture=%u (streamed=%i), glstate->list.compiling=%d\n", PrintEnum(target), glstate->texture.unpack_row_length, width, height, glstate->texture.unpack_skip_pixels, glstate->texture.unpack_skip_rows, PrintEnum(format), PrintEnum(internalformat), PrintEnum(type), data, level, (glstate->texture.bound[glstate->texture.active][what_target(target)])?glstate->texture.bound[glstate->texture.active][what_target(target)]->mipmap_need:0, (glstate->texture.bound[glstate->texture.active][what_target(target)])?glstate->texture.bound[glstate->texture.active][what_target(target)]->mipmap_auto:0, (glstate->texture.bound[glstate->texture.active][what_target(target)])?glstate->texture.bound[glstate->texture.active][what_target(target)]->texture:0, (glstate->texture.bound[glstate->texture.active][what_target(target)])?glstate->texture.bound[glstate->texture.active][what_target(target)]->streamed:0, glstate->list.compiling); + //printf("glTexImage2D on target=%s with unpack_row_length(%i), size(%i,%i) and skip(%i,%i), format(internal)=%s(%s), type=%s, data=%08x, level=%i (mipmap_need=%i, mipmap_auto=%i, base_level=%i, max_level=%i) => texture=%u (streamed=%i), glstate->list.compiling=%d\n", PrintEnum(target), glstate->texture.unpack_row_length, width, height, glstate->texture.unpack_skip_pixels, glstate->texture.unpack_skip_rows, PrintEnum(format), PrintEnum(internalformat), PrintEnum(type), data, level, (glstate->texture.bound[glstate->texture.active][what_target(target)])?glstate->texture.bound[glstate->texture.active][what_target(target)]->mipmap_need:0, (glstate->texture.bound[glstate->texture.active][what_target(target)])?glstate->texture.bound[glstate->texture.active][what_target(target)]->mipmap_auto:0, (glstate->texture.bound[glstate->texture.active][what_target(target)])?glstate->texture.bound[glstate->texture.active][what_target(target)]->base_level:0, (glstate->texture.bound[glstate->texture.active][what_target(target)])?glstate->texture.bound[glstate->texture.active][what_target(target)]->max_level:0, (glstate->texture.bound[glstate->texture.active][what_target(target)])?glstate->texture.bound[glstate->texture.active][what_target(target)]->texture:0, (glstate->texture.bound[glstate->texture.active][what_target(target)])?glstate->texture.bound[glstate->texture.active][what_target(target)]->streamed:0, glstate->list.compiling); // proxy case const GLuint itarget = what_target(target); @@ -542,12 +564,12 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, if (globals4es.texshrink>=8 && max1>8192) max1=8192; proxy_width = ((width<max1)?0:width; proxy_height = ((height<max1)?0:height; - proxy_intformat = swizzle_internalformat(&internalformat); + proxy_intformat = swizzle_internalformat(&internalformat, format); return; } //PUSH_IF_COMPILING(glTexImage2D); GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; } @@ -572,7 +594,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, else bound->mipmap_need = 1; } - GLenum new_format = swizzle_internalformat(&internalformat); + GLenum new_format = swizzle_internalformat(&internalformat, format); if (bound && (level==0)) { bound->orig_internal = internalformat; bound->internalformat = new_format; @@ -857,7 +879,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff //PUSH_IF_COMPILING(glTexSubImage2D); GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; } @@ -1191,7 +1213,7 @@ GLboolean gl4es_glIsTexture(GLuint texture) { gltexture_t* gl4es_getTexture(GLenum target, GLuint texture) { // Get a texture based on glID gltexture_t* tex = NULL; - if (texture == 0) return tex; + //if (texture == 0) return tex; // texture 0 is a texture like any other... it is not "unbind" texture in fact!! int ret; khint_t k; khash_t(tex) *list = glstate->texture.list; @@ -1215,14 +1237,15 @@ gltexture_t* gl4es_getTexture(GLenum target, GLuint texture) { tex->uploaded = false; tex->mipmap_auto = default_tex_mipmap || (globals4es.automipmap==1); tex->mipmap_need = (globals4es.automipmap==1)?1:0; - tex->alpha = true; - tex->streamed = false; tex->streamingID = -1; + tex->base_level = -1; + tex->max_level = -1; + tex->streamed = false; + tex->alpha = true; + tex->compressed = false; tex->min_filter = tex->mag_filter = (globals4es.automipmap==1)?GL_LINEAR_MIPMAP_LINEAR:GL_LINEAR; tex->format = GL_RGBA; tex->type = GL_UNSIGNED_BYTE; - tex->orig_internal = GL_RGBA; - tex->internalformat = GL_RGBA; tex->shrink = 0; tex->data = NULL; } else { @@ -1233,8 +1256,9 @@ gltexture_t* gl4es_getTexture(GLenum target, GLuint texture) { #define batch_activetex (glstate->statebatch.active_tex_changed?(glstate->statebatch.active_tex-GL_TEXTURE0):glstate->texture.active) void gl4es_glBindTexture(GLenum target, GLuint texture) { noerrorShim(); + //printf("glBindTexture(%s, %u), active=%i, client=%i\n", PrintEnum(target), texture, glstate->texture.active, glstate->texture.client); + if(glstate->list.pending) flush(); if ((target!=GL_PROXY_TEXTURE_2D) && (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling))) { - //printf("=> glBindTexture(0x%04X, %u), active=%i, client=%i, batch_active=%i, batch_bound=0x%04X, batch_tex=%u\n", target, texture, glstate->texture.active, glstate->texture.client, batch_activetex, glstate->statebatch.bound_targ[batch_activetex], glstate->statebatch.bound_tex[batch_activetex]); if ((glstate->statebatch.bound_targ[batch_activetex] == target) && (glstate->statebatch.bound_tex[batch_activetex] == texture)) return; // nothing to do... if (glstate->statebatch.bound_targ[batch_activetex]) { @@ -1242,7 +1266,6 @@ void gl4es_glBindTexture(GLenum target, GLuint texture) { } glstate->statebatch.bound_targ[batch_activetex] = target; glstate->statebatch.bound_tex[batch_activetex] = texture; - //printf(" <= glBindTexture(0x%04X, %u), active=%i, client=%i, batch_active=%i, batch_bound=0x%04X, batch_tex=%u\n", target, texture, glstate->texture.active, glstate->texture.client, batch_activetex, glstate->statebatch.bound_targ[batch_activetex], glstate->statebatch.bound_tex[batch_activetex]); } if ((target!=GL_PROXY_TEXTURE_2D) && ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active)) { // check if already a texture binded, if yes, create a new list @@ -1253,18 +1276,13 @@ void gl4es_glBindTexture(GLenum target, GLuint texture) { int streamingID = -1; gltexture_t *tex = NULL; const GLuint itarget = what_target(target); - //printf("glBindTexture(0x%04X, %u), active=%i, client=%i\n", target, texture, glstate->texture.active, glstate->texture.client); - if (texture) { - tex = gl4es_getTexture(target, texture); - if (glstate->texture.bound[glstate->texture.active][itarget] == tex) - tex_changed = 0; - texture = tex->glname; - if (globals4es.texstream && tex->streamed) - streamingID = tex->streamingID; - } else { - if (glstate->texture.bound[glstate->texture.active][itarget] == NULL) - tex_changed = 0; - } + + tex = gl4es_getTexture(target, texture); + if (glstate->texture.bound[glstate->texture.active][itarget] == tex) + tex_changed = 0; + texture = tex->glname; + if (globals4es.texstream && tex->streamed) + streamingID = tex->streamingID; LOAD_GLES(glDisable); LOAD_GLES(glEnable); @@ -1385,7 +1403,7 @@ void gl4es_glTexParameterf(GLenum target, GLenum pname, GLfloat param) { } void gl4es_glDeleteTextures(GLsizei n, const GLuint *textures) { - if (glstate->gl_batch) flush(); + if (glstate->gl_batch || glstate->list.pending) flush(); noerrorShim(); LOAD_GLES(glDeleteTextures); khash_t(tex) *list = glstate->texture.list; @@ -1428,7 +1446,7 @@ void gl4es_glDeleteTextures(GLsizei n, const GLuint *textures) { void gl4es_glGenTextures(GLsizei n, GLuint * textures) { if (n<=0) return; - if (glstate->gl_batch) flush(); + if (glstate->gl_batch || glstate->list.pending) flush(); LOAD_GLES(glGenTextures); gles_glGenTextures(n, textures); errorGL(); @@ -1454,15 +1472,15 @@ void gl4es_glGenTextures(GLsizei n, GLuint * textures) { tex->width = 0; tex->height = 0; tex->uploaded = false; - tex->mipmap_auto = 0; - tex->mipmap_need = 0; + tex->mipmap_auto = default_tex_mipmap || (globals4es.automipmap==1); + tex->mipmap_need = (globals4es.automipmap==1)?1:0; tex->streamingID = -1; tex->base_level = -1; tex->max_level = -1; tex->streamed = false; tex->alpha = true; tex->compressed = false; - tex->min_filter = tex->mag_filter = GL_NEAREST; + tex->min_filter = tex->mag_filter = (globals4es.automipmap==1)?GL_LINEAR_MIPMAP_LINEAR:GL_LINEAR; tex->format = GL_RGBA; tex->type = GL_UNSIGNED_BYTE; tex->shrink = 0; @@ -1484,7 +1502,7 @@ GLboolean gl4es_glAreTexturesResident(GLsizei n, const GLuint *textures, GLboole void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) { //printf("glGetTexLevelParameteriv(%s, %d, %s, %p)\n", PrintEnum(target), level, PrintEnum(pname), params); // simplification: (mostly) not taking "target" into account here - if (glstate->gl_batch) flush(); + if (glstate->gl_batch || glstate->list.pending) flush(); *params = 0; noerrorShim(); const GLuint itarget = what_target(target); @@ -1598,7 +1616,7 @@ void popViewport(); void gl4es_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid * img) { //printf("glGetTexImage(%s, %i, %s, %s, %p)\n", PrintEnum(target), level, PrintEnum(format), PrintEnum(type), img); GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; } @@ -1797,6 +1815,7 @@ void gl4es_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, } void gl4es_glActiveTexture( GLenum texture ) { + if (glstate->list.pending) flush(); if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) { if (glstate->statebatch.active_tex_changed) { if(glstate->statebatch.active_tex == texture) @@ -1830,7 +1849,7 @@ void gl4es_glClientActiveTexture( GLenum texture ) { // try to speed-up things... if (glstate->texture.client == (texture - GL_TEXTURE0)) return; - if (glstate->gl_batch) flush(); + if (glstate->gl_batch || glstate->list.pending) flush(); glstate->texture.client = texture - GL_TEXTURE0; LOAD_GLES(glClientActiveTexture); gles_glClientActiveTexture(texture); @@ -1839,7 +1858,7 @@ void gl4es_glClientActiveTexture( GLenum texture ) { void gl4es_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * data) { //printf("glReadPixels(%i, %i, %i, %i, %s, %s, 0x%p)\n", x, y, width, height, PrintEnum(format), PrintEnum(type), data); GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; } @@ -1887,7 +1906,7 @@ void gl4es_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint //printf("glCopyTexSubImage2D(%s, %i, %i, %i, %i, %i, %i, %i), bounded texture=%u format/type=%s, %s\n", PrintEnum(target), level, xoffset, yoffset, x, y, width, height, (glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->texture:0, PrintEnum((glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->format:0), PrintEnum((glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->type:0)); // PUSH_IF_COMPILING(glCopyTexSubImage2D); GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; } @@ -1948,7 +1967,7 @@ void gl4es_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, //printf("glCopyTexImage2D(0x%04X, %i, 0x%04X, %i, %i, %i, %i, %i), current_fb=%u\n", target, level, internalformat, x, y, width, height, border, current_fb); //PUSH_IF_COMPILING(glCopyTexImage2D); GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; } @@ -2061,7 +2080,7 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor return; } GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; } @@ -2179,7 +2198,7 @@ void gl4es_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, { const GLuint itarget = what_target(target); const GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { + if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; } @@ -2246,7 +2265,7 @@ void gl4es_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, } void gl4es_glGetCompressedTexImage(GLenum target, GLint lod, GLvoid *img) { - if (glstate->gl_batch) flush(); + if (glstate->gl_batch || glstate->list.pending) flush(); const GLuint itarget = what_target(target); gltexture_t* bound = glstate->texture.bound[glstate->texture.active][itarget]; @@ -2349,6 +2368,7 @@ void gl4es_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *param) { gles_glTexEnvfv(target, pname, param); } void gl4es_glTexEnviv(GLenum target, GLenum pname, const GLint *param) { + if (glstate->list.pending) flush(); if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { NewStage(glstate->list.active, STAGE_TEXENV); rlTexEnviv(glstate->list.active, target, pname, param); @@ -2360,6 +2380,7 @@ void gl4es_glTexEnviv(GLenum target, GLenum pname, const GLint *param) { } void gl4es_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params) { LOAD_GLES(glGetTexEnvfv); + if (glstate->list.pending) flush(); if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush(); if(target==GL_POINT_SPRITE && pname==GL_COORD_REPLACE) *params = glstate->texture.pscoordreplace[glstate->texture.active]; @@ -2369,6 +2390,7 @@ void gl4es_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params) { } void gl4es_glGetTexEnviv(GLenum target, GLenum pname, GLint * params) { LOAD_GLES(glGetTexEnviv); + if (glstate->list.pending) flush(); if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush(); if(target==GL_POINT_SPRITE && pname==GL_COORD_REPLACE) *params = glstate->texture.pscoordreplace[glstate->texture.active]; @@ -2438,4 +2460,4 @@ void glCompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, GLi void glCompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) AliasExport("gl4es_glCompressedTexSubImage1D"); void glCompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) AliasExport("gl4es_glCompressedTexSubImage3D"); void glGetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img) AliasExport("gl4es_glGetCompressedTexImage"); -void glCopyTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) AliasExport("gl4es_glCopyTexSubImage3D"); +void glCopyTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) AliasExport("gl4es_glCopyTexSubImage3D"); \ No newline at end of file diff --git a/project/jni/gl4es/src/gl/wrap/gl.c b/project/jni/gl4es/src/gl/wrap/gl.c index c26eb69f2..5dd79fd7f 100755 --- a/project/jni/gl4es/src/gl/wrap/gl.c +++ b/project/jni/gl4es/src/gl/wrap/gl.c @@ -54,15 +54,15 @@ void gl4es_glFogiv(GLenum pname, GLint *iparams) { case GL_FOG_DENSITY: case GL_FOG_START: case GL_FOG_END: + case GL_FOG_MODE: case GL_FOG_INDEX: { gl4es_glFogf(pname, *iparams); break; } - case GL_FOG_MODE: case GL_FOG_COLOR: { GLfloat params[4]; for (int i = 0; i < 4; i++) { - params[i] = iparams[i]; + params[i] = (iparams[i]>>16)*1.0f/32767.f; } gl4es_glFogfv(pname, params); break; @@ -96,10 +96,18 @@ void gl4es_glGetLightiv(GLenum light, GLenum pname, GLint * params) { GLfloat fparams[4]; gl4es_glGetLightfv(light, pname, fparams); int n=4; - if (pname==GL_SPOT_EXPONENT) n=1; - if (pname==GL_SPOT_CUTOFF) n=1; - if (pname==GL_SPOT_EXPONENT) n=1; - if (pname==GL_SPOT_DIRECTION) n=3; + switch(pname) { + case GL_SPOT_EXPONENT: + case GL_SPOT_CUTOFF: + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: + n=1; + break; + case GL_SPOT_DIRECTION: + n=3; + break; + } if(pname==GL_AMBIENT || pname==GL_DIFFUSE || pname==GL_SPECULAR) for (int i=0; i>16)/32767.f; + params[i] = (iparams[i]>>16)*(1.0f/32767.f); } gl4es_glLightfv(light, pname, params); break; @@ -173,7 +181,7 @@ void gl4es_glLightModeliv(GLenum pname, GLint *iparams) { case GL_LIGHT_MODEL_AMBIENT: { GLfloat params[4]; for (int i = 0; i < 4; i++) { - params[i] = iparams[i]; + params[i] = (iparams[i]>>16)*1.f/32767.f; } gl4es_glLightModelfv(pname, params); break; @@ -200,18 +208,14 @@ printf("glMaterialiv(%04X, %04X, [%i,...]\n", face, pname, iparams[0]); { GLfloat params[4]; for (int i = 0; i < 4; i++) { - params[i] = (iparams[i]>>16)/32767.f; + params[i] = (iparams[i]>>16)*1.f/32767.f; } gl4es_glMaterialfv(face, pname, params); break; } case GL_SHININESS: { - GLfloat params[2]; - for (int i = 0; i < 2; i++) { - params[i] = iparams[i]; - } - gl4es_glMaterialfv(face, pname, params); + gl4es_glMaterialf(face, pname, *iparams); break; } case GL_COLOR_INDEXES: diff --git a/project/jni/gl4es/src/gl/wrap/gles.h b/project/jni/gl4es/src/gl/wrap/gles.h index b3a77332d..e1306a6ff 100644 --- a/project/jni/gl4es/src/gl/wrap/gles.h +++ b/project/jni/gl4es/src/gl/wrap/gles.h @@ -1055,7 +1055,7 @@ typedef struct { GLenum a1; GLsizei * a2; GLenum a3; - void * * a4; + const void * const * a4; GLsizei a5; } ARGS_void_GLenum_GLsizei___GENPT___GLenum_const_void___GENPT___const___GENPT___GLsizei; typedef struct { diff --git a/project/jni/gl4es/src/glx/glx.c b/project/jni/gl4es/src/glx/glx.c index 17ee72938..4459da6e3 100755 --- a/project/jni/gl4es/src/glx/glx.c +++ b/project/jni/gl4es/src/glx/glx.c @@ -19,13 +19,11 @@ #include "glx.h" #include "utils.h" -//#include #include "../gl/gl.h" #include "../glx/streaming.h" #include "khash.h" #include "hardext.h" -//#define EXPORT __attribute__((visibility("default"))) #ifndef AliasExport #define AliasExport(name) __attribute__((alias(name))) __attribute__((visibility("default"))) #endif @@ -829,7 +827,7 @@ not set to EGL_NO_CONTEXT. Bool gl4es_glXMakeCurrent(Display *display, GLXDrawable drawable, GLXContext context) { - DBG(printf("glXMakeCurrent(%p, %p, %p) 'isPBuffer(drawable)=%d\n", display, drawable, context, isPBuffer(drawable));) + DBG(printf("glXMakeCurrent(%p, %p, %p) 'isPBuffer(drawable)=%d, context->drawable=%p, context->eglSurface=%p\n", display, drawable, context, isPBuffer(drawable), context?context->drawable:0, context?context->eglSurface:0);) LOAD_EGL(eglMakeCurrent); LOAD_EGL(eglDestroySurface); LOAD_EGL(eglCreateWindowSurface); diff --git a/project/jni/gl4es/src/glx/hardext.c b/project/jni/gl4es/src/glx/hardext.c index 177e3b52d..f5d9dfd1e 100755 --- a/project/jni/gl4es/src/glx/hardext.c +++ b/project/jni/gl4es/src/glx/hardext.c @@ -118,7 +118,7 @@ void GetHardwareExtensions(int notest) S("GL_OES_depth24", depth24, 1); S("GL_OES_rgb8_rgba8", rgba8, 1); S("GL_EXT_multi_draw_arrays", multidraw, 1); - S("GL_EXT_texture_format_BGRA8888", bgra8888, 0); + S("GL_EXT_texture_format_BGRA8888", bgra8888, 1); S("GL_OES_depth_texture", depthtex, 1); S("GL_OES_texture_cube_map", cubemap, 1); @@ -138,7 +138,7 @@ void GetHardwareExtensions(int notest) #endif if(strstr(egl_eglQueryString(eglDisplay, EGL_EXTENSIONS), "EGL_KHR_gl_colorspace")) { - LOGD("LIBGL: sRGB surface supported\n"); + SHUT(LOGD("LIBGL: sRGB surface supported\n")); hardext.srgb = 1; }