diff --git a/project/jni/gl4es/CMakeLists.txt b/project/jni/gl4es/CMakeLists.txt index 13ac06b29..76daee51f 100755 --- a/project/jni/gl4es/CMakeLists.txt +++ b/project/jni/gl4es/CMakeLists.txt @@ -11,6 +11,7 @@ link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) option(PANDORA "Set to ON if targeting an OpenPandora device" ${PANDORA}) option(BCMHOST "Set to ON if targeting an RPi(2) device" ${BCMHOST}) option(ODROID "Set to ON if targeting an ODroid device" ${ODROID}) +option(CHIP "Set to ON if targeting an C.H.I.P. device" ${CHIP}) option(USE_DRAWTEX "Set to ON to use the glDrawTexiOES extension" ${USE_DRAWTEX}) @@ -31,6 +32,11 @@ if(ODROID) add_definitions(-DODROID) endif() +if(CHIP) + add_definitions(-DCHIP) + add_definitions(-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=hard -ftree-vectorize -fsingle-precision-constant -ffast-math) +endif() + if(USE_DRAWTEX) add_definitions(-DUSE_DRAWTEX) endif() diff --git a/project/jni/gl4es/README.md b/project/jni/gl4es/README.md index fd17f187c..b008b07ff 100755 --- a/project/jni/gl4es/README.md +++ b/project/jni/gl4es/README.md @@ -37,6 +37,10 @@ Compiling cmake . -DODROID=1; make GL +*or for CHIP machines* + + cmake . -DCHIP=1; make GL + *or for Android* An Android.mk is provided that should compile with an NDK @@ -71,7 +75,7 @@ Controls the Framebuffer output * 0 : Default, using standard x11 rendering * 1 : Use Framebuffer output (x11 bypassed, only fullscreen) * 2 : Use Framebuffer, but also an intermediary FBO - * 3 : Use PBuffer, allowing x11 rendering even if driver doesn't support it + * 3 : Use PBuffer, allowing x11 (and windowed) rendering even if driver doesn't support it ##### LIBGL_XREFRESH Debug helper in specific cases @@ -206,6 +210,11 @@ Expose glQueries functions * 0 : Don't expose the function (fake one will be used if called) * 1 : Default, expose fake functions (always answer 0) +##### LIBGL_NOTEXMAT +Handling of Texture Matrix + * 0 : Default, perform handling internaly (better handling of NPOT texture on all hardware) + * 1 : Let the driver handle texmat (can be faster in some cases, but NPOT texture may be broken) + ##### LIBGL_NOTEST Initial Hardware test * 0 : Default, perform intial hardware testing (using a PBuffer) @@ -217,6 +226,11 @@ Version history ---- ##### Current version + * Improved Texture state tracking + * Added LIBGL_NOTEXMAT env. var. switch for Texture Matrix handling + * Added GL_EXT_vertex_array_bgra (and NEONinzed some loop) + * Finished GL_EXT_direct_state_access extension + * Mangled glX function (to be abble to use apitrace to capture GL frames) * Return some values in glXQueryServerString, coherent with glXGetClientString ##### 0.9.2 diff --git a/project/jni/gl4es/src/config.h b/project/jni/gl4es/src/config.h index 35ceafb79..76f996062 100755 --- a/project/jni/gl4es/src/config.h +++ b/project/jni/gl4es/src/config.h @@ -35,6 +35,9 @@ #define skip_glFogfv +#define skip_glPointParameterfv +#define skip_glPointParameterf + //#define skip_glBlendEquation #define skip_glBlendEquationSeparate #define skip_glBlendEquationSeparatei diff --git a/project/jni/gl4es/src/gl/array.c b/project/jni/gl4es/src/gl/array.c index c72469632..2f7c602bb 100755 --- a/project/jni/gl4es/src/gl/array.c +++ b/project/jni/gl4es/src/gl/array.c @@ -352,14 +352,29 @@ GLvoid *copy_gl_pointer_color_bgra(pointer_state_t *ptr, GLsizei width, GLsizei GLfloat* dst = out; src += skip*(stride); + static const float d = 1.0f/255.0f; for (int i=skip; i>16) | ((lsrc&0x000000ff)<<16); + asm volatile ( + "vmov s12, %1 \n\t" // because you cannot vmovl.u8 d6, s11 + "vmovl.u8 q3, d6 \n\t" // Expand to 16-bit (so unsetuped s13 is expanded in d7) + "vmovl.u16 q3, d6 \n\t" // Expand to 32-bit, ignoring expanded d7 + "vcvt.f32.u32 q3, q3 \n\t" // Convert to float + "vmul.f32 q3, q3, %y2 \n\t" // Normalize + "vst1.f32 {q3}, [%0]! \n\t" // Store, next + :"+r"(dst) :"r"(lsrc), "w"(d) + : "q3", "memory" + ); + #else const GLubyte b = src[0], g = src[1], r = src[2], a = src[3]; - *dst++ = r*(1.0f/255.0f); - *dst++ = g*(1.0f/255.0f); - *dst++ = b*(1.0f/255.0f); - *dst++ = a*(1.0f/255.0f); + *dst++ = r*d; + *dst++ = g*d; + *dst++ = b*d; + *dst++ = a*d; + #endif src+=stride; } - return out; } diff --git a/project/jni/gl4es/src/gl/const.h b/project/jni/gl4es/src/gl/const.h index b3f1414fd..b31b51a1f 100755 --- a/project/jni/gl4es/src/gl/const.h +++ b/project/jni/gl4es/src/gl/const.h @@ -568,3 +568,35 @@ #define GL_DEPTH_COMPONENT16 0x81A5 #define GL_DEPTH_COMPONENT 0x1902 #define GL_MAX_DRAW_BUFFERS_ARB 0x8824 + +// direct state +#define GL_MATRIX0_ARB 0x88C0 +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_TEXTURE_COORD_ARRAY_COUNT 0x808B + +// cube mapping +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_AX_CUBE_MAP_TEXTURE_SIZE 0x851C \ No newline at end of file diff --git a/project/jni/gl4es/src/gl/directstate.c b/project/jni/gl4es/src/gl/directstate.c index 03c67ff9d..e61a60cc3 100755 --- a/project/jni/gl4es/src/gl/directstate.c +++ b/project/jni/gl4es/src/gl/directstate.c @@ -21,16 +21,16 @@ void gl4es_glClientAttribDefault(GLbitfield mask) { if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { int client = glstate->texture.client; - enable_disable(GL_VERTEX_ARRAY, false); - enable_disable(GL_NORMAL_ARRAY, false); - enable_disable(GL_COLOR_ARRAY, false); - enable_disable(GL_SECONDARY_COLOR_ARRAY, false); + enable_disable(GL_VERTEX_ARRAY, false); + enable_disable(GL_NORMAL_ARRAY, false); + enable_disable(GL_COLOR_ARRAY, false); + enable_disable(GL_SECONDARY_COLOR_ARRAY, false); for (int a=0; atexture.client != client) gl4es_glClientActiveTexture(GL_TEXTURE0+client); + if (glstate->texture.client != client) gl4es_glClientActiveTexture(GL_TEXTURE0+client); } } void gl4es_glPushClientAttribDefault(GLbitfield mask) { @@ -341,6 +341,157 @@ void gl4es_glGetCompressedMultiTexImage(GLenum texunit, GLenum target, GLint lev text(glGetCompressedTexImage(target, level, img)); } +void gl4es_glEnableClientStateIndexedEXT(GLenum array, GLuint index) { + if (array == GL_TEXTURE_COORD_ARRAY) { + int old = glstate->texture.client; + if(old!=index) gl4es_glClientActiveTexture(GL_TEXTURE0+index); + gl4es_glEnableClientState(array); + if(old!=index) gl4es_glClientActiveTexture(GL_TEXTURE0+old); + errorGL(); + } else { + errorShim(GL_INVALID_ENUM); + } +} +void gl4es_glDisableClientStateIndexedEXT(GLenum array, GLuint index) { + if (array == GL_TEXTURE_COORD_ARRAY) { + int old = glstate->texture.client; + if(old!=index) gl4es_glClientActiveTexture(GL_TEXTURE0+index); + gl4es_glDisableClientState(array); + if(old!=index) gl4es_glClientActiveTexture(GL_TEXTURE0+old); + errorGL(); + } else { + errorShim(GL_INVALID_ENUM); + } +} + +#define GETXXX(XXX, xxx) \ +void gl4es_glGet##XXX##IndexedvEXT(GLenum target, GLuint index, GL##xxx *data) { \ + switch(target) { \ + case GL_PROGRAM_MATRIX_EXT: \ + case GL_TRANSPOSE_PROGRAM_MATRIX_EXT: \ + case GL_PROGRAM_MATRIX_STACK_DEPTH_EXT: \ + { \ + int old = glstate->matrix_mode; \ + gl4es_glMatrixMode(GL_MATRIX0_ARB+index); \ + switch(target) { \ + case GL_PROGRAM_MATRIX_EXT: \ + gl4es_glGet##XXX##v(GL_CURRENT_MATRIX_ARB, data); \ + break; \ + case GL_TRANSPOSE_PROGRAM_MATRIX_EXT: \ + gl4es_glGet##XXX##v(GL_TRANSPOSE_CURRENT_MATRIX_ARB, data); \ + break; \ + case GL_PROGRAM_MATRIX_STACK_DEPTH_EXT: \ + gl4es_glGet##XXX##v(GL_CURRENT_MATRIX_STACK_DEPTH_ARB, data); \ + break; \ + } \ + gl4es_glMatrixMode(old); \ + } \ + break; \ + case GL_CURRENT_RASTER_TEXTURE_COORDS: \ + case GL_CURRENT_TEXTURE_COORDS: \ + case GL_TEXTURE_BINDING_1D: \ + case GL_TEXTURE_BINDING_1D_ARRAY: \ + case GL_TEXTURE_BINDING_2D: \ + case GL_TEXTURE_BINDING_2D_ARRAY: \ + case GL_TEXTURE_BINDING_3D: \ + case GL_TEXTURE_BINDING_BUFFER_EXT: \ + case GL_TEXTURE_BINDING_CUBE_MAP: \ + case GL_TEXTURE_BINDING_RECTANGLE_ARB: \ + case GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT: \ + case GL_TEXTURE_BUFFER_FORMAT_EXT: \ + case GL_TEXTURE_GEN_Q: \ + case GL_TEXTURE_GEN_R: \ + case GL_TEXTURE_GEN_S: \ + case GL_TEXTURE_GEN_T: \ + case GL_TEXTURE_MATRIX: \ + case GL_TEXTURE_STACK_DEPTH: \ + case GL_TRANSPOSE_TEXTURE_MATRIX: \ + case GL_TEXTURE_1D: \ + case GL_TEXTURE_2D: \ + case GL_TEXTURE_3D: \ + case GL_TEXTURE_CUBE_MAP: \ + case GL_TEXTURE_RECTANGLE_ARB: \ + { \ + int old = glstate->texture.active; \ + if(old!=index+GL_TEXTURE0) gl4es_glActiveTexture(index+GL_TEXTURE0); \ + gl4es_glGet##XXX##v(target, data); \ + if(old!=index+GL_TEXTURE0) gl4es_glActiveTexture(old); \ + } \ + break; \ + case GL_TEXTURE_COORD_ARRAY: \ + case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: \ + case GL_TEXTURE_COORD_ARRAY_COUNT: \ + case GL_TEXTURE_COORD_ARRAY_SIZE: \ + case GL_TEXTURE_COORD_ARRAY_STRIDE: \ + case GL_TEXTURE_COORD_ARRAY_TYPE: \ + { \ + int old = glstate->texture.client; \ + if(old!=index) gl4es_glClientActiveTexture(index+GL_TEXTURE0); \ + gl4es_glGet##XXX##v(target, data); \ + if(old!=index) gl4es_glClientActiveTexture(old+GL_TEXTURE0); \ + } \ + break; \ + default: \ + gl4es_glGet##XXX##v(target, data); \ + } \ +} + +GETXXX(Float, float); +GETXXX(Double, double); +GETXXX(Integer, int); +GETXXX(Boolean, boolean); +#undef GETXXX + +void gl4es_glGetPointerIndexedvEXT(GLenum pname, GLuint index, GLvoid **params) { + int old = glstate->texture.client; + if(old!=index) gl4es_glClientActiveTexture(index+GL_TEXTURE0); + gl4es_glGetPointerv(pname, params); + if(old!=index) gl4es_glClientActiveTexture(old+GL_TEXTURE0); + +} + +void gl4es_glEnableIndexedEXT(GLenum cap, GLuint index) { + int old = glstate->texture.active; + if(old!=index) gl4es_glActiveTexture(index+GL_TEXTURE0); + gl4es_glEnable(cap); + if(old!=index) gl4es_glActiveTexture(old); +} + +void gl4es_glDisableIndexedEXT(GLenum cap, GLuint index) { + int old = glstate->texture.active; + if(old!=index) gl4es_glActiveTexture(index+GL_TEXTURE0); + gl4es_glDisable(cap); + if(old!=index) gl4es_glActiveTexture(old); +} + +GLboolean gl4es_glIsEnabledIndexedEXT(GLenum cap, GLuint index) { + int old; + GLboolean rv; + switch(cap) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_RECTANGLE_ARB: + case GL_TEXTURE_GEN_S: + case GL_TEXTURE_GEN_T: + case GL_TEXTURE_GEN_R: + case GL_TEXTURE_GEN_Q: + old = glstate->texture.active; + if(old!=index) gl4es_glActiveTexture(index+GL_TEXTURE0); + rv = gl4es_glIsEnabled(cap); + if(old!=index) gl4es_glActiveTexture(old); + return rv; + case GL_TEXTURE_COORD_ARRAY: + old = glstate->texture.client; + if(old!=index) gl4es_glClientActiveTexture(index+GL_TEXTURE0); + rv = gl4es_glIsEnabled(cap); + if(old!=index) gl4es_glClientActiveTexture(old+GL_TEXTURE0); + return rv; + } + return gl4es_glIsEnabled(cap); +} + //EXT wrapper void glClientAttribDefaultEXT(GLbitfield mask) AliasExport("gl4es_glClientAttribDefault"); void glPushClientAttribDefaultEXT(GLbitfield mask) AliasExport("gl4es_glPushClientAttribDefault"); @@ -434,6 +585,15 @@ void glMatrixLoadTransposefEXT(GLenum matrixMode, const GLfloat *m) AliasExport( void glMatrixLoadTransposedEXT(GLenum matrixMode, const GLdouble *m) AliasExport("gl4es_glMatrixLoadTransposed"); void glMatrixMultTransposefEXT(GLenum matrixMode, const GLfloat *m) AliasExport("gl4es_glMatrixMultTransposef"); void glMatrixMultTransposedEXT(GLenum matrixMode, const GLdouble *m) AliasExport("gl4es_glMatrixMultTransposed"); - +void glEnableClientStateIndexedEXT(GLenum array, GLuint index) AliasExport("gl4es_glEnableClientStateIndexedEXT"); +void glDisableClientStateIndexedEXT(GLenum array, GLuint index) AliasExport("gl4es_glDisableClientStateIndexedEXT"); +void glGetPointerIndexedvEXT(GLenum pname, GLuint index, GLvoid **params) AliasExport("gl4es_glGetPointerIndexedvEXT"); +void glGetFloatIndexedvEXT(GLenum target, GLuint index, GLfloat *data) AliasExport("gl4es_glGetFloatIndexedvEXT"); +void glGetDoubleIndexedvEXT(GLenum target, GLuint index, GLdouble *data) AliasExport("gl4es_glGetDoubleIndexedvEXT"); +void glGetIntegerIndexedvEXT(GLenum target, GLuint index, GLint *data) AliasExport("gl4es_glGetIntegerIndexedvEXT"); +void glGetBooleanIndexedvEXT(GLenum target, GLuint index, GLboolean *data) AliasExport("gl4es_glGetBooleanIndexedvEXT"); +void glEnableIndexedEXT(GLenum cap, GLuint index) AliasExport("gl4es_glEnableIndexedEXT"); +void glDisableIndexedEXT(GLenum cap, GLuint index) AliasExport("gl4es_glDisableIndexedEXT"); +GLboolean glIsEnabledIndexedEXT(GLenum cap, GLuint index) AliasExport("gl4es_glIsEnabledIndexedEXT"); #undef text #undef texc diff --git a/project/jni/gl4es/src/gl/directstate.h b/project/jni/gl4es/src/gl/directstate.h index 502069d2e..190deeb26 100755 --- a/project/jni/gl4es/src/gl/directstate.h +++ b/project/jni/gl4es/src/gl/directstate.h @@ -103,4 +103,18 @@ void gl4es_glMatrixLoadTransposed(GLenum matrixMode, const GLdouble *m); void gl4es_glMatrixMultTransposef(GLenum matrixMode, const GLfloat *m); void gl4es_glMatrixMultTransposed(GLenum matrixMode, const GLdouble *m); +void gl4es_glEnableClientStateIndexedEXT(GLenum array, GLuint index); +void gl4es_glDisableClientStateIndexedEXT(GLenum array, GLuint index); + +void gl4es_glGetFloatIndexedvEXT(GLenum target, GLuint index, GLfloat *data); +void gl4es_glGetDoubleIndexedvEXT(GLenum target, GLuint index, GLdouble *data); +void gl4es_glGetIntegerIndexedvEXT(GLenum target, GLuint index, GLint *data); +void gl4es_glGetBooleanIndexedvEXT(GLenum target, GLuint index, GLboolean *data); + +void gl4es_glGetPointerIndexedvEXT(GLenum pname, GLuint index, GLvoid **params); + +void gl4es_glEnableIndexedEXT(GLenum cap, GLuint index); +void gl4es_glDisableIndexedEXT(GLenum cap, GLuint index); +GLboolean gl4es_glIsEnabledIndexedEXT(GLenum cap, GLuint index); + #endif diff --git a/project/jni/gl4es/src/gl/framebuffers.c b/project/jni/gl4es/src/gl/framebuffers.c index 969a03bb7..5943ec39f 100755 --- a/project/jni/gl4es/src/gl/framebuffers.c +++ b/project/jni/gl4es/src/gl/framebuffers.c @@ -208,7 +208,7 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta tex->nwidth = hardext.npot==2?tex->width:npot(tex->width); tex->nheight = hardext.npot==2?tex->height:npot(tex->height); tex->shrink = 0; - gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]; GLuint oldtex = (bound)?bound->glname:0; if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, tex->glname); gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL); @@ -221,7 +221,7 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta tex->nwidth = (tex->nwidth<32)?32:tex->nwidth; tex->nheight = (tex->nheight<32)?32:tex->nheight; tex->shrink = 0; - gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]; GLuint oldtex = (bound)?bound->glname:0; if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, tex->glname); gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL); @@ -255,7 +255,7 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta if ((scrap_width!=twidth) || (scrap_height!=theight)) { scrap_width = twidth; scrap_height = theight; - gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]; GLuint oldtex = (bound)?bound->glname:0; if (oldtex!=scrap_tex) gles_glBindTexture(GL_TEXTURE_2D, scrap_tex); gles_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, scrap_width, scrap_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); @@ -539,8 +539,8 @@ void createMainFBO(int width, int height) { gles_glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } // Put everything back, and active the MainFBO - if (glstate->texture.bound[0]) - gles_glBindTexture(GL_TEXTURE_2D, glstate->texture.bound[0]->glname); + if (glstate->texture.bound[0][ENABLED_TEX2D]) + gles_glBindTexture(GL_TEXTURE_2D, glstate->texture.bound[0][ENABLED_TEX2D]->glname); if (glstate->texture.active != 0) gles_glActiveTexture(GL_TEXTURE0 + glstate->texture.active); if (glstate->texture.client != 0) @@ -669,11 +669,11 @@ void blitMainFBO() { // put back viewport gles_glViewport(old_vp[0], old_vp[1], old_vp[2], old_vp[3]); // Put everything back - if (glstate->texture.bound[0]) - gles_glBindTexture(GL_TEXTURE_2D, glstate->texture.bound[0]->glname); + if (glstate->texture.bound[0][ENABLED_TEX2D]) + gles_glBindTexture(GL_TEXTURE_2D, glstate->texture.bound[0][ENABLED_TEX2D]->glname); else gles_glBindTexture(GL_TEXTURE_2D, 0); - if (!glstate->enable.texture_2d[0]) + if (!IS_TEX2D(glstate->enable.texture[0])) gles_glDisable(GL_TEXTURE_2D); if (old_tex != 0) gl4es_glActiveTexture(GL_TEXTURE0 + old_tex); diff --git a/project/jni/gl4es/src/gl/gl.c b/project/jni/gl4es/src/gl/gl.c index 913f52fa0..a9d6f3b41 100755 --- a/project/jni/gl4es/src/gl/gl.c +++ b/project/jni/gl4es/src/gl/gl.c @@ -180,19 +180,29 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { // Alpha Hack if (globals4es.alphahack && (cap==GL_ALPHA_TEST) && enable) { - if (glstate->texture.bound[glstate->texture.active]) - if (!glstate->texture.bound[glstate->texture.active]->alpha) + if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]) + if (!glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]->alpha) enable = false; } noerrorShim(); #ifdef TEXSTREAM if (cap==GL_TEXTURE_STREAM_IMG) - glstate->enable.texture_2d[glstate->texture.active] = enable; + if(enable) + glstate->enable.texture[glstate->texture.active] |= (1<enable.texture[glstate->texture.active] &= ~(1<texture.active]); + case GL_TEXTURE_2D: + if(enable) + glstate->enable.texture[glstate->texture.active] |= (1<enable.texture[glstate->texture.active] &= ~(1<texture.active]); enable(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active]); enable(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active]); @@ -213,8 +223,34 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { clientenable(GL_TEXTURE_COORD_ARRAY, tex_coord_array[glstate->texture.client]); // Texture 1D and 3D - enable(GL_TEXTURE_1D, texture_1d[glstate->texture.active]); - enable(GL_TEXTURE_3D, texture_3d[glstate->texture.active]); + case GL_TEXTURE_1D: + if(enable) + glstate->enable.texture[glstate->texture.active] |= (1<enable.texture[glstate->texture.active] &= ~(1<enable.texture[glstate->texture.active] |= (1<enable.texture[glstate->texture.active] &= ~(1<enable.texture[glstate->texture.active] |= (1<enable.texture[glstate->texture.active] &= ~(1<list.active && (glstate->gl_batch && !glstate->list.compiling)) { int which_cap = Cap2BatchState(cap); - if (which_cap!=ENABLED_LAST) { + if (which_capstatebatch.enabled[which_cap] == 1)) return; // nothing to do... if (glstate->statebatch.enabled[which_cap]) @@ -250,8 +286,8 @@ void gl4es_glEnable(GLenum cap) { PUSH_IF_COMPILING(glEnable) if (globals4es.texstream && (cap==GL_TEXTURE_2D)) { - if (glstate->texture.bound[glstate->texture.active]) - if (glstate->texture.bound[glstate->texture.active]->streamed) + if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]) + if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]->streamed) cap = GL_TEXTURE_STREAM_IMG; } @@ -263,7 +299,7 @@ void glEnable(GLenum cap) AliasExport("gl4es_glEnable"); void gl4es_glDisable(GLenum cap) { if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) { int which_cap = Cap2BatchState(cap); - if (which_cap!=ENABLED_LAST) { + if (which_capstatebatch.enabled[which_cap] == 2)) return; // nothing to do... if (glstate->statebatch.enabled[which_cap]) @@ -274,8 +310,8 @@ void gl4es_glDisable(GLenum cap) { PUSH_IF_COMPILING(glDisable) if (globals4es.texstream && (cap==GL_TEXTURE_2D)) { - if (glstate->texture.bound[glstate->texture.active]) - if (glstate->texture.bound[glstate->texture.active]->streamed) + if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]) + if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]->streamed) cap = GL_TEXTURE_STREAM_IMG; } @@ -324,8 +360,19 @@ GLboolean gl4es_glIsEnabled(GLenum cap) { isenabled(GL_COLOR_SUM, color_sum); isenabled(GL_POINT_SPRITE, pointsprite); clientisenabled(GL_SECONDARY_COLOR_ARRAY, secondary_array); - isenabled(GL_TEXTURE_1D, texture_1d[glstate->texture.active]); - isenabled(GL_TEXTURE_3D, texture_3d[glstate->texture.active]); + case GL_TEXTURE_1D: return glstate->enable.texture[glstate->texture.active]&(1<enable.texture[glstate->texture.active]&(1<enable.texture[glstate->texture.active]&(1<enable.texture[glstate->texture.active]&(1<enable.texture_2d[aa] || glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa]) { + if (glstate->enable.texture[aa]) { if ((glstate->enable.texgen_s[aa] || glstate->enable.texgen_t[aa] || glstate->enable.texgen_r[aa] || glstate->enable.texgen_q[aa])) return true; } @@ -519,13 +566,17 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid #define TEXTURE(A) gl4es_glClientActiveTexture(A+GL_TEXTURE0); for (int aa=0; aaenable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { - TEXTURE(aa); - gles_glEnable(GL_TEXTURE_2D); - } - if (glstate->vao->tex_coord_array[aa]) { - TEXTURE(aa); - tex_setup_texcoord(len); + // get 1st enabled target + const GLint itarget = get_target(glstate->enable.texture[aa]); + if (itarget>=0) { + if (itarget==ENABLED_TEX1D || itarget==ENABLED_TEX3D) { + TEXTURE(aa); + gles_glEnable(GL_TEXTURE_2D); + } + if (glstate->vao->tex_coord_array[aa]) { + TEXTURE(aa); + tex_setup_texcoord(len, itarget); + } } } if (glstate->texture.client!=old_tex) @@ -534,7 +585,7 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid gles_glDrawElements(mode, count, GL_UNSIGNED_SHORT, sindices); for (int aa=0; aaenable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { + if (!IS_TEX2D(glstate->enable.texture[aa]) && (IS_ANYTEX(glstate->enable.texture[aa]))) { TEXTURE(aa); gles_glDisable(GL_TEXTURE_2D); } @@ -626,16 +677,20 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) { #define TEXTURE(A) gl4es_glClientActiveTexture(A+GL_TEXTURE0); for (int aa=0; aaenable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { - TEXTURE(aa); - gles_glEnable(GL_TEXTURE_2D); + // get 1st enabled target + const GLint itarget = get_target(glstate->enable.texture[aa]); + if(itarget>=0) { + if (itarget==ENABLED_TEX1D || itarget==ENABLED_TEX3D) { + TEXTURE(aa); + gles_glEnable(GL_TEXTURE_2D); + } + if (glstate->vao->tex_coord_array[aa]) { + TEXTURE(aa); + tex_setup_texcoord(count+first, itarget); + /*glClientActiveTexture(aa+GL_TEXTURE0); + gles_glTexCoordPointer(glstate->pointers.tex_coord[aa].size, glstate->pointers.tex_coord[aa].type, glstate->pointers.tex_coord[aa].stride, glstate->pointers.tex_coord[aa].pointer);*/ + } } - if (glstate->vao->tex_coord_array[aa]) { - TEXTURE(aa); - tex_setup_texcoord(count+first); - /*glClientActiveTexture(aa+GL_TEXTURE0); - gles_glTexCoordPointer(glstate->pointers.tex_coord[aa].size, glstate->pointers.tex_coord[aa].type, glstate->pointers.tex_coord[aa].stride, glstate->pointers.tex_coord[aa].pointer);*/ - } } if (glstate->texture.client!=old_tex) TEXTURE(old_tex); @@ -643,7 +698,7 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) { gles_glDrawArrays(mode, first, count); for (int aa=0; aaenable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { + if (!IS_TEX2D(glstate->enable.texture[aa]) && (IS_ANYTEX(glstate->enable.texture[aa]))) { TEXTURE(aa); gles_glDisable(GL_TEXTURE_2D); } @@ -822,7 +877,7 @@ void gl4es_glEnd() { if (!glstate->list.active) return; // 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_2d[a] && ((glstate->list.active->tex[a]==0) && !(glstate->enable.texgen_s[a] || glstate->texture.pscoordreplace[a]))) + if (glstate->enable.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)) { @@ -1477,6 +1532,30 @@ void gl4es_glPointParameteriv(GLenum pname, const GLint * params) } void glPointParameteriv(GLenum pname, const GLint * params) AliasExport("gl4es_glPointParameteriv"); +void gl4es_glPointParameterf(GLenum pname, GLfloat param) { + PUSH_IF_COMPILING(glPointParameterf); + LOAD_GLES(glPointParameterf); + gles_glPointParameterf(pname, param); +}void glPointParameterf(GLenum pname, GLfloat param) AliasExport("gl4es_glPointParameterf"); + +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; + } + } + LOAD_GLES(glPointParameterfv); + + gles_glPointParameterfv(pname, params); +} +void glPointParameterfv(GLenum pname, const GLfloat * params) AliasExport("gl4es_glPointParameterfv"); + void gl4es_glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount) diff --git a/project/jni/gl4es/src/gl/gl.h b/project/jni/gl4es/src/gl/gl.h index b7d983c56..04da0ef92 100755 --- a/project/jni/gl4es/src/gl/gl.h +++ b/project/jni/gl4es/src/gl/gl.h @@ -402,6 +402,8 @@ GLenum gl4es_glGetError(); void gl4es_glPointParameteri(GLenum pname, GLint param); void gl4es_glPointParameteriv(GLenum pname, const GLint * params); +void gl4es_glPointParameterf(GLenum pname, GLfloat param); +void gl4es_glPointParameterfv(GLenum pname, const GLfloat * params); void gl4es_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); diff --git a/project/jni/gl4es/src/gl/init.c b/project/jni/gl4es/src/gl/init.c index b5b55913e..a382a6cfd 100755 --- a/project/jni/gl4es/src/gl/init.c +++ b/project/jni/gl4es/src/gl/init.c @@ -249,6 +249,8 @@ void initialize_gl4es() { globals4es.queries = 0; SHUT(LOGD("LIBGL: Dont't expose fake glQueries functions\n")); } + + env(LIBGL_NOTEXMAT, globals4es.texmat, "Don't handle Texture Matrice internaly"); char cwd[1024]; if (getcwd(cwd, sizeof(cwd))!= NULL) diff --git a/project/jni/gl4es/src/gl/init.h b/project/jni/gl4es/src/gl/init.h index 1e0504933..2c35a8089 100755 --- a/project/jni/gl4es/src/gl/init.h +++ b/project/jni/gl4es/src/gl/init.h @@ -36,6 +36,7 @@ typedef struct _globals4es { #ifdef PANDORA float gamma; #endif + int texmat; char version[50]; } globals4es_t; diff --git a/project/jni/gl4es/src/gl/list.c b/project/jni/gl4es/src/gl/list.c index 7a9b46302..5a4486116 100755 --- a/project/jni/gl4es/src/gl/list.c +++ b/project/jni/gl4es/src/gl/list.c @@ -50,6 +50,8 @@ bool ispurerender_renderlist(renderlist_t *list) { return false; if (list->fog_op) return false; + if (list->pointparam_op) + return false; if (list->mode_init == 0) return false; if (list->set_texture || list->set_tmu) @@ -679,7 +681,7 @@ void adjust_renderlist(renderlist_t *list) { list->stage = STAGE_LAST; list->open = false; for (int a=0; atexture.bound[a]; + gltexture_t *bound = glstate->texture.bound[a][ENABLED_TEX2D]; //TODO check if hardcoded TEX2D is ok // in case of Texture bounding inside a list if (list->set_texture && (list->tmu == a)) bound = gl4es_getTexture(list->target_texture, list->texture); @@ -769,6 +771,13 @@ void draw_renderlist(renderlist_t *list) { break; } } + if (list->pointparam_op) { + switch (list->pointparam_op) { + case 1: // GL_POINT_DISTANCE_ATTENUATION + gl4es_glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION , list->pointparam_val); + break; + } + } if (list->matrix_op) { switch (list->matrix_op) { case 1: // load @@ -925,26 +934,29 @@ void draw_renderlist(renderlist_t *list) { #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]) { + if(glstate->enable.texture[a]) { + const GLint itarget = get_target(glstate->enable.texture[a]); + needclean[a]=0; + use_texgen[a]=0; + if ((glstate->enable.texgen_s[a] || glstate->enable.texgen_t[a] || glstate->enable.texgen_r[a] || glstate->enable.texgen_q[a])) { RS(a, list->len); - memcpy(texgened[a], list->tex[a], 4*sizeof(GLfloat)*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 ((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); } - 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); + // adjust the tex_coord now if needed, even on texgened ones + gltexture_t *bound = glstate->texture.bound[a][itarget]; + if((list->tex[a] || use_texgen[a]) && ((!(globals4es.texmat || 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 (!(globals4es.texmat || 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); + } } } } @@ -953,7 +965,7 @@ void draw_renderlist(renderlist_t *list) { 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] || use_texgen[a])/* && glstate->enable.texture_2d[a]*/) { + if ((list->tex[a] || use_texgen[a])/* && glstate->enable.texture[a]*/) { TEXTURE(a); if(!glstate->clientstate.tex_coord_array[a]) { gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -966,10 +978,10 @@ void draw_renderlist(renderlist_t *list) { gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY); glstate->clientstate.tex_coord_array[a] = 0; } -//else if (!glstate->enable.texgen_s[a] && glstate->enable.texture_2d[a]) printf("LIBGL: texture_2d[%i] without TexCoord, mode=0x%04X (init=0x%04X), listlen=%i\n", a, list->mode, list->mode_init, list->len); +//else if (!glstate->enable.texgen_s[a] && glstate->enable.texture[a]) printf("LIBGL: texture[%i] without TexCoord, mode=0x%04X (init=0x%04X), listlen=%i\n", a, list->mode, list->mode_init, list->len); } - if (!glstate->enable.texture_2d[a] && (glstate->enable.texture_1d[a] || glstate->enable.texture_3d[a])) { + if (!IS_TEX2D(glstate->enable.texture[a]) && (IS_ANYTEX(glstate->enable.texture[a]))) { TEXTURE(a); gles_glEnable(GL_TEXTURE_2D); } @@ -1174,7 +1186,7 @@ void draw_renderlist(renderlist_t *list) { TEXTURE(a); gen_tex_clean(needclean[a], a); } - if (!glstate->enable.texture_2d[a] && (glstate->enable.texture_1d[a] || glstate->enable.texture_3d[a])) { + if (!IS_TEX2D(glstate->enable.texture[a]) && (IS_ANYTEX(glstate->enable.texture[a]))) { TEXTURE(a); gles_glDisable(GL_TEXTURE_2D); } @@ -1425,6 +1437,14 @@ void rlFogOp(renderlist_t *list, int op, const GLfloat* v) { list->fog_val[3] = v[3]; } +void rlPointParamOp(renderlist_t *list, int op, const GLfloat* v) { + list->pointparam_op = op; + list->pointparam_val[0] = v[0]; + list->pointparam_val[1] = v[1]; + list->pointparam_val[2] = v[2]; + list->pointparam_val[3] = v[3]; +} + void rlPushCall(renderlist_t *list, packed_call_t *data) { call_list_t *cl = &list->calls; if (!cl->calls) { diff --git a/project/jni/gl4es/src/gl/list.h b/project/jni/gl4es/src/gl/list.h index 69650fa18..5376a4d48 100755 --- a/project/jni/gl4es/src/gl/list.h +++ b/project/jni/gl4es/src/gl/list.h @@ -10,6 +10,7 @@ typedef enum { STAGE_CALLLIST, STAGE_GLCALL, STAGE_FOG, + STAGE_POINTPARAM, STAGE_MATRIX, STAGE_ACTIVETEX, STAGE_BINDTEX, @@ -31,6 +32,7 @@ static int StageExclusive[STAGE_LAST] = { 1, // STAGE_CALLLIST 0, // STAGE_GLCALL 1, // STAGE_FOG + 1, // STAGE_POINTPARAM 1, // STAGE_MATRIX 1, // STAGE_ACTIVETEX 1, // STAGE_BINDTEX @@ -137,6 +139,9 @@ typedef struct _renderlist_t { int fog_op; GLfloat fog_val[4]; + + int pointparam_op; + GLfloat pointparam_val[4]; khash_t(material) *material; khash_t(light) *light; @@ -184,4 +189,5 @@ void rlVertex4f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z, GLfloat w) void rlSecondary3f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b) FASTMATH; void rlRasterOp(renderlist_t *list, int op, GLfloat x, GLfloat y, GLfloat z) FASTMATH; void rlFogOp(renderlist_t *list, int op, const GLfloat* v); +void rlPointParamOp(renderlist_t *list, int op, const GLfloat* v); #endif diff --git a/project/jni/gl4es/src/gl/matrix.c b/project/jni/gl4es/src/gl/matrix.c index 1343c8bd6..9fafd61ec 100755 --- a/project/jni/gl4es/src/gl/matrix.c +++ b/project/jni/gl4es/src/gl/matrix.c @@ -1,5 +1,6 @@ #include "matrix.h" #include "gl.h" +#include "init.h" #include "debug.h" //#define DEBUG @@ -49,7 +50,7 @@ static int send_to_hardware() { case GL_MODELVIEW: return 1; case GL_TEXTURE: - return 0; + return (globals4es.texmat)?1:0; } return 0; } diff --git a/project/jni/gl4es/src/gl/raster.c b/project/jni/gl4es/src/gl/raster.c index e4ad44eea..01fcf5573 100755 --- a/project/jni/gl4es/src/gl/raster.c +++ b/project/jni/gl4es/src/gl/raster.c @@ -186,8 +186,8 @@ GLuint raster_to_texture() gl4es_glGetIntegerv(GL_ACTIVE_TEXTURE, &old_tex_unit); if (old_tex_unit!=GL_TEXTURE0) gl4es_glActiveTexture(GL_TEXTURE0); old_tex = 0; - if (glstate->texture.bound[0]) - old_tex = glstate->texture.bound[0]->texture; + if (glstate->texture.bound[0][ENABLED_TEX2D]) + old_tex = glstate->texture.bound[0][ENABLED_TEX2D]->texture; GLuint raster_texture; gl4es_glEnable(GL_TEXTURE_2D); gles_glGenTextures(1, &raster_texture); @@ -423,7 +423,7 @@ void render_raster_list(rasterlist_t* rast) { #ifdef USE_DRAWTEX gl4es_glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT); - gltexture_t *old_bind = glstate->texture.bound[0]; + gltexture_t *old_bind = glstate->texture.bound[0][ENABLED_TEX2D]; gl4es_glEnable(GL_TEXTURE_2D); gles_glBindTexture(GL_TEXTURE_2D, rast->texture); @@ -435,7 +435,7 @@ void render_raster_list(rasterlist_t* rast) { } gles_glDrawTexf(glstate->raster.rPos.x-rast->xorig, glstate->raster.rPos.y-rast->yorig, glstate->raster.rPos.z, rast->width * rast->zoomx, rast->height * rast->zoomy); - if (!glstate->enable.texture_2d[0]) gl4es_glDisable(GL_TEXTURE_2D); + if (!IS_TEX2D(glstate->enable.texture[0])) gl4es_glDisable(GL_TEXTURE_2D); if (old_tex!=0) gles_glActiveTexture(GL_TEXTURE0+old_tex); if (old_cli!=0) gles_glClientActiveTexture(GL_TEXTURE0+old_cli); if (old_bind == NULL) diff --git a/project/jni/gl4es/src/gl/stack.c b/project/jni/gl4es/src/gl/stack.c index 5e0338e1a..c9b860a76 100755 --- a/project/jni/gl4es/src/gl/stack.c +++ b/project/jni/gl4es/src/gl/stack.c @@ -106,9 +106,7 @@ void gl4es_glPushAttrib(GLbitfield mask) { cur->stencil_test = gl4es_glIsEnabled(GL_STENCIL_TEST); int a; for (a=0; atexture_1d[a] = glstate->enable.texture_1d[a]; - cur->texture_2d[a] = glstate->enable.texture_2d[a]; - cur->texture_3d[a] = glstate->enable.texture_3d[a]; + cur->tex_enabled[a] = glstate->enable.texture[a]; cur->texgen_s[a] = glstate->enable.texgen_s[a]; cur->texgen_r[a] = glstate->enable.texgen_r[a]; cur->texgen_t[a] = glstate->enable.texgen_t[a]; @@ -248,7 +246,8 @@ void gl4es_glPushAttrib(GLbitfield mask) { cur->texgen_t[a] = glstate->enable.texgen_t[a]; cur->texgen_q[a] = glstate->enable.texgen_q[a]; cur->texgen[a] = glstate->texgen[a]; // all mode and planes per texture in 1 line - cur->texture[a] = (glstate->texture.bound[a])?glstate->texture.bound[a]->texture:0; + for (int j=0; jtexture[a][j] = (glstate->texture.bound[a][j])?glstate->texture.bound[a][j]->texture:0; } //glActiveTexture(GL_TEXTURE0+cur->active); } @@ -426,18 +425,15 @@ void gl4es_glPopAttrib() { int a; int old_tex = glstate->texture.active; for (a=0; aenable.texture_1d[a] != cur->texture_1d[a]) { - gl4es_glActiveTexture(GL_TEXTURE0+a); - enable_disable(GL_TEXTURE_1D, cur->texture_1d[a]); - } - if (glstate->enable.texture_2d[a] != cur->texture_2d[a]) { - gl4es_glActiveTexture(GL_TEXTURE0+a); - enable_disable(GL_TEXTURE_2D, cur->texture_2d[a]); - } - if (glstate->enable.texture_3d[a] != cur->texture_3d[a]) { - gl4es_glActiveTexture(GL_TEXTURE0+a); - enable_disable(GL_TEXTURE_3D, cur->texture_3d[a]); - } + if(glstate->enable.texture[a] != cur->tex_enabled[a]) { + gl4es_glActiveTexture(GL_TEXTURE0+a); + for (int j=0; jtex_enabled[a] & (1<enable.texture[a] & (1<enable.texgen_r[a] = cur->texgen_r[a]; glstate->enable.texgen_s[a] = cur->texgen_s[a]; glstate->enable.texgen_t[a] = cur->texgen_t[a]; @@ -552,10 +548,11 @@ void gl4es_glPopAttrib() { glstate->enable.texgen_t[a] = cur->texgen_t[a]; glstate->enable.texgen_q[a] = cur->texgen_q[a]; glstate->texgen[a] = cur->texgen[a]; // all mode and planes per texture in 1 line - if ((cur->texture[a]==0 && glstate->texture.bound[a] != 0) || (cur->texture[a]!=0 && glstate->texture.bound[a]==0)) { - gl4es_glActiveTexture(GL_TEXTURE0+a); - gl4es_glBindTexture(GL_TEXTURE_2D, cur->texture[a]); - } + for (int j=0; jtexture[a][j]==0 && glstate->texture.bound[a][j] != 0) || (cur->texture[a][j]!=0 && glstate->texture.bound[a][j]==0)) { + gl4es_glActiveTexture(GL_TEXTURE0+a); + gl4es_glBindTexture(to_target(j), cur->texture[a][j]); + } } if (glstate->texture.active!= cur->active) gl4es_glActiveTexture(GL_TEXTURE0+cur->active); } diff --git a/project/jni/gl4es/src/gl/stack.h b/project/jni/gl4es/src/gl/stack.h index e6da1f0e5..dad16ccd4 100755 --- a/project/jni/gl4es/src/gl/stack.h +++ b/project/jni/gl4es/src/gl/stack.h @@ -59,9 +59,7 @@ typedef struct _glstack_t { GLboolean normalize; GLboolean polygon_offset_fill; GLboolean stencil_test; - GLboolean texture_1d[MAX_TEX]; - GLboolean texture_2d[MAX_TEX]; - GLboolean texture_3d[MAX_TEX]; + GLuint tex_enabled[MAX_TEX]; GLboolean texgen_s[MAX_TEX]; GLboolean texgen_r[MAX_TEX]; GLboolean texgen_t[MAX_TEX]; @@ -129,7 +127,7 @@ typedef struct _glstack_t { GLenum stencil_dppass; // GL_TEXTURE_BIT - GLint texture[MAX_TEX]; + GLint texture[MAX_TEX][ENABLED_TEXTURE_LAST]; texgen_state_t texgen[MAX_TEX]; GLint active; diff --git a/project/jni/gl4es/src/gl/state.h b/project/jni/gl4es/src/gl/state.h index 9a20bb810..d3a6489de 100755 --- a/project/jni/gl4es/src/gl/state.h +++ b/project/jni/gl4es/src/gl/state.h @@ -20,13 +20,10 @@ typedef struct { texgen_s[MAX_TEX], texgen_t[MAX_TEX], texgen_r[MAX_TEX], - texgen_q[MAX_TEX], - texture_2d[MAX_TEX], - texture_3d[MAX_TEX], - texture_1d[MAX_TEX]; + texgen_q[MAX_TEX]; + GLuint texture[MAX_TEX]; // flag } enable_state_t; - typedef struct { GLenum S; GLenum T; @@ -56,7 +53,7 @@ typedef struct { GLboolean pack_lsb_first; // TODO: do we only need to worry about GL_TEXTURE_2D? GLboolean rect_arb[MAX_TEX]; - gltexture_t *bound[MAX_TEX]; + gltexture_t *bound[MAX_TEX][ENABLED_TEXTURE_LAST]; GLboolean pscoordreplace[MAX_TEX]; khash_t(tex) *list; GLuint active; // active texture diff --git a/project/jni/gl4es/src/gl/texgen.c b/project/jni/gl4es/src/gl/texgen.c index 42963fde2..51ebf1cca 100755 --- a/project/jni/gl4es/src/gl/texgen.c +++ b/project/jni/gl4es/src/gl/texgen.c @@ -259,7 +259,7 @@ 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]) + if (!IS_TEX2D(glstate->enable.texture[texture])) return; if ((*coords)==NULL) *coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat)); @@ -271,7 +271,7 @@ 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))) { - if (!glstate->enable.texture_2d[texture]) + if (!IS_TEX2D(glstate->enable.texture[texture])) return; if ((*coords)==NULL) *coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat)); @@ -301,7 +301,7 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count return; } - if (!glstate->enable.texture_2d[texture]) + if (!IS_ANYTEX(glstate->enable.texture[texture])) return; if ((*coords)==NULL) *coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat)); diff --git a/project/jni/gl4es/src/gl/texture.c b/project/jni/gl4es/src/gl/texture.c index 1bd12a1fb..b9bcd39fc 100755 --- a/project/jni/gl4es/src/gl/texture.c +++ b/project/jni/gl4es/src/gl/texture.c @@ -71,20 +71,20 @@ void tex_coord_matrix(GLfloat *tex, GLsizei len, const GLfloat* mat) { * Apply texture matrix if not identity * Or some NPOT texture used */ -void tex_setup_texcoord(GLuint len) { +void tex_setup_texcoord(GLuint len, GLuint itarget) { LOAD_GLES(glTexCoordPointer); GLuint texunit = glstate->texture.client; static void * tex[MAX_TEX] = {0}; static int texlen[MAX_TEX] = {0}; - gltexture_t *bound = glstate->texture.bound[texunit]; + gltexture_t *bound = glstate->texture.bound[texunit][itarget]; // check if some changes are needed int changes = 0; if ((glstate->texture.rect_arb[texunit]) || (bound && ((bound->width!=bound->nwidth)||(bound->height!=bound->nheight) - )) || !glstate->texture_matrix[texunit]->identity + )) || !(globals4es.texmat || glstate->texture_matrix[texunit]->identity) ) changes = 1; if (changes) { @@ -99,7 +99,7 @@ void tex_setup_texcoord(GLuint len) { 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) + if (!(globals4es.texmat || glstate->texture_matrix[texunit]->identity)) tex_coord_matrix(tex[texunit], len, getTexMat(texunit)); // NPOT adjust if (bound && ((bound->width!=bound->nwidth) || (bound->height!=bound->nheight))) @@ -447,7 +447,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, //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])?glstate->texture.bound[glstate->texture.active]->mipmap_need:0, (glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->mipmap_auto:0, (glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->texture:0, (glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->streamed:0, glstate->list.compiling); // proxy case - if (target == GL_PROXY_TEXTURE_2D) { + if (target == GL_PROXY_TEXTURE_2D || target == GL_PROXY_TEXTURE_1D || target == GL_PROXY_TEXTURE_3D) { proxy_width = ((width<(globals4es.texshrink>=8)?8192:2048)?0:width; proxy_height = ((height<(globals4es.texshrink>=8)?8192:2048)?0:height; proxy_intformat = swizzle_internalformat(&internalformat); @@ -460,6 +460,8 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, glstate->gl_batch = 0; } + GLuint itarget = what_target(target); + GLvoid *datab = (GLvoid*)data; if (glstate->vao->unpack) @@ -469,7 +471,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, border = 0; //TODO: something? noerrorShim(); - gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active][itarget]; if (bound) bound->alpha = pixel_hasalpha(format); if (globals4es.automipmap) { if (bound && (level>0)) @@ -700,7 +702,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, if (bound->streamingID>-1) { // success bound->streamed = true; ApplyFilterID(bound->streamingID, bound->min_filter, bound->mag_filter); - GLboolean tmp = glstate->enable.texture_2d[glstate->texture.active]; + GLboolean tmp = IS_TEX2D(glstate->enable.texture[glstate->texture.active]); LOAD_GLES(glDisable); LOAD_GLES(glEnable); if (tmp) @@ -787,81 +789,77 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, LOAD_GLES(glTexSubImage2D); LOAD_GLES(glTexParameteri); - switch (target) { - case GL_PROXY_TEXTURE_2D: - break; - default: { - GLsizei nheight = (hardext.npot==2)?height:npot(height), nwidth = (hardext.npot==2)?width:npot(width); + { + GLsizei nheight = (hardext.npot==2)?height:npot(height), nwidth = (hardext.npot==2)?width:npot(width); #ifdef PANDORA #define NO_1x1 #endif #ifdef NO_1x1 - #define MIN_SIZE 2 - if(level==0) { - if(nwidth < MIN_SIZE) nwidth=MIN_SIZE; - if(nheight < MIN_SIZE) nheight=MIN_SIZE; - } - #undef MIN_SIZE -#endif - if (globals4es.texstream && bound && bound->streamed) { - nwidth = width; - nheight = height; - } - if (bound && (level == 0)) { - bound->width = width; - bound->height = height; - bound->nwidth = nwidth; - bound->nheight = nheight; - bound->format = format; - bound->type = type; - bound->compressed = false; - } - if ((bound) && (globals4es.automipmap==4) && (nwidth!=nheight)) - bound->mipmap_auto = 0; - - if (!(globals4es.texstream && bound && bound->streamed)) { - if (bound && ((bound->mipmap_need && (globals4es.automipmap!=3)) || (bound->mipmap_auto))) - gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_TRUE ); - else { - gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE ); - if ((bound) && (bound->mipmap_need)) { - // remove the need for mipmap... - bound->mipmap_need = 0; - gl4es_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, bound->min_filter); - gl4es_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, bound->mag_filter); - } - } - - if (height != nheight || width != nwidth) { - gles_glTexImage2D(target, level, format, nwidth, nheight, border, - format, type, NULL); - if (pixels) gles_glTexSubImage2D(target, level, 0, 0, width, height, - format, type, pixels); - errorGL(); -#ifdef NO_1x1 - if(level==0 && (width==1 || height==1 && pixels)) { - // complete the texture, juste in ase it use GL_REPEAT - // also, don't keep the fact we have resized, the non-adjusted coordinates will work (as the texture is enlarged) - if(width==1) {gles_glTexSubImage2D(target, level, 1, 0, width, height, format, type, pixels); nwidth=1;} - if(height==1) {gles_glTexSubImage2D(target, level, 0, 1, width, height, format, type, pixels); nheight=1;} - if(width==1 && height==1) { // create a manual mipmap just in case_state - gles_glTexSubImage2D(target, level, 1, 1, width, height, format, type, pixels); - gles_glTexImage2D(target, 1, format, 1, 1, 0, format, type, pixels); - } - } -#endif - } else { - gles_glTexImage2D(target, level, format, width, height, border, - format, type, pixels); - errorGL(); - } - /*if (bound && bound->mipmap_need && !bound->mipmap_auto && (globals4es.automipmap!=3)) - gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE );*/ - } else { - if (pixels) - gl4es_glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); // (should never happens) updload the 1st data... - } + #define MIN_SIZE 2 + if(level==0) { + if(nwidth < MIN_SIZE) nwidth=MIN_SIZE; + if(nheight < MIN_SIZE) nheight=MIN_SIZE; } + #undef MIN_SIZE +#endif + if (globals4es.texstream && bound && bound->streamed) { + nwidth = width; + nheight = height; + } + if (bound && (level == 0)) { + bound->width = width; + bound->height = height; + bound->nwidth = nwidth; + bound->nheight = nheight; + bound->format = format; + bound->type = type; + bound->compressed = false; + } + if ((bound) && (globals4es.automipmap==4) && (nwidth!=nheight)) + bound->mipmap_auto = 0; + + if (!(globals4es.texstream && bound && bound->streamed)) { + if (bound && ((bound->mipmap_need && (globals4es.automipmap!=3)) || (bound->mipmap_auto))) + gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_TRUE ); + else { + gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE ); + if ((bound) && (bound->mipmap_need)) { + // remove the need for mipmap... + bound->mipmap_need = 0; + gl4es_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, bound->min_filter); + gl4es_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, bound->mag_filter); + } + } + + if (height != nheight || width != nwidth) { + gles_glTexImage2D(target, level, format, nwidth, nheight, border, + format, type, NULL); + if (pixels) gles_glTexSubImage2D(target, level, 0, 0, width, height, + format, type, pixels); + errorGL(); +#ifdef NO_1x1 + if(level==0 && (width==1 || height==1 && pixels)) { + // complete the texture, juste in ase it use GL_REPEAT + // also, don't keep the fact we have resized, the non-adjusted coordinates will work (as the texture is enlarged) + if(width==1) {gles_glTexSubImage2D(target, level, 1, 0, width, height, format, type, pixels); nwidth=1;} + if(height==1) {gles_glTexSubImage2D(target, level, 0, 1, width, height, format, type, pixels); nheight=1;} + if(width==1 && height==1) { // create a manual mipmap just in case_state + gles_glTexSubImage2D(target, level, 1, 1, width, height, format, type, pixels); + gles_glTexImage2D(target, 1, format, 1, 1, 0, format, type, pixels); + } + } +#endif + } else { + gles_glTexImage2D(target, level, format, width, height, border, + format, type, pixels); + errorGL(); + } + /*if (bound && bound->mipmap_need && !bound->mipmap_auto && (globals4es.automipmap!=3)) + gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE );*/ + } else { + if (pixels) + gl4es_glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); // (should never happens) updload the 1st data... + } } if ((target==GL_TEXTURE_2D) && globals4es.texcopydata && bound && ((globals4es.texstream && !bound->streamed) || !globals4es.texstream)) { if (bound->data) @@ -897,6 +895,8 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff datab += (uintptr_t)glstate->vao->pack->data; GLvoid *pixels = (GLvoid*)datab; + const GLuint itarget = what_target(target); + LOAD_GLES(glTexSubImage2D); LOAD_GLES(glTexParameteri); noerrorShim(); @@ -907,7 +907,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff } target = map_tex_target(target); - gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active][itarget]; if (globals4es.automipmap) { if (bound && (level>0)) if ((globals4es.automipmap==1) || (globals4es.automipmap==3) || bound->mipmap_need) { @@ -1055,30 +1055,30 @@ void gl4es_glTexImage1D(GLenum target, GLint level, GLint internalFormat, GLenum format, GLenum type, const GLvoid *data) { // TODO: maybe too naive to force GL_TEXTURE_2D here? - gl4es_glTexImage2D(GL_TEXTURE_2D, level, internalFormat, width, 1, + gl4es_glTexImage2D(GL_TEXTURE_1D, level, internalFormat, width, 1, border, format, type, data); } void gl4es_glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *data) { - gl4es_glTexSubImage2D(GL_TEXTURE_2D, level, xoffset, 0, + gl4es_glTexSubImage2D(GL_TEXTURE_1D, level, xoffset, 0, width, 1, format, type, data); } void gl4es_glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { - gl4es_glCopyTexImage2D(GL_TEXTURE_2D, level, internalformat, x, y, width, 1, border); + gl4es_glCopyTexImage2D(GL_TEXTURE_1D, level, internalformat, x, y, width, 1, border); } void gl4es_glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { - gl4es_glCopyTexSubImage2D(GL_TEXTURE_2D, level, xoffset, 0, x, y, width, 1); + gl4es_glCopyTexSubImage2D(GL_TEXTURE_1D, level, xoffset, 0, x, y, width, 1); } void gl4es_glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - gl4es_glCopyTexSubImage2D(GL_TEXTURE_2D, level, xoffset, yoffset, x, y, width, height); + gl4es_glCopyTexSubImage2D(GL_TEXTURE_3D, level, xoffset, yoffset, x, y, width, height); } @@ -1090,14 +1090,14 @@ void gl4es_glTexImage3D(GLenum target, GLint level, GLint internalFormat, GLenum format, GLenum type, const GLvoid *data) { // TODO: maybe too naive to force GL_TEXTURE_2D here? - gl4es_glTexImage2D(GL_TEXTURE_2D, level, internalFormat, width, height, + gl4es_glTexImage2D(GL_TEXTURE_3D, level, internalFormat, width, height, border, format, type, data); } void gl4es_glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *data) { - gl4es_glTexSubImage2D(target, level, xoffset, yoffset, + gl4es_glTexSubImage2D(GL_TEXTURE_3D, level, xoffset, yoffset, width, height, format, type, data); } @@ -1149,7 +1149,7 @@ void gl4es_glPixelStorei(GLenum pname, GLint param) { break; } } -GLboolean gl4es_glIsTexture( GLuint texture) { +GLboolean gl4es_glIsTexture(GLuint texture) { noerrorShim(); if (!texture) { return GL_FALSE; @@ -1231,16 +1231,17 @@ void gl4es_glBindTexture(GLenum target, GLuint texture) { int tex_changed = 1; 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] == tex) + 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] == NULL) + if (glstate->texture.bound[glstate->texture.active][itarget] == NULL) tex_changed = 0; } @@ -1250,10 +1251,10 @@ tex_changed=1; // seems buggy, temporary disabling that... if (tex_changed) { - GLboolean tmp = glstate->enable.texture_2d[glstate->texture.active]; + GLuint tmp = glstate->enable.texture[glstate->texture.active]; #ifdef TEXSTREAM if (globals4es.texstream) { // unbind streaming texture if any... - gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active][itarget]; if (bound && bound->streamed) { if (tmp) gles_glDisable(GL_TEXTURE_STREAM_IMG); @@ -1267,15 +1268,15 @@ tex_changed=1; // seems buggy, temporary disabling that... glstate->texture.rect_arb[glstate->texture.active] = (target == GL_TEXTURE_RECTANGLE_ARB); target = map_tex_target(target); - glstate->texture.bound[glstate->texture.active] = tex; + glstate->texture.bound[glstate->texture.active][itarget] = tex; LOAD_GLES(glBindTexture); #ifdef TEXSTREAM if (globals4es.texstream && (streamingID>-1)) { - if (tmp) + if (IS_TEX2D(tmp)) gles_glDisable(GL_TEXTURE_2D); ActivateStreaming(streamingID); - if (tmp) + if (IS_TEX2D(tmp)) gles_glEnable(GL_TEXTURE_STREAM_IMG); } else #endif @@ -1292,8 +1293,9 @@ tex_changed=1; // seems buggy, temporary disabling that... void gl4es_glTexParameteri(GLenum target, GLenum pname, GLint param) { PUSH_IF_COMPILING(glTexParameteri); LOAD_GLES(glTexParameteri); + const GLint itarget = what_target(target); target = map_tex_target(target); - gltexture_t *texture = glstate->texture.bound[glstate->texture.active]; + gltexture_t *texture = glstate->texture.bound[glstate->texture.active][itarget]; switch (pname) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: @@ -1370,8 +1372,9 @@ void gl4es_glDeleteTextures(GLsizei n, const GLuint *textures) { tex = kh_value(list, k); int a; for (a=0; atexture.bound[a]) - glstate->texture.bound[a] = NULL; + for (int j=0; jtexture.bound[a][j]) + glstate->texture.bound[a][j] = NULL; } gles_glDeleteTextures(1, &tex->glname); errorGL(); @@ -1454,7 +1457,9 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL if (glstate->gl_batch) flush(); *params = 0; noerrorShim(); - gltexture_t* bound = glstate->texture.bound[glstate->texture.active]; + const GLuint itarget = what_target(target); + target = map_tex_target(target); + gltexture_t* bound = glstate->texture.bound[glstate->texture.active][itarget]; switch (pname) { case GL_TEXTURE_WIDTH: if (target==GL_PROXY_TEXTURE_2D) @@ -1554,14 +1559,15 @@ 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) { - flush(); - glstate->gl_batch = 0; - } - if (glstate->texture.bound[glstate->texture.active]==NULL) + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { + flush(); + glstate->gl_batch = 0; + } + const GLuint itarget = what_target(target); + if (glstate->texture.bound[glstate->texture.active][itarget]==NULL) return; // no texture bounded... - gltexture_t* bound = glstate->texture.bound[glstate->texture.active]; + gltexture_t* bound = glstate->texture.bound[glstate->texture.active][itarget]; int width = bound->width; int height = bound->height; int nwidth = bound->nwidth; @@ -1856,8 +1862,10 @@ void gl4es_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint glbuffer_t *unpack = glstate->vao->unpack; glstate->vao->pack = NULL; glstate->vao->unpack = NULL; + + const GLuint itarget = what_target(target); - gltexture_t* bound = glstate->texture.bound[glstate->texture.active]; + gltexture_t* bound = glstate->texture.bound[glstate->texture.active][itarget]; if (!bound) { errorShim(GL_INVALID_OPERATION); glstate->gl_batch = old_glbatch; @@ -2007,6 +2015,8 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) { + const GLuint itarget = what_target(target); + target = map_tex_target(target); if (target == GL_PROXY_TEXTURE_2D) { proxy_width = (width>2048)?0:width; proxy_height = (height>2048)?0:height; @@ -2018,7 +2028,8 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor glstate->gl_batch = 0; } - if (glstate->texture.bound[glstate->texture.active]==NULL) { + gltexture_t* bound = glstate->texture.bound[glstate->texture.active][itarget]; + if (bound==NULL) { errorShim(GL_INVALID_OPERATION); return; // no texture bounded... } @@ -2077,7 +2088,7 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor } // automaticaly reduce the pixel size half=pixels; - glstate->texture.bound[glstate->texture.active]->alpha = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true; + bound->alpha = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true; format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA; type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4; if (pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) @@ -2088,9 +2099,9 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor format = GL_RGBA; type = GL_UNSIGNED_BYTE; } - glstate->texture.bound[glstate->texture.active]->format = format; //internalformat; - glstate->texture.bound[glstate->texture.active]->type = type; - glstate->texture.bound[glstate->texture.active]->compressed = true; + bound->format = format; //internalformat; + bound->type = type; + bound->compressed = true; } else { fact = 0; } @@ -2106,10 +2117,10 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor if (pixels!=datab) free(pixels); } else { - glstate->texture.bound[glstate->texture.active]->alpha = true; - glstate->texture.bound[glstate->texture.active]->format = internalformat; - glstate->texture.bound[glstate->texture.active]->type = GL_UNSIGNED_BYTE; - glstate->texture.bound[glstate->texture.active]->compressed = true; + bound->alpha = true; + bound->format = internalformat; + bound->type = GL_UNSIGNED_BYTE; + bound->compressed = true; gles_glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, datab); } glstate->vao->unpack = unpack; @@ -2120,13 +2131,14 @@ void gl4es_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) { - GLuint old_glbatch = glstate->gl_batch; - if (glstate->gl_batch) { - flush(); - glstate->gl_batch = 0; - } - - if (glstate->texture.bound[glstate->texture.active]==NULL) { + const GLuint itarget = what_target(target); + const GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { + flush(); + glstate->gl_batch = 0; + } + gltexture_t *bound = glstate->texture.bound[glstate->texture.active][itarget]; + if (bound==NULL) { errorShim(GL_INVALID_OPERATION); glstate->gl_batch = old_glbatch; return; // no texture bounded... @@ -2172,8 +2184,8 @@ void gl4es_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, gl4es_glTexSubImage2D(target, level, xoffset/2, yoffset/2, width/2, height/2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, half); if (oldalign!=1) gl4es_glPixelStorei(GL_UNPACK_ALIGNMENT, oldalign); #else - GLenum format = glstate->texture.bound[glstate->texture.active]->format; - GLenum type = glstate->texture.bound[glstate->texture.active]->type; + GLenum format = bound->format; + GLenum type = bound->type; pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0); gl4es_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, half); #endif @@ -2190,7 +2202,8 @@ void gl4es_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, void gl4es_glGetCompressedTexImage(GLenum target, GLint lod, GLvoid *img) { if (glstate->gl_batch) flush(); - gltexture_t* bound = glstate->texture.bound[glstate->texture.active]; + const GLuint itarget = what_target(target); + gltexture_t* bound = glstate->texture.bound[glstate->texture.active][itarget]; //printf("glGetCompressedTexImage(%s, %i, %p), bound=%p, bound->orig_internal=%s\n", PrintEnum(target), lod, img, bound, (bound)?PrintEnum(bound->orig_internal):"nil"); errorShim(GL_INVALID_OPERATION); if(!bound) diff --git a/project/jni/gl4es/src/gl/texture.h b/project/jni/gl4es/src/gl/texture.h index c4dfd0195..2473941d1 100755 --- a/project/jni/gl4es/src/gl/texture.h +++ b/project/jni/gl4es/src/gl/texture.h @@ -93,6 +93,19 @@ void tex_coord_matrix(GLfloat *tex, GLsizei len, const GLfloat* mat); int npot(int n); +typedef enum { + ENABLED_TEX1D = 0, + ENABLED_TEX2D, + ENABLED_TEX3D, + ENABLED_CUBE_MAP_POSITIVE_X, + ENABLED_CUBE_MAP_NEGATIVE_X, + ENABLED_CUBE_MAP_POSITIVE_Y, + ENABLED_CUBE_MAP_NEGATIVE_Y, + ENABLED_CUBE_MAP_POSITIVE_Z, + ENABLED_CUBE_MAP_NEGATIVE_Z, + ENABLED_TEXTURE_LAST +} texture_enabled_t; + typedef struct { GLuint texture; GLuint glname; @@ -138,11 +151,62 @@ static inline GLenum map_tex_target(GLenum target) { } gltexture_t* gl4es_getTexture(GLenum target, GLuint texture); +static inline GLuint what_target(GLenum target) { + switch(target) { + case GL_TEXTURE_1D: + return ENABLED_TEX1D; + case GL_TEXTURE_3D: + return ENABLED_TEX3D; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + return ENABLED_CUBE_MAP_POSITIVE_X+(target-GL_TEXTURE_CUBE_MAP_POSITIVE_X); + case GL_TEXTURE_RECTANGLE_ARB: + case GL_TEXTURE_2D: + default: + return ENABLED_TEX2D; + } +} +static inline GLenum to_target(GLuint itarget) { + switch(itarget) { + case ENABLED_TEX1D: + return GL_TEXTURE_1D; + case ENABLED_TEX3D: + return GL_TEXTURE_3D; + case ENABLED_CUBE_MAP_POSITIVE_X: + case ENABLED_CUBE_MAP_NEGATIVE_X: + case ENABLED_CUBE_MAP_POSITIVE_Y: + case ENABLED_CUBE_MAP_NEGATIVE_Y: + case ENABLED_CUBE_MAP_POSITIVE_Z: + case ENABLED_CUBE_MAP_NEGATIVE_Z: + return GL_TEXTURE_CUBE_MAP_POSITIVE_X+(itarget-ENABLED_CUBE_MAP_POSITIVE_X); + case ENABLED_TEX2D: + default: + return GL_TEXTURE_2D; + } +} +#define IS_TEX2D(T) (T&(1<