diff --git a/project/jni/glshim/Android.mk b/project/jni/glshim/Android.mk index 8ea5008ac..ffba7b59f 100644 --- a/project/jni/glshim/Android.mk +++ b/project/jni/glshim/Android.mk @@ -19,6 +19,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) -DBCMHOST LOCAL_SRC_FILES := \ src/gl/array.c \ src/gl/buffers.c \ + src/gl/debug.c \ src/gl/decompress.c \ src/gl/eval.c \ src/gl/framebuffers.c \ diff --git a/project/jni/glshim/src/gl/list.c b/project/jni/glshim/src/gl/list.c index 6aee5532f..2060724e0 100755 --- a/project/jni/glshim/src/gl/list.c +++ b/project/jni/glshim/src/gl/list.c @@ -62,6 +62,7 @@ renderlist_t *alloc_renderlist() { list->set_texture = false; list->texture = 0;*/ list->target_texture = GL_TEXTURE_2D; + list->tmu = state.texture.active; /* list->polygon_mode = 0; list->fog_op = 0; @@ -96,6 +97,8 @@ bool ispurerender_renderlist(renderlist_t *list) { return false; if (list->mode_init == 0) return false; + if (list->set_texture || list->set_tmu) + return false; return true; } @@ -494,6 +497,7 @@ renderlist_t *extend_renderlist(renderlist_t *list) { renderlist_t *new = alloc_renderlist(); list->next = new; new->prev = list; + new->tmu = list->tmu; if (list->open) end_renderlist(list); return new; @@ -584,6 +588,10 @@ void adjust_renderlist(renderlist_t *list) { list->open = false; for (int a=0; aset_texture && (list->tmu == a)) + bound = 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); } @@ -672,11 +680,14 @@ void draw_renderlist(renderlist_t *list) { break; } } - old_tex = state.texture.active; + if (list->set_tmu) { + glActiveTexture(GL_TEXTURE0+list->tmu); + } if (list->set_texture) { - glBindTexture(list->target_texture, list->texture); + glBindTexture(list->target_texture, list->texture); } // raster + old_tex = state.texture.active; if (list->raster_op) { if (list->raster_op==1) { glRasterPos3f(list->raster_xyz[0], list->raster_xyz[1], list->raster_xyz[2]); @@ -1251,6 +1262,11 @@ void rlMultiTexCoord2f(renderlist_t *list, GLenum target, GLfloat s, GLfloat t) tex[0] = s; tex[1] = t; } +void rlActiveTexture(renderlist_t *list, GLenum texture ) { + list->set_tmu = true; + list->tmu = texture - GL_TEXTURE0; +} + void rlBindTexture(renderlist_t *list, GLenum target, GLuint texture) { list->texture = texture; list->target_texture = target; diff --git a/project/jni/glshim/src/gl/list.h b/project/jni/glshim/src/gl/list.h index a88e7f83c..707592e09 100755 --- a/project/jni/glshim/src/gl/list.h +++ b/project/jni/glshim/src/gl/list.h @@ -11,6 +11,7 @@ typedef enum { STAGE_GLCALL, STAGE_FOG, STAGE_MATRIX, + STAGE_ACTIVETEX, STAGE_BINDTEX, STAGE_RASTER, STAGE_MATERIAL, @@ -30,6 +31,7 @@ static int StageExclusive[STAGE_LAST] = { 0, // STAGE_GLCALL 1, // STAGE_FOG 1, // STAGE_MATRIX + 1, // STAGE_ACTIVETEX 1, // STAGE_BINDTEX 1, // STAGE_RASTER 0, // STAGE_MATERIAL @@ -126,8 +128,10 @@ typedef struct _renderlist_t { GLfloat *lightmodel; GLenum lightmodelparam; GLenum polygon_mode; - GLuint texture; // I cannot know the active texture inside a list (for now => TODO?) - GLenum target_texture; // to support cube maps... + GLboolean set_tmu; // TRUE is glActiveTexture called + int tmu; // the current TMU... + GLuint texture; + GLenum target_texture; GLboolean set_texture; struct _renderlist_t *prev; struct _renderlist_t *next; @@ -147,6 +151,7 @@ extern void free_renderlist(renderlist_t *list); extern void draw_renderlist(renderlist_t *list); extern void end_renderlist(renderlist_t *list); +extern void rlActiveTexture(renderlist_t *list, GLenum texture ); extern void rlBindTexture(renderlist_t *list, GLenum target, GLuint texture); extern void rlColor4f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b, GLfloat a); extern void rlMaterialfv(renderlist_t *list, GLenum face, GLenum pname, const GLfloat * params); diff --git a/project/jni/glshim/src/gl/texture.c b/project/jni/glshim/src/gl/texture.c index 1fb217ef5..454a6153a 100755 --- a/project/jni/glshim/src/gl/texture.c +++ b/project/jni/glshim/src/gl/texture.c @@ -826,6 +826,46 @@ GLboolean glIsTexture( GLuint texture) { return GL_TRUE; } +gltexture_t* getTexture(GLenum target, GLuint texture) { + // Get a texture based on glID + gltexture_t* tex = NULL; + if (texture == 0) return tex; + int ret; + khint_t k; + khash_t(tex) *list = state.texture.list; + if (! list) { + list = state.texture.list = kh_init(tex); + // segfaults if we don't do a single put + kh_put(tex, list, 1, &ret); + kh_del(tex, list, 1); + } + k = kh_get(tex, list, texture); + + if (k == kh_end(list)){ + LOAD_GLES(glGenTextures); + k = kh_put(tex, list, texture, &ret); + tex = kh_value(list, k) = malloc(sizeof(gltexture_t)); + tex->texture = texture; + gles_glGenTextures(1, &tex->glname); + tex->target = target; + tex->width = 0; + tex->height = 0; + tex->uploaded = false; + tex->mipmap_auto = default_tex_mipmap; + tex->mipmap_need = 0; + tex->alpha = true; + tex->streamed = false; + tex->streamingID = -1; + tex->min_filter = tex->mag_filter = GL_LINEAR; + tex->format = GL_RGBA; + tex->type = GL_UNSIGNED_BYTE; + tex->data = NULL; + } else { + tex = kh_value(list, k); + } + return tex; +} + void glBindTexture(GLenum target, GLuint texture) { noerrorShim(); if ((target!=GL_PROXY_TEXTURE_2D) && (state.list.active && (state.gl_batch && !state.list.compiling))) { @@ -848,39 +888,7 @@ void glBindTexture(GLenum target, GLuint texture) { gltexture_t *tex = NULL; //printf("glBindTexture(0x%04X, %u), active=%i, client=%i\n", target, texture, state.texture.active, state.texture.client); if (texture) { - int ret; - khint_t k; - khash_t(tex) *list = state.texture.list; - if (! list) { - list = state.texture.list = kh_init(tex); - // segfaults if we don't do a single put - kh_put(tex, list, 1, &ret); - kh_del(tex, list, 1); - } - k = kh_get(tex, list, texture); - - if (k == kh_end(list)){ - LOAD_GLES(glGenTextures); - k = kh_put(tex, list, texture, &ret); - tex = kh_value(list, k) = malloc(sizeof(gltexture_t)); - tex->texture = texture; - gles_glGenTextures(1, &tex->glname); - tex->target = target; - tex->width = 0; - tex->height = 0; - tex->uploaded = false; - tex->mipmap_auto = default_tex_mipmap; - tex->mipmap_need = 0; - tex->alpha = true; - tex->streamed = false; - tex->streamingID = -1; - tex->min_filter = tex->mag_filter = GL_LINEAR; - tex->format = GL_RGBA; - tex->type = GL_UNSIGNED_BYTE; - tex->data = NULL; - } else { - tex = kh_value(list, k); - } + tex = getTexture(target, texture); if (state.texture.bound[state.texture.active] == tex) tex_changed = 0; texture = tex->glname; @@ -1218,7 +1226,11 @@ void glActiveTexture( GLenum texture ) { flush(); } } - PUSH_IF_COMPILING(glActiveTexture); + if (state.list.active) { + NewStage(state.list.active, STAGE_ACTIVETEX); + rlActiveTexture(state.list.active, texture); + return; + } if ((texture < GL_TEXTURE0) || (texture >= GL_TEXTURE0+MAX_TEX)) { errorShim(GL_INVALID_ENUM); @@ -1246,7 +1258,7 @@ void glClientActiveTexture( GLenum texture ) { } void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * data) { -//printf("glReadPixels(%i, %i, %i, %i, 0x%04X, 0x%04X, 0x%p)\n", x, y, width, height, format, type, data); + //printf("glReadPixels(%i, %i, %i, %i, 0x%04X, 0x%04X, 0x%p)\n", x, y, width, height, format, type, data); GLuint old_glbatch = state.gl_batch; if (state.gl_batch) { flush(); @@ -1288,7 +1300,7 @@ void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { //printf("glCopyTexSubImage2D(%s, %i, %i, %i, %i, %i, %i, %i), bounded texture=%u format/type=%s, %s\n", PrintEnum(target), level, xoffset, yoffset, x, y, width, height, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->texture:0, PrintEnum((state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->format:0), PrintEnum((state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->type:0)); -// PUSH_IF_COMPILING(glCopyTexSubImage2D); + // PUSH_IF_COMPILING(glCopyTexSubImage2D); GLuint old_glbatch = state.gl_batch; if (state.gl_batch) { flush(); diff --git a/project/jni/glshim/src/gl/texture.h b/project/jni/glshim/src/gl/texture.h index 23f4e9117..aa3158407 100755 --- a/project/jni/glshim/src/gl/texture.h +++ b/project/jni/glshim/src/gl/texture.h @@ -118,6 +118,7 @@ static inline GLenum map_tex_target(GLenum target) { } return target; } +gltexture_t* getTexture(GLenum target, GLuint texture); void glActiveTexture( GLenum texture ); void glClientActiveTexture( GLenum texture );