diff --git a/project/jni/gl4es/README.md b/project/jni/gl4es/README.md index ee7094c94..58223ef28 100755 --- a/project/jni/gl4es/README.md +++ b/project/jni/gl4es/README.md @@ -236,6 +236,7 @@ Version history ---- ##### current version + * Added tracking of Lights and Materials * Fixed (Added in fact) support for Multisampling on the GLX Context creation (a bit hacky, but seems to works) * Added LIBGL_NODOWNSAMPLING and associated Hint * Try to implement some caching on VAO to avoid some memcpy in renderlist (with a way to disable it just in case) diff --git a/project/jni/gl4es/src/config.h b/project/jni/gl4es/src/config.h index b6987af1c..2abfe86c5 100755 --- a/project/jni/gl4es/src/config.h +++ b/project/jni/gl4es/src/config.h @@ -15,8 +15,6 @@ #define skip_glDisable #define skip_glEnable #define skip_glIsEnabled -#define skip_glMaterialfv -#define skip_glMaterialf #define skip_glNormal3f #define skip_glBindBuffer @@ -51,6 +49,8 @@ #define skip_glGetIntegerv #define skip_glGetFloatv #define skip_glGetString +#define skip_glGetLightfv +#define skip_glGetMaterialfv // hint.c #define skip_glHint @@ -60,6 +60,8 @@ #define skip_glLightModelfv #define skip_glLightfv #define skip_glLightf +#define skip_glMaterialfv +#define skip_glMaterialf // raster.c #define skip_glViewport diff --git a/project/jni/gl4es/src/gl/getter.c b/project/jni/gl4es/src/gl/getter.c index ddc9cd50e..1ffb2955e 100755 --- a/project/jni/gl4es/src/gl/getter.c +++ b/project/jni/gl4es/src/gl/getter.c @@ -3,6 +3,7 @@ #include "texgen.h" #include "../glx/hardext.h" #include "gl4eshint.h" +#include "light.h" GLenum gl4es_glGetError() { LOAD_GLES(glGetError); @@ -100,8 +101,8 @@ const GLubyte *gl4es_glGetString(GLenum name) { "GL_EXT_polygon_offset " "GL_GL4ES_hint " "GL_ARB_vertex_array_bgra " + "GL_ARB_texture_rectangle " // "GL_EXT_blend_logic_op " -// "GL_ARB_texture_cube_map " ); if(globals4es.npot>=1) strcat(extensions, "GL_APPLE_texture_2D_limited_npot "); @@ -295,6 +296,13 @@ void gl4es_glGetIntegerv(GLenum pname, GLint *params) { case GL_MATRIX_MODE: *params=glstate->matrix_mode; break; + case GL_LIGHT_MODEL_TWO_SIDE: + *params=glstate->light.two_side; + break; + case GL_LIGHT_MODEL_AMBIENT: + for (dummy=0; dummy<4; dummy++) + params[dummy]=glstate->light.ambient[dummy]; + break; case GL_SHRINK_HINT_GL4ES: *params=globals4es.texshrink; break; @@ -459,6 +467,12 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) { case GL_TEXTURE_MATRIX: memcpy(params, TOP(texture_matrix[glstate->texture.active]), 16*sizeof(GLfloat)); break; + case GL_LIGHT_MODEL_TWO_SIDE: + *params=glstate->light.two_side; + break; + case GL_LIGHT_MODEL_AMBIENT: + memcpy(params, glstate->light.ambient, 4*sizeof(GLfloat)); + break; case GL_SHRINK_HINT_GL4ES: *params=globals4es.texshrink; break; @@ -498,3 +512,102 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) { } } void glGetFloatv(GLenum pname, GLfloat *params) AliasExport("gl4es_glGetFloatv"); + +void gl4es_glGetLightfv(GLenum light, GLenum pname, GLfloat * params) { + if(light<0 || light>=hardext.maxlights) { + errorShim(GL_INVALID_ENUM); + return; + } + switch(pname) { + case GL_AMBIENT: + memcpy(params, glstate->light.lights[light].ambient, 4*sizeof(GLfloat)); + break; + case GL_DIFFUSE: + memcpy(params, glstate->light.lights[light].diffuse, 4*sizeof(GLfloat)); + break; + case GL_SPECULAR: + memcpy(params, glstate->light.lights[light].specular, 4*sizeof(GLfloat)); + break; + case GL_POSITION: + memcpy(params, glstate->light.lights[light].position, 4*sizeof(GLfloat)); + break; + case GL_SPOT_DIRECTION: + memcpy(params, glstate->light.lights[light].spotDirection, 3*sizeof(GLfloat)); + break; + case GL_SPOT_EXPONENT: + params[0] = glstate->light.lights[light].spotExponent; + break; + case GL_SPOT_CUTOFF: + params[0] = glstate->light.lights[light].spotCutoff; + break; + case GL_CONSTANT_ATTENUATION: + params[0] = glstate->light.lights[light].constantAttenuation; + break; + case GL_LINEAR_ATTENUATION: + params[0] = glstate->light.lights[light].linearAttenuation; + break; + case GL_QUADRATIC_ATTENUATION: + params[0] = glstate->light.lights[light].quadraticAttenuation; + break; + default: + errorShim(GL_INVALID_ENUM); + return; + } + noerrorShim(); +} +void glGetLightfv(GLenum pname, GLfloat *params) AliasExport("gl4es_glGetLightfv"); + +void gl4es_glGetMaterialfv(GLenum face, GLenum pname, GLfloat * params) { + if(face!=GL_FRONT && face!=GL_BACK) { + errorShim(GL_INVALID_ENUM); + return; + } + switch(pname) { + case GL_AMBIENT: + if(face==GL_FRONT) + memcpy(params, glstate->material.front.ambient, 4*sizeof(GLfloat)); + if(face==GL_BACK) + memcpy(params, glstate->material.back.ambient, 4*sizeof(GLfloat)); + break; + case GL_DIFFUSE: + if(face==GL_FRONT) + memcpy(params, glstate->material.front.diffuse, 4*sizeof(GLfloat)); + if(face==GL_BACK) + memcpy(params, glstate->material.back.diffuse, 4*sizeof(GLfloat)); + break; + case GL_SPECULAR: + if(face==GL_FRONT) + memcpy(params, glstate->material.front.specular, 4*sizeof(GLfloat)); + if(face==GL_BACK) + memcpy(params, glstate->material.back.specular, 4*sizeof(GLfloat)); + break; + case GL_EMISSION: + if(face==GL_FRONT) + memcpy(params, glstate->material.front.emission, 4*sizeof(GLfloat)); + if(face==GL_BACK) + memcpy(params, glstate->material.back.emission, 4*sizeof(GLfloat)); + break; + case GL_SHININESS: + if(face==GL_FRONT) + *params = glstate->material.front.shininess; + if(face==GL_BACK) + *params = glstate->material.back.shininess; + break; + case GL_COLOR_INDEXES: + if(face==GL_FRONT) { + params[0] = glstate->material.front.indexes[0]; + params[1] = glstate->material.front.indexes[1]; + params[2] = glstate->material.front.indexes[2]; + } + if(face==GL_BACK) { + params[0] = glstate->material.back.indexes[0]; + params[1] = glstate->material.back.indexes[1]; + params[2] = glstate->material.back.indexes[2]; + } + default: + errorShim(GL_INVALID_ENUM); + return; + } + noerrorShim(); +} +void glGetMaterialfv(GLenum face, GLenum pname, GLfloat * params) AliasExport("gl4es_glGetMaterialfv"); \ No newline at end of file diff --git a/project/jni/gl4es/src/gl/gl.c b/project/jni/gl4es/src/gl/gl.c index f3d3e27ad..32cd0e3c8 100755 --- a/project/jni/gl4es/src/gl/gl.c +++ b/project/jni/gl4es/src/gl/gl.c @@ -66,6 +66,35 @@ void* NewGLState(void* shared_glstate) { // init the matrix tracking init_matrix(glstate); + // init the light tracking + glstate->light.ambient[0]=glstate->light.ambient[1]=glstate->light.ambient[2]=0.2f; + glstate->light.ambient[3]=1.0f; + glstate->light.lights[0].diffuse[0]= + glstate->light.lights[0].diffuse[1]= + glstate->light.lights[0].diffuse[2]= + glstate->light.lights[0].diffuse[3]=1.0f; + memcpy(glstate->light.lights[0].specular, glstate->light.lights[0].diffuse, 4*sizeof(GLfloat)); + for (int i=0; ilight.lights[i].ambient[3] = 1.0f; + glstate->light.lights[i].position[2] = 1.0f; + glstate->light.lights[i].spotDirection[2] = -1.0f; + glstate->light.lights[i].spotCutoff = 180; + glstate->light.lights[i].constantAttenuation = 1; + } + // Materials + glstate->material.front.ambient[0] = + glstate->material.front.ambient[1] = + glstate->material.front.ambient[2] = 0.2f; + glstate->material.front.ambient[3] = 1.0f; + glstate->material.front.diffuse[0] = + glstate->material.front.diffuse[1] = + glstate->material.front.diffuse[2] = 0.8f; + glstate->material.front.diffuse[3] = 1.0f; + glstate->material.front.specular[3] = 1.0f; + glstate->material.front.emission[3] = 1.0f; + glstate->material.front.colormat = GL_AMBIENT_AND_DIFFUSE; + memcpy(&glstate->material.back, &glstate->material.front, sizeof(material_t)); + for(int i=0; i<4; i++) glstate->raster.raster_scale[i] = 1.0f; LOAD_GLES(glGetFloatv); @@ -1085,42 +1114,6 @@ void gl4es_glSecondaryColor3f(GLfloat r, GLfloat g, GLfloat b) { } void glSecondaryColor3f(GLfloat r, GLfloat g, GLfloat b) AliasExport("gl4es_glSecondaryColor3f"); -#ifndef USE_ES2 -void gl4es_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { - LOAD_GLES(glMaterialfv); - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - //TODO: Materialfv can be done per vertex, how to handle that ?! - //NewStage(glstate->list.active, STAGE_MATERIAL); - rlMaterialfv(glstate->list.active, face, pname, params); - noerrorShim(); - } else { - if (face!=GL_FRONT_AND_BACK) { - face=GL_FRONT_AND_BACK; - } - gles_glMaterialfv(face, pname, params); - errorGL(); - } -} -void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) AliasExport("gl4es_glMaterialfv"); -void gl4es_glMaterialf(GLenum face, GLenum pname, const GLfloat param) { - LOAD_GLES(glMaterialf); - if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { - GLfloat params[4]; - memset(params, 0, 4*sizeof(GLfloat)); - params[0] = param; - NewStage(glstate->list.active, STAGE_MATERIAL); - rlMaterialfv(glstate->list.active, face, pname, params); - noerrorShim(); - } else { - if (face!=GL_FRONT_AND_BACK) { - face=GL_FRONT_AND_BACK; - } - gles_glMaterialf(face, pname, param); - errorGL(); - } -} -void glMaterialf(GLenum face, GLenum pname, const GLfloat param) AliasExport("gl4es_glMaterialf"); -#endif void gl4es_glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { if (glstate->list.active) { diff --git a/project/jni/gl4es/src/gl/light.c b/project/jni/gl4es/src/gl/light.c index 6839541c7..dbb2e88a5 100755 --- a/project/jni/gl4es/src/gl/light.c +++ b/project/jni/gl4es/src/gl/light.c @@ -1,4 +1,7 @@ #include "light.h" +#include "../glx/hardext.h" +#include "matrix.h" +#include "matvec.h" #ifndef USE_ES2 void gl4es_glLightModelf(GLenum pname, GLfloat param) { @@ -9,18 +12,18 @@ void gl4es_glLightModelf(GLenum pname, GLfloat param) { gl4es_glLightModelfv(pname, dummy); return; } - LOAD_GLES(glLightModelf); switch (pname) { - case GL_LIGHT_MODEL_AMBIENT: case GL_LIGHT_MODEL_TWO_SIDE: errorGL(); - gles_glLightModelf(pname, param); + glstate->light.two_side = param; break; + case GL_LIGHT_MODEL_AMBIENT: default: errorShim(GL_INVALID_ENUM); - //printf("stubbed glLightModelf(%i, %.2f)\n", pname, param); - break; + return; } + LOAD_GLES(glLightModelf); + gles_glLightModelf(pname, param); } void gl4es_glLightModelfv(GLenum pname, const GLfloat* params) { @@ -35,28 +38,121 @@ void gl4es_glLightModelfv(GLenum pname, const GLfloat* params) { noerrorShim(); return; } - LOAD_GLES(glLightModelfv); switch (pname) { case GL_LIGHT_MODEL_AMBIENT: - case GL_LIGHT_MODEL_TWO_SIDE: + if(memcmp(glstate->light.ambient, params, 4*sizeof(GLfloat))==0) { + noerrorShim(); + return; + } errorGL(); - gles_glLightModelfv(pname, params); + memcpy(glstate->light.ambient, params, 4*sizeof(GLfloat)); + break; + case GL_LIGHT_MODEL_TWO_SIDE: + if(glstate->light.two_side == params[0]) { + noerrorShim(); + return; + } + errorGL(); + glstate->light.two_side = params[0]; break; default: errorShim(GL_INVALID_ENUM); - //printf("stubbed glLightModelfv(%i, %p [%.2f])\n", pname, params, params[0]); - break; + return; } + LOAD_GLES(glLightModelfv); + gles_glLightModelfv(pname, params); } void gl4es_glLightfv(GLenum light, GLenum pname, const GLfloat* params) { //printf("%sglLightfv(%04X, %04X, %p=[%.2f, %.2f, %.2f, %.2f])\n", (glstate->list.compiling)?"list":"", light, pname, params, (params)?params[0]:0.0f, (params)?params[1]:0.0f, (params)?params[2]:0.0f, (params)?params[3]:0.0f); + if(light<0 || light>=hardext.maxlights) { + errorShim(GL_INVALID_ENUM); + return; + } if (glstate->list.compiling && glstate->list.active) { NewStage(glstate->list.active, STAGE_LIGHT); rlLightfv(glstate->list.active, light, pname, params); noerrorShim(); return; } + GLfloat tmp[4]; + noerrorShim(); + switch(pname) { + case GL_AMBIENT: + if(memcmp(glstate->light.lights[light].ambient, params, 4*sizeof(GLfloat))==0) + return; + memcpy(glstate->light.lights[light].ambient, params, 4*sizeof(GLfloat)); + break; + case GL_DIFFUSE: + if(memcmp(glstate->light.lights[light].diffuse, params, 4*sizeof(GLfloat))) + return; + memcpy(glstate->light.lights[light].diffuse, params, 4*sizeof(GLfloat)); + break; + case GL_SPECULAR: + if(memcmp(glstate->light.lights[light].specular, params, 4*sizeof(GLfloat))) + return; + memcpy(glstate->light.lights[light].specular, params, 4*sizeof(GLfloat)); + break; + case GL_POSITION: + vector_matrix(params, getMVMat(), tmp); + if(memcmp(glstate->light.lights[light].position, tmp, 4*sizeof(GLfloat))) + return; + memcpy(glstate->light.lights[light].position, tmp, 4*sizeof(GLfloat)); + break; + case GL_SPOT_DIRECTION: + memcpy(tmp, params, 3*sizeof(GLfloat)); + tmp[3] = 0.0f; + vector_matrix(tmp, getMVMat(), tmp); + if(memcmp(glstate->light.lights[light].spotDirection, tmp, 4*sizeof(GLfloat))) + return; + memcpy(glstate->light.lights[light].spotDirection, tmp, 4*sizeof(GLfloat)); + break; + case GL_SPOT_EXPONENT: + if(params[0]<0 || params[0]>128) { + errorShim(GL_INVALID_VALUE); + return; + } + if(glstate->light.lights[light].spotExponent == params[0]) + return; + glstate->light.lights[light].spotExponent = params[0]; + break; + case GL_SPOT_CUTOFF: + if(params[0]<0 || (params[0]>90 && params[0]!=180)) { + errorShim(GL_INVALID_VALUE); + return; + } + if(glstate->light.lights[light].spotCutoff == params[0]) + return; + glstate->light.lights[light].spotCutoff = params[0]; + break; + case GL_CONSTANT_ATTENUATION: + if(params[0]<0) { + errorShim(GL_INVALID_VALUE); + return; + } + if(glstate->light.lights[light].constantAttenuation == params[0]) + return; + glstate->light.lights[light].constantAttenuation = params[0]; + break; + case GL_LINEAR_ATTENUATION: + if(params[0]<0) { + errorShim(GL_INVALID_VALUE); + return; + } + if(glstate->light.lights[light].linearAttenuation == params[0]) + return; + glstate->light.lights[light].linearAttenuation = params[0]; + break; + case GL_QUADRATIC_ATTENUATION: + if(params[0]<0) { + errorShim(GL_INVALID_VALUE); + return; + } + if(glstate->light.lights[light].quadraticAttenuation == params[0]) + return; + glstate->light.lights[light].quadraticAttenuation = params[0]; + break; + } LOAD_GLES(glLightfv); gles_glLightfv(light, pname, params); errorGL(); @@ -69,8 +165,141 @@ void gl4es_glLightf(GLenum light, GLenum pname, const GLfloat params) { errorGL(); } +void gl4es_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + //TODO: Materialfv can be done per vertex, how to handle that ?! + //NewStage(glstate->list.active, STAGE_MATERIAL); + rlMaterialfv(glstate->list.active, face, pname, params); + noerrorShim(); + } else { + if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) { + errorShim(GL_INVALID_ENUM); + return; + } + switch(pname) { + case GL_AMBIENT: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + memcpy(glstate->material.front.ambient, params, 4*sizeof(GLfloat)); + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + memcpy(glstate->material.back.ambient, params, 4*sizeof(GLfloat)); + break; + case GL_DIFFUSE: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + memcpy(glstate->material.front.diffuse, params, 4*sizeof(GLfloat)); + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + memcpy(glstate->material.back.diffuse, params, 4*sizeof(GLfloat)); + break; + case GL_SPECULAR: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + memcpy(glstate->material.front.specular, params, 4*sizeof(GLfloat)); + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + memcpy(glstate->material.back.specular, params, 4*sizeof(GLfloat)); + break; + case GL_EMISSION: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + memcpy(glstate->material.front.emission, params, 4*sizeof(GLfloat)); + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + memcpy(glstate->material.back.emission, params, 4*sizeof(GLfloat)); + break; + case GL_AMBIENT_AND_DIFFUSE: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) { + memcpy(glstate->material.front.ambient, params, 4*sizeof(GLfloat)); + memcpy(glstate->material.front.diffuse, params, 4*sizeof(GLfloat)); + } + if(face==GL_FRONT_AND_BACK || face==GL_BACK) { + memcpy(glstate->material.back.ambient, params, 4*sizeof(GLfloat)); + memcpy(glstate->material.back.diffuse, params, 4*sizeof(GLfloat)); + } + break; + case GL_SHININESS: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + glstate->material.front.shininess = *params; + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + glstate->material.back.shininess = *params; + break; + case GL_COLOR_INDEXES: + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) { + glstate->material.front.indexes[0] = params[0]; + glstate->material.front.indexes[1] = params[1]; + glstate->material.front.indexes[2] = params[2]; + } + if(face==GL_FRONT_AND_BACK || face==GL_BACK) { + glstate->material.back.indexes[0] = params[0]; + glstate->material.back.indexes[1] = params[1]; + glstate->material.back.indexes[2] = params[2]; + } + break; + + } + + if (face!=GL_FRONT_AND_BACK) { + face=GL_FRONT_AND_BACK; + } + LOAD_GLES(glMaterialfv); + gles_glMaterialfv(face, pname, params); + errorGL(); + } +} + +void gl4es_glMaterialf(GLenum face, GLenum pname, const GLfloat param) { + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + GLfloat params[4]; + memset(params, 0, 4*sizeof(GLfloat)); + params[0] = param; + NewStage(glstate->list.active, STAGE_MATERIAL); + rlMaterialfv(glstate->list.active, face, pname, params); + noerrorShim(); + } else { + if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) { + errorShim(GL_INVALID_ENUM); + return; + } + if(pname!=GL_SHININESS) { + errorShim(GL_INVALID_ENUM); + return; + } + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + glstate->material.front.shininess = param; + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + glstate->material.back.shininess = param; + + LOAD_GLES(glMaterialf); + if (face!=GL_FRONT_AND_BACK) { + face=GL_FRONT_AND_BACK; + } + gles_glMaterialf(face, pname, param); + errorGL(); + } +} + +void gl4es_glColorMaterial(GLenum face, GLenum mode) { + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_COLOR_MATERIAL); + glstate->list.active->colormat_face = face; + glstate->list.active->colormat_mode = mode; + noerrorShim(); + } else { + if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) { + errorShim(GL_INVALID_ENUM); + return; + } + if(mode!=GL_EMISSION && mode!=GL_AMBIENT && mode!=GL_DIFFUSE && mode!=GL_SPECULAR && mode!=GL_AMBIENT_AND_DIFFUSE) { + errorShim(GL_INVALID_ENUM); + return; + } + if(face==GL_FRONT_AND_BACK || face==GL_FRONT) + glstate->material.front.colormat = mode; + if(face==GL_FRONT_AND_BACK || face==GL_BACK) + glstate->material.back.colormat = mode; + noerrorShim(); + } +} + void glLightModelf(GLenum pname, GLfloat param) AliasExport("gl4es_glLightModelf"); void glLightModelfv(GLenum pname, const GLfloat* params) AliasExport("gl4es_glLightModelfv"); void glLightfv(GLenum light, GLenum pname, const GLfloat* params) AliasExport("gl4es_glLightfv"); void glLightf(GLenum light, GLenum pname, const GLfloat params) AliasExport("gl4es_glLightf"); +void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) AliasExport("gl4es_glMaterialfv"); +void glMaterialf(GLenum face, GLenum pname, const GLfloat param) AliasExport("gl4es_glMaterialf"); +void glColorMaterial(GLenum face, GLenum mode) AliasExport("gl4es_glColorMaterial"); #endif diff --git a/project/jni/gl4es/src/gl/light.h b/project/jni/gl4es/src/gl/light.h index d8d2b3f9f..e61a12f3a 100755 --- a/project/jni/gl4es/src/gl/light.h +++ b/project/jni/gl4es/src/gl/light.h @@ -1,6 +1,50 @@ #include "gl.h" +#ifndef __LIGHT_H_ +#define __LIGHT_H_ + +typedef struct { + GLfloat ambient[4]; + GLfloat diffuse[4]; + GLfloat specular[4]; + GLfloat constantAttenuation, linearAttenuation, quadraticAttenuation; + GLfloat position[4]; + GLfloat spotDirection[4]; // It's only 3 in fact, because it's a direction + GLfloat spotExponent; + GLfloat spotCutoff; +} light_t; + +typedef struct { + light_t lights[MAX_LIGHT]; + GLfloat ambient[4]; + GLboolean two_side; +} light_state_t; + +typedef struct { + GLfloat ambient[4]; + GLfloat diffuse[4]; + GLfloat specular[4]; + GLfloat emission[4]; + GLfloat shininess; + int indexes[3]; + GLenum colormat; +} material_t; + +typedef struct { + material_t front; + material_t back; +} material_state_t; + void gl4es_glLightModelf(GLenum pname, GLfloat param); void gl4es_glLightModelfv(GLenum pname, const GLfloat* params); void gl4es_glLightfv(GLenum light, GLenum pname, const GLfloat* params); void gl4es_glLightf(GLenum light, GLenum pname, const GLfloat params); + +void gl4es_glGetLightfv(GLenum light, GLenum pname, GLfloat * params); +void gl4es_glGetLightiv(GLenum light, GLenum pname, GLint * params); + +void gl4es_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) ; +void gl4es_glMaterialf(GLenum face, GLenum pname, const GLfloat param); +void gl4es_glColorMaterial(GLenum face, GLenum mode); + +#endif //__LIGHT_H_ \ No newline at end of file diff --git a/project/jni/gl4es/src/gl/list.c b/project/jni/gl4es/src/gl/list.c index df33de80e..cacedf794 100755 --- a/project/jni/gl4es/src/gl/list.c +++ b/project/jni/gl4es/src/gl/list.c @@ -46,7 +46,7 @@ bool ispurerender_renderlist(renderlist_t *list) { return false; if (list->popattribute) return false; - if (list->material || list->light || list->lightmodel || list->texgen || list->texenv) + if (list->material || list->colormat_face || list->light || list->lightmodel || list->texgen || list->texenv) return false; if (list->fog_op) return false; @@ -828,6 +828,8 @@ void draw_renderlist(renderlist_t *list) { } ) } + if (list->colormat_face) + gl4es_glColorMaterial(list->colormat_face, list->colormat_mode); if (list->light) { khash_t(light) *lig = list->light; renderlight_t *m; diff --git a/project/jni/gl4es/src/gl/list.h b/project/jni/gl4es/src/gl/list.h index 5376a4d48..ddfdc8318 100755 --- a/project/jni/gl4es/src/gl/list.h +++ b/project/jni/gl4es/src/gl/list.h @@ -16,6 +16,7 @@ typedef enum { STAGE_BINDTEX, STAGE_RASTER, STAGE_MATERIAL, + STAGE_COLOR_MATERIAL, STAGE_LIGHT, STAGE_LIGHTMODEL, STAGE_TEXENV, @@ -38,6 +39,7 @@ static int StageExclusive[STAGE_LAST] = { 1, // STAGE_BINDTEX 1, // STAGE_RASTER 0, // STAGE_MATERIAL + 1, // STAGE_COLOR_MATERIAL 0, // STAGE_LIGHT 1, // STAGE_LIGTMODEL 0, // STAGE_TEXENV @@ -144,6 +146,8 @@ typedef struct _renderlist_t { GLfloat pointparam_val[4]; khash_t(material) *material; + GLenum colormat_face; + GLenum colormat_mode; khash_t(light) *light; khash_t(texgen) *texgen; khash_t(texenv) *texenv; diff --git a/project/jni/gl4es/src/gl/matrix.h b/project/jni/gl4es/src/gl/matrix.h index 8bb94065d..5c6d663b7 100755 --- a/project/jni/gl4es/src/gl/matrix.h +++ b/project/jni/gl4es/src/gl/matrix.h @@ -15,3 +15,7 @@ void gl4es_glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, static inline GLfloat* getTexMat(int tmu) { return glstate->texture_matrix[tmu]->stack+glstate->texture_matrix[tmu]->top*16; } + +static inline GLfloat* getMVMat() { + return glstate->modelview_matrix->stack+glstate->modelview_matrix->top*16; +} \ No newline at end of file diff --git a/project/jni/gl4es/src/gl/stack.c b/project/jni/gl4es/src/gl/stack.c index c9b860a76..76bc7c8d3 100755 --- a/project/jni/gl4es/src/gl/stack.c +++ b/project/jni/gl4es/src/gl/stack.c @@ -1,5 +1,6 @@ #include "stack.h" #include "../glx/hardext.h" +#include "matrix.h" void gl4es_glPushAttrib(GLbitfield mask) { //printf("glPushAttrib(0x%04X)\n", mask); @@ -161,8 +162,9 @@ void gl4es_glPushAttrib(GLbitfield mask) { #undef L } j=0; - cur->materials = (GLfloat *)malloc(1 * sizeof(GLfloat)*(5*4)); - #define M(A) gl4es_glGetMaterialfv(GL_FRONT, A, cur->materials+j); j+=4 + cur->materials = (GLfloat *)malloc(2 * sizeof(GLfloat)*(5*4)); + memset(cur->materials, 0, 2 * sizeof(GLfloat)*(5*4)); + #define M(A) gl4es_glGetMaterialfv(GL_BACK, A, cur->materials+j); j+=4; gl4es_glGetMaterialfv(GL_FRONT, A, cur->materials+j); j+=4 M(GL_AMBIENT); M(GL_DIFFUSE); M(GL_SPECULAR); M(GL_EMISSION); M(GL_SHININESS); // handle both face at some point? #undef M gl4es_glGetIntegerv(GL_SHADE_MODEL, &cur->shade_model); @@ -468,6 +470,14 @@ void gl4es_glPopAttrib() { int i; int j=0; + int old_matrixmode = glstate->matrix_mode; + // Light position / direction is transformed. So load identity in modelview to restore correct stuff + int identity = is_identity(getMVMat()); + if(!identity) { + if(old_matrixmode != GL_MODELVIEW) gl4es_glMatrixMode(GL_MODELVIEW); + gl4es_glPushMatrix(); + gl4es_glLoadIdentity(); + } for (i = 0; i < hardext.maxlights; i++) { enable_disable(GL_LIGHT0 + i, *(cur->lights_enabled + i)); #define L(A) gl4es_glLightfv(GL_LIGHT0 + i, A, cur->lights+j); j+=4 @@ -483,8 +493,15 @@ void gl4es_glPopAttrib() { L(GL_QUADRATIC_ATTENUATION); #undef L } + if(!identity) { + gl4es_glPopMatrix(); + if(old_matrixmode != GL_MODELVIEW) gl4es_glMatrixMode(old_matrixmode); + } j=0; - #define M(A) gl4es_glMaterialfv(GL_FRONT_AND_BACK, A, cur->materials+j); j+=4 + #define M(A) if(memcmp(cur->materials+j, cur->materials+j+4, 4*sizeof(GLfloat))==0) \ + {gl4es_glMaterialfv(GL_FRONT_AND_BACK, A, cur->materials+j); j+=8;} \ + else \ + {gl4es_glMaterialfv(GL_BACK, A, cur->materials+j); j+=4; gl4es_glMaterialfv(GL_FRONT, A, cur->materials+j); j+=4;} M(GL_AMBIENT); M(GL_DIFFUSE); M(GL_SPECULAR); M(GL_EMISSION); M(GL_SHININESS); // handle both face at some point? #undef M diff --git a/project/jni/gl4es/src/gl/state.h b/project/jni/gl4es/src/gl/state.h index f148393bc..9eed4e6a9 100755 --- a/project/jni/gl4es/src/gl/state.h +++ b/project/jni/gl4es/src/gl/state.h @@ -7,6 +7,7 @@ #include "texture.h" #include "buffers.h" #include "queries.h" +#include "light.h" typedef struct _glstack_t glstack_t; typedef struct _glclientstack_t glclientstack_t; @@ -189,6 +190,8 @@ typedef struct { int emulatedPixmap; int emulatedWin; int shared_cnt; + light_state_t light; + material_state_t material; } glstate_t; #endif diff --git a/project/jni/gl4es/src/gl/texture.c b/project/jni/gl4es/src/gl/texture.c index 4f6547de9..84318fdde 100755 --- a/project/jni/gl4es/src/gl/texture.c +++ b/project/jni/gl4es/src/gl/texture.c @@ -843,10 +843,11 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff // compressed format are not handled here, so mask them.... GLenum orig_internal = bound->orig_internal; GLenum internalformat = bound->internalformat; - if (orig_internal==GL_COMPRESSED_RGB) orig_internal=GL_RGB; - if (orig_internal==GL_COMPRESSED_RGBA) orig_internal=GL_RGBA; - if (internalformat==GL_COMPRESSED_RGB) internalformat=GL_RGB; - if (internalformat==GL_COMPRESSED_RGBA) internalformat=GL_RGBA; + // compressed format are not handled here, so mask them.... + if (is_fake_compressed_rgb(orig_internal)) orig_internal=GL_RGB; + if (is_fake_compressed_rgba(orig_internal)) orig_internal=GL_RGBA; + if (is_fake_compressed_rgb(internalformat)) internalformat=GL_RGB; + if (is_fake_compressed_rgba(internalformat)) internalformat=GL_RGBA; GLvoid *old = pixels; diff --git a/project/jni/gl4es/src/gl/wrap/gl.c b/project/jni/gl4es/src/gl/wrap/gl.c index 5aad073ef..c26eb69f2 100755 --- a/project/jni/gl4es/src/gl/wrap/gl.c +++ b/project/jni/gl4es/src/gl/wrap/gl.c @@ -85,7 +85,12 @@ void gl4es_glGetMaterialiv(GLenum face, GLenum pname, GLint * params) { GLfloat fparams[4]; gl4es_glGetMaterialfv(face, pname, fparams); if (pname==GL_SHININESS) *params=fparams[0]; - else for (int i=0; i<4; i++) params[i]=fparams[i]; + else { + if (pname==GL_COLOR_INDEXES) + for (int i=0; i<3; i++) params[i]=fparams[i]; + else + for (int i=0; i<4; i++) params[i]=((int)fparams[i]*32767)<<16; + } } void gl4es_glGetLightiv(GLenum light, GLenum pname, GLint * params) { GLfloat fparams[4]; @@ -95,7 +100,10 @@ void gl4es_glGetLightiv(GLenum light, GLenum pname, GLint * params) { if (pname==GL_SPOT_CUTOFF) n=1; if (pname==GL_SPOT_EXPONENT) n=1; if (pname==GL_SPOT_DIRECTION) n=3; - else for (int i=0; i>16)/32767.f; + } + gl4es_glLightfv(light, pname, params); + break; + case GL_POSITION: for (int i = 0; i < 4; i++) { params[i] = iparams[i]; } gl4es_glLightfv(light, pname, params); break; - } - case GL_SPOT_DIRECTION: { - GLfloat params[4]; + case GL_SPOT_DIRECTION: for (int i = 0; i < 4; i++) { params[i] = iparams[i]; } gl4es_glLightfv(light, pname, params); break; - } case GL_SPOT_EXPONENT: case GL_SPOT_CUTOFF: case GL_CONSTANT_ATTENUATION: @@ -186,10 +196,11 @@ printf("glMaterialiv(%04X, %04X, [%i,...]\n", face, pname, iparams[0]); case GL_DIFFUSE: case GL_SPECULAR: case GL_EMISSION: + case GL_AMBIENT_AND_DIFFUSE: { GLfloat params[4]; for (int i = 0; i < 4; i++) { - params[i] = iparams[i]; // should divide by MAX_INT + params[i] = (iparams[i]>>16)/32767.f; } gl4es_glMaterialfv(face, pname, params); break; @@ -202,10 +213,6 @@ printf("glMaterialiv(%04X, %04X, [%i,...]\n", face, pname, iparams[0]); } gl4es_glMaterialfv(face, pname, params); break; - } - case GL_AMBIENT_AND_DIFFUSE: { - gl4es_glMaterialf(face, pname, *iparams); - break; } case GL_COLOR_INDEXES: { diff --git a/project/jni/gl4es/src/gl/wrap/glstub.c b/project/jni/gl4es/src/gl/wrap/glstub.c index a7657ede3..560a249c4 100755 --- a/project/jni/gl4es/src/gl/wrap/glstub.c +++ b/project/jni/gl4es/src/gl/wrap/glstub.c @@ -47,7 +47,7 @@ STUB(void glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha) STUB(void glBlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)) */ STUB(void,glClearAccum,(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)); -STUB(void,glColorMaterial,(GLenum face, GLenum mode)); +//STUB(void,glColorMaterial,(GLenum face, GLenum mode)); STUB(void,glCopyPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)); STUB(void,glDrawBuffer,(GLenum mode)); STUB(void,glEdgeFlag,(GLboolean flag)); diff --git a/project/jni/gl4es/src/gl/wrap/stub.h b/project/jni/gl4es/src/gl/wrap/stub.h index 08ac21ca2..eac60e038 100755 --- a/project/jni/gl4es/src/gl/wrap/stub.h +++ b/project/jni/gl4es/src/gl/wrap/stub.h @@ -5,7 +5,7 @@ void gl4es_glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha); //void gl4es_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); void gl4es_glBlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -void gl4es_glColorMaterial(GLenum face, GLenum mode); +//void gl4es_glColorMaterial(GLenum face, GLenum mode); void gl4es_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); void gl4es_glDrawBuffer(GLenum mode); void gl4es_glEdgeFlag(GLboolean flag); diff --git a/project/jni/gl4es/src/glx/lookup.c b/project/jni/gl4es/src/glx/lookup.c index d52f5bc2b..502b35325 100755 --- a/project/jni/gl4es/src/glx/lookup.c +++ b/project/jni/gl4es/src/glx/lookup.c @@ -485,7 +485,7 @@ EXPORT void *glXGetProcAddressARB(const char *name) { STUB(glAccum); STUB(glAreTexturesResident); STUB(glClearAccum); - STUB(glColorMaterial); + _EX(glColorMaterial); _EX(glCopyTexSubImage3D); // It's a stub, calling the 2D one STUB(glFeedbackBuffer); STUB(glGetClipPlane);