From 90a3f4dbf19cab7b287d74abdf3c1f37448e7563 Mon Sep 17 00:00:00 2001 From: lubomyr Date: Sun, 6 Nov 2016 22:07:01 +0200 Subject: [PATCH] gl4es updated, added latest changes by ptitSeb --- project/jni/gl4es/README.md | 10 ++++- project/jni/gl4es/src/gl/array.c | 12 ++++-- project/jni/gl4es/src/gl/array.h | 1 + project/jni/gl4es/src/gl/gl.c | 5 --- project/jni/gl4es/src/gl/list.c | 38 +++++++++++------ project/jni/gl4es/src/gl/matrix.c | 62 ++++++++++++++++++++-------- project/jni/gl4es/src/gl/matrix.h | 4 ++ project/jni/gl4es/src/gl/matvec.c | 20 +++++++-- project/jni/gl4es/src/gl/matvec.h | 3 +- project/jni/gl4es/src/gl/state.h | 1 + project/jni/gl4es/src/gl/texgen.c | 65 +++++++++++++++++++----------- project/jni/gl4es/src/gl/texture.c | 44 ++++++++++++-------- project/jni/gl4es/src/gl/texture.h | 3 ++ project/jni/gl4es/src/glx/glx.c | 1 - project/jni/gl4es/version.h | 2 +- 15 files changed, 184 insertions(+), 87 deletions(-) diff --git a/project/jni/gl4es/README.md b/project/jni/gl4es/README.md index 45de2f112..5256f4bab 100755 --- a/project/jni/gl4es/README.md +++ b/project/jni/gl4es/README.md @@ -1,19 +1,21 @@ gl4es ==== -This is a library providing OpenGL 1.x functionality for OpenGL ES accelerated cards. +This is a library providing OpenGL 1.x functionality for OpenGL ES accelerated hardware. This is a fork a glshim (https://github.com/lunixbochs/glshim). Go check this lib if you need things like RemoteGL or if need support for TinyGLES (for 100% software rendering). The focusse is on compatibility with a wide selection of game and software, as well as speed. +It has been tested successfully of a large selection of games and software, including: Mincraft, OpenMW, SeriousSam, RVGL, TSMC, TORCS, SpeedDreams, GL-117, Blender 2.68 and many more. + Most function of OpenGL up to 1.5 are supported, with some notable exceptions: * Reading of Depth or Stencil buffer will not work * GL_FEEDBACK mode is not implemented Some know limitations: * GL_SELECT as some limitation in its implementation (for exemple, current Depth buffer or binded texture are not taken into account) - * NPOT texture are supported, but not with GL_REPEAT / GL_MIRRORED, only GL_CLAMP will work properly + * NPOT texture are supported, but not with GL_REPEAT / GL_MIRRORED, only GL_CLAMP will work properly (unless the GLES Hardware support NPOT) * Framebuffer use FRAMEBUFFER_OES extension (that must be present in the GLES 1.1 stack) * Multiple Color attachment on Framebuffer are not supported * OcclusionQuery is implemented, but with a 0 bits precision @@ -214,6 +216,10 @@ Initial Hardware test Version history ---- +##### 0.9.2 + * All matrix are tracked now + * Texture Matrix are 100% handled by gl4es. GLES Hardware keep an Identity matrix (TexCoord are transformed if needed). This allows a better handling of NPOT texture on hadware that doesn't support Full NPOT (fixed movies beiing horizontaly shifted in openmw with LIBGL_NPOT=1 for example) + ##### 0.9.1 * Added gl4es specifics glHint capabilities. If the extension GL_GL4ES_hint is present, than a few Hint are accessible. Look in include/gl4eshint.h for the list. diff --git a/project/jni/gl4es/src/gl/array.c b/project/jni/gl4es/src/gl/array.c index f1447a144..5d0a36aa0 100755 --- a/project/jni/gl4es/src/gl/array.c +++ b/project/jni/gl4es/src/gl/array.c @@ -66,7 +66,7 @@ GLvoid *copy_gl_array(const GLvoid *src, GLvoid *copy_gl_array_texcoord(const GLvoid *src, GLenum from, GLsizei width, GLsizei stride, - GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, GLvoid* filler) { + GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, GLvoid* filler, void* dest) { if (! src || !count) return NULL; @@ -74,7 +74,7 @@ GLvoid *copy_gl_array_texcoord(const GLvoid *src, stride = width * gl_sizeof(from); const char *unknown_str = "libGL: copy_gl_array -> unknown type: %x\n"; - GLvoid *dst = malloc((count-skip) * to_width * gl_sizeof(to)); + GLvoid *dst = (dest)?dest:malloc((count-skip) * to_width * gl_sizeof(to)); GLsizei from_size = gl_sizeof(from) * width; GLsizei to_elem = gl_sizeof(to); //texcoord are now 4 dim, so this should never happens @@ -262,7 +262,13 @@ GLvoid *copy_gl_pointer_raw(pointer_state_t *ptr, GLsizei width, GLsizei skip, G GLvoid *copy_gl_pointer_tex(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { float filler = 1.0f; return copy_gl_array_texcoord(ptr->pointer, ptr->type, ptr->size, ptr->stride, - GL_FLOAT, width, skip, count, &filler); + GL_FLOAT, width, skip, count, &filler, 0); +} + +void copy_gl_pointer_tex_noalloc(void* dest, pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { + float filler = 1.0f; + copy_gl_array_texcoord(ptr->pointer, ptr->type, ptr->size, ptr->stride, + GL_FLOAT, width, skip, count, &filler, dest); } GLfloat *gl_pointer_index(pointer_state_t *p, GLint index) { diff --git a/project/jni/gl4es/src/gl/array.h b/project/jni/gl4es/src/gl/array.h index b0c685502..e03fe06f1 100755 --- a/project/jni/gl4es/src/gl/array.h +++ b/project/jni/gl4es/src/gl/array.h @@ -18,6 +18,7 @@ GLvoid *copy_gl_pointer_color(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLvoid *copy_gl_pointer_bytecolor(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count); GLvoid *copy_gl_pointer_raw(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count); GLvoid *copy_gl_pointer_tex(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count); +void copy_gl_pointer_tex_noalloc(void* dest, pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count); GLfloat *gl_pointer_index(pointer_state_t *ptr, GLint index); GLfloat *copy_eval_double(GLenum target, GLint ustride, GLint uorder, GLint vstride, GLint vorder, const GLdouble *points); void normalize_indices(GLushort *indices, GLsizei *max, GLsizei *min, GLsizei count); diff --git a/project/jni/gl4es/src/gl/gl.c b/project/jni/gl4es/src/gl/gl.c index d6280e62c..2aee64734 100755 --- a/project/jni/gl4es/src/gl/gl.c +++ b/project/jni/gl4es/src/gl/gl.c @@ -373,11 +373,6 @@ static inline bool should_intercept_render(GLenum mode) { // check bounded tex that will be used if one need some transformations for (int aa=0; aaenable.texture_2d[aa] || glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa]) { - if(glstate->texture.rect_arb[aa]) - return true; - gltexture_t *bound = glstate->texture.bound[aa]; - if (bound && (bound->width!=bound->nwidth || bound->height!=bound->nheight)) - return true; if ((glstate->enable.texgen_s[aa] || glstate->enable.texgen_t[aa] || glstate->enable.texgen_r[aa] || glstate->enable.texgen_q[aa])) return true; } diff --git a/project/jni/gl4es/src/gl/list.c b/project/jni/gl4es/src/gl/list.c index 672357abf..7a9b46302 100755 --- a/project/jni/gl4es/src/gl/list.c +++ b/project/jni/gl4es/src/gl/list.c @@ -3,6 +3,7 @@ #include "debug.h" #include "../glx/hardext.h" #include "init.h" +#include "matrix.h" #define alloc_sublist(n, cap) \ (GLfloat *)malloc(n * sizeof(GLfloat) * cap) @@ -682,10 +683,6 @@ void adjust_renderlist(renderlist_t *list) { // in case of Texture bounding inside a list if (list->set_texture && (list->tmu == a)) bound = gl4es_getTexture(list->target_texture, list->texture); - // adjust the tex_coord now - if ((list->tex[a]) && (bound) && ((bound->width != bound->nwidth) || (bound->height != bound->nheight))) { - tex_coord_npot(list->tex[a], list->len, bound->width, bound->height, bound->nwidth, bound->nheight); - } // GL_ARB_texture_rectangle if ((list->tex[a]) && glstate->texture.rect_arb[a] && (bound)) { tex_coord_rect_arb(list->tex[a], list->len, bound->width, bound->height); @@ -922,28 +919,47 @@ void draw_renderlist(renderlist_t *list) { list->tex[0] = gen_stipple_tex_coords(list->vert, list->len); } } - GLfloat *texgened[MAX_TEX]; + static GLfloat *texgened[MAX_TEX] = {0}; + static int texgenedsz[MAX_TEX] = {0}; + int use_texgen[MAX_TEX]; + #define RS(A, len) if(texgenedsz[A]enable.texgen_s[a] || glstate->enable.texgen_t[a] || glstate->enable.texgen_r[a] || glstate->enable.texgen_q[a])) { + RS(a, list->len); gen_tex_coords(list->vert, list->normal, &texgened[a], list->len, &needclean[a], a, (list->ilenlen)?indices:NULL, (list->ilenlen)?list->ilen:0); } else if (glstate->enable.texture_2d[a] && (list->tex[a]==NULL) && !(list->mode==GL_POINT && glstate->texture.pscoordreplace[a])) { + RS(a, list->len); gen_tex_coords(list->vert, list->normal, &texgened[a], list->len, &needclean[a], a, (list->ilenlen)?indices:NULL, (list->ilenlen)?list->ilen:0); - } + } + // adjust the tex_coord now if needed, even on texgened ones + gltexture_t *bound = glstate->texture.bound[a]; + if((list->tex[a] || use_texgen[a]) && ((!glstate->texture_matrix[a]->identity) || (bound) && ((bound->width != bound->nwidth) || (bound->height != bound->nheight)))) { + if(!use_texgen[a]) { + RS(a, list->len); + memcpy(texgened[a], list->tex[a], 4*sizeof(GLfloat)*list->len); + } + if (!glstate->texture_matrix[a]->identity) + tex_coord_matrix(texgened[a], list->len, getTexMat(a)); + if ((bound) && ((bound->width != bound->nwidth) || (bound->height != bound->nheight))) { + tex_coord_npot(texgened[a], list->len, bound->width, bound->height, bound->nwidth, bound->nheight); + } + } } + #undef RS old_tex = glstate->texture.client; GLuint cur_tex = old_tex; #define TEXTURE(A) if (cur_tex!=A) {gl4es_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;} for (int a=0; atex[a] || texgened[a])/* && glstate->enable.texture_2d[a]*/) { + if ((list->tex[a] || use_texgen[a])/* && glstate->enable.texture_2d[a]*/) { TEXTURE(a); if(!glstate->clientstate.tex_coord_array[a]) { gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); glstate->clientstate.tex_coord_array[a] = 1; } - gles_glTexCoordPointer(4, GL_FLOAT, 0, (texgened[a])?texgened[a]:list->tex[a]); + gles_glTexCoordPointer(4, GL_FLOAT, 0, (use_texgen[a])?texgened[a]:list->tex[a]); } else { if (glstate->clientstate.tex_coord_array[a]) { TEXTURE(a); @@ -1158,10 +1174,6 @@ void draw_renderlist(renderlist_t *list) { TEXTURE(a); gen_tex_clean(needclean[a], a); } - if (texgened[a]) { - free(texgened[a]); - texgened[a] = NULL; - } if (!glstate->enable.texture_2d[a] && (glstate->enable.texture_1d[a] || glstate->enable.texture_3d[a])) { TEXTURE(a); gles_glDisable(GL_TEXTURE_2D); diff --git a/project/jni/gl4es/src/gl/matrix.c b/project/jni/gl4es/src/gl/matrix.c index 45396f2c6..1343c8bd6 100755 --- a/project/jni/gl4es/src/gl/matrix.c +++ b/project/jni/gl4es/src/gl/matrix.c @@ -12,14 +12,10 @@ void alloc_matrix(matrixstack_t **matrixstack, int depth) { *matrixstack = (matrixstack_t*)malloc(sizeof(matrixstack_t)); (*matrixstack)->top = 0; + (*matrixstack)->identity = 0; (*matrixstack)->stack = (GLfloat*)malloc(sizeof(GLfloat)*depth*16); } -void set_identity(GLfloat* mat) { - memset(mat, 0, 16*sizeof(GLfloat)); - mat[0] = mat[1+4] = mat[2+8] = mat[3+12] = 1.0f; -} - #define TOP(A) (glstate->A->stack+(glstate->A->top*16)) static GLfloat* update_current_mat() { @@ -34,19 +30,45 @@ static GLfloat* update_current_mat() { return NULL; } +static int update_current_identity(int I) { + switch(glstate->matrix_mode) { + case GL_MODELVIEW: + return glstate->modelview_matrix->identity = (I)?1:is_identity(TOP(modelview_matrix)); + case GL_PROJECTION: + return glstate->projection_matrix->identity = (I)?1:is_identity(TOP(projection_matrix)); + case GL_TEXTURE: + return glstate->texture_matrix[glstate->texture.active]->identity = (I)?1:is_identity(TOP(texture_matrix[glstate->texture.active])); + } + return 0; +} + +static int send_to_hardware() { + switch(glstate->matrix_mode) { + case GL_PROJECTION: + return 1; + case GL_MODELVIEW: + return 1; + case GL_TEXTURE: + return 0; + } + return 0; +} + void init_matrix(glstate_t* glstate) { alloc_matrix(&glstate->projection_matrix, MAX_STACK_PROJECTION); set_identity(TOP(projection_matrix)); + glstate->projection_matrix->identity = 1; alloc_matrix(&glstate->modelview_matrix, MAX_STACK_MODELVIEW); set_identity(TOP(modelview_matrix)); + glstate->modelview_matrix->identity = 1; glstate->texture_matrix = (matrixstack_t**)malloc(sizeof(matrixstack_t*)*MAX_TEX); for (int i=0; itexture_matrix[i], MAX_STACK_TEXTURE); set_identity(TOP(texture_matrix[i])); + glstate->texture_matrix[i]->identity = 1; } } - void gl4es_glMatrixMode(GLenum mode) { DBG(printf("glMatrixMode(%s), list=%p\n", PrintEnum(mode), glstate->list.active);) PUSH_IF_COMPILING(glMatrixMode); @@ -81,7 +103,7 @@ DBG(printf("glPushMatrix(), list=%p\n", glstate->list.active);) P(modelview_matrix, MODELVIEW); break; case GL_TEXTURE: - P(texture_matrix[glstate->texture.active], PROJECTION); + P(texture_matrix[glstate->texture.active], TEXTURE); break; #undef P default: @@ -103,7 +125,8 @@ DBG(printf("glPopMatrix(), list=%p\n", glstate->list.active);) switch(matrix_mode) { #define P(A) if(glstate->A->top) { \ --glstate->A->top; \ - gles_glLoadMatrixf(update_current_mat()); \ + glstate->A->identity = is_identity(update_current_mat()); \ + if (send_to_hardware()) gles_glLoadMatrixf(update_current_mat()); \ } else errorShim(GL_STACK_UNDERFLOW) case GL_PROJECTION: P(projection_matrix); @@ -127,6 +150,7 @@ DBG(printf("glPopMatrix(), list=%p\n", glstate->list.active);) void gl4es_glLoadMatrixf(const GLfloat * m) { DBG(printf("glLoadMatrix(%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) { NewStage(glstate->list.active, STAGE_MATRIX); @@ -135,12 +159,16 @@ DBG(printf("glLoadMatrix(%f, %f, %f, %f, %f, %f, %f...), list=%p\n", m[0], m[1], return; } memcpy(update_current_mat(), m, 16*sizeof(GLfloat)); - gles_glLoadMatrixf(m); + const int id = update_current_identity(0); + if(send_to_hardware()) + if(id) gles_glLoadIdentity(); // in case the driver as some special optimisations + else gles_glLoadMatrixf(m); } 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.... @@ -154,7 +182,10 @@ DBG(printf("glMultMatrix(%f, %f, %f, %f, %f, %f, %f...), list=%p\n", m[0], m[1], } GLfloat *current_mat = update_current_mat(); matrix_mul(current_mat, m, current_mat); - gles_glLoadMatrixf(current_mat); + const int id = update_current_identity(0); + if(send_to_hardware()) + if(id) gles_glLoadIdentity(); // in case the driver as some special optimisations + else gles_glLoadMatrixf(current_mat); } void gl4es_glLoadIdentity() { @@ -168,7 +199,8 @@ DBG(printf("glLoadIdentity(), list=%p\n", glstate->list.active);) } set_identity(update_current_mat()); - gles_glLoadIdentity(); + update_current_identity(1); + if(send_to_hardware()) gles_glLoadIdentity(); } void gl4es_glTranslatef(GLfloat x, GLfloat y, GLfloat z) { @@ -237,16 +269,14 @@ DBG(printf("glFrustumf(%f, %f, %f, %f, %f, %f) list=%p\n", left, right, top, bot GLfloat tmp[16]; memset(tmp, 0, 16*sizeof(GLfloat)); - tmp[0+0] = 2.0f*nearVal/(right-left); tmp[0+8] = -(right+left)/(right-left); - tmp[1+4] = 2.0f*nearVal/(top-bottom); tmp[1+8] = -(top+bottom)/(top-bottom); - tmp[2+8] =-(farVal+nearVal)/(farVal-nearVal); tmp[2+12] = -2.0f*farVal*nearVal/(farVal-nearVal); + tmp[0+0] = 2.0f*nearVal/(right-left); tmp[0+8] = (right+left)/(right-left); + tmp[1+4] = 2.0f*nearVal/(top-bottom); tmp[1+8] = (top+bottom)/(top-bottom); + tmp[2+8] =-(farVal+nearVal)/(farVal-nearVal); tmp[2+12] =-2.0f*farVal*nearVal/(farVal-nearVal); tmp[3+8] = -1.0f; gl4es_glMultMatrixf(tmp); } - - void glMatrixMode(GLenum mode) AliasExport("gl4es_glMatrixMode"); void glPushMatrix() AliasExport("gl4es_glPushMatrix"); void glPopMatrix() AliasExport("gl4es_glPopMatrix"); diff --git a/project/jni/gl4es/src/gl/matrix.h b/project/jni/gl4es/src/gl/matrix.h index 4de0e3d9d..8bb94065d 100755 --- a/project/jni/gl4es/src/gl/matrix.h +++ b/project/jni/gl4es/src/gl/matrix.h @@ -11,3 +11,7 @@ void gl4es_glScalef(GLfloat x, GLfloat y, GLfloat z); void gl4es_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); void gl4es_glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal); void gl4es_glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal); + +static inline GLfloat* getTexMat(int tmu) { + return glstate->texture_matrix[tmu]->stack+glstate->texture_matrix[tmu]->top*16; +} diff --git a/project/jni/gl4es/src/gl/matvec.c b/project/jni/gl4es/src/gl/matvec.c index cbbafea81..be3b9efc0 100755 --- a/project/jni/gl4es/src/gl/matvec.c +++ b/project/jni/gl4es/src/gl/matvec.c @@ -67,10 +67,11 @@ void vector_matrix(const float *a, const float *b, float *c) { : "%2", "q0", "q1", "q2", "memory" ); #else - c[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12]; - c[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13]; - c[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14]; - c[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15]; + const float a0=a[0], a1=a[1], a2=a[2], a3=a[3]; + c[0] = a0 * b[0] + a1 * b[4] + a2 * b[8] + a3 * b[12]; + c[1] = a0 * b[1] + a1 * b[5] + a2 * b[9] + a3 * b[13]; + c[2] = a0 * b[2] + a1 * b[6] + a2 * b[10] + a3 * b[14]; + c[3] = a0 * b[3] + a1 * b[7] + a2 * b[11] + a3 * b[15]; #endif } @@ -283,3 +284,14 @@ void matrix_mul(const float *a, const float *b, float *c) { #endif } +void set_identity(float* mat) { + memset(mat, 0, 16*sizeof(GLfloat)); + mat[0] = mat[1+4] = mat[2+8] = mat[3+12] = 1.0f; +} + +int is_identity(const float* mat) { + static float i1[16]; + static int set=0; + if(!set) {set_identity(i1); set=1;} + return memcmp(mat, i1, 16*sizeof(float))==0?1:0; +} \ No newline at end of file diff --git a/project/jni/gl4es/src/gl/matvec.h b/project/jni/gl4es/src/gl/matvec.h index 769314ff0..49dca5228 100755 --- a/project/jni/gl4es/src/gl/matvec.h +++ b/project/jni/gl4es/src/gl/matvec.h @@ -13,6 +13,7 @@ void vector4_normalize(float *a); void matrix_transpose(const float *a, float *b); void matrix_inverse(const float *m, float *r); void matrix_mul(const float *a, const float *b, float *c); - +void set_identity(float* mat); +int is_identity(const float* mat); #endif \ No newline at end of file diff --git a/project/jni/gl4es/src/gl/state.h b/project/jni/gl4es/src/gl/state.h index 673828393..9a20bb810 100755 --- a/project/jni/gl4es/src/gl/state.h +++ b/project/jni/gl4es/src/gl/state.h @@ -117,6 +117,7 @@ typedef struct { typedef struct { int top; + int identity; GLfloat *stack; } matrixstack_t; diff --git a/project/jni/gl4es/src/gl/texgen.c b/project/jni/gl4es/src/gl/texgen.c index fde3800cc..42963fde2 100755 --- a/project/jni/gl4es/src/gl/texgen.c +++ b/project/jni/gl4es/src/gl/texgen.c @@ -19,7 +19,7 @@ void gl4es_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { generation function specified by pname. */ - //printf("glTexGenfv(%s, %s, [%s, ...]), texture=%i\n", PrintEnum(coord), PrintEnum(pname), PrintEnum(param[0]), glstate->texture.active); + //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); @@ -151,9 +151,7 @@ void sphere_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint GLfloat ModelviewMatrix[16], InvModelview[16]; gl4es_glGetFloatv(GL_MODELVIEW_MATRIX, InvModelview); // column major -> row major - for (int i=0; i<4; i++) - for (int j=0; j<4; j++) - ModelviewMatrix[i*4+j]=InvModelview[i+j*4]; + matrix_transpose(InvModelview, ModelviewMatrix); // And get the inverse matrix_inverse(ModelviewMatrix, InvModelview); GLfloat eye[4], eye_norm[4], reflect[4]; @@ -177,6 +175,36 @@ void sphere_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint } +void reflection_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint count, GLushort *indices) { + // based on https://www.opengl.org/wiki/Mathematics_of_glTexGen +/* if (!norm) { + printf("LIBGL: GL_REFLECTION_MAP without Normals\n"); + return; + }*/ + // First get the ModelviewMatrix + GLfloat ModelviewMatrix[16], InvModelview[16]; + gl4es_glGetFloatv(GL_MODELVIEW_MATRIX, InvModelview); + // column major -> row major + matrix_transpose(InvModelview, ModelviewMatrix); + // And get the inverse + matrix_inverse(ModelviewMatrix, InvModelview); + GLfloat eye[4], eye_norm[4]; + GLfloat a; + for (int i=0; inormal, InvModelview, eye_norm); + vector4_normalize(eye_norm); + a=dot4(eye, eye_norm)*2.0f; + out[k*4+0] = eye[0] - eye_norm[0]*a; + out[k*4+1] = eye[1] - eye_norm[1]*a; + out[k*4+2] = eye[2] - eye_norm[2]*a; + out[k*4+3] = 1.0f; + } + +} + void eye_loop(const GLfloat *verts, const GLfloat *param, GLfloat *out, GLint count, GLushort *indices) { // based on https://www.opengl.org/wiki/Mathematics_of_glTexGen // First get the ModelviewMatrix @@ -231,10 +259,10 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count // special case: SPHERE_MAP needs both texgen to make sense if ((glstate->enable.texgen_s[texture] && (glstate->texgen[texture].S==GL_SPHERE_MAP)) && (glstate->enable.texgen_t[texture] && (glstate->texgen[texture].T==GL_SPHERE_MAP))) { - if (!glstate->enable.texture_2d[texture]) - return; - if ((*coords)==NULL) - *coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat)); + if (!glstate->enable.texture_2d[texture]) + return; + if ((*coords)==NULL) + *coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat)); sphere_loop(verts, norm, *coords, (indices)?ilen:count, indices); return; } @@ -243,22 +271,11 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count && (glstate->enable.texgen_t[texture] && (glstate->texgen[texture].T==GL_REFLECTION_MAP)) && (glstate->enable.texgen_r[texture] && (glstate->texgen[texture].R==GL_REFLECTION_MAP))) { - *needclean=1; - // setup reflection map! - GLuint old_tex=glstate->texture.active; - if (old_tex!=texture) gl4es_glActiveTexture(GL_TEXTURE0 + texture); - LOAD_GLES_OES(glTexGeni); - LOAD_GLES_OES(glTexGenfv); - LOAD_GLES(glEnable); - // setup cube map mode - gles_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - gles_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - gles_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - // enable texgen - gles_glEnable(GL_TEXTURE_GEN_STR); //GLES only support the 3 gen at the same time! - - if (old_tex!=texture) gl4es_glActiveTexture(GL_TEXTURE0 + old_tex); - + if (!glstate->enable.texture_2d[texture]) + return; + if ((*coords)==NULL) + *coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat)); + reflection_loop(verts, norm, *coords, (indices)?ilen:count, indices); return; } // special case: NORMAL_MAP needs the 3 texgen to make sense diff --git a/project/jni/gl4es/src/gl/texture.c b/project/jni/gl4es/src/gl/texture.c index 832951acb..60b02eb8c 100755 --- a/project/jni/gl4es/src/gl/texture.c +++ b/project/jni/gl4es/src/gl/texture.c @@ -9,6 +9,7 @@ #include "../glx/streaming.h" #include "../glx/hardext.h" #include "init.h" +#include "matrix.h" #ifndef GL_TEXTURE_STREAM_IMG #define GL_TEXTURE_STREAM_IMG 0x8C0D @@ -46,7 +47,6 @@ void tex_coord_npot(GLfloat *tex, GLsizei len, GLsizei nwidth, GLsizei nheight) { if (!tex || !nwidth || !nheight) return; - GLfloat wratio = (width / (GLfloat)nwidth); GLfloat hratio = (height / (GLfloat)nheight); for (int i = 0; i < len; i++) { @@ -56,42 +56,52 @@ void tex_coord_npot(GLfloat *tex, GLsizei len, } } +void tex_coord_matrix(GLfloat *tex, GLsizei len, const GLfloat* mat) { + if (!tex || !len || !mat) + return; + for (int i = 0; i < len; i++) { + vector_matrix(tex, mat, tex); + tex += 4; + } +} + /* Setup the texture coordinates * * Have to check is ARB_RECTANGLE is used + * Apply texture matrix if not identity * Or some NPOT texture used - * Or SHRINKED texure used */ void tex_setup_texcoord(GLuint len) { LOAD_GLES(glTexCoordPointer); GLuint texunit = glstate->texture.client; - static void * tex[8] = {0,0,0,0,0,0,0,0}; // hugly but convenient... + static void * tex[MAX_TEX] = {0}; + static int texlen[MAX_TEX] = {0}; - if (tex[texunit]) { - free(tex[texunit]); - tex[texunit]=NULL; - } - gltexture_t *bound = glstate->texture.bound[texunit]; // check if some changes are needed int changes = 0; - if ((glstate->texture.rect_arb[texunit]) || - (bound && ((bound->width!=bound->nwidth)||(bound->height!=bound->nheight)|| - (bound->shrink && (glstate->vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (glstate->vao->pointers.tex_coord[texunit].type!=GL_DOUBLE))))) + if ((glstate->texture.rect_arb[texunit]) + || (bound && ((bound->width!=bound->nwidth)||(bound->height!=bound->nheight) + )) || !glstate->texture_matrix[texunit]->identity + ) changes = 1; if (changes) { // first convert to GLfloat, without normalization - tex[texunit] = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[texunit], 4, 0, len); - if (!tex[texunit]) { - printf("LIBGL: Error with Texture tranform\n"); - gles_glTexCoordPointer(glstate->vao->pointers.tex_coord[texunit].size, glstate->vao->pointers.tex_coord[texunit].type, glstate->vao->pointers.tex_coord[texunit].stride, glstate->vao->pointers.tex_coord[texunit].pointer); - return; + if(texlen[texunit]vao->pointers.tex_coord[texunit], 4, 0, len); // Normalize if needed - if ((glstate->texture.rect_arb[texunit]) || ((glstate->vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (glstate->vao->pointers.tex_coord[texunit].type!=GL_DOUBLE))) + if ((glstate->texture.rect_arb[texunit])) tex_coord_rect_arb(tex[texunit], len, bound->width, bound->height); + // Apply transformation matrix if any + if (!glstate->texture_matrix[texunit]->identity) + tex_coord_matrix(tex[texunit], len, getTexMat(texunit)); + // NPOT adjust if ((bound->width!=bound->nwidth) || (bound->height!=bound->nheight)) tex_coord_npot(tex[texunit], len, bound->width, bound->height, bound->nwidth, bound->nheight); // All done, setup the texcoord array now diff --git a/project/jni/gl4es/src/gl/texture.h b/project/jni/gl4es/src/gl/texture.h index d0d03799a..c4dfd0195 100755 --- a/project/jni/gl4es/src/gl/texture.h +++ b/project/jni/gl4es/src/gl/texture.h @@ -88,6 +88,9 @@ void tex_coord_rect_arb(GLfloat *tex, GLsizei len, void tex_coord_npot(GLfloat *tex, GLsizei len, GLsizei width, GLsizei height, GLsizei nwidth, GLsizei nheight); + +void tex_coord_matrix(GLfloat *tex, GLsizei len, const GLfloat* mat); + int npot(int n); typedef struct { diff --git a/project/jni/gl4es/src/glx/glx.c b/project/jni/gl4es/src/glx/glx.c index 8f9f1dd83..2e91810aa 100755 --- a/project/jni/gl4es/src/glx/glx.c +++ b/project/jni/gl4es/src/glx/glx.c @@ -3,7 +3,6 @@ #endif #include -#include "../../version.h" #include "../gl/init.h" #ifdef USE_FBIO diff --git a/project/jni/gl4es/version.h b/project/jni/gl4es/version.h index 6e41b9bae..d72f1a932 100755 --- a/project/jni/gl4es/version.h +++ b/project/jni/gl4es/version.h @@ -3,6 +3,6 @@ #define MAJOR 0 #define MINOR 9 -#define REVISION 1 +#define REVISION 2 #endif //_GL4ES_VERSION_H \ No newline at end of file