From ad9bbd68f3e41f1b627fd90cb887e8f598f45308 Mon Sep 17 00:00:00 2001 From: lubomyr Date: Tue, 3 Nov 2015 21:47:36 +0200 Subject: [PATCH] glshim updated, added latest changes by ptitSeb --- project/jni/glshim/src/gl/array.c | 2 +- project/jni/glshim/src/gl/buffers.c | 126 +++++------ project/jni/glshim/src/gl/const.h | 20 +- project/jni/glshim/src/gl/debug.c | 33 ++- project/jni/glshim/src/gl/framebuffers.c | 28 ++- project/jni/glshim/src/gl/gl.c | 263 +++++++++++++++-------- project/jni/glshim/src/gl/gl.h | 1 + project/jni/glshim/src/gl/list.c | 32 ++- project/jni/glshim/src/gl/pixel.c | 181 +++++++++++++--- project/jni/glshim/src/gl/raster.c | 26 ++- project/jni/glshim/src/gl/stack.c | 24 +-- project/jni/glshim/src/gl/state.h | 33 ++- project/jni/glshim/src/gl/texture.c | 228 ++++++++++++++++---- project/jni/glshim/src/gl/texture.h | 2 + project/jni/glshim/src/gl/wrap/gl.c | 6 +- project/jni/glshim/src/glx/glx.c | 2 +- 16 files changed, 718 insertions(+), 289 deletions(-) diff --git a/project/jni/glshim/src/gl/array.c b/project/jni/glshim/src/gl/array.c index 1199f15a9..c34966ee4 100755 --- a/project/jni/glshim/src/gl/array.c +++ b/project/jni/glshim/src/gl/array.c @@ -201,7 +201,7 @@ GLfloat *gl_pointer_index(pointer_state_t *p, GLint index) { GLsizei size = gl_sizeof(p->type); GLsizei stride = p->stride ? p->stride : size * p->size; uintptr_t ptr = (uintptr_t)(p->pointer) + (stride * index) - + (uintptr_t)((state.buffers.vertex)?state.buffers.vertex->data:0); + + (uintptr_t)((state.vao->vertex)?state.vao->vertex->data:0); GL_TYPE_SWITCH(src, ptr, p->type, for (int i = 0; i < p->size; i++) { diff --git a/project/jni/glshim/src/gl/buffers.c b/project/jni/glshim/src/gl/buffers.c index 2eb0c7e67..4d5755890 100755 --- a/project/jni/glshim/src/gl/buffers.c +++ b/project/jni/glshim/src/gl/buffers.c @@ -1,22 +1,23 @@ #include "buffers.h" +#include "debug.h" static GLuint lastbuffer = 1; -// Utility function to bond / unbind a particular buffer +// Utility function to bind / unbind a particular buffer glbuffer_t** BUFF(GLenum target) { switch(target) { case GL_ARRAY_BUFFER: - return &state.buffers.vertex; + return &state.vao->vertex; break; case GL_ELEMENT_ARRAY_BUFFER: - return &state.buffers.elements; + return &state.vao->elements; break; case GL_PIXEL_PACK_BUFFER: - return &state.buffers.pack; + return &state.vao->pack; break; case GL_PIXEL_UNPACK_BUFFER: - return &state.buffers.unpack; + return &state.vao->unpack; break; default: printf("LIBGL: Warning, unknown buffer target 0x%04X\n", target); @@ -66,13 +67,16 @@ void glGenBuffers(GLsizei n, GLuint * buffers) { } void glBindBuffer(GLenum target, GLuint buffer) { -//printf("glBindBuffer(0x%04X, %u)\n", target, buffer); +//printf("glBindBuffer(%s, %u)\n", PrintEnum(target), buffer); + if (state.gl_batch) { + flush(); + } khint_t k; int ret; - khash_t(buff) *list = state.buffers.list; + khash_t(buff) *list = state.buffers; if (! list) { - list = state.buffers.list = kh_init(buff); + list = state.buffers = kh_init(buff); // segfaults if we don't do a single put kh_put(buff, list, 1, &ret); kh_del(buff, list, 1); @@ -108,7 +112,7 @@ void glBindBuffer(GLenum target, GLuint buffer) { } void glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) { -//printf("glBufferData(0x%04X, %i, %p, 0x%04X)\n", target, size, data, usage); +//printf("glBufferData(%s, %i, %p, %s)\n", PrintEnum(target), size, data, PrintEnum(usage)); if (!buffer_target(target)) { errorShim(GL_INVALID_ENUM); return; @@ -132,7 +136,7 @@ void glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum us } void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { -//printf("glBufferSubData(0x%04X, %p, %i, %p)\n", target, offset, size, data); +//printf("glBufferSubData(%s, %p, %i, %p)\n", PrintEnum(target), offset, size, data); if (!buffer_target(target)) { errorShim(GL_INVALID_ENUM); return; @@ -149,26 +153,32 @@ void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvo void glDeleteBuffers(GLsizei n, const GLuint * buffers) { //printf("glDeleteBuffers(%i, %p)\n", n, buffers); - khash_t(buff) *list = state.buffers.list; + if (state.gl_batch) { + flush(); + } + + khash_t(buff) *list = state.buffers; if (list) { khint_t k; glbuffer_t *buff; for (int i = 0; i < n; i++) { GLuint t = buffers[i]; - k = kh_get(buff, list, t); - if (k != kh_end(list)) { - buff = kh_value(list, k); - if (state.buffers.vertex == buff) - state.buffers.vertex = NULL; - if (state.buffers.elements == buff) - state.buffers.elements = NULL; - if (state.buffers.pack == buff) - state.buffers.pack = NULL; - if (state.buffers.unpack == buff) - state.buffers.unpack = NULL; - if (buff->data) free(buff->data); - kh_del(buff, list, k); - free(buff); + if (t) { // don't allow to remove default one + k = kh_get(buff, list, t); + if (k != kh_end(list)) { + buff = kh_value(list, k); + if (state.vao->vertex == buff) + state.vao->vertex = NULL; + if (state.vao->elements == buff) + state.vao->elements = NULL; + if (state.vao->pack == buff) + state.vao->pack = NULL; + if (state.vao->unpack == buff) + state.vao->unpack = NULL; + if (buff->data) free(buff->data); + kh_del(buff, list, k); + free(buff); + } } } } @@ -177,7 +187,7 @@ void glDeleteBuffers(GLsizei n, const GLuint * buffers) { GLboolean glIsBuffer(GLuint buffer) { //printf("glIsBuffer(%u)\n", buffer); - khash_t(buff) *list = state.buffers.list; + khash_t(buff) *list = state.buffers; khint_t k; noerrorShim(); if (list) { @@ -192,7 +202,7 @@ GLboolean glIsBuffer(GLuint buffer) { void glGetBufferParameteriv(GLenum target, GLenum value, GLint * data) { -//printf("glGetBufferParameteriv(0x%04X, 0x%04X, %p)\n", target, value, data); +//printf("glGetBufferParameteriv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(value), data); if (!buffer_target(target)) { errorShim(GL_INVALID_ENUM); return; @@ -232,7 +242,7 @@ void glGetBufferParameteriv(GLenum target, GLenum value, GLint * data) { } void *glMapBuffer(GLenum target, GLenum access) { -//printf("glMapBuffer(0x%04X, 0x%04X)\n", target, access); +//printf("glMapBuffer(%s, %s)\n", PrintEnum(target), PrintEnum(access)); if (!buffer_target(target)) { errorShim(GL_INVALID_ENUM); return (void*)NULL; @@ -247,7 +257,7 @@ void *glMapBuffer(GLenum target, GLenum access) { } GLboolean glUnmapBuffer(GLenum target) { -//printf("glUnmapBuffer(0x%04X)\n", target); +//printf("glUnmapBuffer(%s)\n", PrintEnum(target)); if (!buffer_target(target)) { errorShim(GL_INVALID_ENUM); return GL_FALSE; @@ -264,7 +274,7 @@ GLboolean glUnmapBuffer(GLenum target) { } void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid * data) { -//printf("glGetBufferSubData(0x%04X, %p, %i, %p)\n", target, offset, size, data); +//printf("glGetBufferSubData(%s, %p, %i, %p)\n", PrintEnum(target), offset, size, data); if (!buffer_target(target)) { errorShim(GL_INVALID_ENUM); return; @@ -278,7 +288,7 @@ void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid } void glGetBufferPointerv(GLenum target, GLenum pname, GLvoid ** params) { -//printf("glGetBufferPointerv(0x%04X, 0x%04X, %p)\n", target, pname, params); +//printf("glGetBufferPointerv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(pname), params); if (!buffer_target(target)) { errorShim(GL_INVALID_ENUM); return; @@ -348,6 +358,9 @@ void glGenVertexArrays(GLsizei n, GLuint *arrays) { } void glBindVertexArray(GLuint array) { //printf("glBindVertexArray(%u)\n", array); + if (state.gl_batch) { + flush(); + } khint_t k; int ret; @@ -358,25 +371,10 @@ void glBindVertexArray(GLuint array) { kh_put(glvao, list, 1, &ret); kh_del(glvao, list, 1); } - // check if needs to copy the data to current vao - if ((state.bindedvao!=NULL) && (state.bindedvao->array!=array)) - { - memcpy(&state.bindedvao->pointers, &state.pointers, sizeof(pointer_states_t)); - state.bindedvao->vertex = state.buffers.vertex; - state.bindedvao->elements = state.buffers.elements; - state.bindedvao->pack = state.buffers.pack; - state.bindedvao->unpack = state.buffers.unpack; - state.bindedvao->secondary_array = state.enable.secondary_array; - state.bindedvao->color_array = state.enable.color_array; - state.bindedvao->normal_array = state.enable.normal_array; - state.bindedvao->vertex_array = state.enable.vertex_array; - memcpy(state.bindedvao->tex_coord_array, state.enable.tex_coord_array, MAX_TEX*sizeof(GLboolean)); - - } // if array = 0 => unbind buffer! if (array == 0) { // unbind buffer - state.bindedvao = NULL; + state.vao = state.defaultvao; } else { // search for an existing buffer k = kh_get(glvao, list, array); @@ -386,38 +384,40 @@ void glBindVertexArray(GLuint array) { glvao = kh_value(list, k) = malloc(sizeof(glvao_t)); // new vao is binded to nothing memset(glvao, 0, sizeof(glvao_t)); + /* + state.vao->vertex = state.defaultvbo; + state.vao->elements = state.defaultvbo; + state.vao->pack = state.defaultvbo; + state.vao->unpack = state.defaultvbo; + */ + // just put is number glvao->array = array; } else { glvao = kh_value(list, k); } - state.bindedvao = glvao; - memcpy(&state.pointers, &glvao->pointers, sizeof(pointer_states_t)); - state.buffers.vertex = glvao->vertex; - state.buffers.elements = glvao->elements; - state.buffers.pack = glvao->pack; - state.buffers.unpack = glvao->unpack; - state.enable.secondary_array = glvao->secondary_array; - state.enable.color_array = glvao->color_array; - state.enable.normal_array = glvao->normal_array; - state.enable.vertex_array = glvao->vertex_array; - memcpy(state.enable.tex_coord_array, glvao->tex_coord_array, MAX_TEX*sizeof(GLboolean)); + state.vao = glvao; } noerrorShim(); } void glDeleteVertexArrays(GLsizei n, const GLuint *arrays) { //printf("glDeleteVertexArrays(%i, %p)\n", n, arrays); + if (state.gl_batch) { + flush(); + } khash_t(glvao) *list = state.vaos; if (list) { khint_t k; glvao_t *glvao; for (int i = 0; i < n; i++) { GLuint t = arrays[i]; - k = kh_get(glvao, list, t); - if (k != kh_end(list)) { - glvao = kh_value(list, k); - kh_del(glvao, list, k); - free(glvao); + if (t) { // don't allow to remove the default one + k = kh_get(glvao, list, t); + if (k != kh_end(list)) { + glvao = kh_value(list, k); + kh_del(glvao, list, k); + free(glvao); + } } } } diff --git a/project/jni/glshim/src/gl/const.h b/project/jni/glshim/src/gl/const.h index 4825fea52..449537843 100755 --- a/project/jni/glshim/src/gl/const.h +++ b/project/jni/glshim/src/gl/const.h @@ -122,6 +122,7 @@ // pixel formats #define GL_RED 0x1903 +#define GL_R3_G3_B2 0x2A10 #define GL_RG 0x8227 #define GL_BGR 0x80E0 #define GL_BGRA 0x80E1 @@ -140,7 +141,21 @@ #define GL_RGB8 0x8051 #define GL_RGB5 0x8050 #define GL_RGBA8 0x8058 - +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_RGBA16 0x805B +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE16 0x8042 +#define GL_ALPHA8 0x803C +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_RGB16 0x8054 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 // types #define GL_BYTE 0x1400 #define GL_UNSIGNED_BYTE 0x1401 @@ -252,8 +267,11 @@ #define GL_UNPACK_SKIP_PIXELS 0x0CF4 #define GL_UNPACK_SKIP_ROWS 0x0CF3 #define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_PACK_IMAGE_HEIGHT 0x806C #define GL_ZOOM_X 0x0D16 #define GL_ZOOM_Y 0x0D17 +#define GL_TEXTURE_BASE_LEVEL 0x813C // blending #define GL_BLEND 0x0BE2 diff --git a/project/jni/glshim/src/gl/debug.c b/project/jni/glshim/src/gl/debug.c index 9bf41ddf9..4b936f3c5 100755 --- a/project/jni/glshim/src/gl/debug.c +++ b/project/jni/glshim/src/gl/debug.c @@ -20,14 +20,36 @@ const char* PrintEnum(GLenum what) { p(GL_DRAW_FRAMEBUFFER); // format p(GL_RED); + p(GL_R3_G3_B2); p(GL_RGB); - p(GL_RGBA); - p(GL_RGBA8); + p(GL_BGR); p(GL_RGB8); + p(GL_RGB5); + p(GL_RGB16); + p(GL_RGB16F); + p(GL_RGB32F); + p(GL_BGRA); + p(GL_RGBA); + p(GL_RGBA4); + p(GL_RGB5_A1); + p(GL_RGB10_A2); + p(GL_RGBA8); + p(GL_RGBA16); + p(GL_RGBA16F); + p(GL_RGBA32F); 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); + p(GL_LUMINANCE8_ALPHA8); + p(GL_LUMINANCE_ALPHA); + p(GL_LUMINANCE4_ALPHA4); + p(GL_LUMINANCE16_ALPHA16); + p(GL_LUMINANCE); + p(GL_ALPHA); + p(GL_LUMINANCE8); + p(GL_LUMINANCE16); + p(GL_ALPHA8); // type p(GL_UNSIGNED_BYTE); p(GL_UNSIGNED_BYTE_2_3_3_REV); @@ -52,6 +74,13 @@ const char* PrintEnum(GLenum what) { p(GL_COLOR_ATTACHMENT4); p(GL_DEPTH_ATTACHMENT); p(GL_STENCIL_ATTACHMENT); + // VBO + p(GL_STATIC_DRAW); + p(GL_READ_WRITE); + p(GL_ARRAY_BUFFER); + p(GL_ELEMENT_ARRAY_BUFFER); + p(GL_PIXEL_PACK_BUFFER); + p(GL_PIXEL_UNPACK_BUFFER); default: sprintf(fallback, "0x%04X", what); } diff --git a/project/jni/glshim/src/gl/framebuffers.c b/project/jni/glshim/src/gl/framebuffers.c index da6388271..ae503d58f 100755 --- a/project/jni/glshim/src/gl/framebuffers.c +++ b/project/jni/glshim/src/gl/framebuffers.c @@ -581,13 +581,31 @@ void blitMainFBO() { glDisable(GL_BLEND); // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + + if(!state.clientstate.vertex_array) { + gles_glEnableClientState(GL_VERTEX_ARRAY); + state.clientstate.vertex_array = 1; + } gles_glVertexPointer(2, GL_FLOAT, 0, vert); + if(!state.clientstate.tex_coord_array[0]) { + gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); + state.clientstate.tex_coord_array[0] = 1; + } gles_glTexCoordPointer(2, GL_FLOAT, 0, tex); + for (int a=1; a buffer = 0; + buff->type = 0; + buff->data = NULL; + buff->usage = GL_STATIC_DRAW; + buff->size = 0; + buff->access = GL_READ_WRITE; + buff->mapped = 0; + state.defaultvbo = buff; + } + // add default VAO + { + khint_t k; + int ret; + khash_t(glvao) *list = state.vaos; + if (! list) { + list = state.vaos = kh_init(glvao); + } + k = kh_put(glvao, list, 0, &ret); + glvao_t *glvao = kh_value(list, k) = malloc(sizeof(glvao_t)); + // new vao is binded to default vbo + memset(glvao, 0, sizeof(glvao_t)); + // just put is number + glvao->array = 0; + state.defaultvao = glvao; + } + // Bind defaults... + state.vao = state.defaultvao; + // init read hack char *env_readhack = getenv("LIBGL_READHACK"); if (env_readhack && strcmp(env_readhack, "1") == 0) { @@ -183,6 +221,9 @@ void glGetIntegerv(GLenum pname, GLint *params) { case GL_UNPACK_LSB_FIRST: *params = state.texture.unpack_lsb_first; break; + case GL_UNPACK_IMAGE_HEIGHT: + *params = state.texture.unpack_image_height; + break; case GL_PACK_ROW_LENGTH: *params = state.texture.pack_row_length; break; @@ -195,6 +236,9 @@ void glGetIntegerv(GLenum pname, GLint *params) { case GL_PACK_LSB_FIRST: *params = state.texture.pack_lsb_first; break; + case GL_PACK_IMAGE_HEIGHT: + *params = state.texture.pack_image_height; + break; case GL_UNPACK_SWAP_BYTES: case GL_PACK_SWAP_BYTES: //Fake, *TODO* ? @@ -253,16 +297,16 @@ void glGetIntegerv(GLenum pname, GLint *params) { *params=64; // fake, no limit in fact break; case GL_ARRAY_BUFFER_BINDING: - *params=(state.buffers.vertex)?state.buffers.vertex->buffer:0; + *params=(state.vao->vertex)?state.vao->vertex->buffer:0; break; case GL_ELEMENT_ARRAY_BUFFER_BINDING: - *params=(state.buffers.elements)?state.buffers.elements->buffer:0; + *params=(state.vao->elements)?state.vao->elements->buffer:0; break; case GL_PIXEL_PACK_BUFFER_BINDING: - *params=(state.buffers.pack)?state.buffers.pack->buffer:0; + *params=(state.vao->pack)?state.vao->pack->buffer:0; break; case GL_PIXEL_UNPACK_BUFFER_BINDING: - *params=(state.buffers.unpack)?state.buffers.unpack->buffer:0; + *params=(state.vao->unpack)?state.vao->unpack->buffer:0; break; default: errorGL(); @@ -364,16 +408,16 @@ void glGetFloatv(GLenum pname, GLfloat *params) { *params=64; // fake, no limit in fact break; case GL_ARRAY_BUFFER_BINDING: - *params=(state.buffers.vertex)?state.buffers.vertex->buffer:0; + *params=(state.vao->vertex)?state.vao->vertex->buffer:0; break; case GL_ELEMENT_ARRAY_BUFFER_BINDING: - *params=(state.buffers.elements)?state.buffers.elements->buffer:0; + *params=(state.vao->elements)?state.vao->elements->buffer:0; break; case GL_PIXEL_PACK_BUFFER_BINDING: - *params=(state.buffers.pack)?state.buffers.pack->buffer:0; + *params=(state.vao->pack)?state.vao->pack->buffer:0; break; case GL_PIXEL_UNPACK_BUFFER_BINDING: - *params=(state.buffers.unpack)?state.buffers.unpack->buffer:0; + *params=(state.vao->unpack)?state.vao->unpack->buffer:0; break; case GL_TRANSPOSE_PROJECTION_MATRIX: gles_glGetFloatv(GL_PROJECTION_MATRIX, params); @@ -405,6 +449,10 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { case constant: state.enable.name = enable; next(cap); break #define enable(constant, name) \ case constant: state.enable.name = enable; break; + #define proxy_clientenable(constant, name) \ + case constant: state.vao->name = enable; next(cap); break + #define clientenable(constant, name) \ + case constant: state.vao->name = enable; break; // TODO: maybe could be weird behavior if someone tried to: // 1. enable GL_TEXTURE_1D @@ -434,13 +482,13 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { // Secondary color enable(GL_COLOR_SUM, color_sum); - enable(GL_SECONDARY_COLOR_ARRAY, secondary_array); + clientenable(GL_SECONDARY_COLOR_ARRAY, secondary_array); // for glDrawArrays - proxy_enable(GL_VERTEX_ARRAY, vertex_array); - proxy_enable(GL_NORMAL_ARRAY, normal_array); - proxy_enable(GL_COLOR_ARRAY, color_array); - proxy_enable(GL_TEXTURE_COORD_ARRAY, tex_coord_array[state.texture.client]); + clientenable(GL_VERTEX_ARRAY, vertex_array); + clientenable(GL_NORMAL_ARRAY, normal_array); + clientenable(GL_COLOR_ARRAY, color_array); + clientenable(GL_TEXTURE_COORD_ARRAY, tex_coord_array[state.texture.client]); // Texture 1D and 3D enable(GL_TEXTURE_1D, texture_1d[state.texture.active]); @@ -450,6 +498,8 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { } #undef proxy_enable #undef enable + #undef proxy_clientenable + #undef clientenable } void glEnable(GLenum cap) { @@ -518,7 +568,6 @@ void glDisable(GLenum cap) { proxy_glEnable(cap, false, gles_glDisable); } -#ifndef USE_ES2 void glEnableClientState(GLenum cap) { LOAD_GLES(glEnableClientState); proxy_glEnable(cap, true, gles_glEnableClientState); @@ -528,10 +577,11 @@ void glDisableClientState(GLenum cap) { LOAD_GLES(glDisableClientState); proxy_glEnable(cap, false, gles_glDisableClientState); } -#endif #define isenabled(what, where) \ case what: return state.enable.where +#define clientisenabled(what, where) \ + case what: return state.vao->where GLboolean glIsEnabled(GLenum cap) { // should flush for now... to be optimized later! @@ -545,19 +595,20 @@ GLboolean glIsEnabled(GLenum cap) { 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); + clientisenabled(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]); + clientisenabled(GL_VERTEX_ARRAY, vertex_array); + clientisenabled(GL_NORMAL_ARRAY, normal_array); + clientisenabled(GL_COLOR_ARRAY, color_array); + clientisenabled(GL_TEXTURE_COORD_ARRAY, tex_coord_array[state.texture.client]); default: errorGL(); return gles_glIsEnabled(cap); } } #undef isenabled +#undef clientisenabled static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode, GLsizei skip, GLsizei count) { @@ -569,21 +620,21 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode, list->len = count-skip; list->cap = count-skip; - if (state.enable.vertex_array) { - list->vert = copy_gl_pointer_raw(&state.pointers.vertex, 3, skip, count, state.pointers.vertex.buffer); //TODO, what if size == 4 + if (state.vao->vertex_array) { + list->vert = copy_gl_pointer_raw(&state.vao->pointers.vertex, 3, skip, count, state.vao->pointers.vertex.buffer); //TODO, what if size == 4 } - if (state.enable.color_array) { - list->color = copy_gl_pointer_color(&state.pointers.color, 4, skip, count, state.pointers.color.buffer); + if (state.vao->color_array) { + list->color = copy_gl_pointer_color(&state.vao->pointers.color, 4, skip, count, state.vao->pointers.color.buffer); } - if (state.enable.secondary_array/* && state.enable.color_array*/) { - list->secondary = copy_gl_pointer(&state.pointers.secondary, 4, skip, count, state.pointers.secondary.buffer); // alpha chanel is always 0 for secondary... + if (state.vao->secondary_array/* && state.enable.color_array*/) { + list->secondary = copy_gl_pointer(&state.vao->pointers.secondary, 4, skip, count, state.vao->pointers.secondary.buffer); // alpha chanel is always 0 for secondary... } - if (state.enable.normal_array) { - list->normal = copy_gl_pointer_raw(&state.pointers.normal, 3, skip, count, state.pointers.normal.buffer); + if (state.vao->normal_array) { + list->normal = copy_gl_pointer_raw(&state.vao->pointers.normal, 3, skip, count, state.vao->pointers.normal.buffer); } for (int i=0; itex[i] = copy_gl_pointer_raw(&state.pointers.tex_coord[i], 2, skip, count, state.pointers.tex_coord[i].buffer); + if (state.vao->tex_coord_array[i]) { + list->tex[i] = copy_gl_pointer_raw(&state.vao->pointers.tex_coord[i], 2, skip, count, state.vao->pointers.tex_coord[i].buffer); } } @@ -593,7 +644,7 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode, static inline bool should_intercept_render(GLenum mode) { return ( - (state.enable.vertex_array && ! valid_vertex_type(state.pointers.vertex.type)) || + (state.vao->vertex_array && ! valid_vertex_type(state.vao->pointers.vertex.type)) || (/*state.enable.texture_2d[0] && */(state.enable.texgen_s[0] || state.enable.texgen_t[0] || state.enable.texgen_r[0])) || (/*state.enable.texture_2d[1] && */(state.enable.texgen_s[1] || state.enable.texgen_t[1] || state.enable.texgen_r[1])) || (/*state.enable.texture_2d[2] && */(state.enable.texgen_s[2] || state.enable.texgen_t[2] || state.enable.texgen_r[2])) || @@ -620,7 +671,7 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic } noerrorShim(); - GLushort *sindices = copy_gl_array((state.buffers.elements)?state.buffers.elements->data + (uintptr_t)indices:indices, + GLushort *sindices = copy_gl_array((state.vao->elements)?state.vao->elements->data + (uintptr_t)indices:indices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count); bool compiling = (state.list.active && (state.list.compiling || state.gl_batch)); @@ -659,12 +710,14 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic LOAD_GLES(glTexCoordPointer); LOAD_GLES(glEnable); LOAD_GLES(glDisable); + LOAD_GLES(glEnableClientState); + LOAD_GLES(glDisableClientState); GLuint len = 0; for (int i=0; idata; + if (state.vao->b && state.vao->pointers.a.buffer) state.vao->pointers.a.pointer += (uintptr_t)state.vao->pointers.a.buffer->data; shift_pointer(color, color_array); shift_pointer(secondary, secondary_array); @@ -672,7 +725,16 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic for (int aa=0; aaA != state.clientstate.A) { \ + C \ + if((state.clientstate.A = state.vao->A)==true) \ + gles_glEnableClientState(B); \ + else \ + gles_glDisableClientState(B); \ + } GLenum mode_init = mode; @@ -686,44 +748,47 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic if (mode == GL_POLYGON) mode = GL_TRIANGLE_FAN; if (state.render_mode == GL_SELECT) { - select_glDrawElements(&state.pointers.vertex, mode, count, GL_UNSIGNED_SHORT, sindices); + select_glDrawElements(&state.vao->pointers.vertex, mode, count, GL_UNSIGNED_SHORT, sindices); } else { // secondary color... GLfloat *final_colors = NULL; pointer_state_t old_color; - if (/*state.enable.color_sum && */(state.enable.secondary_array) && (state.enable.color_array)) { - final_colors=copy_gl_pointer_color(&state.pointers.color, 4, 0, len, 0); - GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&state.pointers.secondary, 4, 0, len, 0); + client_state(color_array, GL_COLOR_ARRAY, ); + if (/*state.enable.color_sum && */(state.vao->secondary_array) && (state.vao->color_array)) { + final_colors=copy_gl_pointer_color(&state.vao->pointers.color, 4, 0, len, 0); + GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&state.vao->pointers.secondary, 4, 0, len, 0); for (int i=0; icolor_array && (state.vao->pointers.color.size != 4)) { // Pandora doesn't like Color Pointer with size != 4 - if(state.pointers.color.type == GL_UNSIGNED_BYTE) { - final_colors=copy_gl_pointer_bytecolor(&state.pointers.color, 4, 0, len, 0); + if(state.vao->pointers.color.type == GL_UNSIGNED_BYTE) { + final_colors=copy_gl_pointer_bytecolor(&state.vao->pointers.color, 4, 0, len, 0); gles_glColorPointer(4, GL_UNSIGNED_BYTE, 0, final_colors); } else { - final_colors=copy_gl_pointer_color(&state.pointers.color, 4, 0, len, 0); + final_colors=copy_gl_pointer_color(&state.vao->pointers.color, 4, 0, len, 0); gles_glColorPointer(4, GL_FLOAT, 0, final_colors); } - } else if (state.enable.color_array) - gles_glColorPointer(state.pointers.color.size, state.pointers.color.type, state.pointers.color.stride, state.pointers.color.pointer); - if (state.enable.normal_array) - gles_glNormalPointer(state.pointers.normal.type, state.pointers.normal.stride, state.pointers.normal.pointer); - if (state.enable.vertex_array) - gles_glVertexPointer(state.pointers.vertex.size, state.pointers.vertex.type, state.pointers.vertex.stride, state.pointers.vertex.pointer); + } else if (state.vao->color_array) + gles_glColorPointer(state.vao->pointers.color.size, state.vao->pointers.color.type, state.vao->pointers.color.stride, state.vao->pointers.color.pointer); + client_state(normal_array, GL_NORMAL_ARRAY, ); + if (state.vao->normal_array) + gles_glNormalPointer(state.vao->pointers.normal.type, state.vao->pointers.normal.stride, state.vao->pointers.normal.pointer); + client_state(vertex_array, GL_VERTEX_ARRAY, ); + if (state.vao->vertex_array) + gles_glVertexPointer(state.vao->pointers.vertex.size, state.vao->pointers.vertex.type, state.vao->pointers.vertex.stride, state.vao->pointers.vertex.pointer); GLuint old_tex = state.texture.client; - for (int aa=0; aatex_coord_array[aa]) { tex_setup_texcoord(aa, len); - /*glClientActiveTexture(aa+GL_TEXTURE0); - gles_glTexCoordPointer(state.pointers.tex_coord[aa].size, state.pointers.tex_coord[aa].type, state.pointers.tex_coord[aa].stride, state.pointers.tex_coord[aa].pointer);*/ - } + } } if (state.texture.client!=old_tex) glClientActiveTexture(old_tex+GL_TEXTURE0); @@ -776,7 +841,7 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic glClientActiveTexture(old_tex+GL_TEXTURE0); } #define shift_pointer(a, b) \ - if (state.enable.b && state.pointers.a.buffer) state.pointers.a.pointer -= (uintptr_t)state.pointers.a.buffer->data; + if (state.vao->b && state.vao->pointers.a.buffer) state.vao->pointers.a.pointer -= (uintptr_t)state.vao->pointers.a.buffer->data; shift_pointer(color, color_array); shift_pointer(secondary, secondary_array); @@ -819,6 +884,8 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) { LOAD_GLES(glTexCoordPointer); LOAD_GLES(glEnable); LOAD_GLES(glDisable); + LOAD_GLES(glEnableClientState); + LOAD_GLES(glDisableClientState); renderlist_t *list; if (state.list.active && (state.list.compiling || state.gl_batch)) { @@ -843,7 +910,7 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) { LOAD_GLES(glDrawArrays); #define shift_pointer(a, b) \ - if (state.enable.b && state.pointers.a.buffer) state.pointers.a.pointer = state.pointers.a.buffer->data + (uintptr_t)state.pointers.a.pointer; + if (state.vao->b && state.vao->pointers.a.buffer) state.vao->pointers.a.pointer = state.vao->pointers.a.buffer->data + (uintptr_t)state.vao->pointers.a.pointer; shift_pointer(color, color_array); shift_pointer(secondary, secondary_array); @@ -861,41 +928,46 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) { mode = GL_TRIANGLE_FAN; if (state.render_mode == GL_SELECT) { - select_glDrawArrays(&state.pointers.vertex, mode, first, count); + select_glDrawArrays(&state.vao->pointers.vertex, mode, first, count); } else { // setup the Array Pointers // secondary color... GLfloat *final_colors = NULL; - if (/*state.enable.color_sum && */(state.enable.secondary_array) && (state.enable.color_array)) { - final_colors=copy_gl_pointer_color(&state.pointers.color, 4, 0, count+first, 0); - GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&state.pointers.secondary, 4, first, count+first, 0); + client_state(color_array, GL_COLOR_ARRAY, ); + if (/*state.enable.color_sum && */(state.vao->secondary_array) && (state.vao->color_array)) { + final_colors=copy_gl_pointer_color(&state.vao->pointers.color, 4, 0, count+first, 0); + GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&state.vao->pointers.secondary, 4, first, count+first, 0); for (int i=0; i<(count+first)*4; i++) final_colors[i]+=seconds_colors[i]; gles_glColorPointer(4, GL_FLOAT, 0, final_colors); free(seconds_colors); - } else if ((state.enable.color_array && (state.pointers.color.size != 4)) - || (state.enable.color_array && (state.pointers.color.stride!=0) && (state.pointers.color.type != GL_FLOAT))) { + } else if ((state.vao->color_array && (state.vao->pointers.color.size != 4)) + || (state.vao->color_array && (state.vao->pointers.color.stride!=0) && (state.vao->pointers.color.type != GL_FLOAT))) { // Pandora doesn't like Color Pointer with size != 4 - if(state.pointers.color.type == GL_UNSIGNED_BYTE) { - final_colors=copy_gl_pointer_bytecolor(&state.pointers.color, 4, 0, count+first, 0); + if(state.vao->pointers.color.type == GL_UNSIGNED_BYTE) { + final_colors=copy_gl_pointer_bytecolor(&state.vao->pointers.color, 4, 0, count+first, 0); gles_glColorPointer(4, GL_UNSIGNED_BYTE, 0, final_colors); } else { - final_colors=copy_gl_pointer_color(&state.pointers.color, 4, 0, count+first, 0); + final_colors=copy_gl_pointer_color(&state.vao->pointers.color, 4, 0, count+first, 0); gles_glColorPointer(4, GL_FLOAT, 0, final_colors); } - } else if (state.enable.color_array) - gles_glColorPointer(state.pointers.color.size, state.pointers.color.type, state.pointers.color.stride, state.pointers.color.pointer); - if (state.enable.normal_array) - gles_glNormalPointer(state.pointers.normal.type, state.pointers.normal.stride, state.pointers.normal.pointer); - if (state.enable.vertex_array) - gles_glVertexPointer(state.pointers.vertex.size, state.pointers.vertex.type, state.pointers.vertex.stride, state.pointers.vertex.pointer); + } else if (state.vao->color_array) + gles_glColorPointer(state.vao->pointers.color.size, state.vao->pointers.color.type, state.vao->pointers.color.stride, state.vao->pointers.color.pointer); + client_state(normal_array, GL_NORMAL_ARRAY, ); + if (state.vao->normal_array) + gles_glNormalPointer(state.vao->pointers.normal.type, state.vao->pointers.normal.stride, state.vao->pointers.normal.pointer); + client_state(vertex_array, GL_VERTEX_ARRAY, ); + if (state.vao->vertex_array) + gles_glVertexPointer(state.vao->pointers.vertex.size, state.vao->pointers.vertex.type, state.vao->pointers.vertex.stride, state.vao->pointers.vertex.pointer); GLuint old_tex = state.texture.client; - for (int aa=0; aatex_coord_array[aa]) { tex_setup_texcoord(aa, count+first); /*glClientActiveTexture(aa+GL_TEXTURE0); gles_glTexCoordPointer(state.pointers.tex_coord[aa].size, state.pointers.tex_coord[aa].type, state.pointers.tex_coord[aa].stride, state.pointers.tex_coord[aa].pointer);*/ @@ -950,7 +1022,7 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) { if (state.texture.client!=old_tex) glClientActiveTexture(old_tex+GL_TEXTURE0); #define shift_pointer(a, b) \ - if (state.enable.b && state.pointers.a.buffer) state.pointers.a.pointer = state.pointers.a.pointer - (uintptr_t)state.pointers.a.buffer->data; + if (state.vao->b && state.vao->pointers.a.buffer) state.vao->pointers.a.pointer = state.vao->pointers.a.pointer - (uintptr_t)state.vao->pointers.a.buffer->data; shift_pointer(color, color_array); shift_pointer(secondary, secondary_array); @@ -962,34 +1034,35 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) { } } } +#undef client_state #ifndef USE_ES2 #define clone_gl_pointer(t, s)\ - t.size = s; t.type = type; t.stride = stride; t.pointer = pointer; t.buffer = state.buffers.vertex + t.size = s; t.type = type; t.stride = stride; t.pointer = pointer; t.buffer = state.vao->vertex void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { noerrorShim(); - clone_gl_pointer(state.pointers.vertex, size); + clone_gl_pointer(state.vao->pointers.vertex, size); } void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { noerrorShim(); - clone_gl_pointer(state.pointers.color, size); + clone_gl_pointer(state.vao->pointers.color, size); } void glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) { noerrorShim(); - clone_gl_pointer(state.pointers.normal, 3); + clone_gl_pointer(state.vao->pointers.normal, 3); } void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { noerrorShim(); - clone_gl_pointer(state.pointers.tex_coord[state.texture.client], size); + clone_gl_pointer(state.vao->pointers.tex_coord[state.texture.client], size); } void glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { if (size!=3) return; // Size must be 3... - clone_gl_pointer(state.pointers.secondary, size); + clone_gl_pointer(state.vao->pointers.secondary, size); noerrorShim(); } @@ -1240,8 +1313,8 @@ void glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) { void glArrayElement(GLint i) { GLfloat *v; pointer_state_t *p; - p = &state.pointers.color; - if (state.enable.color_array) { + p = &state.vao->pointers.color; + if (state.vao->color_array) { v = gl_pointer_index(p, i); GLfloat scale = gl_max_value(p->type); // color[3] defaults to 1.0f @@ -1254,8 +1327,8 @@ void glArrayElement(GLint i) { } glColor4fv(v); } - p = &state.pointers.secondary; - if (state.enable.secondary_array) { + p = &state.vao->pointers.secondary; + if (state.vao->secondary_array) { v = gl_pointer_index(p, i); GLfloat scale = gl_max_value(p->type); // color[3] defaults to 0.0f @@ -1268,26 +1341,26 @@ void glArrayElement(GLint i) { } glSecondaryColor3fv(v); } - p = &state.pointers.normal; - if (state.enable.normal_array) { + p = &state.vao->pointers.normal; + if (state.vao->normal_array) { v = gl_pointer_index(p, i); glNormal3fv(v); } - p = &state.pointers.tex_coord[0]; - if (state.enable.tex_coord_array[0]) { + p = &state.vao->pointers.tex_coord[0]; + if (state.vao->tex_coord_array[0]) { v = gl_pointer_index(p, i); glTexCoord2fv(v); } int a; for (a=1; apointers.tex_coord[a]; + if (state.vao->tex_coord_array[a]) { v = gl_pointer_index(p, i); glMultiTexCoord2fv(GL_TEXTURE0+a, v); } } - p = &state.pointers.vertex; - if (state.enable.vertex_array) { + p = &state.vao->pointers.vertex; + if (state.vao->vertex_array) { v = gl_pointer_index(p, i); if (p->size == 4) { glVertex4fv(v); @@ -1797,7 +1870,7 @@ void glGetPointerv(GLenum pname, GLvoid* *params) { noerrorShim(); switch(pname) { case GL_COLOR_ARRAY_POINTER: - *params = state.pointers.color.pointer; + *params = (void*)state.vao->pointers.color.pointer; break; case GL_EDGE_FLAG_ARRAY_POINTER: *params = NULL; @@ -1808,16 +1881,16 @@ void glGetPointerv(GLenum pname, GLvoid* *params) { case GL_INDEX_ARRAY_POINTER: *params = NULL; case GL_NORMAL_ARRAY_POINTER: - *params = state.pointers.normal.pointer; + *params = (void*)state.vao->pointers.normal.pointer; break; case GL_TEXTURE_COORD_ARRAY_POINTER: - *params = state.pointers.tex_coord[state.texture.client].pointer; + *params = (void*)state.vao->pointers.tex_coord[state.texture.client].pointer; break; case GL_SELECTION_BUFFER_POINTER: *params = state.selectbuf.buffer; break; case GL_VERTEX_ARRAY_POINTER : - *params = state.pointers.vertex.pointer; + *params = (void*)state.vao->pointers.vertex.pointer; break; default: errorShim(GL_INVALID_ENUM); diff --git a/project/jni/glshim/src/gl/gl.h b/project/jni/glshim/src/gl/gl.h index dd82d580b..5193bc7e0 100755 --- a/project/jni/glshim/src/gl/gl.h +++ b/project/jni/glshim/src/gl/gl.h @@ -385,6 +385,7 @@ static const GLsizei pixel_sizeof(GLenum format, GLenum type) { static const GLboolean pixel_hasalpha(GLenum format) { switch (format) { case GL_ALPHA: + case GL_LUMINANCE_ALPHA: case GL_RGBA: case GL_BGRA: case GL_RGBA8: diff --git a/project/jni/glshim/src/gl/list.c b/project/jni/glshim/src/gl/list.c index 276270d85..3a51491d2 100755 --- a/project/jni/glshim/src/gl/list.c +++ b/project/jni/glshim/src/gl/list.c @@ -643,6 +643,8 @@ void draw_renderlist(renderlist_t *list) { #endif LOAD_GLES(glEnable); LOAD_GLES(glDisable); + LOAD_GLES(glEnableClientState); + LOAD_GLES(glDisableClientState); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); GLfloat *final_colors; @@ -754,24 +756,29 @@ void draw_renderlist(renderlist_t *list) { gles_glDrawArrays(list->mode, 0, list->len); #else if (list->vert) { - glEnableClientState(GL_VERTEX_ARRAY); + gles_glEnableClientState(GL_VERTEX_ARRAY); gles_glVertexPointer(3, GL_FLOAT, 0, list->vert); + state.clientstate.vertex_array = 1; } else { - glDisableClientState(GL_VERTEX_ARRAY); + gles_glDisableClientState(GL_VERTEX_ARRAY); + state.clientstate.vertex_array = false; } if (list->normal) { - glEnableClientState(GL_NORMAL_ARRAY); + gles_glEnableClientState(GL_NORMAL_ARRAY); gles_glNormalPointer(GL_FLOAT, 0, list->normal); + state.clientstate.normal_array = 1; } else { - glDisableClientState(GL_NORMAL_ARRAY); + gles_glDisableClientState(GL_NORMAL_ARRAY); + state.clientstate.normal_array = 0; } indices = list->indices; final_colors = NULL; if (list->color) { - glEnableClientState(GL_COLOR_ARRAY); + gles_glEnableClientState(GL_COLOR_ARRAY); + state.clientstate.color_array = 1; if (state.enable.color_sum && (list->secondary)) { final_colors=(GLfloat*)malloc(list->len * 4 * sizeof(GLfloat)); if (indices) { @@ -788,7 +795,8 @@ void draw_renderlist(renderlist_t *list) { } else gles_glColorPointer(4, GL_FLOAT, 0, list->color); } else { - glDisableClientState(GL_COLOR_ARRAY); + gles_glDisableClientState(GL_COLOR_ARRAY); + state.clientstate.color_array = 0; } GLuint texture; bool stipple; @@ -819,13 +827,15 @@ void draw_renderlist(renderlist_t *list) { for (int a=0; atex[a] || texgened[a])/* && state.enable.texture_2d[a]*/) { glClientActiveTexture(GL_TEXTURE0+a); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); + state.clientstate.tex_coord_array[a] = 1; gles_glTexCoordPointer(2, GL_FLOAT, 0, (texgened[a])?texgened[a]:list->tex[a]); } else { - if (state.enable.tex_coord_array[a]) { - glClientActiveTexture(GL_TEXTURE0+a); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } + if (state.clientstate.tex_coord_array[a]) { + glClientActiveTexture(GL_TEXTURE0+a); + gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY); + state.clientstate.tex_coord_array[a] = 0; + } //else if (!state.enable.texgen_s[a] && state.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); } diff --git a/project/jni/glshim/src/gl/pixel.c b/project/jni/glshim/src/gl/pixel.c index 09ee088ac..9d5d2c3b0 100755 --- a/project/jni/glshim/src/gl/pixel.c +++ b/project/jni/glshim/src/gl/pixel.c @@ -1,4 +1,5 @@ #include "pixel.h" +#include "debug.h" static const colorlayout_t *get_color_map(GLenum format) { #define map(fmt, ...) \ @@ -79,7 +80,7 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, }; read_each(, / 31.0f); ) - type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, + type_case(GL_UNSIGNED_SHORT_5_6_5_REV, GLushort, s = (GLushort[]){ (v & 31)*2, ((v & 0x07e0) >> 5), @@ -87,7 +88,7 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, }; read_each(, / 63.0f); ) - type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, + type_case(GL_UNSIGNED_SHORT_4_4_4_4_REV, GLushort, s = (GLushort[]){ (v & 0x000f), ((v & 0x00f0) >> 4), @@ -96,6 +97,32 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, }; read_each(, / 15.0f); ) + type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, + s = (GLushort[]){ + ((v & 0xF800) >>11)*2, + ((v & 0x07e0) >> 5), + ((v & 0x0031) )*2, + }; + read_each(, / 63.0f); + ) + type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, + s = (GLushort[]){ + ((v & 0xf000) >>12), + ((v & 0x0f00) >> 8), + ((v & 0x00f0) >> 4), + ((v & 0x000f) ) + }; + read_each(, / 15.0f); + ) + type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, + s = (GLushort[]){ + ((v & 0xf800) >> 11), + ((v & 0x07c0) >> 6), + ((v & 0x003e) >> 1), + ((v & 1))*31, + }; + read_each(, / 31.0f); + ) default: // TODO: add glSetError? printf("libGL: Unsupported source data type: %04X\n", src_type); @@ -123,9 +150,9 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, color[dst_color->red] = pixel.r; color[dst_color->green] = pixel.g; color[dst_color->blue] = pixel.b; - *d = ((GLushort)(color[0] * 31.0) & 0x1f << 11) | - ((GLushort)(color[1] * 63.0) & 0x3f << 5) | - ((GLushort)(color[2] * 31.0) & 0x1f); + *d = ((GLushort)(color[0] * 31.0f) & 0x1f << 11) | + ((GLushort)(color[1] * 63.0f) & 0x3f << 5) | + ((GLushort)(color[2] * 31.0f) & 0x1f); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, GLfloat color[4]; @@ -134,9 +161,9 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, color[dst_color->blue] = pixel.b; color[dst_color->alpha] = pixel.a; // TODO: can I macro this or something? it follows a pretty strict form. - *d = ((GLuint)(color[0] * 31) & 0x1f << 0) | - ((GLuint)(color[1] * 31) & 0x1f << 5) | - ((GLuint)(color[2] * 31) & 0x1f << 10) | + *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) | + ((GLuint)(color[1] * 31.0f) & 0x1f << 5) | + ((GLuint)(color[2] * 31.0f) & 0x1f << 10) | ((GLuint)(color[3] * 1) & 0x01 << 15); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, @@ -231,6 +258,15 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, }; read_each(, / 63.0f); ) + type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, + s = (GLushort[]){ + ((v & 0xf800) >> 11), + ((v & 0x07c0) >> 6), + ((v & 0x003e) >> 1), + ((v & 1))*31, + }; + read_each(, / 31.0f); + ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, s = (GLushort[]){ (v & 0x000f), @@ -262,9 +298,21 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, color[src_color->red] = pixel.r; color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; - *d = ((GLuint)(color[2] * 31) & 0x1f << 11) | - ((GLuint)(color[1] * 63) & 0x3f << 5) | - ((GLuint)(color[0] * 31) & 0x1f); + *d = ((GLuint)(color[2] * 31.0f) & 0x1f << 11) | + ((GLuint)(color[1] * 63.0f) & 0x3f << 5) | + ((GLuint)(color[0] * 31.0f) & 0x1f); + ) + type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, + GLfloat color[4]; + color[src_color->red] = pixel.r; + color[src_color->green] = pixel.g; + color[src_color->blue] = pixel.b; + color[src_color->alpha] = pixel.a; + // TODO: can I macro this or something? it follows a pretty strict form. + *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) | + ((GLuint)(color[1] * 31.0f) & 0x1f << 5) | + ((GLuint)(color[2] * 31.0f) & 0x1f << 10) | + ((GLuint)(color[3] * 1) & 0x01 << 15); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, GLfloat color[4]; @@ -272,10 +320,10 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; - *d = ((GLushort)(color[3] * 15.0) & 0x0f << 12) | - ((GLushort)(color[2] * 15.0) & 0x0f << 8) | - ((GLushort)(color[1] * 15.0) & 0x0f << 4) | - ((GLushort)(color[0] * 15.0) & 0x0f); + *d = ((GLushort)(color[3] * 15.0f) & 0x0f << 12) | + ((GLushort)(color[2] * 15.0f) & 0x0f << 8) | + ((GLushort)(color[1] * 15.0f) & 0x0f << 4) | + ((GLushort)(color[0] * 15.0f) & 0x0f); ) default: printf("libGL: Unsupported target data type: %04X\n", src_type); @@ -363,13 +411,45 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, }; read_each(, / 31.0f); ) + type_case(GL_UNSIGNED_SHORT_4_4_4_4_REV, GLushort, + for (int ii=0; ii<4; ii++) { + s[ii] = (GLushort[]) { + ((v[ii] & 0x000f) ), + ((v[ii] & 0x00f0) >> 4), + ((v[ii] & 0x0f00) >> 8), + ((v[ii] & 0xf000) >>12) + }; + }; + read_each(, / 15.0f); + ) + type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, + for (int ii=0; ii<4; ii++) { + s[ii] = (GLushort[]) { + ((v[ii] & 0x001f) )*2, + ((v[ii] & 0x07e0) >> 5), + ((v[ii] & 0xF800) >>11)*2, + }; + }; + read_each(, / 63.0f); + ) + type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, + for (int ii=0; ii<4; ii++) { + s[ii] = (GLushort[]) { + ((v[ii] & 0xf800) >>11), + ((v[ii] & 0x07c0) >> 6), + ((v[ii] & 0x003e) >> 1), + ((v[ii] & 1) )*31, + }; + }; + read_each(, / 31.0f); + ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, for (int ii=0; ii<4; ii++) { s[ii] = (GLushort[]) { - (v[ii] & 0x000f), - ((v[ii] & 0x00f0) >> 4), + ((v[ii] & 0xf000) >>12), ((v[ii] & 0x0f00) >> 8), - ((v[ii] & 0xf000) >> 12) + ((v[ii] & 0x00f0) >> 4), + ((v[ii] & 0x000f) ) }; }; read_each(, / 15.0f); @@ -396,9 +476,21 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, color[src_color->red] = pixel.r; color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; - *d = ((GLuint)(color[0] * 31) & 0x1f << 11) | - ((GLuint)(color[1] * 63) & 0x3f << 5) | - ((GLuint)(color[2] * 31) & 0x1f); + *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 11) | + ((GLuint)(color[1] * 63.0f) & 0x3f << 5) | + ((GLuint)(color[2] * 31.0f) & 0x1f); + ) + type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, + GLfloat color[4]; + color[src_color->red] = pixel.r; + color[src_color->green] = pixel.g; + color[src_color->blue] = pixel.b; + color[src_color->alpha] = pixel.a; + // TODO: can I macro this or something? it follows a pretty strict form. + *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) | + ((GLuint)(color[1] * 31.0f) & 0x1f << 5) | + ((GLuint)(color[2] * 31.0f) & 0x1f << 10) | + ((GLuint)(color[3] * 1) & 0x01 << 15); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, GLfloat color[4]; @@ -406,10 +498,10 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; - *d = ((GLushort)(color[0] * 15.0) & 0x0f << 12) | - ((GLushort)(color[1] * 15.0) & 0x0f << 8) | - ((GLushort)(color[2] * 15.0) & 0x0f << 4) | - ((GLushort)(color[3] * 15.0) & 0x0f); + *d = ((GLushort)(color[0] * 15.0f) & 0x0f << 12) | + ((GLushort)(color[1] * 15.0f) & 0x0f << 8) | + ((GLushort)(color[2] * 15.0f) & 0x0f << 4) | + ((GLushort)(color[3] * 15.0f) & 0x0f); ) default: printf("libGL: half_pixel: Unsupported target data type: %04X\n", src_type); @@ -576,16 +668,18 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, GLuint pixels = width * height; GLuint dst_size = pixels * 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); + GLuint src_width = width * pixel_sizeof(src_format, src_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()); + //printf("pixel conversion: %ix%i - %s, %s (%d) ==> %s, %s (%d), transform=%i\n", width, height, PrintEnum(src_format), PrintEnum(src_type),pixel_sizeof(src_format, src_type), PrintEnum(dst_format), PrintEnum(dst_type), pixel_sizeof(dst_format, dst_type), raster_need_transform()); src_color = get_color_map(src_format); dst_color = get_color_map(dst_format); if (!dst_size || !pixel_sizeof(src_format, src_type) - || !src_color->type || !dst_color->type) + || !src_color->type || !dst_color->type) { + printf("pixel conversion, anticipated abort\n"); return false; + } - if (src_type == dst_type && src_color->type == dst_color->type) { + if ((src_type == dst_type) && (src_color->type == dst_color->type)) { if (*dst == src) return true; if (*dst == NULL) // alloc dst only if dst==NULL @@ -618,6 +712,35 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + if ((src_format == GL_BGRA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + GLuint tmp; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + tmp = *(const GLuint*)src_pos; + *(GLushort*)dst_pos = (tmp&0x0000ff00) | (tmp&0x000000ff); + src_pos += src_stride; + dst_pos += dst_stride; + } + if (stride) + dst_pos += dst_width; + } + return true; + } + if ((src_format == GL_BGR) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + GLuint tmp; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + ((char*)dst_pos)[0] = ((char*)src_pos)[2]; + ((char*)dst_pos)[1] = ((char*)src_pos)[1]; + ((char*)dst_pos)[2] = ((char*)src_pos)[0]; + src_pos += src_stride; + dst_pos += dst_stride; + } + if (stride) + dst_pos += dst_width; + } + return true; + } if ((src_format == GL_RGB) && (dst_format == GL_RGB) && (dst_type = GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { GLuint tmp; for (int i = 0; i < height; i++) { diff --git a/project/jni/glshim/src/gl/raster.c b/project/jni/glshim/src/gl/raster.c index 2ba9be55f..364528e56 100755 --- a/project/jni/glshim/src/gl/raster.c +++ b/project/jni/glshim/src/gl/raster.c @@ -425,12 +425,30 @@ void render_raster_list(rasterlist_t* rast) { gles_glBindTexture(GL_TEXTURE_2D, rast->texture); 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); + if(!state.clientstate.vertex_array) { + gles_glEnableClientState(GL_VERTEX_ARRAY); + state.clientstate.vertex_array = 1; + } gles_glVertexPointer(3, GL_FLOAT, 0, vert); + if(!state.clientstate.tex_coord_array[0]) { + gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); + state.clientstate.tex_coord_array[0] = 1; + } gles_glTexCoordPointer(2, GL_FLOAT, 0, tex); + for (int a=1; a vert_enable = state.enable.vertex_array; - cur->color_enable = state.enable.color_array; - cur->secondary_enable = state.enable.secondary_array; - cur->normal_enable = state.enable.normal_array; + cur->vert_enable = state.vao->vertex_array; + cur->color_enable = state.vao->color_array; + cur->secondary_enable = state.vao->secondary_array; + cur->normal_enable = state.vao->normal_array; int a; for (a=0; atex_enable[a] = state.enable.tex_coord_array[a]; + cur->tex_enable[a] = state.vao->tex_coord_array[a]; } - memcpy(&(cur->pointers), &state.pointers, sizeof(pointer_states_t)); + memcpy(&(cur->pointers), &state.vao->pointers, sizeof(pointer_states_t)); cur->client = state.texture.client; } @@ -555,22 +555,22 @@ void glPopClientAttrib() { } if (cur->mask & GL_CLIENT_VERTEX_ARRAY_BIT) { - if (state.enable.vertex_array != cur->vert_enable) + if (state.vao->vertex_array != cur->vert_enable) enable_disable(GL_VERTEX_ARRAY, cur->vert_enable); - if (state.enable.normal_array != cur->normal_enable) + if (state.vao->normal_array != cur->normal_enable) enable_disable(GL_NORMAL_ARRAY, cur->normal_enable); - if (state.enable.color_array != cur->color_enable) + if (state.vao->color_array != cur->color_enable) enable_disable(GL_COLOR_ARRAY, cur->color_enable); - if (state.enable.secondary_array != cur->secondary_enable) + if (state.vao->secondary_array != cur->secondary_enable) enable_disable(GL_SECONDARY_COLOR_ARRAY, cur->secondary_enable); for (int a=0; atex_enable[a]) { + if (state.vao->tex_coord_array[a] != cur->tex_enable[a]) { glClientActiveTexture(GL_TEXTURE0+a); enable_disable(GL_TEXTURE_COORD_ARRAY, cur->tex_enable[a]); } } - memcpy(&state.pointers, &(cur->pointers), sizeof(pointer_states_t)); + memcpy(&state.vao->pointers, &(cur->pointers), sizeof(pointer_states_t)); if (state.texture.client != cur->client) glClientActiveTexture(GL_TEXTURE0+cur->client); } diff --git a/project/jni/glshim/src/gl/state.h b/project/jni/glshim/src/gl/state.h index b99b2c8c9..c8380e2e4 100755 --- a/project/jni/glshim/src/gl/state.h +++ b/project/jni/glshim/src/gl/state.h @@ -12,11 +12,6 @@ typedef struct { auto_normal, blend, color_sum, - secondary_array, - color_array, - normal_array, - vertex_array, - tex_coord_array[MAX_TEX], texgen_s[MAX_TEX], texgen_t[MAX_TEX], texgen_r[MAX_TEX], @@ -41,12 +36,14 @@ typedef struct { typedef struct { GLuint unpack_row_length, unpack_skip_pixels, - unpack_skip_rows; + unpack_skip_rows, + unpack_image_height; GLboolean unpack_lsb_first; // TODO: use those values GLuint pack_row_length, pack_skip_pixels, - pack_skip_rows; + pack_skip_rows, + pack_image_height; GLboolean pack_lsb_first; // TODO: do we only need to worry about GL_TEXTURE_2D? GLboolean rect_arb[MAX_TEX]; @@ -102,14 +99,6 @@ typedef struct { GLfloat *stack; } matrixstack_t; -typedef struct { - glbuffer_t *vertex; - glbuffer_t *elements; - glbuffer_t *pack; - glbuffer_t *unpack; - khash_t(buff) *list; -} buffers_t; - typedef enum { ENABLED_ALPHA, ENABLED_BLEND, @@ -128,13 +117,18 @@ typedef struct { GLenum blendfunc_d; } statebatch_t; +typedef struct { + GLboolean vertex_array, + color_array, + normal_array, + tex_coord_array[MAX_TEX]; +} clientstate_t; typedef struct { displaylist_state_t list; enable_state_t enable; map_state_t *map_grid; map_states_t map1, map2; - pointer_states_t pointers; renderlist_t **lists; texgen_state_t texgen[MAX_TEX]; texture_state_t texture; @@ -149,14 +143,17 @@ typedef struct { matrixstack_t *projection_matrix; matrixstack_t **texture_matrix; selectbuf_t selectbuf; - buffers_t buffers; khash_t(glvao) *vaos; - glvao_t *bindedvao; + khash_t(buff) *buffers; + glvao_t *vao; + glbuffer_t *defaultvbo; + glvao_t *defaultvao; int shim_error; GLenum last_error; GLuint gl_batch; GLint vp[4]; statebatch_t statebatch; + clientstate_t clientstate; } glstate_t; #endif diff --git a/project/jni/glshim/src/gl/texture.c b/project/jni/glshim/src/gl/texture.c index 8f1840537..ef7500106 100755 --- a/project/jni/glshim/src/gl/texture.c +++ b/project/jni/glshim/src/gl/texture.c @@ -75,27 +75,27 @@ void tex_setup_texcoord(GLuint texunit, GLuint len) { int changes = 0; if ((state.texture.rect_arb[texunit]) || (bound && ((bound->width!=bound->nwidth)||(bound->height!=bound->nheight)|| - (bound->shrink && (state.pointers.tex_coord[texunit].type!=GL_FLOAT) && (state.pointers.tex_coord[texunit].type!=GL_DOUBLE))))) + (bound->shrink && (state.vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (state.vao->pointers.tex_coord[texunit].type!=GL_DOUBLE))))) changes = 1; if (old!=texunit) glClientActiveTexture(texunit+GL_TEXTURE0); if (changes) { // first convert to GLfloat, without normalization - tex[texunit] = copy_gl_pointer_raw(&state.pointers.tex_coord[texunit], 2, 0, len, state.pointers.tex_coord[texunit].buffer); + tex[texunit] = copy_gl_pointer_raw(&state.vao->pointers.tex_coord[texunit], 2, 0, len, state.vao->pointers.tex_coord[texunit].buffer); if (!tex[texunit]) { printf("LibGL: Error with Texture tranform\n"); - gles_glTexCoordPointer(len, state.pointers.tex_coord[texunit].type, state.pointers.tex_coord[texunit].stride, state.pointers.tex_coord[texunit].pointer); + gles_glTexCoordPointer(len, state.vao->pointers.tex_coord[texunit].type, state.vao->pointers.tex_coord[texunit].stride, state.vao->pointers.tex_coord[texunit].pointer); if (old!=texunit) glClientActiveTexture(old+GL_TEXTURE0); return; } // Normalize if needed - if ((state.texture.rect_arb[texunit]) || ((state.pointers.tex_coord[texunit].type!=GL_FLOAT) && (state.pointers.tex_coord[texunit].type!=GL_DOUBLE))) + if ((state.texture.rect_arb[texunit]) || ((state.vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (state.vao->pointers.tex_coord[texunit].type!=GL_DOUBLE))) tex_coord_rect_arb(tex[texunit], len, bound->width, bound->height); if ((bound->width!=bound->nwidth) || (bound->height!=bound->nheight)) tex_coord_npot(tex[texunit], len, bound->width, bound->height, bound->nwidth, bound->nheight); // All done, setup the texcoord array now gles_glTexCoordPointer(2, GL_FLOAT, 0, tex[texunit]); } else { - gles_glTexCoordPointer(state.pointers.tex_coord[texunit].size, state.pointers.tex_coord[texunit].type, state.pointers.tex_coord[texunit].stride, state.pointers.tex_coord[texunit].pointer); + gles_glTexCoordPointer(state.vao->pointers.tex_coord[texunit].size, state.vao->pointers.tex_coord[texunit].type, state.vao->pointers.tex_coord[texunit].stride, state.vao->pointers.tex_coord[texunit].pointer); } if (old!=texunit) glClientActiveTexture(old+GL_TEXTURE0); } @@ -104,6 +104,7 @@ int nolumalpha = 0; static void *swizzle_texture(GLsizei width, GLsizei height, GLenum *format, GLenum *type, + GLenum intermediaryformat, GLenum internalformat, const GLvoid *data) { bool convert = false; GLenum dest_format = GL_RGBA; @@ -114,11 +115,22 @@ static void *swizzle_texture(GLsizei width, GLsizei height, dest_format = GL_RGB; break; case GL_ALPHA: + dest_format = GL_ALPHA; case GL_RGBA: break; + case GL_LUMINANCE8_ALPHA8: + if(nolumalpha) + convert = true; + else { + dest_format = GL_LUMINANCE_ALPHA; + *format = GL_LUMINANCE_ALPHA; + } + break; case GL_LUMINANCE_ALPHA: if(nolumalpha) convert = true; + else + dest_format = GL_LUMINANCE_ALPHA; break; case GL_RGB5: dest_type = GL_UNSIGNED_SHORT_5_6_5; @@ -127,7 +139,6 @@ static void *swizzle_texture(GLsizei width, GLsizei height, case GL_RGB8: dest_format = GL_RGB; *format = GL_RGB; - //convert = true; break; case GL_RGBA8: dest_format = GL_RGBA; @@ -138,14 +149,36 @@ static void *swizzle_texture(GLsizei width, GLsizei height, break; } switch (*type) { + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + if(dest_format==GL_RGBA) + dest_type = GL_UNSIGNED_SHORT_4_4_4_4; + convert = true; + break; + case GL_UNSIGNED_SHORT_4_4_4_4: + if(dest_format==GL_RGBA) + dest_type = GL_UNSIGNED_SHORT_4_4_4_4; + convert = true; + break; + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + if(dest_format==GL_RGBA) + dest_type = GL_UNSIGNED_SHORT_5_5_5_1; + convert = true; + break; + case GL_UNSIGNED_SHORT_5_5_5_1: + if(dest_format==GL_RGBA) + dest_type = GL_UNSIGNED_SHORT_5_5_5_1; + convert = true; + break; + case GL_UNSIGNED_SHORT_5_6_5_REV: + if (dest_format==GL_RGB) + dest_type = GL_UNSIGNED_SHORT_5_6_5; + convert = true; + break; case GL_UNSIGNED_SHORT_5_6_5: if (dest_format==GL_RGB) dest_type = GL_UNSIGNED_SHORT_5_6_5; break; - //case GL_FLOAT: case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: break; case GL_UNSIGNED_INT_8_8_8_8_REV: *type = GL_UNSIGNED_BYTE; @@ -153,24 +186,46 @@ static void *swizzle_texture(GLsizei width, GLsizei height, default: convert = true; break; + } + if(*format != intermediaryformat || intermediaryformat!=internalformat) { + dest_format = intermediaryformat; + dest_type = GL_UNSIGNED_BYTE; + convert = true; } if (data) { if (convert) { GLvoid *pixels = (GLvoid *)data; if (! pixel_convert(data, &pixels, width, height, *format, *type, dest_format, dest_type, 0)) { - printf("libGL swizzle error: (%#4x, %#4x -> %#4x, %#4x)\n", - *format, *type, dest_format, dest_type); + printf("libGL swizzle error: (%s, %s -> %s, %s)\n", + PrintEnum(*format), PrintEnum(*type), PrintEnum(dest_format), PrintEnum(dest_type)); return NULL; } *type = dest_type; *format = dest_format; + if(dest_format!=internalformat) { + GLvoid *pix2 = (GLvoid *)pixels; + if (! pixel_convert(pixels, &pix2, width, height, + dest_format, dest_type, internalformat, dest_type, 0)) { + printf("libGL swizzle error: (%s, %s -> %s, %s)\n", + PrintEnum(dest_format), PrintEnum(dest_type), PrintEnum(internalformat), PrintEnum(dest_type)); + return NULL; + } + if(pix2!=pixels) { + if (pixels!=data) + free(pixels); + pixels = pix2; + } + dest_format = internalformat; + *type = internalformat; + *format = dest_format; + } GLvoid *pix2 = pixels; if (raster_need_transform()) if (!pixel_transform(data, &pixels, width, height, *format, *type, raster_scale, raster_bias)) { - printf("libGL swizzle/convert error: (%#4x, %#4x -> %#4x, %#4x)\n", - *format, *type, dest_format, dest_type); + printf("libGL swizzle/convert error: (%s, %s -> %s, %s)\n", + PrintEnum(*format), PrintEnum(*type), PrintEnum(dest_format), PrintEnum(dest_type)); pix2 = pixels; } if (pix2!=pixels && pixels!=data) @@ -180,12 +235,74 @@ static void *swizzle_texture(GLsizei width, GLsizei height, } else { if (convert) { *type = dest_type; - *format = dest_format; + *format = internalformat; } } return (void *)data; } +GLenum swizzle_internalformat(GLenum *internalformat) { + GLenum ret; + GLenum sret; + switch(*internalformat) { + case GL_R: + case 1: + ret = GL_R; sret = GL_RGB; + break; + case GL_RG: + case 2: + ret = GL_RG; sret = GL_RGB; + break; + case GL_RGB5: + case GL_RGB8: + case GL_RGB: + case GL_BGR: + case GL_RGB16: + case GL_RGB16F: + case GL_RGB32F: + case 3: + ret = GL_RGB; sret = GL_RGB; + break; + case GL_RGBA8: + case GL_RGBA4: + case GL_BGRA: + case GL_RGBA16: + case GL_RGBA16F: + case GL_RGBA32F: + case GL_RGB5_A1: + case GL_RGB10_A2: + case 4: + ret = GL_RGBA; sret = GL_RGBA; + break; + case GL_ALPHA8: + case GL_ALPHA: + ret = GL_ALPHA; sret = GL_ALPHA; + break; + case GL_LUMINANCE8: + case GL_LUMINANCE16: + case GL_LUMINANCE: + ret = GL_LUMINANCE; sret = GL_LUMINANCE; + break; + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE16_ALPHA16: + case GL_LUMINANCE_ALPHA: + ret = GL_LUMINANCE_ALPHA; + if (nolumalpha) + sret = GL_RGBA; + else + sret = GL_LUMINANCE_ALPHA; + break; + default: + ret = GL_RGBA; + sret = GL_RGBA; + break; + // Default...RGBA / RGBA will be fine.... + } + *internalformat = ret; + return sret; +} + int automipmap = 0; int texcopydata = 0; int tested_env = 0; @@ -220,8 +337,8 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLvoid *datab = (GLvoid*)data; - if (state.buffers.unpack) - datab += (uintptr_t)state.buffers.pack->data; + if (state.vao->unpack) + datab += (uintptr_t)state.vao->pack->data; GLvoid *pixels = (GLvoid *)datab; border = 0; //TODO: something? @@ -238,6 +355,11 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, else bound->mipmap_need = 1; } + GLenum new_format = swizzle_internalformat(&internalformat); + if (bound) { + bound->orig_internal = internalformat; + bound->internalformat = new_format; + } if (datab) { // implements GL_UNPACK_ROW_LENGTH @@ -257,7 +379,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, } GLvoid *old = pixels; - pixels = (GLvoid *)swizzle_texture(width, height, &format, &type, old); + pixels = (GLvoid *)swizzle_texture(width, height, &format, &type, internalformat, new_format, old); if (old != pixels && old != datab) { free(old); } @@ -469,7 +591,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, if (bound) { bound->shrink = 0; if (!bound->streamed) - swizzle_texture(width, height, &format, &type, NULL); // convert format even if data is NULL + swizzle_texture(width, height, &format, &type, internalformat, new_format, NULL); // convert format even if data is NULL if ((texshrink>0) && !bound->streamed) { switch(texshrink) { case 1: //everything / 2 @@ -623,8 +745,8 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, } GLvoid *datab = (GLvoid*)data; - if (state.buffers.unpack) - datab += (uintptr_t)state.buffers.pack->data; + if (state.vao->unpack) + datab += (uintptr_t)state.vao->pack->data; GLvoid *pixels = (GLvoid*)datab; LOAD_GLES(glTexSubImage2D); @@ -680,10 +802,19 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, #endif { //pixels = (GLvoid *)swizzle_texture(width, height, &format, &type, old); - if (!pixel_convert(old, &pixels, width, height, format, type, bound->format, bound->type, 0)) { + if (!pixel_convert(old, &pixels, width, height, format, type, bound->orig_internal, bound->type, 0)) { printf("LIBGL: Error in pixel_convert while glTexSubImage2D\n"); } else { - format = bound->format; + if(bound->orig_internal!=bound->internalformat) { + GLvoid* pix2 = pixels; + if (!pixel_convert(pixels, &pix2, width, height, bound->orig_internal, bound->type, bound->internalformat, bound->type, 0)) { + printf("LIBGL: Error in pixel_convert while glTexSubImage2D\n"); + } + if (pixels != pix2 && pixels != old) + free(pixels); + pixels = pix2; + } + format = bound->internalformat; type = bound->type; } @@ -827,6 +958,9 @@ void glPixelStorei(GLenum pname, GLint param) { case GL_UNPACK_LSB_FIRST: state.texture.unpack_lsb_first = param; break; + case GL_UNPACK_IMAGE_HEIGHT: + state.texture.unpack_image_height = param; + break; case GL_UNPACK_SWAP_BYTES: case GL_PACK_SWAP_BYTES: // Fake... TODO? @@ -844,6 +978,9 @@ void glPixelStorei(GLenum pname, GLint param) { case GL_PACK_LSB_FIRST: state.texture.pack_lsb_first = param; break; + case GL_PACK_IMAGE_HEIGHT: + state.texture.pack_image_height = param; + break; default: errorGL(); gles_glPixelStorei(pname, param); @@ -902,6 +1039,8 @@ gltexture_t* getTexture(GLenum target, GLuint texture) { tex->min_filter = tex->mag_filter = GL_LINEAR; tex->format = GL_RGBA; tex->type = GL_UNSIGNED_BYTE; + tex->orig_internal = GL_RGBA; + tex->internalformat = GL_RGBA; tex->data = NULL; } else { tex = kh_value(list, k); @@ -1028,6 +1167,7 @@ void glTexParameteri(GLenum target, GLenum pname, GLint param) { if (texture) texture->mipmap_auto = (param)?1:0; return; // not on GLES + case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_LOD_BIAS: @@ -1227,8 +1367,8 @@ void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoi //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) - dst += (uintptr_t)state.buffers.pack->data; + if (state.vao->pack) + dst += (uintptr_t)state.vao->pack->data; #ifdef TEXSTREAM if (texstream && bound->streamed) { noerrorShim(); @@ -1315,8 +1455,8 @@ void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format LOAD_GLES(glReadPixels); errorGL(); GLvoid* dst = data; - if (state.buffers.pack) - dst += (uintptr_t)state.buffers.pack->data; + if (state.vao->pack) + dst += (uintptr_t)state.vao->pack->data; readfboBegin(); if (format == GL_RGBA && format == GL_UNSIGNED_BYTE) { @@ -1354,10 +1494,10 @@ void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffse errorGL(); // "Unmap" if buffer mapped... - glbuffer_t *pack = state.buffers.pack; - glbuffer_t *unpack = state.buffers.unpack; - state.buffers.pack = NULL; - state.buffers.unpack = NULL; + glbuffer_t *pack = state.vao->pack; + glbuffer_t *unpack = state.vao->unpack; + state.vao->pack = NULL; + state.vao->unpack = NULL; gltexture_t* bound = state.texture.bound[state.texture.active]; if (!bound) { @@ -1393,8 +1533,8 @@ void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffse } } // "Remap" if buffer mapped... - state.buffers.pack = pack; - state.buffers.unpack = unpack; + state.vao->pack = pack; + state.vao->unpack = unpack; state.gl_batch = old_glbatch; } @@ -1412,10 +1552,10 @@ void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLin errorGL(); // "Unmap" if buffer mapped... - glbuffer_t *pack = state.buffers.pack; - glbuffer_t *unpack = state.buffers.unpack; - state.buffers.pack = NULL; - state.buffers.unpack = NULL; + glbuffer_t *pack = state.vao->pack; + glbuffer_t *unpack = state.vao->unpack; + state.vao->pack = NULL; + state.vao->unpack = NULL; if (copytex) { LOAD_GLES(glCopyTexImage2D); @@ -1428,8 +1568,8 @@ void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLin } // "Remap" if buffer mapped... - state.buffers.pack = pack; - state.buffers.unpack = unpack; + state.vao->pack = pack; + state.vao->unpack = unpack; state.gl_batch = old_glbatch; } @@ -1524,7 +1664,7 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, errorShim(GL_INVALID_OPERATION); return; // no texture bounded... } -//printf("glCompressedTexImage2D on target=0x%04X with size(%i,%i), internalformat=%04x, imagesize=%i, upackbuffer=%p\n", target, width, height, internalformat, imageSize, state.buffers.unpack?state.buffers.unpack->data:0); +//printf("glCompressedTexImage2D on target=%s with size(%i,%i), internalformat=s, imagesize=%i, upackbuffer=%p\n", PrintEnum(target), width, height, PrintEnum(internalformat), imageSize, state.buffers.unpack?state.buffers.unpack->data:0); // hack... if (internalformat==GL_RGBA8) internalformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; @@ -1542,8 +1682,8 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, LOAD_GLES(glCompressedTexImage2D); errorGL(); - glbuffer_t *unpack = state.buffers.unpack; - state.buffers.unpack = NULL; + glbuffer_t *unpack = state.vao->unpack; + state.vao->unpack = NULL; GLvoid *datab = (GLvoid*)data; if (unpack) datab += (uintptr_t)unpack->data; @@ -1599,7 +1739,7 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, state.texture.bound[state.texture.active]->compressed = true; gles_glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, datab); } - state.buffers.unpack = unpack; + state.vao->unpack = unpack; state.gl_batch = old_glbatch; } @@ -1626,8 +1766,8 @@ void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint return; } //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; + glbuffer_t *unpack = state.vao->unpack; + state.vao->unpack = NULL; GLvoid *datab = (GLvoid*)data; if (unpack) datab += (uintptr_t)unpack->data; diff --git a/project/jni/glshim/src/gl/texture.h b/project/jni/glshim/src/gl/texture.h index 4f17c60b1..9d18b2b11 100755 --- a/project/jni/glshim/src/gl/texture.h +++ b/project/jni/glshim/src/gl/texture.h @@ -93,6 +93,8 @@ typedef struct { GLsizei nheight; GLenum format; GLenum type; + GLenum orig_internal; + GLenum internalformat; int shrink; GLboolean mipmap_auto; GLboolean mipmap_need; diff --git a/project/jni/glshim/src/gl/wrap/gl.c b/project/jni/glshim/src/gl/wrap/gl.c index 68c92f0e3..db67d8a06 100755 --- a/project/jni/glshim/src/gl/wrap/gl.c +++ b/project/jni/glshim/src/gl/wrap/gl.c @@ -734,8 +734,8 @@ void glDrawRangeElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenu //printf("glDrawRangeElements(0x%04X, %i, %i, %i, 0x%04X, @%p), inlist=%i\n", mode, start, end, count, type, indices, (state.list.active)?1:0); GLushort *newinds = (GLushort*)malloc(sizeof(GLushort)*count); int newcount=0; - glbuffer_t *elements = state.buffers.elements; - state.buffers.elements = NULL; + glbuffer_t *elements = state.vao->elements; + state.vao->elements = NULL; uintptr_t ptr = (uintptr_t)indices; if (elements) @@ -750,7 +750,7 @@ void glDrawRangeElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenu glDrawElements(mode, newcount, GL_UNSIGNED_SHORT, newinds); free(newinds); - state.buffers.elements = elements; + state.vao->elements = elements; } void glDrawRangeElementsEXT(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const void *indices) { diff --git a/project/jni/glshim/src/glx/glx.c b/project/jni/glshim/src/glx/glx.c index b84fe9555..b7e3a3695 100755 --- a/project/jni/glshim/src/glx/glx.c +++ b/project/jni/glshim/src/glx/glx.c @@ -266,7 +266,7 @@ static void scan_env() { return; /* Check for some corruption inside state.... */ if ((state.texture.active < 0) || (state.texture.active > MAX_TEX) || - (state.pointers.vertex.buffer!= 0) || (state.buffers.vertex != 0)) { + (state.vao->pointers.vertex.buffer!= 0) || (state.vao->vertex != 0)) { printf("LIBGL: Warning, memory corruption detected at init, trying to compensate\n"); initialize_glshim(); }