From 4f2acb52ad17cd99e61993711d7ffa61d2117f24 Mon Sep 17 00:00:00 2001 From: lubomyr Date: Sun, 27 Sep 2015 15:11:13 +0300 Subject: [PATCH] glshim updated. added changes from https://github.com/ptitSeb/glshim --- project/jni/glshim/src/gl/array.c | 53 +++++- project/jni/glshim/src/gl/debug.c | 59 +++++++ project/jni/glshim/src/gl/debug.h | 8 + project/jni/glshim/src/gl/framebuffers.c | 200 ++++++++++++++--------- project/jni/glshim/src/gl/gl.c | 69 ++++---- project/jni/glshim/src/gl/gl.h | 22 +++ project/jni/glshim/src/gl/list.c | 167 +++++++++---------- project/jni/glshim/src/gl/pixel.c | 12 +- project/jni/glshim/src/gl/stack.c | 6 +- project/jni/glshim/src/gl/stack.h | 13 +- project/jni/glshim/src/gl/state.h | 10 +- project/jni/glshim/src/gl/texgen.c | 166 +++++++++---------- project/jni/glshim/src/gl/texture.c | 30 +++- project/jni/glshim/src/gl/wrap/gl.c | 7 +- project/jni/glshim/src/glx/glx.c | 2 + 15 files changed, 492 insertions(+), 332 deletions(-) create mode 100755 project/jni/glshim/src/gl/debug.c create mode 100755 project/jni/glshim/src/gl/debug.h diff --git a/project/jni/glshim/src/gl/array.c b/project/jni/glshim/src/gl/array.c index e0f7aa60a..c94688d49 100755 --- a/project/jni/glshim/src/gl/array.c +++ b/project/jni/glshim/src/gl/array.c @@ -1,4 +1,5 @@ #include "array.h" +#include "debug.h" GLvoid *copy_gl_array(const GLvoid *src, GLenum from, GLsizei width, GLsizei stride, @@ -63,16 +64,51 @@ GLvoid *copy_gl_array(const GLvoid *src, return dst; } +GLvoid *copy_gl_array_quickconvert(const GLvoid *src, + GLenum from, GLsizei stride, + GLsizei skip, GLsizei count) { + + if (! stride) + stride = 4 * gl_sizeof(from); + const char *unknown_str = "libGL: copy_gl_array_quickconvert -> unknown type: %x\n"; + GLvoid *dst = malloc((count-skip) * 4 * gl_sizeof(GL_FLOAT)); + GLsizei from_size = gl_sizeof(from) * 4; + GLsizei to_size = gl_sizeof(GL_FLOAT) * 4; + + uintptr_t in = (uintptr_t)src; + in += stride*skip; + int j; + + GLfloat *out = (GLfloat*)dst; + GL_TYPE_SWITCH2(input, in, from, + const GLfloat maxf = 1.0f/gl_max_value(from); + for (int i = skip; i < count; i++) + , + for (j = 0; j < 4; j++) { + out[j] = ((GLfloat)input[j])*maxf; + } + out += 4; + in += stride; + , + default: + printf(unknown_str, from); + return NULL; + ) + return dst; +} + GLvoid *copy_gl_array_convert(const GLvoid *src, GLenum from, GLsizei width, GLsizei stride, GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, GLvoid* filler) { if (! src || !count) return NULL; + + if(to==GL_FLOAT && width==to_width && width==4) + return copy_gl_array_quickconvert(src, from, stride, skip, count); if (! stride) stride = width * gl_sizeof(from); - - const char *unknown_str = "libGL: copy_gl_array -> unknown type: %x\n"; + const char *unknown_str = "libGL: copy_gl_array_convert -> unknown type: %x\n"; GLvoid *dst = malloc((count-skip) * to_width * gl_sizeof(to)); GLsizei from_size = gl_sizeof(from) * width; GLsizei to_size = gl_sizeof(to) * to_width; @@ -106,10 +142,12 @@ GLvoid *copy_gl_array_convert(const GLvoid *src, ) } else { GL_TYPE_SWITCH_MAX(out, dst, to, - for (int i = skip; i < count; i++) { - GL_TYPE_SWITCH(input, in, from, + GL_TYPE_SWITCH2(input, in, from, + const GLuint maxf = gl_max_value(from); + for (int i = skip; i < count; i++) + , for (j = 0; j < width; j++) { - out[j] = input[j]*maxv/gl_max_value(from); + out[j] = input[j]*maxv/maxf; } for (; j < to_width-1; j++) { out[j]=0; @@ -119,12 +157,11 @@ GLvoid *copy_gl_array_convert(const GLvoid *src, } out += to_width; in += stride; - , + , default: printf(unknown_str, from); return NULL; - ) - }, + ), default: printf(unknown_str, to); return NULL; diff --git a/project/jni/glshim/src/gl/debug.c b/project/jni/glshim/src/gl/debug.c new file mode 100755 index 000000000..9bf41ddf9 --- /dev/null +++ b/project/jni/glshim/src/gl/debug.c @@ -0,0 +1,59 @@ +#include "debug.h" + +#define p(a) \ + case a: return #a + +const char* PrintEnum(GLenum what) { + static char fallback[64]; + switch(what) + { + // target + p(GL_TEXTURE_1D); + p(GL_TEXTURE_2D); + p(GL_TEXTURE_3D); + p(GL_FRAMEBUFFER); + p(GL_RENDERBUFFER); + p(GL_PROXY_TEXTURE_1D); + p(GL_PROXY_TEXTURE_2D); + p(GL_PROXY_TEXTURE_3D); + p(GL_READ_FRAMEBUFFER); + p(GL_DRAW_FRAMEBUFFER); + // format + p(GL_RED); + p(GL_RGB); + p(GL_RGBA); + p(GL_RGBA8); + p(GL_RGB8); + p(GL_COMPRESSED_RGB_S3TC_DXT1_EXT); + p(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); + p(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); + p(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); + // type + p(GL_UNSIGNED_BYTE); + p(GL_UNSIGNED_BYTE_2_3_3_REV); + p(GL_UNSIGNED_BYTE_3_3_2); + p(GL_UNSIGNED_INT); + p(GL_UNSIGNED_SHORT); + p(GL_UNSIGNED_SHORT_5_5_5_1); + p(GL_UNSIGNED_SHORT_1_5_5_5_REV); + p(GL_UNSIGNED_SHORT_4_4_4_4); + p(GL_UNSIGNED_SHORT_4_4_4_4_REV); + p(GL_UNSIGNED_SHORT_5_6_5); + p(GL_UNSIGNED_SHORT_5_6_5_REV); + p(GL_FLOAT); + p(GL_DOUBLE); + // texture pack/unpack + p(GL_UNPACK_ALIGNMENT); + // framebuffer + p(GL_COLOR_ATTACHMENT0); + p(GL_COLOR_ATTACHMENT1); + p(GL_COLOR_ATTACHMENT2); + p(GL_COLOR_ATTACHMENT3); + p(GL_COLOR_ATTACHMENT4); + p(GL_DEPTH_ATTACHMENT); + p(GL_STENCIL_ATTACHMENT); + default: + sprintf(fallback, "0x%04X", what); + } + return fallback; +} diff --git a/project/jni/glshim/src/gl/debug.h b/project/jni/glshim/src/gl/debug.h new file mode 100755 index 000000000..105b98a70 --- /dev/null +++ b/project/jni/glshim/src/gl/debug.h @@ -0,0 +1,8 @@ +#ifndef __DEBUG_H_ +#define __DEBUG_H_ + +#include "gl.h" + +const char* PrintEnum(GLenum what); + +#endif diff --git a/project/jni/glshim/src/gl/framebuffers.c b/project/jni/glshim/src/gl/framebuffers.c index 3a3f86e1d..1ad4c6099 100755 --- a/project/jni/glshim/src/gl/framebuffers.c +++ b/project/jni/glshim/src/gl/framebuffers.c @@ -1,4 +1,5 @@ #include "framebuffers.h" +#include "debug.h" #ifndef ANDROID #include @@ -19,13 +20,19 @@ int mainfbo_height = 480; int mainfbo_nwidth = 1024; int mainfbo_nheight = 512; +extern bool g_recyclefbo; + GLuint fbo_read = 0; // if not 0, that's the READ only Framebuffer attached GLuint fbo_draw = 0; // if not 0, that's the DRAW only Framebuffer attached +GLuint *old_fbos = NULL; +int nbr_fbos = 0; +int cap_fbos = 0; + int npot(int n); void readfboBegin() { -//printf("readfboBegin, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb); + //printf("readfboBegin, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb); LOAD_GLES_OES(glBindFramebuffer); if (!(fbo_read || fbo_draw)) return; @@ -36,7 +43,7 @@ void readfboBegin() { } void readfboEnd() { -//printf("readfboEnd, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb); + //printf("readfboEnd, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb); LOAD_GLES_OES(glBindFramebuffer); if (!(fbo_read || fbo_draw)) return; @@ -48,23 +55,44 @@ void readfboEnd() { void glGenFramebuffers(GLsizei n, GLuint *ids) { LOAD_GLES_OES(glGenFramebuffers); -//printf("glGenFramebuffers(%i, %p)\n", n, ids); - + //printf("glGenFramebuffers(%i, %p)\n", n, ids); + GLsizei m = 0; + while(g_recyclefbo && (nbr_fbos>0) && (n-m>0)) { + //printf("Recycled 1 FBO\n"); + ids[m++] = old_fbos[--nbr_fbos]; + } + noerrorShim(); + if(n-m == 0) + return; errorGL(); - gles_glGenFramebuffers(n, ids); + gles_glGenFramebuffers(n-m, ids+m); } void glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) { -//printf("glDeleteFramebuffers(%i, %p), framebuffers[0]=%u\n", n, framebuffers, framebuffers[0]); + //printf("glDeleteFramebuffers(%i, %p), framebuffers[0]=%u\n", n, framebuffers, framebuffers[0]); if (state.gl_batch) flush(); - LOAD_GLES_OES(glDeleteFramebuffers); - - errorGL(); - gles_glDeleteFramebuffers(n, framebuffers); + if (g_recyclefbo) { + //printf("Recycling %i FBOs\n", n); + noerrorShim(); + if(cap_fbos == 0) { + cap_fbos = 16; + old_fbos = (GLuint*)malloc(cap_fbos * sizeof(GLuint)); + } + if (nbr_fbos+n == cap_fbos) { + cap_fbos += n; + old_fbos = (GLuint*)realloc(old_fbos, cap_fbos *sizeof(GLuint)); + } + memcpy(old_fbos+nbr_fbos, framebuffers, n*sizeof(GLuint)); + nbr_fbos += n; + } else { + LOAD_GLES_OES(glDeleteFramebuffers); + errorGL(); + gles_glDeleteFramebuffers(n, framebuffers); + } } GLboolean glIsFramebuffer(GLuint framebuffer) { -//printf("glIsFramebuffer(%u)\n", framebuffer); + //printf("glIsFramebuffer(%u)\n", framebuffer); if (state.gl_batch) flush(); LOAD_GLES_OES(glIsFramebuffer); @@ -92,7 +120,7 @@ GLenum glCheckFramebufferStatus(GLenum target) { } void glBindFramebuffer(GLenum target, GLuint framebuffer) { -//printf("glBindFramebuffer(0x%04X, %u), list=%s\n", target, framebuffer, state.list.active?"active":"none"); + //printf("glBindFramebuffer(%s, %u), list=%s\n", PrintEnum(target), framebuffer, state.list.active?"active":"none"); //PUSH_IF_COMPILING(glBindFramebuffer); if (state.gl_batch) flush(); LOAD_GLES_OES(glBindFramebuffer); @@ -118,13 +146,16 @@ void glBindFramebuffer(GLenum target, GLuint framebuffer) { fbo_draw = framebuffer; } + if(target==GL_FRAMEBUFFER && framebuffer!=0) { + gles_glBindFramebuffer(target, 0); + gles_glCheckFramebufferStatus(target); + } + current_fb = framebuffer; if (mainfbo_fbo && (framebuffer==0)) framebuffer = mainfbo_fbo; - //errorGL(); - //noerrorShim(); gles_glBindFramebuffer(target, framebuffer); GLenum err=gles_glGetError(); errorShim(err); @@ -132,14 +163,17 @@ void glBindFramebuffer(GLenum target, GLuint framebuffer) { fb_status = gles_glCheckFramebufferStatus(target); } + void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + static GLuint scrap_tex = 0; + static int scrap_width = 0; + static int scrap_height = 0; + if (state.gl_batch) flush(); LOAD_GLES_OES(glFramebufferTexture2D); LOAD_GLES(glTexImage2D); LOAD_GLES(glBindTexture); -//printf("glFramebufferTexture2D(0x%04X, 0x%04X, 0x%04X, %u, %i)\n", target, attachment, textarget, texture, level); - if (level!=0) - return; + //printf("glFramebufferTexture2D(%s, %s, %s, %u, %i)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(textarget), texture, level); // Ignore Color attachment 1 .. 9 if ((attachment>=GL_COLOR_ATTACHMENT0+1) && (attachment<=GL_COLOR_ATTACHMENT0+9)) { @@ -147,6 +181,7 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, return; } + int twidth = 0, theight = 0; // find texture and get it's real name if (texture) { gltexture_t *tex = NULL; @@ -162,7 +197,7 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, k = kh_get(tex, list, texture); if (k == kh_end(list)){ -//printf("*WARNING* texture for FBO not found, name=%u\n", texture); + printf("*WARNING* texture for FBO not found, name=%u\n", texture); } else { tex = kh_value(list, k); texture = tex->glname; @@ -180,6 +215,8 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL); if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, oldtex); } + twidth = tex->nwidth; + theight = tex->nheight; /* if ((tex->width<32) || (tex->height<32)) { printf("LIBGL: enlarging too-small texture for FBO\n"); tex->nwidth = (tex->nwidth<32)?32:tex->nwidth; @@ -191,10 +228,29 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL); if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, oldtex); }*/ -//printf("found texture, glname=%u, size=%ix%i(%ix%i), format/type=0x%04X/0x%04X\n", texture, tex->width, tex->height, tex->nwidth, tex->nheight, tex->format, tex->type); + //printf("found texture, glname=%u, size=%ix%i(%ix%i), format/type=0x%04X/0x%04X\n", texture, tex->width, tex->height, tex->nwidth, tex->nheight, tex->format, tex->type); } } + twidth = twidth >> level; if(twidth<1) twidth=1; + theight = theight >> level; if(theight<1) theight=1; + + if (level!=0) { + //bind a scrap texture, we don't want level != 0 binding on GLES + if(!scrap_tex) + glGenTextures(1, &scrap_tex); + if ((scrap_width!=twidth) || (scrap_height!=theight)) { + scrap_width = twidth; + scrap_height = theight; + gltexture_t *bound = state.texture.bound[state.texture.active]; + 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); + if (oldtex!=scrap_tex) gles_glBindTexture(GL_TEXTURE_2D, oldtex); + } + texture = scrap_tex; + } + errorGL(); gles_glFramebufferTexture2D(target, attachment, textarget, texture, 0); } @@ -209,7 +265,7 @@ void glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) { LOAD_GLES_OES(glGenRenderbuffers); -//printf("glGenRenderbuffers(%i, %p)\n", n, renderbuffers); + //printf("glGenRenderbuffers(%i, %p)\n", n, renderbuffers); errorGL(); gles_glGenRenderbuffers(n, renderbuffers); @@ -218,9 +274,9 @@ void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) { void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { LOAD_GLES_OES(glFramebufferRenderbuffer); LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv); -//printf("glFramebufferRenderbuffer(0x%04X, 0x%04X, 0x%04X, %u)\n", target, attachment, renderbuffertarget, renderbuffer); + //printf("glFramebufferRenderbuffer(%s, %s, %s, %u)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(renderbuffertarget), renderbuffer); + //TODO: handle target=READBUFFER or DRAWBUFFER... - if (depthstencil && (attachment==GL_STENCIL_ATTACHMENT)) { khint_t k = kh_get(dsr, depthstencil, renderbuffer); if (k != kh_end(depthstencil)) { @@ -235,15 +291,7 @@ void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbu noerrorShim(); return; } - if ((current_fb!=0) && (renderbuffer!=0) && ((attachment==GL_DEPTH_ATTACHMENT) || (attachment==GL_STENCIL_ATTACHMENT))) { - GLuint tmp; - gles_glGetFramebufferAttachmentParameteriv(target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tmp); - if (tmp==renderbuffer) { - noerrorShim(); - return; - } - } - + errorGL(); gles_glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); } @@ -278,7 +326,7 @@ void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, LOAD_GLES_OES(glRenderbufferStorage); LOAD_GLES_OES(glGenRenderbuffers); LOAD_GLES_OES(glBindRenderbuffer); -//printf("glRenderbufferStorage(0x%04X, 0x%04X, %i, %i)\n", target, internalformat, width, height); + //printf("glRenderbufferStorage(0x%04X, 0x%04X, %i, %i)\n", target, internalformat, width, height); errorGL(); width = npot(width); @@ -325,7 +373,7 @@ void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum int void glBindRenderbuffer(GLenum target, GLuint renderbuffer) { if (state.gl_batch) flush(); LOAD_GLES_OES(glBindRenderbuffer); -//printf("glBindRenderbuffer(0x%04X, %u)\n", target, renderbuffer); + //printf("glBindRenderbuffer(%s, %u), binded Fbo=%u\n", PrintEnum(target), renderbuffer, current_fb); current_rb = renderbuffer; @@ -334,7 +382,7 @@ void glBindRenderbuffer(GLenum target, GLuint renderbuffer) { } GLboolean glIsRenderbuffer(GLuint renderbuffer) { -//printf("glIsRenderbuffer(%u)\n", renderbuffer); + //printf("glIsRenderbuffer(%u)\n", renderbuffer); if (state.gl_batch) flush(); LOAD_GLES_OES(glIsRenderbuffer); @@ -343,7 +391,7 @@ GLboolean glIsRenderbuffer(GLuint renderbuffer) { } void glGenerateMipmap(GLenum target) { -//printf("glGenerateMipmap(0x%04X)\n", target); + //printf("glGenerateMipmap(0x%04X)\n", target); LOAD_GLES_OES(glGenerateMipmap); errorGL(); @@ -351,6 +399,7 @@ void glGenerateMipmap(GLenum target) { } void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) { + //printf("glGetFramebufferAttachmentParameteriv(%s, %s, %s, %p)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(pname), params); LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv); errorGL(); @@ -358,6 +407,7 @@ void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLe } void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint * params) { + //printf("glGetRenderbufferParameteriv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(pname), params); LOAD_GLES_OES(glGetRenderbufferParameteriv); errorGL(); @@ -381,10 +431,12 @@ void createMainFBO(int width, int height) { LOAD_GLES(glClientActiveTexture); LOAD_GLES(glClear); - // If there is already a Framebuffer created, let's delete it.... - if (mainfbo_fbo) + // If there is already a Framebuffer created, let's delete it.... unless it's already the right size! + if (mainfbo_fbo) { + if (width==mainfbo_width && height==mainfbo_height) + return; deleteMainFBO(); - + } // switch to texture unit 0 if needed if (state.texture.active != 0) gles_glActiveTexture(GL_TEXTURE0); @@ -463,10 +515,12 @@ void blitMainFBO() { return; // switch to texture unit 0 if needed + int old_tex = state.texture.active; + int old_client = state.texture.client; if (state.texture.active != 0) - gles_glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0); if (state.texture.client != 0) - gles_glClientActiveTexture(GL_TEXTURE0); + glClientActiveTexture(GL_TEXTURE0); // bind the FBO texture gles_glEnable(GL_TEXTURE_2D); gles_glBindTexture(GL_TEXTURE_2D, mainfbo_tex); @@ -475,7 +529,7 @@ void blitMainFBO() { gles_glGetIntegerv(GL_VIEWPORT, old_vp); gles_glViewport(0, 0, mainfbo_width, mainfbo_height); // Draw the texture - #if 1 + #if 0 gles_glDrawTexi(0, 0, 0, mainfbo_width, mainfbo_height); #else { @@ -485,33 +539,29 @@ void blitMainFBO() { LOAD_GLES(glVertexPointer); LOAD_GLES(glTexCoordPointer); LOAD_GLES(glDrawArrays); + LOAD_GLES(glOrthof); + LOAD_GLES(glPushMatrix); + LOAD_GLES(glPopMatrix); glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT); - GLfloat old_projection[16], old_modelview[16], old_texture[16]; glMatrixMode(GL_TEXTURE); - glGetFloatv(GL_TEXTURE_MATRIX, old_texture); + gles_glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); - glGetFloatv(GL_PROJECTION_MATRIX, old_projection); + gles_glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); - glGetFloatv(GL_MODELVIEW_MATRIX, old_modelview); + gles_glPushMatrix(); glLoadIdentity(); - float w2 = 800 / 2.0f; - float h2 = 480 / 2.0f; - float x1=0; - float x2=mainfbo_width; - float y1=0; - float y2=mainfbo_height; GLfloat vert[] = { - (x1-w2)/w2, (y1-h2)/h2, 0, - (x2-w2)/w2, (y1-h2)/h2, 0, - (x2-w2)/w2, (y2-h2)/h2, 0, - (x1-w2)/w2, (y2-h2)/h2, 0, + -1, -1, + +1, -1, + +1, +1, + -1, +1, }; - float sw = mainfbo_width / mainfbo_nwidth; - float sh = mainfbo_height / mainfbo_nheight; + float sw = (float)mainfbo_width / (float)mainfbo_nwidth; + float sh = (float)mainfbo_height / (float)mainfbo_nheight; GLfloat tex[] = { 0, 0, sw, 0, @@ -519,35 +569,35 @@ void blitMainFBO() { 0, sh }; - glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT | GL_CLIENT_PIXEL_STORE_BIT); + glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glDisable(GL_CULL_FACE); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.0f); + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - gles_glEnableClientState(GL_VERTEX_ARRAY); - gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); - gles_glDisableClientState(GL_COLOR_ARRAY); - gles_glDisableClientState(GL_NORMAL_ARRAY); - gles_glVertexPointer(3, GL_FLOAT, 0, vert); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + gles_glVertexPointer(2, GL_FLOAT, 0, vert); gles_glTexCoordPointer(2, GL_FLOAT, 0, tex); - //glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); gles_glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // All the previous states are Pushed / Poped anyway... glPopClientAttrib(); - glMatrixMode(GL_TEXTURE); - glLoadMatrixf(old_texture); glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(old_modelview); + gles_glPopMatrix(); glMatrixMode(GL_PROJECTION); - glLoadMatrixf(old_projection); + gles_glPopMatrix(); + glMatrixMode(GL_TEXTURE); + gles_glPopMatrix(); glPopAttrib(); } #endif @@ -560,10 +610,10 @@ void blitMainFBO() { gles_glBindTexture(GL_TEXTURE_2D, 0); if (!state.enable.texture_2d[0]) gles_glDisable(GL_TEXTURE_2D); - if (state.texture.active != 0) - gles_glActiveTexture(GL_TEXTURE0 + state.texture.active); - if (state.texture.client != 0) - gles_glClientActiveTexture(GL_TEXTURE0 + state.texture.client); + if (old_tex != 0) + glActiveTexture(GL_TEXTURE0 + old_tex); + if (old_client != 0) + glClientActiveTexture(GL_TEXTURE0 + old_client); } void bindMainFBO() { diff --git a/project/jni/glshim/src/gl/gl.c b/project/jni/glshim/src/gl/gl.c index 412ccb1aa..7716f1ff7 100755 --- a/project/jni/glshim/src/gl/gl.c +++ b/project/jni/glshim/src/gl/gl.c @@ -71,21 +71,16 @@ void initialize_glshim() { // config functions const GLubyte *glGetString(GLenum name) { - LOAD_GLES(glGetString); +// LOAD_GLES(glGetString); const GLubyte *str; errorShim(GL_NO_ERROR); - if ((str=gles_glGetString(name))==NULL) - printf("**warning** glGetString(%i) called with bad init\n", name); +/* if ((str=gles_glGetString(name))==NULL) + printf("**warning** glGetString(%i) called with bad init\n", name);*/ switch (name) { case GL_VERSION: -#ifdef USE_ES2 - return (GLubyte *)"4.3 glshim wrapper"; -#else return (GLubyte *)"1.5 glshim wrapper"; -#endif case GL_EXTENSIONS: return (const GLubyte *)(char *){ -#ifndef USE_ES2 "GL_ARB_vertex_buffer_object " "GL_ARB_vertex_buffer " "GL_EXT_vertex_array " @@ -124,24 +119,13 @@ const GLubyte *glGetString(GLenum name) { // "GL_EXT_blend_logic_op " // "GL_EXT_blend_color " // "GL_ARB_texture_cube_map " -#else - "GL_ARB_vertex_shader " - "GL_ARB_fragment_shader " - "GL_ARB_vertex_buffer_object " - "GL_EXT_framebuffer_object " - "GL_EXT_vertex_array " -#endif }; case GL_VENDOR: return (GLubyte *)"OpenPandora"; case GL_RENDERER: -#ifdef USE_ES2 - return (GLubyte *)"GLESv2 wrapper"; -#else return (GLubyte *)"GLES_CM wrapper"; case GL_SHADING_LANGUAGE_VERSION: return (GLubyte *)""; -#endif default: errorShim(GL_INVALID_ENUM); return (str)?str:(GLubyte*)""; @@ -436,6 +420,7 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { state.enable.texture_2d[state.texture.active] = enable; #endif switch (cap) { + enable(GL_AUTO_NORMAL, auto_normal); proxy_enable(GL_BLEND, blend); proxy_enable(GL_TEXTURE_2D, texture_2d[state.texture.active]); enable(GL_TEXTURE_GEN_S, texgen_s[state.texture.active]); @@ -541,35 +526,34 @@ void glDisableClientState(GLenum cap) { } #endif +#define isenabled(what, where) \ + case what: return state.enable.where + GLboolean glIsEnabled(GLenum cap) { // should flush for now... to be optimized later! if (state.gl_batch) flush(); LOAD_GLES(glIsEnabled); noerrorShim(); switch (cap) { - case GL_LINE_STIPPLE: - return state.enable.line_stipple; - case GL_TEXTURE_GEN_S: - return state.enable.texgen_s[state.texture.active]; - case GL_TEXTURE_GEN_T: - return state.enable.texgen_t[state.texture.active]; - case GL_TEXTURE_GEN_R: - return state.enable.texgen_t[state.texture.active]; - case GL_TEXTURE_COORD_ARRAY: - return state.enable.tex_coord_array[state.texture.client]; - case GL_COLOR_SUM: - return state.enable.color_sum; - case GL_SECONDARY_COLOR_ARRAY: - return state.enable.secondary_array; - case GL_TEXTURE_1D: - return state.enable.texture_1d[state.texture.active]; - case GL_TEXTURE_3D: - return state.enable.texture_1d[state.texture.active]; + isenabled(GL_AUTO_NORMAL, auto_normal); + isenabled(GL_LINE_STIPPLE, line_stipple); + isenabled(GL_TEXTURE_GEN_S, texgen_s[state.texture.active]); + isenabled(GL_TEXTURE_GEN_T, texgen_t[state.texture.active]); + isenabled(GL_TEXTURE_GEN_R, texgen_r[state.texture.active]); + isenabled(GL_COLOR_SUM, color_sum); + isenabled(GL_SECONDARY_COLOR_ARRAY, secondary_array); + isenabled(GL_TEXTURE_1D, texture_1d[state.texture.active]); + isenabled(GL_TEXTURE_3D, texture_3d[state.texture.active]); + isenabled(GL_VERTEX_ARRAY, vertex_array); + isenabled(GL_NORMAL_ARRAY, normal_array); + isenabled(GL_COLOR_ARRAY, color_array); + isenabled(GL_TEXTURE_COORD_ARRAY, tex_coord_array[state.texture.client]); default: errorGL(); return gles_glIsEnabled(cap); } } +#undef isenabled static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode, GLsizei skip, GLsizei count) { @@ -648,7 +632,7 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic list->indices = sindices; list->ilen = count; list->indice_cap = count; - end_renderlist(list); + //end_renderlist(list); state.list.active = extend_renderlist(list); return; @@ -1371,12 +1355,12 @@ void glEndList() { state.list.compiling = false; end_renderlist(state.list.active); state.list.active = NULL; + if (gl_batch==1) { + init_batch(); + } if (state.list.mode == GL_COMPILE_AND_EXECUTE) { glCallList(list); } - if (gl_batch) { - init_batch(); - } } } @@ -1437,6 +1421,9 @@ void glCallLists(GLsizei n, GLenum type, const GLvoid *lists) { } void glDeleteList(GLuint list) { + if(state.gl_batch) { + flush(); + } renderlist_t *l = glGetList(list); if (l) { free_renderlist(l); diff --git a/project/jni/glshim/src/gl/gl.h b/project/jni/glshim/src/gl/gl.h index 28e52c503..2790d445b 100755 --- a/project/jni/glshim/src/gl/gl.h +++ b/project/jni/glshim/src/gl/gl.h @@ -201,6 +201,15 @@ static void load_egl_lib() { break; \ } +#define GL_TYPE_CASE2(name, var, magic, type, code2, code) \ + case magic: { \ + code2 { \ + type *name = (type *)var; \ + code \ + } \ + break; \ + } + #define GL_TYPE_CASE_MAX(name, var, magic, type, code, max) \ case magic: { \ type *name = (type *)var; \ @@ -222,6 +231,19 @@ static void load_egl_lib() { extra \ } +#define GL_TYPE_SWITCH2(name, var, type, code2, code, extra) \ + switch (type) { \ + GL_TYPE_CASE2(name, var, GL_DOUBLE, GLdouble, code2, code) \ + GL_TYPE_CASE2(name, var, GL_FLOAT, GLfloat, code2, code) \ + GL_TYPE_CASE2(name, var, GL_INT, GLint, code2, code) \ + GL_TYPE_CASE2(name, var, GL_SHORT, GLshort, code2, code) \ + GL_TYPE_CASE2(name, var, GL_BYTE, GLbyte, code2, code) \ + GL_TYPE_CASE2(name, var, GL_UNSIGNED_BYTE, GLubyte, code2, code) \ + GL_TYPE_CASE2(name, var, GL_UNSIGNED_INT, GLuint, code2, code) \ + GL_TYPE_CASE2(name, var, GL_UNSIGNED_SHORT, GLushort, code2, code) \ + extra \ + } + #define GL_TYPE_SWITCH_MAX(name, var, type, code, extra) \ switch (type) { \ GL_TYPE_CASE_MAX(name, var, GL_DOUBLE, GLdouble, code, 1.0d) \ diff --git a/project/jni/glshim/src/gl/list.c b/project/jni/glshim/src/gl/list.c index 2c5839c7b..6aee5532f 100755 --- a/project/jni/glshim/src/gl/list.c +++ b/project/jni/glshim/src/gl/list.c @@ -726,13 +726,7 @@ void draw_renderlist(renderlist_t *list) { khash_t(texgen) *tgn = list->texgen; rendertexgen_t *m; kh_foreach_value(tgn, m, - switch (m->pname) { - case GL_TEXTURE_GEN_MODE: - glTexGeni(m->coord, m->pname, m->color[0]); - break; - default: - glTexGenfv(m->coord, m->pname, m->color); - } + glTexGenfv(m->coord, m->pname, m->color); ) } @@ -853,74 +847,76 @@ void draw_renderlist(renderlist_t *list) { if (state.polygon_mode == GL_LINE && list->mode_init>=GL_TRIANGLES) { int n, s; int ilen = list->ilen; - GLushort ind_line[ilen*3+1]; + GLushort ind_line[ilen*4+2]; int k=0; switch (list->mode_init) { case GL_TRIANGLES: - // 1 triangle -> 3 lines - for (int i = 0; i2) { + // 1 triangle -> 3 lines + for (int i = 0; i2) { ind_line[k++] = indices[0]; ind_line[k++] = indices[1]; - } - for (int i = 2; i2) { ind_line[k++] = indices[0]; ind_line[k++] = indices[1]; - } - for (int i = 2; imode == GL_TRIANGLE_FAN) { - // just 1 Quad - for (int i=0; i<4; i++) { - ind_line[k++] = indices[i+0]; ind_line[k++] = indices[(i+1)%4]; - } - } else { - // list of triangles, 2 per quads... - for (int i=0; i3) { + // 4 lines per quads, but dest may already be a triangles list... + if (list->mode == GL_TRIANGLE_FAN) { + // just 1 Quad + for (int i=0; i<4; i++) { + ind_line[k++] = indices[i+0]; ind_line[k++] = indices[(i+1)%4]; + } + } else { + // list of triangles, 2 per quads... + for (int i=0; i2) { + if (ilen>3) { ind_line[k++] = indices[0]; ind_line[k++] = indices[1]; - } - for (int i = 2; ilen; if ((state.polygon_mode == GL_LINE) && (list->mode_init>=GL_TRIANGLES)) { int n, s; - GLushort ind_line[len*3+1]; + GLushort ind_line[len*4+2]; int k=0; switch (list->mode_init) { case GL_TRIANGLES: // 1 triangle -> 3 lines - for (int i = 0; i2) { + for (int i = 0; i2) { ind_line[k++] = 0; ind_line[k++] = 1; - } - for (int i = 2; i2) { ind_line[k++] = 0; ind_line[k++] = 1; - } - for (int i = 2; imode == GL_TRIANGLE_FAN) { - // just 1 Quad - for (int i=0; i<4; i++) { - ind_line[k++] = i+0; ind_line[k++] = (i+1)%4; + if(len>3) { + // 4 lines per quads, QUAD without indices means 1 single quad + if (list->mode == GL_TRIANGLE_FAN) { + // just 1 Quad + for (int i=0; i<4; i++) { + ind_line[k++] = i+0; ind_line[k++] = (i+1)%4; + } + } else { + // list of triangles, 2 per quads... + for (int i=0; i2) { - ind_line[k++] = 0; ind_line[k++] = 1; - } - for (int i = 2; i3) { + // first 4 points is a quad, then 2 points per new quad + if (len>2) { + ind_line[k++] = 0; ind_line[k++] = 1; + } + for (int i = 2; icoord = coord; m->pname = pname; - m->color[0] = params[0]; - m->color[1] = params[1]; - m->color[2] = params[2]; - m->color[3] = params[3]; + memcpy(m->color, params, 4*sizeof(GLfloat)); } void rlTexCoord2f(renderlist_t *list, GLfloat s, GLfloat t) { diff --git a/project/jni/glshim/src/gl/pixel.c b/project/jni/glshim/src/gl/pixel.c index 6a6acbb39..09ee088ac 100755 --- a/project/jni/glshim/src/gl/pixel.c +++ b/project/jni/glshim/src/gl/pixel.c @@ -575,7 +575,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, const colorlayout_t *src_color, *dst_color; GLuint pixels = width * height; GLuint dst_size = pixels * pixel_sizeof(dst_format, dst_type); - GLuint dst_width = stride * pixel_sizeof(dst_format, dst_type); + GLuint dst_width = ((stride?stride:width) - width) * pixel_sizeof(dst_format, dst_type); GLuint src_width = width * pixel_sizeof(dst_format, dst_type); //printf("pixel conversion: %ix%i - %04x, %04x -> %04x, %04x, transform=%i\n", width, height, src_format, src_type, dst_format, dst_type, raster_need_transform()); @@ -592,7 +592,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, *dst = malloc(dst_size); if (stride) // for in-place conversion for (int yy=0; yytexgen_r[a] = state.enable.texgen_r[a]; - cur->texgen_r[a] = state.enable.texgen_s[a]; - cur->texgen_r[a] = state.enable.texgen_t[a]; + cur->texgen_s[a] = state.enable.texgen_s[a]; + cur->texgen_t[a] = state.enable.texgen_t[a]; + cur->texgen[a] = state.texgen[a]; // all mode and planes per texture in 1 line cur->texture[a] = (state.texture.bound[a])?state.texture.bound[a]->texture:0; } //glActiveTexture(GL_TEXTURE0+cur->active); @@ -478,6 +479,7 @@ void glPopAttrib() { state.enable.texgen_r[a] = cur->texgen_r[a]; state.enable.texgen_s[a] = cur->texgen_s[a]; state.enable.texgen_t[a] = cur->texgen_t[a]; + state.texgen[a] = cur->texgen[a]; // all mode and planes per texture in 1 line if ((cur->texture[a]==0 && state.texture.bound[a] != 0) || (cur->texture[a]!=0 && state.texture.bound[a]==0)) { glActiveTexture(GL_TEXTURE0+a); glBindTexture(GL_TEXTURE_2D, cur->texture[a]); diff --git a/project/jni/glshim/src/gl/stack.h b/project/jni/glshim/src/gl/stack.h index 857462c6a..126cc0587 100755 --- a/project/jni/glshim/src/gl/stack.h +++ b/project/jni/glshim/src/gl/stack.h @@ -118,6 +118,7 @@ typedef struct { // GL_TEXTURE_BIT GLint texture[MAX_TEX]; + texgen_state_t texgen[MAX_TEX]; GLint active; // GL_TRANSFORM_BIT @@ -159,18 +160,6 @@ typedef struct { GLboolean normal_enable; GLboolean secondary_enable; pointer_states_t pointers; - /*pointer_state_t verts; - pointer_state_t color; - pointer_state_t normal; - pointer_state_t tex[MAX_TEX]; - pointer_state_t secondary;*/ - // lets track old pointer address to avoid useless copy back - /*GLvoid *ref_verts, - *ref_colors, - *ref_secondary, - *ref_normal, - *ref_tex[MAX_TEX]; - */ unsigned int len; unsigned int cap; } glclientstack_t; diff --git a/project/jni/glshim/src/gl/state.h b/project/jni/glshim/src/gl/state.h index 5b4543a97..99449cd23 100755 --- a/project/jni/glshim/src/gl/state.h +++ b/project/jni/glshim/src/gl/state.h @@ -9,6 +9,7 @@ typedef struct { GLboolean line_stipple, + auto_normal, blend, color_sum, secondary_array, @@ -29,9 +30,12 @@ typedef struct { GLenum S; GLenum T; GLenum R; - GLfloat Sv[4]; - GLfloat Tv[4]; - GLfloat Rv[4]; + GLfloat S_E[4]; // Eye Plane + GLfloat T_E[4]; + GLfloat R_E[4]; + GLfloat S_O[4]; // Object Plane + GLfloat T_O[4]; + GLfloat R_O[4]; } texgen_state_t; typedef struct { diff --git a/project/jni/glshim/src/gl/texgen.c b/project/jni/glshim/src/gl/texgen.c index 7fb394739..7dc9062ce 100755 --- a/project/jni/glshim/src/gl/texgen.c +++ b/project/jni/glshim/src/gl/texgen.c @@ -3,25 +3,23 @@ //extern void* eglGetProcAddress(const char*); void glTexGeni(GLenum coord, GLenum pname, GLint param) { - // coord is in: GL_S, GL_T, GL_R, GL_Q - // pname == GL_TEXTURE_GEN_MODE - /* param is in: - GL_OBJECT_LINEAR, GL_EYE_LINEAR, - GL_SPHERE_MAP, GL_NORMAL_MAP, or GL_REFLECTION_MAP - */ - /* - switch (coord) { - case GL_S: state.texgen[state.texture.active].S = param; break; - case GL_T: state.texgen[state.texture.active].T = param; break; - } - */ GLfloat params[4] = {0,0,0,0}; params[0]=param; glTexGenfv(coord, pname, params); } void glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { -//printf("glTexGenfv(0x%04X, 0x%04X, [%.02f, ...]), texture=%i\n", coord, pname, param[0], state.texture.active); + + /* + If pname is GL_TEXTURE_GEN_MODE, then the array must contain + a single symbolic constant, one of + GL_OBJECT_LINEAR, GL_EYE_LINEAR, GL_SPHERE_MAP, GL_NORMAL_MAP, + or GL_REFLECTION_MAP. + Otherwise, params holds the coefficients for the texture-coordinate + generation function specified by pname. + */ + + //printf("glTexGenfv(0x%04X, 0x%04X, [%.02f, ...]), texture=%i\n", coord, pname, param[0], state.texture.active); if ((state.list.compiling || state.gl_batch) && state.list.active) { NewStage(state.list.active, STAGE_TEXGEN); rlTexGenfv(state.list.active, coord, pname, param); @@ -31,38 +29,49 @@ void glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { // pname is in: GL_TEXTURE_GEN_MODE, GL_OBJECT_PLANE, GL_EYE_PLANE noerrorShim(); - if (pname == GL_TEXTURE_GEN_MODE) { - switch (coord) { - case GL_S: state.texgen[state.texture.active].S = param[0]; break; - case GL_T: state.texgen[state.texture.active].T = param[0]; break; - case GL_R: state.texgen[state.texture.active].R = param[0]; break; - default: - errorShim(GL_INVALID_ENUM); - } - } else { - switch (coord) { - case GL_S: - memcpy(state.texgen[state.texture.active].Sv, param, 4 * sizeof(GLfloat)); - break; - case GL_T: - memcpy(state.texgen[state.texture.active].Tv, param, 4 * sizeof(GLfloat)); - break; - case GL_R: - memcpy(state.texgen[state.texture.active].Rv, param, 4 * sizeof(GLfloat)); - break; - default: - errorShim(GL_INVALID_ENUM); - } + switch(pname) { + case GL_TEXTURE_GEN_MODE: + switch (coord) { + case GL_S: state.texgen[state.texture.active].S = param[0]; break; + case GL_T: state.texgen[state.texture.active].T = param[0]; break; + case GL_R: state.texgen[state.texture.active].R = param[0]; break; + default: + errorShim(GL_INVALID_ENUM); + return; + } + case GL_OBJECT_PLANE: + switch (coord) { + case GL_S: + memcpy(state.texgen[state.texture.active].S_O, param, 4 * sizeof(GLfloat)); + break; + case GL_T: + memcpy(state.texgen[state.texture.active].T_O, param, 4 * sizeof(GLfloat)); + break; + case GL_R: + memcpy(state.texgen[state.texture.active].R_O, param, 4 * sizeof(GLfloat)); + break; + default: + errorShim(GL_INVALID_ENUM); + return; + } + case GL_EYE_PLANE: + switch (coord) { + case GL_S: + memcpy(state.texgen[state.texture.active].S_E, param, 4 * sizeof(GLfloat)); + break; + case GL_T: + memcpy(state.texgen[state.texture.active].T_E, param, 4 * sizeof(GLfloat)); + break; + case GL_R: + memcpy(state.texgen[state.texture.active].R_E, param, 4 * sizeof(GLfloat)); + break; + default: + errorShim(GL_INVALID_ENUM); + return; + } + default: + errorShim(GL_INVALID_ENUM); } - - /* - If pname is GL_TEXTURE_GEN_MODE, then the array must contain - a single symbolic constant, one of - GL_OBJECT_LINEAR, GL_EYE_LINEAR, GL_SPHERE_MAP, GL_NORMAL_MAP, - or GL_REFLECTION_MAP. - Otherwise, params holds the coefficients for the texture-coordinate - generation function specified by pname. - */ } void glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) { if (gl_batch) flush(); @@ -77,16 +86,29 @@ void glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) { } break; case GL_OBJECT_PLANE: - case GL_EYE_PLANE: // probably wrong... switch (coord) { case GL_S: - memcpy(params, state.texgen[state.texture.active].Sv, 4 * sizeof(GLfloat)); + memcpy(params, state.texgen[state.texture.active].S_O, 4 * sizeof(GLfloat)); break; case GL_T: - memcpy(params, state.texgen[state.texture.active].Tv, 4 * sizeof(GLfloat)); + memcpy(params, state.texgen[state.texture.active].T_O, 4 * sizeof(GLfloat)); break; case GL_R: - memcpy(params, state.texgen[state.texture.active].Rv, 4 * sizeof(GLfloat)); + memcpy(params, state.texgen[state.texture.active].R_O, 4 * sizeof(GLfloat)); + break; + default: + errorShim(GL_INVALID_ENUM); + } + case GL_EYE_PLANE: + switch (coord) { + case GL_S: + memcpy(params, state.texgen[state.texture.active].S_E, 4 * sizeof(GLfloat)); + break; + case GL_T: + memcpy(params, state.texgen[state.texture.active].T_E, 4 * sizeof(GLfloat)); + break; + case GL_R: + memcpy(params, state.texgen[state.texture.active].R_E, 4 * sizeof(GLfloat)); break; default: errorShim(GL_INVALID_ENUM); @@ -261,13 +283,13 @@ void eye_loop(const GLfloat *verts, const GLfloat *param, GLfloat *out, GLint co } -static inline void tex_coord_loop(GLfloat *verts, GLfloat *norm, GLfloat *out, GLint count, GLenum type, GLfloat *params, GLushort *indices) { +static inline void tex_coord_loop(GLfloat *verts, GLfloat *norm, GLfloat *out, GLint count, GLenum type, GLfloat *param_o, GLfloat *param_e, GLushort *indices) { switch (type) { case GL_OBJECT_LINEAR: - dot_loop(verts, params, out, count, indices); + dot_loop(verts, param_o, out, count, indices); break; case GL_EYE_LINEAR: - eye_loop(verts, params, out, count, indices); + eye_loop(verts, param_e, out, count, indices); break; case GL_SPHERE_MAP: //printf("LIBGL: GL_SPHERE_MAP with only 1 TexGen available"); //Broken here @@ -352,30 +374,10 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count return; if ((*coords)==NULL) *coords = (GLfloat *)malloc(count * 2 * sizeof(GLfloat)); -/* LOAD_GLES(glPushMatrix); - LOAD_GLES(glGetIntegerv); - LOAD_GLES(glMatrixMode); - LOAD_GLES(glLoadIdentity); - LOAD_GLES(glActiveTexture); - GLuint old=state.texture.active; - GLuint matmode; - gles_glGetIntegerv(GL_MATRIX_MODE, &matmode); - if (matmode!=GL_TEXTURE) - gles_glMatrixMode(GL_TEXTURE); - if (old!=texture) - gles_glActiveTexture(GL_TEXTURE0+texture); - gles_glPushMatrix(); - gles_glLoadIdentity(); - if (matmode!=GL_TEXTURE) - gles_glMatrixMode(matmode); - if (old!=texture) - gles_glActiveTexture(GL_TEXTURE0+old); - *needclean=2; -*/ if (state.enable.texgen_s[texture]) - tex_coord_loop(verts, norm, *coords, (indices)?ilen:count, state.texgen[texture].S, state.texgen[texture].Sv, indices); + tex_coord_loop(verts, norm, *coords, (indices)?ilen:count, state.texgen[texture].S, state.texgen[texture].S_O, state.texgen[texture].S_E, indices); if (state.enable.texgen_t[texture]) - tex_coord_loop(verts, norm, *coords+1, (indices)?ilen:count, state.texgen[texture].T, state.texgen[texture].Tv, indices); + tex_coord_loop(verts, norm, *coords+1, (indices)?ilen:count, state.texgen[texture].T, state.texgen[texture].T_O, state.texgen[texture].T_E, indices); } void gen_tex_clean(GLint cleancode, int texture) { @@ -389,24 +391,6 @@ void gen_tex_clean(GLint cleancode, int texture) { if (old_tex!=texture) glActiveTexture(GL_TEXTURE0 + old_tex); return; } -/* if (cleancode == 2) { - LOAD_GLES(glPopMatrix); - LOAD_GLES(glGetIntegerv); - LOAD_GLES(glMatrixMode); - LOAD_GLES(glActiveTexture); - GLuint old=state.texture.active; - GLuint matmode; - gles_glGetIntegerv(GL_MATRIX_MODE, &matmode); - if (matmode!=GL_TEXTURE) - gles_glMatrixMode(GL_TEXTURE); - if (old!=texture) - gles_glActiveTexture(GL_TEXTURE0+texture); - gles_glPopMatrix(); - if (matmode!=GL_TEXTURE) - gles_glMatrixMode(matmode); - if (old!=texture) - gles_glActiveTexture(GL_TEXTURE0+old); - }*/ } void glLoadTransposeMatrixf(const GLfloat *m) { diff --git a/project/jni/glshim/src/gl/texture.c b/project/jni/glshim/src/gl/texture.c index c5f06cd9d..1fb217ef5 100755 --- a/project/jni/glshim/src/gl/texture.c +++ b/project/jni/glshim/src/gl/texture.c @@ -1,6 +1,7 @@ #include "texture.h" #include "raster.h" #include "decompress.h" +#include "debug.h" #include #include #include "../glx/streaming.h" @@ -99,6 +100,8 @@ void tex_setup_texcoord(GLuint texunit, GLuint len) { if (old!=texunit) glClientActiveTexture(old+GL_TEXTURE0); } +int nolumalpha = 0; + static void *swizzle_texture(GLsizei width, GLsizei height, GLenum *format, GLenum *type, const GLvoid *data) { @@ -112,7 +115,10 @@ static void *swizzle_texture(GLsizei width, GLsizei height, break; case GL_ALPHA: case GL_RGBA: + break; case GL_LUMINANCE_ALPHA: + if(nolumalpha) + convert = true; break; case GL_RGB5: dest_type = GL_UNSIGNED_SHORT_5_6_5; @@ -197,7 +203,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *data) { -//printf("glTexImage2D on target=0x%04X with unpack_row_length(%i), size(%i,%i) and skip(%i,%i), format(internal)=%04x(%04x), type=%04x, data=%08x, level=%i (mipmap_need=%i, mipmap_auto=%i) => texture=%u (streamed=%i)\n", target, state.texture.unpack_row_length, width, height, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, format, internalformat, type, data, level, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->mipmap_need:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->mipmap_auto:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->texture:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->streamed:0); + //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)\n", PrintEnum(target), state.texture.unpack_row_length, width, height, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, PrintEnum(format), PrintEnum(internalformat), PrintEnum(type), data, level, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->mipmap_need:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->mipmap_auto:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->texture:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->streamed:0); // proxy case if (target == GL_PROXY_TEXTURE_2D) { @@ -301,6 +307,11 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, printf("LIBGL: No glCopyTexImage2D / glCopyTexSubImage2D hack\n"); copytex = 1; } + char *env_lumalpha = getenv("LIBGL_NOLUMALPHA"); + if (env_lumalpha && strcmp(env_lumalpha, "1") == 0) { + nolumalpha = 1; + printf("LIBGL: GL_LUMINANCE_ALPHA hardware support disabled\n"); + } tested_env = true; } @@ -582,7 +593,7 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, LOAD_GLES(glTexSubImage2D); LOAD_GLES(glTexParameteri); noerrorShim(); -//printf("glTexSubImage2D on target=0x%04X with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, format=%04x, type=%04x, level=%i, texture=%u\n", target, state.texture.unpack_row_length, width, height, xoffset, yoffset, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, format, type, level, state.texture.bound[state.texture.active]->texture); + //printf("glTexSubImage2D on target=%s with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, format=%s, type=%s, level=%i, texture=%u\n", PrintEnum(target), state.texture.unpack_row_length, width, height, xoffset, yoffset, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, PrintEnum(format), PrintEnum(type), level, state.texture.bound[state.texture.active]->texture); if (width==0 || height==0) { state.gl_batch = old_glbatch; return; @@ -696,7 +707,7 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE ); if ((target==GL_TEXTURE_2D) && texcopydata && bound && ((texstream && !bound->streamed) || !texstream)) { -//printf("*texcopy* glTexSubImage2D, xy=%i,%i, size=%i,%i, format=0x%04X, type=0x%04X, tex=%u\n", xoffset, yoffset, width, height, format, type, bound->glname); + //printf("*texcopy* glTexSubImage2D, xy=%i,%i, size=%i,%i=>%i,%i, format=%s, type=%s, tex=%u\n", xoffset, yoffset, width, height, bound->width, bound->height, PrintEnum(format), PrintEnum(type), bound->glname); GLvoid * tmp = bound->data; tmp += (yoffset*bound->width + xoffset)*4; if (!pixel_convert(pixels, &tmp, width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE, bound->width)) @@ -835,7 +846,7 @@ void glBindTexture(GLenum target, GLuint texture) { int tex_changed = 1; int streamingID = -1; gltexture_t *tex = NULL; -//printf("glBindTexture(0x%04X, %u), active=%i, client=%i\n", target, texture, state.texture.active, state.texture.client); + //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; @@ -1162,7 +1173,7 @@ void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoi gltexture_t* bound = state.texture.bound[state.texture.active]; int width = bound->width; int height = bound->height; -//printf("glGetTexImage(0x%04X, %i, 0x%04X, 0x%04X, 0x%p), texture=%u, size=%i,%i\n", target, level, format, type, img, bound->glname, width, height); + //printf("glGetTexImage(0x%04X, %i, 0x%04X, 0x%04X, 0x%p), texture=%u, size=%i,%i\n", target, level, format, type, img, bound->glname, width, height); GLvoid *dst = img; if (state.buffers.pack) @@ -1176,7 +1187,8 @@ void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoi } #endif if (texcopydata && bound->data) { - errorShim(GL_INVALID_ENUM); + printf("texcopydata* glGetTexImage(0x%04X, %d, 0x%04x, 0x%04X, %p)\n", target, level, format, type, img); + noerrorShim(); if (!pixel_convert(bound->data, &dst, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) printf("LIBGL: Error on pixel_convert while glGetTexImage\n"); } else { @@ -1275,7 +1287,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(%i, %i, %i, %i, %i, %i, %i, %i), bounded texture=%u format/type=0x%04X, 0x%04X\n", target, level, xoffset, yoffset, x, y, width, height, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->texture:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->format:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->type:0); + //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); GLuint old_glbatch = state.gl_batch; if (state.gl_batch) { @@ -1334,7 +1346,7 @@ void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffse void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { -//printf("glCopyTexImage2D(0x%04X, %i, 0x%04X, %i, %i, %i, %i, %i), current_fb=%u\n", target, level, internalformat, x, y, width, height, border, current_fb); + //printf("glCopyTexImage2D(0x%04X, %i, 0x%04X, %i, %i, %i, %i, %i), current_fb=%u\n", target, level, internalformat, x, y, width, height, border, current_fb); //PUSH_IF_COMPILING(glCopyTexImage2D); GLuint old_glbatch = state.gl_batch; if (state.gl_batch) { @@ -1558,7 +1570,7 @@ void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint state.gl_batch = old_glbatch; return; } -//printf("glCompressedTexSubImage2D with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, internalformat=%04x, imagesize=%i\n", state.texture.unpack_row_length, width, height, xoffset, yoffset, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, format, imageSize); + //printf("glCompressedTexSubImage2D with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, internalformat=%s, imagesize=%i\n", state.texture.unpack_row_length, width, height, xoffset, yoffset, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, PrintEnum(format), imageSize); glbuffer_t *unpack = state.buffers.unpack; state.buffers.unpack = NULL; GLvoid *datab = (GLvoid*)data; diff --git a/project/jni/glshim/src/gl/wrap/gl.c b/project/jni/glshim/src/gl/wrap/gl.c index 7bfe05c41..68c92f0e3 100755 --- a/project/jni/glshim/src/gl/wrap/gl.c +++ b/project/jni/glshim/src/gl/wrap/gl.c @@ -678,11 +678,12 @@ void glTexCoord4fv(GLfloat *t) { // texgen void glTexGend(GLenum coord, GLenum pname, GLdouble param) { - glTexGeni(coord, pname, param); + glTexGenf(coord, pname, param); } void glTexGenf(GLenum coord, GLenum pname, GLfloat param) { - // TODO: this is gross/lossy. - glTexGeni(coord, pname, param); + GLfloat params[4] = {0,0,0,0}; + params[0] = param; + glTexGenfv(coord, pname, params); } void glTexGendv(GLenum coord, GLenum pname, const GLdouble *params) { GLfloat tmp[4]; diff --git a/project/jni/glshim/src/glx/glx.c b/project/jni/glshim/src/glx/glx.c index 763e29243..e6700884b 100755 --- a/project/jni/glshim/src/glx/glx.c +++ b/project/jni/glshim/src/glx/glx.c @@ -156,6 +156,7 @@ static bool g_usefbo = false; static bool g_xrefresh = false; static bool g_stacktrace = false; static bool g_bcm_active = false; +bool g_recyclefbo = false; static int g_width=0, g_height=0; #ifndef BCMHOST static bool g_bcmhost = false; @@ -303,6 +304,7 @@ static void scan_env() { printf("LIBGL: LiveInfo detected, fps will be shown\n"); } #endif + env(LIBGL_RECYCLEFBO, g_recyclefbo, "Recycling of FBO enabled"); char cwd[1024]; if (getcwd(cwd, sizeof(cwd))!= NULL) printf("LIBGL: Current folder is:%s\n", cwd);