From 360fc0b1124ac6c76944e4a5e36b02de1db4df52 Mon Sep 17 00:00:00 2001 From: lubomyr Date: Sat, 13 May 2017 13:42:21 +0300 Subject: [PATCH] gl4es updated, added latest changes by ptitSeb --- project/jni/gl4es/Android.mk | 3 + project/jni/gl4es/README.md | 20 +- project/jni/gl4es/include/gl4eshint.h | 2 + project/jni/gl4es/spec/yml/gles-1.1-full.yml | 177 +++++++++++ project/jni/gl4es/spec/yml/gles-1.1.yml | 4 +- project/jni/gl4es/src/CMakeLists.txt | 6 + project/jni/gl4es/src/config.h | 12 +- project/jni/gl4es/src/gl/blend.c | 150 +++++++++ project/jni/gl4es/src/gl/blend.h | 13 + project/jni/gl4es/src/gl/const.h | 7 +- project/jni/gl4es/src/gl/fog.c | 54 ++++ project/jni/gl4es/src/gl/fog.h | 18 ++ project/jni/gl4es/src/gl/framebuffers.c | 110 +++++-- project/jni/gl4es/src/gl/getter.c | 79 ++++- project/jni/gl4es/src/gl/gl.c | 315 +++++++------------ project/jni/gl4es/src/gl/gl.h | 5 +- project/jni/gl4es/src/gl/hint.c | 6 + project/jni/gl4es/src/gl/init.c | 7 +- project/jni/gl4es/src/gl/init.h | 1 + project/jni/gl4es/src/gl/light.c | 25 +- project/jni/gl4es/src/gl/list.c | 17 +- project/jni/gl4es/src/gl/list.h | 4 +- project/jni/gl4es/src/gl/loader.h | 18 ++ project/jni/gl4es/src/gl/pixel.c | 130 ++++---- project/jni/gl4es/src/gl/pixel.h | 6 +- project/jni/gl4es/src/gl/raster.c | 2 +- project/jni/gl4es/src/gl/state.h | 6 +- project/jni/gl4es/src/gl/texgen.c | 8 +- project/jni/gl4es/src/gl/texture.c | 188 ++++++++--- project/jni/gl4es/src/gl/wrap/gl.c | 4 +- project/jni/gl4es/src/gl/wrap/gles.c | 12 +- project/jni/gl4es/src/gl/wrap/gles.h | 20 +- project/jni/gl4es/src/glx/glx.c | 139 +++++--- project/jni/gl4es/src/glx/glx.h | 1 + project/jni/gl4es/src/glx/hardext.c | 10 +- project/jni/gl4es/src/glx/rpi.c | 84 +++++ project/jni/gl4es/src/glx/rpi.h | 10 + project/jni/gl4es/version.h | 2 +- 38 files changed, 1229 insertions(+), 446 deletions(-) create mode 100644 project/jni/gl4es/spec/yml/gles-1.1-full.yml create mode 100755 project/jni/gl4es/src/gl/blend.c create mode 100644 project/jni/gl4es/src/gl/blend.h create mode 100755 project/jni/gl4es/src/gl/fog.c create mode 100755 project/jni/gl4es/src/gl/fog.h mode change 100644 => 100755 project/jni/gl4es/src/gl/wrap/gles.h create mode 100644 project/jni/gl4es/src/glx/rpi.c create mode 100644 project/jni/gl4es/src/glx/rpi.h diff --git a/project/jni/gl4es/Android.mk b/project/jni/gl4es/Android.mk index 600711596..7a9fe72bc 100755 --- a/project/jni/gl4es/Android.mk +++ b/project/jni/gl4es/Android.mk @@ -16,11 +16,13 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) -DBCMHOST LOCAL_SRC_FILES := \ src/gl/array.c \ + src/gl/blend.c \ src/gl/buffers.c \ src/gl/debug.c \ src/gl/decompress.c \ src/gl/directstate.c \ src/gl/eval.c \ + src/gl/fog.c \ src/gl/framebuffers.c \ src/gl/getter.c \ src/gl/gl.c \ @@ -46,6 +48,7 @@ LOCAL_SRC_FILES := \ src/glx/hardext.c \ src/glx/glx.c \ src/glx/lookup.c \ + src/glx/rpi.c \ src/glx/streaming.c \ LOCAL_CFLAGS += -g -std=c99 -funwind-tables -O3 -DBCMHOST -fvisibility=hidden -include include/android_debug.h diff --git a/project/jni/gl4es/README.md b/project/jni/gl4es/README.md index 5d4c21e9e..a8cdbb615 100755 --- a/project/jni/gl4es/README.md +++ b/project/jni/gl4es/README.md @@ -7,7 +7,7 @@ This is a fork a glshim (https://github.com/lunixbochs/glshim). Go check this li The focus is on compatibility with a wide selection of game and software, as well as speed. -It has been tested successfully of a large selection of games and software, including: Mincraft, OpenMW, SeriousSam, RVGL, TSMC, TORCS, SpeedDreams, GL-117, Foobillard(plus), Blender 2.68 and many more. +It has been tested successfully of a large selection of games and software, including: Minecraft, OpenMW, SeriousSam (both First and Second Encounters), RVGL (ReVolt GL), TSMC (The Secret Maryo Chronicles), TORCS, SpeedDreams, GL-117, Foobillard(plus), Blender 2.68 to name just a few. Most function of OpenGL up to 1.5 are supported, with some notable exceptions: * Reading of Depth or Stencil buffer will not work @@ -135,7 +135,7 @@ Experimental: enable Alpha test only when using texture that contains an alpha c * 1 : Alpha Hack enabled ##### LIBGL_NODOWNSAMPLING -Texture downsampling control +Texture downsampling control (deprecated, use LIBGL_AVOID16BITS instead) * 0 : Default, DXTc texture are downsampled to 16bits * 1 : DXTc texture are left as 32bits RGBA @@ -241,10 +241,26 @@ Merge of subsequent glBegin/glEnd blocks (will be non-effective if BATCH mode is * 1 : Try to merge, even if there is a glColor / glNormal in between (default) * 2 : Try hard to merge, even if there is a glColor / glNormal or Matrix operations in between +##### LIBGL_AVOID16BITS +Try to avoid 16bits textures + * 0 : Default, use 16bits texture if it can avoid a convertion or for DXTc textures + * 1 : Use 32bits texture unless specifically requested (using internalformat) + ---- Version history ---- +##### Current version + * Some fix with the PixMap glX context creation + +##### 0.9.6 + * Some fixes in GL_TEXTURE_RECTANGLE_ARB handling + * Some other fixes in texture handling (unpack and glList related) + * Some fix with the PBuffer glX context creation + * Tracking of glFog + * Exposed glBlendEquation if supported + * New LIBGL_AVOID16BITS parameter to prefer 32bits texture (usefull on ODroid) + * Some optimisations in texture conversion ##### 0.9.5 * Added some optimisations for sequencial glBegin/glEnd blocks, with a switch to control them diff --git a/project/jni/gl4es/include/gl4eshint.h b/project/jni/gl4es/include/gl4eshint.h index 5c72988cc..7fe378de8 100755 --- a/project/jni/gl4es/include/gl4eshint.h +++ b/project/jni/gl4es/include/gl4eshint.h @@ -29,5 +29,7 @@ #define GL_NOVAOCACHE_HINT_GL4ES 0xA10C // same as using LIBGL_BEGINEND=x #define GL_BEGINEND_HINT_GL4ES 0xA10D +// same as using LIBGL_AVOID16BITS=x +#define GL_AVOID16BITS_HINT_GL4ES 0xA10E #endif \ No newline at end of file diff --git a/project/jni/gl4es/spec/yml/gles-1.1-full.yml b/project/jni/gl4es/spec/yml/gles-1.1-full.yml new file mode 100644 index 000000000..006da9fbd --- /dev/null +++ b/project/jni/gl4es/spec/yml/gles-1.1-full.yml @@ -0,0 +1,177 @@ +glActiveTexture: [void, GLenum texture] +glAlphaFunc: [void, GLenum func, GLclampf ref] +glAlphaFuncx: [void, GLenum func, GLclampx ref] +glBindBuffer: [void, GLenum target, GLuint buffer] +glBindTexture: [void, GLenum target, GLuint texture] +glBlendFunc: [void, GLenum sfactor, GLenum dfactor] +glBufferData: [void, GLenum target, GLsizeiptr size, "const GLvoid *data", GLenum usage] +glBufferSubData: [void, GLenum target, GLintptr offset, GLsizeiptr size, "const GLvoid *data"] +glClear: [void, GLbitfield mask] +glClearColor: [void, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha] +glClearColorx: [void, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha] +glClearDepthf: [void, GLclampf depth] +glClearDepthx: [void, GLclampx depth] +glClearStencil: [void, GLint s] +glClientActiveTexture: [void, GLenum texture] +glClipPlanef: [void, GLenum plane, "const GLfloat *equation"] +glClipPlanex: [void, GLenum plane, "const GLfixed *equation"] +glColor4f: [void, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha] +glColor4ub: [void, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha] +glColor4x: [void, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha] +glColorMask: [void, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha] +glColorPointer: [void, GLint size, GLenum type, GLsizei stride, "const GLvoid *pointer"] +glCompressedTexImage2D: [void, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, "const GLvoid *data"] +glCompressedTexSubImage2D: [void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, "const GLvoid *data"] +glCopyTexImage2D: [void, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border] +glCopyTexSubImage2D: [void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height] +glCullFace: [void, GLenum mode] +glDeleteBuffers: [void, GLsizei n, "const GLuint *buffers"] +glDeleteTextures: [void, GLsizei n, "const GLuint *textures"] +glDepthFunc: [void, GLenum func] +glDepthMask: [void, GLboolean flag] +glDepthRangef: [void, GLclampf near, GLclampf far] +glDepthRangex: [void, GLclampx near, GLclampx far] +glDisable: [void, GLenum cap] +glDisableClientState: [void, GLenum array] +glDisableClientState: [void, GLenum array] +glDrawArrays: [void, GLenum mode, GLint first, GLsizei count] +glDrawElements: [void, GLenum mode, GLsizei count, GLenum type, "const GLvoid *indices"] +glEnable: [void, GLenum cap] +glEnableClientState: [void, GLenum array] +glEnableClientState: [void, GLenum array] +glFinish: [void, void] +glFlush: [void, void] +glFogf: [void, GLenum pname, GLfloat param] +glFogfv: [void, GLenum pname, "const GLfloat *params"] +glFogx: [void, GLenum pname, GLfixed param] +glFogxv: [void, GLenum pname, "const GLfixed *params"] +glFrontFace: [void, GLenum mode] +glFrustumf: [void, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far] +glFrustumx: [void, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed near, GLfixed far] +glGenBuffers: [void, GLsizei n, "GLuint *buffers"] +glGenTextures: [void, GLsizei n, "GLuint *textures"] +glGetBooleanv: [void, GLenum pname, "GLboolean *params"] +glGetBufferParameteriv: [void, GLenum target, GLenum pname, "GLint *params"] +glGetClipPlanef: [void, GLenum plane, "GLfloat *equation"] +glGetClipPlanex: [void, GLenum plane, "GLfixed *equation"] +glGetError: [GLenum, void] +glGetFixedv: [void, GLenum pname, "GLfixed *params"] +glGetFloatv: [void, GLenum pname, "GLfloat *params"] +glGetIntegerv: [void, GLenum pname, "GLint *params"] +glGetLightfv: [void, GLenum light, GLenum pname, "GLfloat *params"] +glGetLightxv: [void, GLenum light, GLenum pname, "GLfixed *params"] +glGetMaterialfv: [void, GLenum face, GLenum pname, "GLfloat *params"] +glGetMaterialxv: [void, GLenum face, GLenum pname, "GLfixed *params"] +glGetPointerv: [void, GLenum pname, "GLvoid **params"] +glGetString: [const GLubyte *, GLenum name] +glGetTexEnvfv: [void, GLenum target, GLenum pname, "GLfloat *params"] +glGetTexEnviv: [void, GLenum target, GLenum pname, "GLint *params"] +glGetTexEnvxv: [void, GLenum target, GLenum pname, "GLfixed *params"] +glGetTexParameterfv: [void, GLenum target, GLenum pname, "GLfloat *params"] +glGetTexParameteriv: [void, GLenum target, GLenum pname, "GLint *params"] +glGetTexParameterxv: [void, GLenum target, GLenum pname, "GLfixed *params"] +glHint: [void, GLenum target, GLenum mode] +glIsBuffer: [GLboolean, GLuint buffer] +glIsEnabled: [GLboolean, GLenum cap] +glIsTexture: [GLboolean, GLuint texture] +glLightf: [void, GLenum light, GLenum pname, GLfloat param] +glLightfv: [void, GLenum light, GLenum pname, "const GLfloat *params"] +glLightModelf: [void, GLenum pname, GLfloat param] +glLightModelfv: [void, GLenum pname, "const GLfloat *params"] +glLightModelx: [void, GLenum pname, GLfixed param] +glLightModelxv: [void, GLenum pname, "const GLfixed *params"] +glLightx: [void, GLenum light, GLenum pname, GLfixed param] +glLightxv: [void, GLenum light, GLenum pname, "const GLfixed *params"] +glLineWidth: [void, GLfloat width] +glLineWidthx: [void, GLfixed width] +glLoadIdentity: [void, void] +glLoadMatrixf: [void, "const GLfloat *m"] +glLoadMatrixx: [void, "const GLfixed *m"] +glLogicOp: [void, GLenum opcode] +glMaterialf: [void, GLenum face, GLenum pname, GLfloat param] +glMaterialfv: [void, GLenum face, GLenum pname, "const GLfloat *params"] +glMaterialx: [void, GLenum face, GLenum pname, GLfixed param] +glMaterialxv: [void, GLenum face, GLenum pname, "const GLfixed *params"] +glMatrixMode: [void, GLenum mode] +glMultiTexCoord4f: [void, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q] +glMultiTexCoord4x: [void, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q] +glMultMatrixf: [void, "const GLfloat *m"] +glMultMatrixx: [void, "const GLfixed *m"] +glNormal3f: [void, GLfloat nx, GLfloat ny, GLfloat nz] +glNormal3x: [void, GLfixed nx, GLfixed ny, GLfixed nz] +glNormalPointer: [void, GLenum type, GLsizei stride, "const GLvoid *pointer"] +glOrthof: [void, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far] +glOrthox: [void, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed near, GLfixed far] +glPixelStorei: [void, GLenum pname, GLint param] +glPointParameterf: [void, GLenum pname, GLfloat param] +glPointParameterfv: [void, GLenum pname, "const GLfloat *params"] +glPointParameterx: [void, GLenum pname, GLfixed param] +glPointParameterxv: [void, GLenum pname, "const GLfixed *params"] +glPointSize: [void, GLfloat size] +glPointSizePointerOES: [void, GLenum type, GLsizei stride, "const GLvoid *pointer"] +glPointSizex: [void, GLfixed size] +glPolygonOffset: [void, GLfloat factor, GLfloat units] +glPolygonOffsetx: [void, GLfixed factor, GLfixed units] +glPopMatrix: [void, void] +glPushMatrix: [void, void] +glReadPixels: [void, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, "GLvoid *pixels"] +glRotatef: [void, GLfloat angle, GLfloat x, GLfloat y, GLfloat z] +glRotatex: [void, GLfixed angle, GLfixed x, GLfixed y, GLfixed z] +glSampleCoverage: [void, GLclampf value, GLboolean invert] +glSampleCoveragex: [void, GLclampx value, GLboolean invert] +glScalef: [void, GLfloat x, GLfloat y, GLfloat z] +glScalex: [void, GLfixed x, GLfixed y, GLfixed z] +glScissor: [void, GLint x, GLint y, GLsizei width, GLsizei height] +glShadeModel: [void, GLenum mode] +glStencilFunc: [void, GLenum func, GLint ref, GLuint mask] +glStencilMask: [void, GLuint mask] +glStencilOp: [void, GLenum fail, GLenum zfail, GLenum zpass] +glTexCoordPointer: [void, GLint size, GLenum type, GLsizei stride, "const GLvoid *pointer"] +glTexEnvf: [void, GLenum target, GLenum pname, GLfloat param] +glTexEnvfv: [void, GLenum target, GLenum pname, "const GLfloat *params"] +glTexEnvi: [void, GLenum target, GLenum pname, GLint param] +glTexEnviv: [void, GLenum target, GLenum pname, "const GLint *params"] +glTexEnvx: [void, GLenum target, GLenum pname, GLfixed param] +glTexEnvxv: [void, GLenum target, GLenum pname, "const GLfixed *params"] +glTexImage2D: [void, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, "const GLvoid *data"] +glTexParameterf: [void, GLenum target, GLenum pname, GLfloat param] +glTexParameterfv: [void, GLenum target, GLenum pname, "const GLfloat *params"] +glTexParameteri: [void, GLenum target, GLenum pname, GLint param] +glTexParameteriv: [void, GLenum target, GLenum pname, "const GLint *params"] +glTexParameterx: [void, GLenum target, GLenum pname, GLfixed param] +glTexParameterxv: [void, GLenum target, GLenum pname, "const GLfixed *params"] +glTexSubImage2D: [void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, "const GLvoid *data"] +glTranslatef: [void, GLfloat x, GLfloat y, GLfloat z] +glTranslatex: [void, GLfixed x, GLfixed y, GLfixed z] +glVertexPointer: [void, GLint size, GLenum type, GLsizei stride, "const GLvoid *pointer"] +glViewport: [void, GLint x, GLint y, GLsizei width, GLsizei height] +glBlendColor_OES_: [void, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha] +glBlendEquation_OES_: [void, GLenum mode] +glBlendEquationSeparate_OES_: [void, GLenum modeRGB, GLenum modeA] +glBlendFuncSeparate_OES_: [void, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha] +# glTexGenfOES_OES_: [void, GLenum coord, GLenum pname, GLfloat param] +glTexGenfv_OES_: [void, GLenum coord, GLenum pname, "const GLfloat *params"] +glTexGeni_OES_: [void, GLenum coord, GLenum pname, GLint param] +# glTexGenivOES_OES_: [void, GLenum coord, GLenum pname, "const GLint *params"] + +glGenFramebuffers_OES_: [void, GLsizei n, "GLuint *ids"] +glDeleteFramebuffers_OES_: [void, GLsizei n, "GLuint *framebuffers"] +glIsFramebuffer_OES_: [GLboolean, GLuint framebuffer] +glCheckFramebufferStatus_OES_: [GLenum, GLenum target] +glBindFramebuffer_OES_: [void, GLenum target, GLuint framebuffer] +glFramebufferTexture2D_OES_: [void, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level] +glGenRenderbuffers_OES_: [void, GLsizei n, "GLuint *renderbuffers"] +glFramebufferRenderbuffer_OES_: [void, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer] +glDeleteRenderbuffers_OES_: [void, GLsizei n, "GLuint *renderbuffers"] +glRenderbufferStorage_OES_: [void, GLenum target, GLenum internalformat, GLsizei width, GLsizei height] +glBindRenderbuffer_OES_: [void, GLenum target, GLuint renderbuffer] +glIsRenderbuffer_OES_: [GLboolean, GLuint renderbuffer] +glGenerateMipmap_OES_: [void, GLenum target] +glGetFramebufferAttachmentParameteriv_OES_: [void, GLenum target, GLenum attachment, GLenum pname, "GLint *params"] +glGetRenderbufferParameteriv_OES_: [void, GLenum target, GLenum pname, "GLint * params"] + +glDrawTexi_OES_: [void, GLint x, GLint y, GLint z, GLint width, GLint height] +glDrawTexf_OES_: [void, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height] + +glMultiDrawArrays_OES_: [void, GLenum mode, "const GLint *first", "const GLsizei *count", GLsizei primcount] +glMultiDrawElements_OES_: [void, GLenum mode, "GLsizei *count", GLenum type, "const void * const *indices", GLsizei primcount] diff --git a/project/jni/gl4es/spec/yml/gles-1.1.yml b/project/jni/gl4es/spec/yml/gles-1.1.yml index 7085b4b66..5873961a4 100755 --- a/project/jni/gl4es/spec/yml/gles-1.1.yml +++ b/project/jni/gl4es/spec/yml/gles-1.1.yml @@ -133,14 +133,14 @@ glTexEnvi: [void, GLenum target, GLenum pname, GLint param] glTexEnviv: [void, GLenum target, GLenum pname, "const GLint *params"] glTexEnvx: [void, GLenum target, GLenum pname, GLfixed param] glTexEnvxv: [void, GLenum target, GLenum pname, "const GLfixed *params"] -glTexImage2D: [void, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, "const GLvoid *pixels"] +glTexImage2D: [void, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, "const GLvoid *data"] glTexParameterf: [void, GLenum target, GLenum pname, GLfloat param] glTexParameterfv: [void, GLenum target, GLenum pname, "const GLfloat *params"] glTexParameteri: [void, GLenum target, GLenum pname, GLint param] glTexParameteriv: [void, GLenum target, GLenum pname, "const GLint *params"] glTexParameterx: [void, GLenum target, GLenum pname, GLfixed param] glTexParameterxv: [void, GLenum target, GLenum pname, "const GLfixed *params"] -glTexSubImage2D: [void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, "const GLvoid *pixels"] +glTexSubImage2D: [void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, "const GLvoid *data"] glTranslatef: [void, GLfloat x, GLfloat y, GLfloat z] glTranslatex: [void, GLfixed x, GLfixed y, GLfixed z] glVertexPointer: [void, GLint size, GLenum type, GLsizei stride, "const GLvoid *pointer"] diff --git a/project/jni/gl4es/src/CMakeLists.txt b/project/jni/gl4es/src/CMakeLists.txt index 1254a671a..306f17b1f 100755 --- a/project/jni/gl4es/src/CMakeLists.txt +++ b/project/jni/gl4es/src/CMakeLists.txt @@ -3,11 +3,13 @@ include_directories(util) #file(GLOB_RECURSE GL_SOURCES gl/*.c) SET(GL_SRC gl/array.c + gl/blend.c gl/buffers.c gl/debug.c gl/decompress.c gl/directstate.c gl/eval.c + gl/fog.c gl/framebuffers.c gl/getter.c gl/gl.c @@ -35,12 +37,14 @@ SET(GL_SRC SET(GL_H ../version.h gl/array.h + gl/blend.h gl/buffers.h gl/const.h gl/debug.h gl/decompress.h gl/defines.h gl/directstate.h + gl/fog.h gl/eval.h gl/framebuffers.h gl/gles.h @@ -78,12 +82,14 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") glx/hardext.c glx/glx.c glx/lookup.c + glx/rpi.c glx/streaming.c glx/utils.c ) list(APPEND GL_H glx/glx.h glx/hardext.h + glx/rpi.h glx/streaming.h glx/utils.h ) diff --git a/project/jni/gl4es/src/config.h b/project/jni/gl4es/src/config.h index 9699f502a..f4b88caf7 100755 --- a/project/jni/gl4es/src/config.h +++ b/project/jni/gl4es/src/config.h @@ -31,17 +31,17 @@ #define skip_glBlendColor #define skip_glBlendFunc +#define skip_glBlendEquation +#define skip_glBlendEquationSeparate +#define skip_glBlendEquationSeparatei +#define skip_glBlendFuncSeparate +#define skip_glBlendFuncSeparatei #define skip_glFogfv #define skip_glPointParameterfv #define skip_glPointParameterf -//#define skip_glBlendEquation -#define skip_glBlendEquationSeparate -#define skip_glBlendEquationSeparatei -#define skip_glBlendFuncSeparate -#define skip_glBlendFuncSeparatei // getter.c #define skip_glGetError @@ -78,6 +78,8 @@ #define skip_glTexImage2D #define skip_glTexParameteri #define skip_glTexParameterf +#define skip_glTexParameterfv +#define skip_glTexParameteriv #define skip_glTexSubImage2D #define skip_glActiveTexture #define skip_glClientActiveTexture diff --git a/project/jni/gl4es/src/gl/blend.c b/project/jni/gl4es/src/gl/blend.c new file mode 100755 index 000000000..caee7b664 --- /dev/null +++ b/project/jni/gl4es/src/gl/blend.c @@ -0,0 +1,150 @@ +#include "blend.h" +#include "debug.h" +#include "../glx/hardext.h" +#include "init.h" + +void gl4es_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + PUSH_IF_COMPILING(glBlendColor); + LOAD_GLES_OR_OES(glBlendColor); + if (gles_glBlendColor) + gles_glBlendColor(red, green, blue, alpha); + else { + static int test = 1; + if (test) { + LOGD("stub glBlendColor(%f, %f, %f, %f)\n", red, green, blue, alpha); + test = 0; + } + } +} +void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor"); +void glBlendColorEXT(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor"); +void glBlendColorARB(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor"); + +void gl4es_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +{ + PUSH_IF_COMPILING(glBlendFuncSeparate); + LOAD_GLES_OES(glBlendFuncSeparate); +#ifndef PANDORA + if(gles_glBlendFuncSeparate==NULL) { + // some fallback function to have better rendering with SDL2, better then nothing... + if(sfactorRGB==GL_SRC_ALPHA && dfactorRGB==GL_ONE_MINUS_SRC_ALPHA && sfactorAlpha==GL_ONE && dfactorAlpha==GL_ONE_MINUS_SRC_ALPHA) + gl4es_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + else if (sfactorRGB==GL_SRC_ALPHA && dfactorRGB==GL_ONE && sfactorAlpha==GL_ZERO && dfactorAlpha==GL_ONE) + gl4es_glBlendFunc(GL_SRC_ALPHA, GL_ONE); + else if (sfactorRGB==GL_ZERO && dfactorRGB==GL_SRC_COLOR && sfactorAlpha==GL_ZERO && dfactorAlpha==GL_ONE) + gl4es_glBlendFunc(GL_ZERO, GL_SRC_COLOR); + else if (sfactorRGB==sfactorAlpha && dfactorRGB==dfactorAlpha) + gl4es_glBlendFunc(sfactorRGB, dfactorRGB); + } else +#endif + gles_glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); +} +void glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) AliasExport("gl4es_glBlendFuncSeparate"); +void glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) AliasExport("gl4es_glBlendFuncSeparate"); + +void gl4es_glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) { + PUSH_IF_COMPILING(glBlendEquationSeparate); + LOAD_GLES_OES(glBlendEquationSeparate); +#ifndef PANDORA + if(gles_glBlendEquationSeparate) +#endif + gles_glBlendEquationSeparate(modeRGB, modeA); +} +void glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) AliasExport("gl4es_glBlendEquationSeparate"); +void glBlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) AliasExport("gl4es_glBlendEquationSeparate"); + +void gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor) { + if (glstate->list.active) + if (!glstate->list.compiling && glstate->gl_batch) { + if ((glstate->statebatch.blendfunc_s == sfactor) && (glstate->statebatch.blendfunc_d == dfactor)) + return; // nothing to do... + if (!glstate->statebatch.blendfunc_s) { + glstate->statebatch.blendfunc_s = sfactor; + glstate->statebatch.blendfunc_d = dfactor; + } + } + + PUSH_IF_COMPILING(glBlendFunc) + LOAD_GLES(glBlendFunc); + LOAD_GLES_OES(glBlendFuncSeparate); + errorGL(); + // There are some limitations in GLES1.1 Blend functions + switch(sfactor) { + #if 0 + case GL_SRC_COLOR: + if (gles_glBlendFuncSeparate) { + gles_glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); + return; + } + sfactor = GL_ONE; // approx... + break; + case GL_ONE_MINUS_SRC_COLOR: + if (gles_glBlendFuncSeparate) { + gles_glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); + return; + } + sfactor = GL_ONE; // not sure it make sense... + break; + #endif + // here, we need support for glBlendColor... + case GL_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + if(hardext.blendcolor==0) + sfactor = GL_ONE; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_ALPHA: + if(hardext.blendcolor==0) + sfactor = GL_ZERO; + break; + default: + break; + } + + switch(dfactor) { + #if 0 + case GL_DST_COLOR: + sfactor = GL_ONE; // approx... + break; + case GL_ONE_MINUS_DST_COLOR: + sfactor = GL_ZERO; // not sure it make sense... + break; + #endif + // here, we need support for glBlendColor... + case GL_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + if(hardext.blendcolor==0) + sfactor = GL_ONE; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_ALPHA: + if(hardext.blendcolor==0) + sfactor = GL_ZERO; + break; + default: + break; + } + + if ((globals4es.blendhack) && (sfactor==GL_SRC_ALPHA) && (dfactor==GL_ONE)) { + // special case, as seen in Xash3D, but it breaks torus_trooper, so behind a parameter + sfactor = GL_ONE; + } + +#ifdef ODROID + if(gles_glBlendFunc) +#endif + gles_glBlendFunc(sfactor, dfactor); +} +void glBlendFunc(GLenum sfactor, GLenum dfactor) AliasExport("gl4es_glBlendFunc"); + +void gl4es_glBlendEquation(GLenum mode) { + PUSH_IF_COMPILING(glBlendEquation) + LOAD_GLES_OR_OES(glBlendEquation); + errorGL(); +#ifdef ODROID + if(gles_glBlendEquation) +#endif + gles_glBlendEquation(mode); +} +void glBlendEquation(GLenum mode) AliasExport("gl4es_glBlendEquation"); +void glBlendEquationEXT(GLenum mode) AliasExport("gl4es_glBlendEquation"); \ No newline at end of file diff --git a/project/jni/gl4es/src/gl/blend.h b/project/jni/gl4es/src/gl/blend.h new file mode 100644 index 000000000..818d2362a --- /dev/null +++ b/project/jni/gl4es/src/gl/blend.h @@ -0,0 +1,13 @@ +#include "gl.h" + +#ifndef GL_BLEND_H +#define GL_BLEND_H + +void gl4es_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +void gl4es_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +void gl4es_glBlendEquationSeparate(GLenum modeRGB, GLenum modeA); +void gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor); +void gl4es_glBlendEquation(GLenum mode); + + +#endif //GL_BLEND_H \ No newline at end of file diff --git a/project/jni/gl4es/src/gl/const.h b/project/jni/gl4es/src/gl/const.h index b70e5fb53..a4d69a5f7 100755 --- a/project/jni/gl4es/src/gl/const.h +++ b/project/jni/gl4es/src/gl/const.h @@ -61,7 +61,7 @@ #define GL_TEXTURE_LOD_BIAS 0x8501 #define GL_TEXTURE_CUBE_MAP 0x8513 #define GL_TEXTURE_GEN_STR 0x8D60 - +#define GL_CLAMP_TO_BORDER 0x812D // GL_ARB_point_sprite #define GL_POINT_SPRITE 0x8861 @@ -197,6 +197,11 @@ #define GL_LINEAR 0x2601 #define GL_EXP 0x0800 #define GL_EXP2 0x0801 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FOG_COORD GL_FOG_COORDINATE // lighting #define GL_LIGHTING 0x0B50 diff --git a/project/jni/gl4es/src/gl/fog.c b/project/jni/gl4es/src/gl/fog.c new file mode 100755 index 000000000..7d61959c7 --- /dev/null +++ b/project/jni/gl4es/src/gl/fog.c @@ -0,0 +1,54 @@ +#include "fog.h" +#include "../glx/hardext.h" +#include "matrix.h" +#include "matvec.h" + +void gl4es_glFogfv(GLenum pname, const GLfloat* params) { + + if (glstate->list.active) + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_FOG); + rlFogOp(glstate->list.active, pname, params); + return; + } + else flush(); + noerrorShim(); + #define GO(A,name, size) if(memcmp(A glstate->fog.name, params, size)==0) return; else memcpy(A glstate->fog.name, params, size); + switch (pname) { + case GL_FOG_MODE: + GO(&, mode, sizeof(GLfloat)) + break; + case GL_FOG_DENSITY: + GO(&, density, sizeof(GLfloat)) + break; + case GL_FOG_START: + GO(&, start, sizeof(GLfloat)) + break; + case GL_FOG_END: + GO(&, end, sizeof(GLfloat)) + break; + case GL_FOG_INDEX: + GO(&, index, sizeof(GLfloat)) + return; // unsupported on GLES1.1 + case GL_FOG_COLOR: + GO(, color, 4*sizeof(GLfloat)) + break; + case GL_FOG_COORD_SRC: + GO(&, coord_src, sizeof(GLfloat)) + return; // unsupported on GLES1.1 + default: + errorShim(GL_INVALID_ENUM); + return; + } + #undef GO + LOAD_GLES(glFogfv); + gles_glFogfv(pname, params); + errorGL(); +} + + + + + +void glFogfv(GLenum pname, const GLfloat* params) AliasExport("gl4es_glFogfv"); + diff --git a/project/jni/gl4es/src/gl/fog.h b/project/jni/gl4es/src/gl/fog.h new file mode 100755 index 000000000..7710295a1 --- /dev/null +++ b/project/jni/gl4es/src/gl/fog.h @@ -0,0 +1,18 @@ +#include "gl.h" + +#ifndef __FOG_H_ +#define __FOG_H_ + +typedef struct { + GLenum mode; + GLfloat density; + GLfloat start; + GLfloat end; + GLfloat index; + GLfloat color[4]; + GLenum coord_src; +} fog_t; + +void gl4es_glFogfv(GLenum pname, const GLfloat* params); + +#endif \ No newline at end of file diff --git a/project/jni/gl4es/src/gl/framebuffers.c b/project/jni/gl4es/src/gl/framebuffers.c index 5943ec39f..ec967dfec 100755 --- a/project/jni/gl4es/src/gl/framebuffers.c +++ b/project/jni/gl4es/src/gl/framebuffers.c @@ -5,6 +5,14 @@ #ifndef ANDROID #include #endif + +//#define DEBUG +#ifdef DEBUG +#define DBG(a) a +#else +#define DBG(a) +#endif + //extern void* eglGetProcAddress(const char* name); khash_t(dsr) *depthstencil = NULL; @@ -31,7 +39,7 @@ int cap_fbos = 0; int npot(int n); void readfboBegin() { - //printf("readfboBegin, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb); + DBG(printf("readfboBegin, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb);) LOAD_GLES_OES(glBindFramebuffer); if (!(fbo_read || fbo_draw)) return; @@ -42,7 +50,7 @@ void readfboBegin() { } void readfboEnd() { - //printf("readfboEnd, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb); + DBG(printf("readfboEnd, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb);) LOAD_GLES_OES(glBindFramebuffer); if (!(fbo_read || fbo_draw)) return; @@ -53,11 +61,11 @@ void readfboEnd() { } void gl4es_glGenFramebuffers(GLsizei n, GLuint *ids) { + DBG(printf("glGenFramebuffers(%i, %p)\n", n, ids);) LOAD_GLES_OES(glGenFramebuffers); - //printf("glGenFramebuffers(%i, %p)\n", n, ids); GLsizei m = 0; while(globals4es.recyclefbo && (nbr_fbos>0) && (n-m>0)) { - //printf("Recycled 1 FBO\n"); + DBG(printf("Recycled 1 FBO\n");) ids[m++] = old_fbos[--nbr_fbos]; } noerrorShim(); @@ -68,10 +76,10 @@ void gl4es_glGenFramebuffers(GLsizei n, GLuint *ids) { } void gl4es_glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) { - //printf("glDeleteFramebuffers(%i, %p), framebuffers[0]=%u\n", n, framebuffers, framebuffers[0]); + DBG(printf("glDeleteFramebuffers(%i, %p), framebuffers[0]=%u\n", n, framebuffers, framebuffers[0]);) if (glstate->gl_batch) flush(); if (globals4es.recyclefbo) { - //printf("Recycling %i FBOs\n", n); + DBG(printf("Recycling %i FBOs\n", n);) noerrorShim(); if(cap_fbos == 0) { cap_fbos = 16; @@ -91,7 +99,7 @@ void gl4es_glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) { } GLboolean gl4es_glIsFramebuffer(GLuint framebuffer) { - //printf("glIsFramebuffer(%u)\n", framebuffer); + DBG(printf("glIsFramebuffer(%u)\n", framebuffer);) if (glstate->gl_batch) flush(); LOAD_GLES_OES(glIsFramebuffer); @@ -114,14 +122,14 @@ GLenum gl4es_glCheckFramebufferStatus(GLenum target) { GLenum result = gles_glCheckFramebufferStatus(target); #endif #undef BEFORE -//printf("glCheckFramebufferStatus(0x%04X)=0x%04X\n", target, result); +DBG(printf("glCheckFramebufferStatus(0x%04X)=0x%04X\n", target, result);) return result; } void gl4es_glBindFramebuffer(GLenum target, GLuint framebuffer) { - //printf("glBindFramebuffer(%s, %u), list=%s\n", PrintEnum(target), framebuffer, glstate->list.active?"active":"none"); - //PUSH_IF_COMPILING(glBindFramebuffer); + DBG(printf("glBindFramebuffer(%s, %u), list=%s, current_fb=%d (draw=%d, read=%d)\n", PrintEnum(target), framebuffer, glstate->list.active?"active":"none", current_fb, fbo_draw, fbo_read);) if (glstate->gl_batch) flush(); + PUSH_IF_COMPILING(glBindFramebuffer); LOAD_GLES_OES(glBindFramebuffer); LOAD_GLES_OES(glCheckFramebufferStatus); LOAD_GLES(glGetError); @@ -162,8 +170,36 @@ void gl4es_glBindFramebuffer(GLenum target, GLuint framebuffer) { fb_status = gles_glCheckFramebufferStatus(target); } +GLenum ReadDraw_Push(GLenum target) { + if(target==GL_FRAMEBUFFER) + return GL_FRAMEBUFFER; + LOAD_GLES_OES(glBindFramebuffer); + if(target==GL_DRAW_FRAMEBUFFER) { + if(current_fb!=fbo_draw) + gles_glBindFramebuffer(GL_FRAMEBUFFER, fbo_draw); + return GL_FRAMEBUFFER; + } + if(target==GL_READ_FRAMEBUFFER) { + if(current_fb!=fbo_read) + gles_glBindFramebuffer(GL_FRAMEBUFFER, fbo_read); + return GL_FRAMEBUFFER; + } + return target; +} +void ReadDraw_Pop(GLenum target) { + if(target==GL_FRAMEBUFFER) + return; + LOAD_GLES_OES(glBindFramebuffer); + if(target==GL_DRAW_FRAMEBUFFER && current_fb!=fbo_draw) { + gles_glBindFramebuffer(GL_FRAMEBUFFER, (mainfbo_fbo && (current_fb==0))?mainfbo_fbo:current_fb); + } + if(target==GL_READ_FRAMEBUFFER && current_fb!=fbo_read) { + gles_glBindFramebuffer(GL_FRAMEBUFFER, (mainfbo_fbo && (current_fb==0))?mainfbo_fbo:current_fb); + } +} void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + DBG(printf("glFramebufferTexture2D(%s, %s, %s, %u, %i) current_fb=%d (draw=%d, read=%d)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(textarget), texture, level, current_fb, fbo_draw, fbo_read);) static GLuint scrap_tex = 0; static int scrap_width = 0; static int scrap_height = 0; @@ -172,7 +208,6 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta LOAD_GLES_OES(glFramebufferTexture2D); LOAD_GLES(glTexImage2D); LOAD_GLES(glBindTexture); - //printf("glFramebufferTexture2D(%s, %s, %s, %u, %i)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(textarget), texture, level); // Ignore Color attachment 1 .. 9 if ((attachment>=GL_COLOR_ATTACHMENT0+1) && (attachment<=GL_COLOR_ATTACHMENT0+9)) { @@ -227,10 +262,12 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL); if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, oldtex); }*/ - //printf("found texture, glname=%u, size=%ix%i(%ix%i), format/type=0x%04X/0x%04X\n", texture, tex->width, tex->height, tex->nwidth, tex->nheight, tex->format, tex->type); + DBG(printf("found texture, glname=%u, size=%ix%i(%ix%i), format/type=0x%04X/0x%04X\n", texture, tex->width, tex->height, tex->nwidth, tex->nheight, tex->format, tex->type);) } } + GLenum ntarget = ReadDraw_Push(target); + if(attachment==GL_DEPTH_ATTACHMENT /*&& hardext.depthtex==0*/) { noerrorShim(); if (level!=0) return; @@ -241,7 +278,8 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta gl4es_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, twidth, theight); gl4es_glBindRenderbuffer(GL_RENDERBUFFER, 0); errorGL(); - gl4es_glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth); + gl4es_glFramebufferRenderbuffer(ntarget, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth); + ReadDraw_Pop(target); return; } @@ -265,7 +303,8 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta } errorGL(); - gles_glFramebufferTexture2D(target, attachment, textarget, texture, 0); + gles_glFramebufferTexture2D(ntarget, attachment, textarget, texture, 0); + ReadDraw_Pop(target); } void gl4es_glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { @@ -277,17 +316,17 @@ void gl4es_glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum texta } void gl4es_glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) { + DBG(printf("glGenRenderbuffers(%i, %p)\n", n, renderbuffers);) LOAD_GLES_OES(glGenRenderbuffers); - //printf("glGenRenderbuffers(%i, %p)\n", n, renderbuffers); errorGL(); gles_glGenRenderbuffers(n, renderbuffers); } void gl4es_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { + DBG(printf("glFramebufferRenderbuffer(%s, %s, %s, %u)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(renderbuffertarget), renderbuffer);) LOAD_GLES_OES(glFramebufferRenderbuffer); LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv); - //printf("glFramebufferRenderbuffer(%s, %s, %s, %u)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(renderbuffertarget), renderbuffer); //TODO: handle target=READBUFFER or DRAWBUFFER... if (depthstencil && (attachment==GL_STENCIL_ATTACHMENT)) { @@ -304,21 +343,26 @@ void gl4es_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum re noerrorShim(); return; } + + GLenum ntarget = ReadDraw_Push(target); if ((current_fb!=0) && (renderbuffer!=0) && ((attachment==GL_DEPTH_ATTACHMENT) || (attachment==GL_STENCIL_ATTACHMENT))) { GLuint tmp; - gles_glGetFramebufferAttachmentParameteriv(target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tmp); + gles_glGetFramebufferAttachmentParameteriv(ntarget, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tmp); if (tmp==renderbuffer) { noerrorShim(); + ReadDraw_Pop(target); return; } } errorGL(); - gles_glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); + gles_glFramebufferRenderbuffer(ntarget, attachment, renderbuffertarget, renderbuffer); + ReadDraw_Pop(target); } void gl4es_glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) { + DBG(printf("glDeleteRenderbuffer(%d, %p)\n", n, renderbuffers);) if (glstate->gl_batch) flush(); LOAD_GLES_OES(glDeleteRenderbuffers); @@ -345,10 +389,10 @@ void gl4es_glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) { } void gl4es_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { + DBG(printf("glRenderbufferStorage(%s, %s, %i, %i)\n", PrintEnum(target), PrintEnum(internalformat), width, height);) LOAD_GLES_OES(glRenderbufferStorage); LOAD_GLES_OES(glGenRenderbuffers); LOAD_GLES_OES(glBindRenderbuffer); - //printf("glRenderbufferStorage(0x%04X, 0x%04X, %i, %i)\n", target, internalformat, width, height); errorGL(); width = hardext.npot==2?width:npot(width); @@ -401,9 +445,9 @@ void gl4es_glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLen } void gl4es_glBindRenderbuffer(GLenum target, GLuint renderbuffer) { + DBG(printf("glBindRenderbuffer(%s, %u), binded Fbo=%u\n", PrintEnum(target), renderbuffer, current_fb);) if (glstate->gl_batch) flush(); LOAD_GLES_OES(glBindRenderbuffer); - //printf("glBindRenderbuffer(%s, %u), binded Fbo=%u\n", PrintEnum(target), renderbuffer, current_fb); current_rb = renderbuffer; @@ -412,7 +456,7 @@ void gl4es_glBindRenderbuffer(GLenum target, GLuint renderbuffer) { } GLboolean gl4es_glIsRenderbuffer(GLuint renderbuffer) { - //printf("glIsRenderbuffer(%u)\n", renderbuffer); + DBG(printf("glIsRenderbuffer(%u)\n", renderbuffer);) if (glstate->gl_batch) flush(); LOAD_GLES_OES(glIsRenderbuffer); @@ -421,36 +465,40 @@ GLboolean gl4es_glIsRenderbuffer(GLuint renderbuffer) { } void gl4es_glGenerateMipmap(GLenum target) { - //printf("glGenerateMipmap(0x%04X)\n", target); + DBG(printf("glGenerateMipmap(%s)\n", PrintEnum(target));) LOAD_GLES_OES(glGenerateMipmap); errorGL(); - return gles_glGenerateMipmap(target); + if(globals4es.automipmap != 3) + gles_glGenerateMipmap(target); } void gl4es_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) { - //printf("glGetFramebufferAttachmentParameteriv(%s, %s, %s, %p)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(pname), params); + DBG(printf("glGetFramebufferAttachmentParameteriv(%s, %s, %s, %p)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(pname), params);) LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv); + GLenum ntarget = ReadDraw_Push(target); // hack to return DEPTH size - if(target==GL_FRAMEBUFFER && attachment==GL_DEPTH_ATTACHMENT && pname==GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE && hardext.depthtex==0) { + if(ntarget==GL_FRAMEBUFFER && attachment==GL_DEPTH_ATTACHMENT && pname==GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE && hardext.depthtex==0) { noerrorShim(); - gl4es_glGetFramebufferAttachmentParameteriv(target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, params); + gl4es_glGetFramebufferAttachmentParameteriv(ntarget, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, params); if (params) *params = 16; //Depth buffer is 16 on GLES. No check for 24 bits here... + ReadDraw_Pop(target); return; } errorGL(); - return gles_glGetFramebufferAttachmentParameteriv(target, attachment, pname, params); + gles_glGetFramebufferAttachmentParameteriv(ntarget, attachment, pname, params); + ReadDraw_Pop(target); } void gl4es_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint * params) { - //printf("glGetRenderbufferParameteriv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(pname), params); + DBG(printf("glGetRenderbufferParameteriv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(pname), params);) LOAD_GLES_OES(glGetRenderbufferParameteriv); errorGL(); - return gles_glGetRenderbufferParameteriv(target, pname, params); + gles_glGetRenderbufferParameteriv(target, pname, params); } void createMainFBO(int width, int height) { @@ -737,8 +785,8 @@ void gl4es_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, // glCopyPixel of read FBO // set viewport / matrixs // glDraw of write FBO -printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, 0x%04X, 0x%04X)\n", - srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +DBG(printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, 0x%04X, 0x%04X)\n", + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);) } // direct wrapper diff --git a/project/jni/gl4es/src/gl/getter.c b/project/jni/gl4es/src/gl/getter.c index dd80633d8..8afda7dcb 100755 --- a/project/jni/gl4es/src/gl/getter.c +++ b/project/jni/gl4es/src/gl/getter.c @@ -179,6 +179,12 @@ void gl4es_glGetIntegerv(GLenum pname, GLint *params) { case GL_MAX_DRAW_BUFFERS_ARB: // fake... *params = 1; break; + case GL_PACK_ALIGNMENT: + *params = glstate->texture.pack_align; + break; + case GL_UNPACK_ALIGNMENT: + *params = glstate->texture.unpack_align; + break; case GL_UNPACK_ROW_LENGTH: *params = glstate->texture.unpack_row_length; break; @@ -310,39 +316,64 @@ void gl4es_glGetIntegerv(GLenum pname, GLint *params) { for (dummy=0; dummy<4; dummy++) params[dummy]=glstate->light.ambient[dummy]; break; + case GL_FOG_MODE: + *params=glstate->fog.mode; + break; + case GL_FOG_DENSITY: + *params=glstate->fog.density; + break; + case GL_FOG_START: + *params=glstate->fog.start; + break; + case GL_FOG_END: + *params=glstate->fog.end; + break; + case GL_FOG_INDEX: + *params=glstate->fog.start; + break; + case GL_FOG_COLOR: + for (dummy=0; dummy<4; dummy++) + params[dummy]=glstate->fog.color[dummy]; + break; + case GL_FOG_COORD_SRC: + *params=glstate->fog.coord_src; + break; case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB: *params=hardext.maxsize; break; case GL_SHRINK_HINT_GL4ES: *params=globals4es.texshrink; break; - case GL_ALPHAHACK_HINT_GL4ES: + case GL_ALPHAHACK_HINT_GL4ES: *params=globals4es.alphahack; break; - case GL_RECYCLEFBO_HINT_GL4ES: + case GL_RECYCLEFBO_HINT_GL4ES: *params=globals4es.recyclefbo; break; - case GL_MIPMAP_HINT_GL4ES: + case GL_MIPMAP_HINT_GL4ES: *params=globals4es.automipmap; break; - case GL_TEXDUMP_HINT_GL4ES: + case GL_TEXDUMP_HINT_GL4ES: *params=globals4es.texdump; break; - case GL_COPY_HINT_GL4ES: + case GL_COPY_HINT_GL4ES: *params=globals4es.copytex; break; - case GL_NOLUMAPHA_HINT_GL4ES: + case GL_NOLUMAPHA_HINT_GL4ES: *params=globals4es.nolumalpha; break; - case GL_BLENDHACK_HINT_GL4ES: + case GL_BLENDHACK_HINT_GL4ES: *params=globals4es.blendhack; break; - case GL_BATCH_HINT_GL4ES: + case GL_BATCH_HINT_GL4ES: *params=globals4es.batch; break; - case GL_NOERROR_HINT_GL4ES: + case GL_NOERROR_HINT_GL4ES: *params=globals4es.noerror; break; + case GL_AVOID16BITS_HINT_GL4ES: + *params=globals4es.avoid16bits; + break; default: errorGL(); gles_glGetIntegerv(pname, params); @@ -370,6 +401,12 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) { case GL_AUX_BUFFERS: *params = 0; break; + case GL_PACK_ALIGNMENT: + *params = glstate->texture.pack_align; + break; + case GL_UNPACK_ALIGNMENT: + *params = glstate->texture.unpack_align; + break; case GL_UNPACK_ROW_LENGTH: *params = glstate->texture.unpack_row_length; break; @@ -489,6 +526,27 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) { case GL_LIGHT_MODEL_AMBIENT: memcpy(params, glstate->light.ambient, 4*sizeof(GLfloat)); break; + case GL_FOG_MODE: + *params=glstate->fog.mode; + break; + case GL_FOG_DENSITY: + *params=glstate->fog.density; + break; + case GL_FOG_START: + *params=glstate->fog.start; + break; + case GL_FOG_END: + *params=glstate->fog.end; + break; + case GL_FOG_INDEX: + *params=glstate->fog.start; + break; + case GL_FOG_COLOR: + memcpy(params, glstate->fog.color, 4*sizeof(GLfloat)); + break; + case GL_FOG_COORD_SRC: + *params=glstate->fog.coord_src; + break; case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB: *params=hardext.maxsize; break; @@ -531,6 +589,9 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) { case GL_BEGINEND_HINT_GL4ES: *params=globals4es.beginend; break; + case GL_AVOID16BITS_HINT_GL4ES: + *params=globals4es.avoid16bits; + break; default: errorGL(); gles_glGetFloatv(pname, params); diff --git a/project/jni/gl4es/src/gl/gl.c b/project/jni/gl4es/src/gl/gl.c index 0247bdb15..bb0e8e978 100755 --- a/project/jni/gl4es/src/gl/gl.c +++ b/project/jni/gl4es/src/gl/gl.c @@ -53,6 +53,14 @@ void* NewGLState(void* shared_glstate) { glvao->array = 0; glstate->defaultvao = glvao; } + // initialize gllists + { + khint_t k; + int ret; + khash_t(gllisthead) *list = glstate->headlists = kh_init(gllisthead); + kh_put(gllisthead, list, 1, &ret); + kh_del(gllisthead, list, 1); + } // Bind defaults... glstate->vao = glstate->defaultvao; @@ -64,6 +72,10 @@ void* NewGLState(void* shared_glstate) { glstate->raster.raster_zoomx=1.0f; glstate->raster.raster_zoomy=1.0f; + // pack & unpack alignment + glstate->texture.pack_align = 4; + glstate->texture.unpack_align = 4; + // init the matrix tracking init_matrix(glstate); @@ -95,7 +107,12 @@ void* NewGLState(void* shared_glstate) { 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)); - + // Fog + glstate->fog.mode = GL_EXP; + glstate->fog.density = 1.0f; + glstate->fog.end = 1.0f; + glstate->fog.coord_src = GL_FRAGMENT_DEPTH; + // Raster for(int i=0; i<4; i++) glstate->raster.raster_scale[i] = 1.0f; LOAD_GLES(glGetFloatv); @@ -117,18 +134,19 @@ void DeleteGLState(void* oldstate) { glstate = NULL; - #define free_hashmap(T, N, K) \ + #define free_hashmap(T, N, K, F) \ { \ T *m; \ kh_foreach_value(state->N, m, \ - free(m); \ + F(m); \ ) \ kh_destroy(K, state->N); \ } - free_hashmap(glvao_t, vaos, glvao); - free_hashmap(glbuffer_t, buffers, buff); - free_hashmap(glquery_t, queries, queries); - free_hashmap(gltexture_t, texture.list, tex); + free_hashmap(glvao_t, vaos, glvao, free); + free_hashmap(glbuffer_t, buffers, buff, free); + free_hashmap(glquery_t, queries, queries, free); + free_hashmap(gltexture_t, texture.list, tex, free); + free_hashmap(renderlist_t, headlists, gllisthead, free_renderlist); #undef free_hashmap // free eval maps #define freemap(dims, name) \ @@ -143,12 +161,7 @@ void DeleteGLState(void* oldstate) { freemap(2, vertex3); freemap(2, vertex4); freemap(2, index); freemap(2, color4); freemap(2, normal); freemap(2, texture1); freemap(2, texture2); freemap(2, texture3); freemap(2, texture4); #undef freemap - // free lists - if(state->lists) { - for (int i=0; ilist.count; i++) - free_renderlist(state->lists[i]); - free(state->lists); - } + // free active list if(state->list.active) free_renderlist(state->list.active); // free matrix stack @@ -192,22 +205,15 @@ void gl_init() { #endif static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { - #define proxy_enable(constant, name) \ + #define proxy_GO(constant, name) \ case constant: glstate->enable.name = enable; next(cap); break - #define enable(constant, name) \ + #define GO(constant, name) \ case constant: glstate->enable.name = enable; break; - #define proxy_clientenable(constant, name) \ + #define proxy_clientGO(constant, name) \ case constant: glstate->vao->name = enable; next(cap); break - #define clientenable(constant, name) \ + #define clientGO(constant, name) \ case constant: glstate->vao->name = enable; break; - // TODO: maybe could be weird behavior if someone tried to: - // 1. enable GL_TEXTURE_1D - // 2. enable GL_TEXTURE_2D - // 3. disable GL_TEXTURE_1D - // 4. render. GL_TEXTURE_2D would be disabled. - // cap = map_tex_target(cap); - // Alpha Hack if (globals4es.alphahack && (cap==GL_ALPHA_TEST) && enable) { if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]) @@ -223,8 +229,8 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { glstate->enable.texture[glstate->texture.active] &= ~(1<enable.texture[glstate->texture.active] |= (1<texture.active]); - enable(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active]); - enable(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active]); - enable(GL_TEXTURE_GEN_Q, texgen_q[glstate->texture.active]); - enable(GL_LINE_STIPPLE, line_stipple); + GO(GL_TEXTURE_GEN_S, texgen_s[glstate->texture.active]); + GO(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active]); + GO(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active]); + GO(GL_TEXTURE_GEN_Q, texgen_q[glstate->texture.active]); + GO(GL_LINE_STIPPLE, line_stipple); // point sprite - proxy_enable(GL_POINT_SPRITE, pointsprite); + proxy_GO(GL_POINT_SPRITE, pointsprite); // Secondary color - enable(GL_COLOR_SUM, color_sum); - clientenable(GL_SECONDARY_COLOR_ARRAY, secondary_array); + GO(GL_COLOR_SUM, color_sum); + clientGO(GL_SECONDARY_COLOR_ARRAY, secondary_array); // for glDrawArrays - 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[glstate->texture.client]); + clientGO(GL_VERTEX_ARRAY, vertex_array); + clientGO(GL_NORMAL_ARRAY, normal_array); + clientGO(GL_COLOR_ARRAY, color_array); + clientGO(GL_TEXTURE_COORD_ARRAY, tex_coord_array[glstate->texture.client]); // Texture 1D and 3D case GL_TEXTURE_1D: @@ -282,10 +288,10 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { default: errorGL(); next(cap); break; } - #undef proxy_enable - #undef enable - #undef proxy_clientenable - #undef clientenable + #undef proxy_GO + #undef GO + #undef proxy_clientGO + #undef clientGO } int Cap2BatchState(GLenum cap) { @@ -318,6 +324,11 @@ void gl4es_glEnable(GLenum cap) { if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]->streamed) cap = GL_TEXTURE_STREAM_IMG; } + if (globals4es.texstream && (cap==GL_TEXTURE_RECTANGLE_ARB)) { + if (glstate->texture.bound[glstate->texture.active][ENABLED_TEXTURE_RECTANGLE]) + if (glstate->texture.bound[glstate->texture.active][ENABLED_TEXTURE_RECTANGLE]->streamed) + cap = GL_TEXTURE_STREAM_IMG; + } #endif LOAD_GLES(glEnable); proxy_glEnable(cap, true, gles_glEnable); @@ -337,12 +348,18 @@ void gl4es_glDisable(GLenum cap) { } PUSH_IF_COMPILING(glDisable) +#ifdef TEXSTREAM if (globals4es.texstream && (cap==GL_TEXTURE_2D)) { if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]) if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]->streamed) cap = GL_TEXTURE_STREAM_IMG; } - + if (globals4es.texstream && (cap==GL_TEXTURE_RECTANGLE_ARB)) { + if (glstate->texture.bound[glstate->texture.active][ENABLED_TEXTURE_RECTANGLE]) + if (glstate->texture.bound[glstate->texture.active][ENABLED_TEXTURE_RECTANGLE]->streamed) + cap = GL_TEXTURE_STREAM_IMG; + } +#endif LOAD_GLES(glDisable); proxy_glEnable(cap, false, gles_glDisable); } @@ -1051,20 +1068,25 @@ void gl4es_glEnd() { for (int a=0; aenable.texture[a] && ((glstate->list.active->tex[a]==0) && !(glstate->enable.texgen_s[a] || glstate->texture.pscoordreplace[a]))) rlMultiTexCoord4f(glstate->list.active, GL_TEXTURE0+a, glstate->texcoord[a][0], glstate->texcoord[a][1], glstate->texcoord[a][2], glstate->texcoord[a][3]); + int withColor = 0; // render if we're not in a display list if (!(glstate->list.compiling || glstate->gl_batch) && (!(globals4es.beginend) || (glstate->polygon_mode==GL_LINE))) { renderlist_t *mylist = glstate->list.active; + withColor = (mylist->color!=NULL); glstate->list.active = NULL; mylist = end_renderlist(mylist); draw_renderlist(mylist); free_renderlist(mylist); } else { if(!(glstate->list.compiling || glstate->gl_batch)) { + withColor = (glstate->list.active->color!=NULL); glstate->list.pending = 1; NewStage(glstate->list.active, STAGE_POSTDRAW); } else glstate->list.active = extend_renderlist(glstate->list.active); } + if(withColor) + gl4es_glColor4f(glstate->color[0], glstate->color[1], glstate->color[2], glstate->color[3]); noerrorShim(); } void glEnd() AliasExport("gl4es_glEnd"); @@ -1272,9 +1294,12 @@ void glUnlockArraysEXT() AliasExport("gl4es_glUnlockArrays"); // display lists static renderlist_t *gl4es_glGetList(GLuint list) { - if (glIsList(list)) - return glstate->lists[list - 1]; - + khint_t k; + int ret; + khash_t(gllisthead) *lists = glstate->headlists; + k = kh_get(gllisthead, lists, list); + if (k != kh_end(lists)) + return kh_value(lists, k); return NULL; } @@ -1284,18 +1309,18 @@ GLuint gl4es_glGenLists(GLsizei range) { return 0; } noerrorShim(); + khint_t k; + int ret; + khash_t(gllisthead) *lists = glstate->headlists; int start = glstate->list.count; - if (glstate->lists == NULL) { - glstate->list.cap += range + 100; - glstate->lists = malloc(glstate->list.cap * sizeof(uintptr_t)); - } else if (glstate->list.count + range > glstate->list.cap) { - glstate->list.cap += range + 100; - glstate->lists = realloc(glstate->lists, glstate->list.cap * sizeof(uintptr_t)); - } glstate->list.count += range; for (int i = 0; i < range; i++) { - glstate->lists[start+i] = NULL; + k = kh_get(gllisthead, lists, start+i); + if (k == kh_end(lists)){ + k = kh_put(gllisthead, lists, start+i, &ret); + kh_value(lists, k) = NULL; // create an empty gllist + } } return start + 1; } @@ -1306,8 +1331,16 @@ void gl4es_glNewList(GLuint list, GLenum mode) { errorShim(GL_INVALID_VALUE); if (list==0) return; - if (! glIsList(list)) - return; + { + khint_t k; + int ret; + khash_t(gllisthead) *lists = glstate->headlists; + k = kh_get(gllisthead, lists, list); + if (k == kh_end(lists)){ + k = kh_put(gllisthead, lists, list, &ret); + kh_value(lists, k) = NULL; + } + } noerrorShim(); if (glstate->gl_batch) { glstate->gl_batch = 0; @@ -1324,10 +1357,20 @@ void glNewList(GLuint list, GLenum mode) AliasExport("gl4es_glNewList"); void gl4es_glEndList() { noerrorShim(); GLuint list = glstate->list.name; + khash_t(gllisthead) *lists = glstate->headlists; + khint_t k; + { + int ret; + k = kh_get(gllisthead, lists, list); + if (k == kh_end(lists)){ + k = kh_put(gllisthead, lists, list, &ret); + kh_value(lists, k) = NULL; + } + } if (glstate->list.compiling) { // Free the previous list if it exist... - free_renderlist(glstate->lists[list - 1]); - glstate->lists[list - 1] = GetFirst(glstate->list.active); + free_renderlist(kh_value(lists, k)); + kh_value(lists, k) = GetFirst(glstate->list.active); glstate->list.compiling = false; end_renderlist(glstate->list.active); glstate->list.active = NULL; @@ -1403,13 +1446,19 @@ void gl4es_glDeleteList(GLuint list) { if(glstate->gl_batch) { flush(); } - renderlist_t *l = gl4es_glGetList(list); - if (l) { - free_renderlist(l); - glstate->lists[list-1] = NULL; + renderlist_t *gllist = NULL; + { + khint_t k; + int ret; + khash_t(gllisthead) *lists = glstate->headlists; + k = kh_get(gllisthead, lists, list); + renderlist_t *gllist = NULL; + if (k != kh_end(lists)){ + gllist = kh_value(lists, k); + free_renderlist(gllist); + kh_del(gllisthead, lists, k); + } } - - // lists just grow upwards, maybe use a better storage mechanism? } void gl4es_glDeleteLists(GLuint list, GLsizei range) { @@ -1428,9 +1477,12 @@ void glListBase(GLuint base) AliasExport("gl4es_glListBase"); GLboolean gl4es_glIsList(GLuint list) { noerrorShim(); - if (list - 1 < glstate->list.count) { + khint_t k; + int ret; + khash_t(gllisthead) *lists = glstate->headlists; + k = kh_get(gllisthead, lists, list); + if (k != kh_end(lists)) return true; - } return false; } GLboolean glIsList(GLuint list) AliasExport("gl4es_glIsList"); @@ -1463,122 +1515,6 @@ void gl4es_glPolygonMode(GLenum face, GLenum mode) { } void glPolygonMode(GLenum face, GLenum mode) AliasExport("gl4es_glPolygonMode"); -void gl4es_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - PUSH_IF_COMPILING(glBlendColor); - LOAD_GLES_OES(glBlendColor); - if (gles_glBlendColor) - gles_glBlendColor(red, green, blue, alpha); - else { - static int test = 1; - if (test) { - LOGD("stub glBlendColor(%f, %f, %f, %f)\n", red, green, blue, alpha); - test = 0; - } - } -} -void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor"); -void glBlendColorEXT(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor"); -void glBlendColorARB(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor"); - -void gl4es_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) -{ - PUSH_IF_COMPILING(glBlendFuncSeparate); - LOAD_GLES_OES(glBlendFuncSeparate); -#ifdef ODROID - if(gles_glBlendFuncSeparate) -#endif - gles_glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); -} -void glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) AliasExport("gl4es_glBlendFuncSeparate"); -void glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) AliasExport("gl4es_glBlendFuncSeparate"); - -void gl4es_glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) { - PUSH_IF_COMPILING(glBlendEquationSeparate); - LOAD_GLES_OES(glBlendEquationSeparate); -#ifdef ODROID - if(gles_glBlendEquationSeparate) -#endif - gles_glBlendEquationSeparate(modeRGB, modeA); -} -void glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) AliasExport("gl4es_glBlendEquationSeparate"); -void glBlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) AliasExport("gl4es_glBlendEquationSeparate"); - -void gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor) { - if (glstate->list.active) - if (!glstate->list.compiling && glstate->gl_batch) { - if ((glstate->statebatch.blendfunc_s == sfactor) && (glstate->statebatch.blendfunc_d == dfactor)) - return; // nothing to do... - if (!glstate->statebatch.blendfunc_s) { - glstate->statebatch.blendfunc_s = sfactor; - glstate->statebatch.blendfunc_d = dfactor; - } - } - - PUSH_IF_COMPILING(glBlendFunc) - LOAD_GLES(glBlendFunc); - LOAD_GLES_OES(glBlendFuncSeparate); - errorGL(); - // There are some limitations in GLES1.1 Blend functions - switch(sfactor) { - case GL_SRC_COLOR: - if (gles_glBlendFuncSeparate) { - gles_glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); - return; - } - sfactor = GL_ONE; // approx... - break; - case GL_ONE_MINUS_SRC_COLOR: - if (gles_glBlendFuncSeparate) { - gles_glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); - return; - } - sfactor = GL_ONE; // not sure it make sense... - break; - // here, we need support for glBlendColor... - case GL_CONSTANT_COLOR: - case GL_CONSTANT_ALPHA: - sfactor = GL_ONE; - break; - case GL_ONE_MINUS_CONSTANT_COLOR: - case GL_ONE_MINUS_CONSTANT_ALPHA: - sfactor = GL_ZERO; - break; - default: - break; - } - - switch(dfactor) { - case GL_DST_COLOR: - sfactor = GL_ONE; // approx... - break; - case GL_ONE_MINUS_DST_COLOR: - sfactor = GL_ZERO; // not sure it make sense... - break; - // here, we need support for glBlendColor... - case GL_CONSTANT_COLOR: - case GL_CONSTANT_ALPHA: - sfactor = GL_ONE; - break; - case GL_ONE_MINUS_CONSTANT_COLOR: - case GL_ONE_MINUS_CONSTANT_ALPHA: - sfactor = GL_ZERO; - break; - default: - break; - } - - if ((globals4es.blendhack) && (sfactor==GL_SRC_ALPHA) && (dfactor==GL_ONE)) { - // special case, as seen in Xash3D, but it breaks torus_trooper, so behind a parameter - sfactor = GL_ONE; - } - -#ifdef ODROID - if(gles_glBlendFunc) -#endif - gles_glBlendFunc(sfactor, dfactor); -} -void glBlendFunc(GLenum sfactor, GLenum dfactor) AliasExport("gl4es_glBlendFunc"); - void gl4es_glStencilMaskSeparate(GLenum face, GLuint mask) { // fake function..., call it only for front or front_and_back, just ignore back (crappy, I know) @@ -1647,21 +1583,6 @@ void gl4es_glFinish() { } void glFinish() AliasExport("gl4es_glFinish"); -void gl4es_glFogfv(GLenum pname, const GLfloat* params) { - - if (glstate->list.active) - if (glstate->list.compiling || glstate->gl_batch) { - NewStage(glstate->list.active, STAGE_FOG); - rlFogOp(glstate->list.active, pname, params); - return; - } - else flush(); - - LOAD_GLES(glFogfv); - gles_glFogfv(pname, params); -} -void glFogfv(GLenum pname, const GLfloat* params) AliasExport("gl4es_glFogfv"); - void gl4es_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) { static bool warning = false; if(!warning) { diff --git a/project/jni/gl4es/src/gl/gl.h b/project/jni/gl4es/src/gl/gl.h index b588e0bcd..5faf61b04 100755 --- a/project/jni/gl4es/src/gl/gl.h +++ b/project/jni/gl4es/src/gl/gl.h @@ -369,6 +369,7 @@ static inline const GLboolean valid_vertex_type(GLenum type) { #include "texture.h" #include "array.h" #include "framebuffers.h" +#include "blend.h" const GLubyte *gl4es_glGetString(GLenum name); void gl4es_glGetIntegerv(GLenum pname, GLint *params); @@ -415,10 +416,6 @@ void gl4es_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, cons void gl4es_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer); void gl4es_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer); void gl4es_glGetPointerv(GLenum pname, GLvoid* *params); -void gl4es_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -void gl4es_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -void gl4es_glBlendEquationSeparate(GLenum modeRGB, GLenum modeA); -void gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor); void gl4es_glFlush(); void gl4es_glFinish(); void gl4es_glFogfv(GLenum pname, const GLfloat* params); diff --git a/project/jni/gl4es/src/gl/hint.c b/project/jni/gl4es/src/gl/hint.c index 9ec81015c..359e0915b 100755 --- a/project/jni/gl4es/src/gl/hint.c +++ b/project/jni/gl4es/src/gl/hint.c @@ -89,6 +89,12 @@ void gl4es_glHint(GLenum pname, GLenum mode) { globals4es.beginend = mode; else errorShim(GL_INVALID_ENUM); + case GL_AVOID16BITS_HINT_GL4ES: + if (mode<=1) + globals4es.avoid16bits = mode; + else + errorShim(GL_INVALID_ENUM); + break; default: errorGL(); gles_glHint(pname, mode); diff --git a/project/jni/gl4es/src/gl/init.c b/project/jni/gl4es/src/gl/init.c index ae4e2c17b..57ce35094 100755 --- a/project/jni/gl4es/src/gl/init.c +++ b/project/jni/gl4es/src/gl/init.c @@ -86,14 +86,14 @@ void initialize_gl4es() { } if (env_fb && strcmp(env_fb, "2") == 0) { SHUT(LOGD("LIBGL: using framebuffer + fbo\n")); - globals4es.usefb = true; - globals4es.usefbo = true; + globals4es.usefb = 1; + globals4es.usefbo = 1; } #ifndef ANDROID if (env_fb && strcmp(env_fb, "3") == 0) { SHUT(LOGD("LIBGL: using pbuffer\n")); globals4es.usefb = 1; - globals4es.usepbuffer = true; + globals4es.usepbuffer = 1; } #endif env(LIBGL_FPS, globals4es.showfps, "fps counter enabled"); @@ -283,6 +283,7 @@ void initialize_gl4es() { SHUT(LOGD("LIBGL: Try hard to merge subsequent glBegin/glEnd blocks, even if there is a glColor / glNormal or Matrix operations in between\n")); } } + env(LIBGL_AVOID16BITS, globals4es.avoid16bits, "Avoid 16bits textures"); char cwd[1024]; if (getcwd(cwd, sizeof(cwd))!= NULL) diff --git a/project/jni/gl4es/src/gl/init.h b/project/jni/gl4es/src/gl/init.h index 3ec6f5fa4..5c1bc863d 100755 --- a/project/jni/gl4es/src/gl/init.h +++ b/project/jni/gl4es/src/gl/init.h @@ -41,6 +41,7 @@ typedef struct _globals4es { int texmat; int novaocache; int beginend; + int avoid16bits; char version[50]; } globals4es_t; diff --git a/project/jni/gl4es/src/gl/light.c b/project/jni/gl4es/src/gl/light.c index 72dbc139b..9b0043a44 100755 --- a/project/jni/gl4es/src/gl/light.c +++ b/project/jni/gl4es/src/gl/light.c @@ -173,16 +173,23 @@ void gl4es_glLightf(GLenum light, GLenum pname, const GLfloat params) { } void gl4es_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { - ERROR_IN_BEGIN // that not true, but don't know how to handle it if(glstate->list.active) - if (glstate->list.compiling || glstate->gl_batch) { - //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(); - return; - } else flush(); - + if(glstate->list.begin) { + // if a glMaterialfv is called inside a glBegin/glEnd block + // then use rlMaterial to store in current list the material wanted + // as if the material was asked before the glBegin() + // It's not real behavour, but it's better then nothing + rlMaterialfv(glstate->list.active, face, pname, params); + noerrorShim(); + return; + } else { + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_MATERIAL); + rlMaterialfv(glstate->list.active, face, pname, params); + noerrorShim(); + return; + } else flush(); + } if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) { errorShim(GL_INVALID_ENUM); return; diff --git a/project/jni/gl4es/src/gl/list.c b/project/jni/gl4es/src/gl/list.c index c0d85f5d9..1b93fad71 100755 --- a/project/jni/gl4es/src/gl/list.c +++ b/project/jni/gl4es/src/gl/list.c @@ -500,7 +500,7 @@ renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a) a->shared_indices = (int*)malloc(sizeof(int)); *a->shared_indices = 0; } - if(a->calls.cap && !a->shared_calls) { + if(a->calls.len && !a->shared_calls) { a->shared_calls = (int*)malloc(sizeof(int)); *a->shared_calls = 0; } @@ -523,7 +523,7 @@ renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a) } } } - if (list->calls.cap > 0) { + if (list->calls.len > 0) { ++(*list->shared_calls); /* list->calls.calls = (packed_call_t**)malloc(sizeof(packed_call_t*)*a->calls.cap); @@ -548,7 +548,6 @@ renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a) if(list->len) { ++(*list->shared_arrays); } - #undef PROCESS if(list->ilen) { ++(*list->shared_indices); } @@ -603,7 +602,7 @@ void free_renderlist(renderlist_t *list) { renderlist_t *next; do { - if ((list->calls.cap > 0) && (!list->shared_calls || ((*list->shared_calls)--)==0)) { + if ((list->calls.len > 0) && (!list->shared_calls || ((*list->shared_calls)--)==0)) { if(list->shared_calls) free(list->shared_calls); for (int i = 0; i < list->calls.len; i++) { free(list->calls.calls[i]); @@ -971,11 +970,11 @@ void draw_renderlist(renderlist_t *list) { static GLfloat *texgened[MAX_TEX] = {0}; static int texgenedsz[MAX_TEX] = {0}; int use_texgen[MAX_TEX] = {0}; - #define TEXTURE(A) if (cur_tex!=A) {gl4es_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;} old_tex = glstate->texture.client; GLuint cur_tex = old_tex; - #define RS(A, len) if(texgenedsz[A]enable.texture[a]) { const GLint itarget = get_target(glstate->enable.texture[a]); @@ -1003,9 +1002,6 @@ void draw_renderlist(renderlist_t *list) { } } } - } - #undef RS - for (int a=0; atex[a] || (use_texgen[a] && !needclean[a]))/* && glstate->enable.texture[a]*/) { TEXTURE(a); if(!glstate->clientstate.tex_coord_array[a]) { @@ -1028,7 +1024,8 @@ void draw_renderlist(renderlist_t *list) { } } if (glstate->texture.client != old_tex) TEXTURE(old_tex); - #undef TEXTURE + #undef RS + #undef TEXTURE GLenum mode; mode = list->mode; if ((glstate->polygon_mode == GL_LINE) && (mode>=GL_TRIANGLES)) diff --git a/project/jni/gl4es/src/gl/list.h b/project/jni/gl4es/src/gl/list.h index ead2930cd..08317e921 100755 --- a/project/jni/gl4es/src/gl/list.h +++ b/project/jni/gl4es/src/gl/list.h @@ -7,7 +7,6 @@ typedef enum { STAGE_NONE = 0, STAGE_PUSH, STAGE_POP, - STAGE_CALLLIST, STAGE_GLCALL, STAGE_RENDER, STAGE_FOG, @@ -33,7 +32,6 @@ static int StageExclusive[] = { 0, // STAGE_NONE 1, // STAGE_PUSH 1, // STAGE_POP - 1, // STAGE_CALLLIST 0, // STAGE_GLCALL 1, // STAGE_RENDER 1, // STAGE_FOG @@ -182,6 +180,8 @@ typedef struct _renderlist_t { GLboolean open; } renderlist_t; +KHASH_MAP_INIT_INT(gllisthead, renderlist_t*) + #define DEFAULT_CALL_LIST_CAPACITY 20 #define DEFAULT_RENDER_LIST_CAPACITY 64 diff --git a/project/jni/gl4es/src/gl/loader.h b/project/jni/gl4es/src/gl/loader.h index 233a0a003..f544a5e0a 100755 --- a/project/jni/gl4es/src/gl/loader.h +++ b/project/jni/gl4es/src/gl/loader.h @@ -30,6 +30,17 @@ void *open_lib(const char **names, const char *override); WARN_NULL(lib##_##name); \ } \ } + +#define LOAD_RAW_SILENT(lib, name, ...) \ + { \ + static bool first = true; \ + if (first) { \ + first = false; \ + if (lib != NULL) { \ + lib##_##name = (name##_PTR)__VA_ARGS__; \ + } \ + } \ + } #endif #define LOAD_LIB(lib, name) DEFINE_RAW(lib, name); LOAD_RAW(lib, name, dlsym(lib, #name)) @@ -55,4 +66,11 @@ void *open_lib(const char **names, const char *override); LOAD_RAW(gles, name, egl_eglGetProcAddress(#name"EXT")); \ } +#define LOAD_GLES_OR_OES(name) \ + DEFINE_RAW(gles, name); \ + { \ + LOAD_EGL(eglGetProcAddress); \ + LOAD_RAW_SILENT(gles, name, (egl_eglGetProcAddress(#name"OES")!=NULL)?(void*)egl_eglGetProcAddress(#name"OES"):(void*)dlsym(gles, #name)); \ + } + #endif diff --git a/project/jni/gl4es/src/gl/pixel.c b/project/jni/gl4es/src/gl/pixel.c index 6aa208d0a..7288d4e20 100755 --- a/project/jni/gl4es/src/gl/pixel.c +++ b/project/jni/gl4es/src/gl/pixel.c @@ -656,12 +656,17 @@ bool quarter_pixel(const GLvoid *src[16], bool pixel_convert(const GLvoid *src, GLvoid **dst, GLuint width, GLuint height, GLenum src_format, GLenum src_type, - GLenum dst_format, GLenum dst_type, GLuint stride) { + GLenum dst_format, GLenum dst_type, GLuint stride, GLuint align) { const colorlayout_t *src_color, *dst_color; GLuint pixels = width * height; - GLuint dst_size = pixels * pixel_sizeof(dst_format, dst_type); - GLuint dst_width = ((stride?stride:width) - width) * pixel_sizeof(dst_format, dst_type); - GLuint src_width = width * pixel_sizeof(src_format, src_type); + if(src_type==GL_UNSIGNED_INT_8_8_8_8_REV) src_type=GL_UNSIGNED_BYTE; + if(dst_type==GL_UNSIGNED_INT_8_8_8_8_REV) dst_type=GL_UNSIGNED_BYTE; + + GLuint dst_size = height * widthalign(width*pixel_sizeof(dst_format, dst_type), align); + GLuint dst_width2 = widthalign((stride?stride:width) * pixel_sizeof(dst_format, dst_type), align); + GLuint dst_width = dst_width2 - (width * pixel_sizeof(dst_format, dst_type)); + GLuint src_width = widthalign(width * pixel_sizeof(src_format, src_type), align); + GLuint src_widthadj = src_width -(width * pixel_sizeof(src_format, src_type)); //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); @@ -679,7 +684,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, *dst = malloc(dst_size); if (stride) // for in-place conversion for (int yy=0; yy RGBA / UNSIGNED_BYTE if ((((src_format == GL_BGRA) && (dst_format == GL_RGBA)) || ((src_format == GL_RGBA) && (dst_format == GL_BGRA))) - && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) { GLuint tmp; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -703,8 +708,8 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } @@ -721,13 +726,13 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // RGBA -> LA - if ((src_format == GL_RGBA) && (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))) { + if ((src_format == GL_RGBA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) { GLuint tmp; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -737,13 +742,13 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // BGRA -> LA - 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))) { + if ((src_format == GL_BGRA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) { GLuint tmp; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -753,13 +758,13 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // RGB(A) -> L - if (((src_format == GL_RGBA)||(src_format == GL_RGB)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + if (((src_format == GL_RGBA)||(src_format == GL_RGB)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) { GLuint tmp; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -769,13 +774,13 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // BGR(A) -> L - if (((src_format == GL_BGRA)||(src_format == GL_BGR)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + if (((src_format == GL_BGRA)||(src_format == GL_BGR)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) { GLuint tmp; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -785,13 +790,13 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // BGR(A) -> RGB - if (((src_format == GL_BGR)||(src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + if (((src_format == GL_BGR)||(src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { ((char*)dst_pos)[0] = ((char*)src_pos)[2]; @@ -800,13 +805,29 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; + } + return true; + } + // BGR -> RGBA + if (((src_format == GL_BGR)) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) { + 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]; + ((char*)dst_pos)[3] = 255; + src_pos += src_stride; + dst_pos += dst_stride; + } + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // RGBA -> RGB - if ((src_format == GL_RGBA) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + if ((src_format == GL_RGBA) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { ((char*)dst_pos)[0] = ((char*)src_pos)[0]; @@ -815,86 +836,86 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // RGB(A) -> RGB565 - if (((src_format == GL_RGB)||(src_format == GL_RGBA)) && (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))) { + if (((src_format == GL_RGB)||(src_format == GL_RGBA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { *(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[2]&0xf8)>>(3)) | ((GLushort)(((char*)src_pos)[1]&0xfc)<<(5-2)) | ((GLushort)(((char*)src_pos)[0]&0xf8)<<(11-3)); src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // BGR(A) -> RGB565 - if (((src_format == GL_BGR) || (src_format == GL_BGRA)) && (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))) { + if (((src_format == GL_BGR) || (src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { *(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[0]&0xf8)>>(3)) | ((GLushort)(((char*)src_pos)[1]&0xfc)<<(5-2)) | ((GLushort)(((char*)src_pos)[2]&0xf8)<<(11-3)); src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // RGBA -> RGBA5551 - if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { *(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[2]&0xf8)>>(3-1)) | ((GLushort)(((char*)src_pos)[1]&0xf8)<<(5-2)) | ((GLushort)(((char*)src_pos)[0]&0xf8)<<(10-2)) | ((GLushort)(((char*)src_pos)[3])>>15); src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // BGRA -> RGBA5551 - if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { *(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[0]&0xf8)>>(3-1)) | ((GLushort)(((char*)src_pos)[1]&0xf8)<<(5-2)) | ((GLushort)(((char*)src_pos)[2]&0xf8)<<(10-2)) | ((GLushort)(((char*)src_pos)[3])>>15); src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // RGBA -> RGBA4444 - if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { *(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[3]&0xf0))>>(4) | ((GLushort)(((char*)src_pos)[2]&0xf0)) | ((GLushort)(((char*)src_pos)[1]&0xf0))<<(4) | ((GLushort)(((char*)src_pos)[0]&0xf0))<<(8); src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } // BGRA -> RGBA4444 - if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { *(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[3]&0xf0)>>(4)) | ((GLushort)(((char*)src_pos)[0]&0xf0)) | ((GLushort)(((char*)src_pos)[1]&0xf0)<<(4)) | ((GLushort)(((char*)src_pos)[2]&0xf0)<<(8)); src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } @@ -910,8 +931,8 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } @@ -927,8 +948,8 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } @@ -944,8 +965,8 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, src_pos += src_stride; dst_pos += dst_stride; } - if (stride) - dst_pos += dst_width; + dst_pos += dst_width; + src_pos += src_widthadj; } return true; } @@ -1165,7 +1186,8 @@ bool pixel_doublescale(const GLvoid *old, GLvoid **new, } bool pixel_to_ppm(const GLvoid *pixels, GLuint width, GLuint height, - GLenum format, GLenum type, GLuint name) { + GLenum format, GLenum type, GLuint name, GLuint align) { + // this function should be redone, using write_png from STB for example if (! pixels) return false; @@ -1175,7 +1197,7 @@ bool pixel_to_ppm(const GLvoid *pixels, GLuint width, GLuint height, if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { src = (GLvoid*)pixels; } else { - if (! pixel_convert(pixels, (GLvoid **)&src, width, height, format, type, GL_RGB, GL_UNSIGNED_BYTE, 0)) { + if (! pixel_convert(pixels, (GLvoid **)&src, width, height, format, type, GL_RGB, GL_UNSIGNED_BYTE, 0, align)) { return false; } } diff --git a/project/jni/gl4es/src/gl/pixel.h b/project/jni/gl4es/src/gl/pixel.h index 798d856b7..26b351623 100755 --- a/project/jni/gl4es/src/gl/pixel.h +++ b/project/jni/gl4es/src/gl/pixel.h @@ -12,10 +12,12 @@ typedef struct { GLfloat r, g, b, a; } pixel_t; +#define widthalign(width, align) ((width+(align-1))&(~(align-1))) + bool pixel_convert(const GLvoid *src, GLvoid **dst, GLuint width, GLuint height, GLenum src_format, GLenum src_type, - GLenum dst_format, GLenum dst_type, GLuint stride); + GLenum dst_format, GLenum dst_type, GLuint stride, GLuint align); bool pixel_transform(const GLvoid *src, GLvoid **dst, GLuint width, GLuint height, @@ -45,6 +47,6 @@ bool pixel_doublescale(const GLvoid *src, GLvoid **dst, bool pixel_to_ppm(const GLvoid *pixels, GLuint width, GLuint height, - GLenum format, GLenum type, GLuint name); + GLenum format, GLenum type, GLuint name, GLuint align); #endif diff --git a/project/jni/gl4es/src/gl/raster.c b/project/jni/gl4es/src/gl/raster.c index 99dd80c70..1e629f032 100755 --- a/project/jni/gl4es/src/gl/raster.c +++ b/project/jni/gl4es/src/gl/raster.c @@ -343,7 +343,7 @@ void gl4es_glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLsizei bmp_width = (glstate->texture.unpack_row_length)?glstate->texture.unpack_row_length:width; if (! pixel_convert(data, &dst, bmp_width, height, - format, type, GL_RGBA, GL_UNSIGNED_BYTE, 0)) { + format, type, GL_RGBA, GL_UNSIGNED_BYTE, 0, 1)) { // pack_align is forced to 1 when drawing return; } diff --git a/project/jni/gl4es/src/gl/state.h b/project/jni/gl4es/src/gl/state.h index 2e7bf64ff..28bbcdf79 100755 --- a/project/jni/gl4es/src/gl/state.h +++ b/project/jni/gl4es/src/gl/state.h @@ -8,6 +8,7 @@ #include "buffers.h" #include "queries.h" #include "light.h" +#include "fog.h" typedef struct _glstack_t glstack_t; typedef struct _glclientstack_t glclientstack_t; @@ -51,6 +52,8 @@ typedef struct { pack_skip_pixels, pack_skip_rows, pack_image_height; + GLuint pack_align, + unpack_align; GLboolean pack_lsb_first; gltexture_t *bound[MAX_TEX][ENABLED_TEXTURE_LAST]; GLboolean pscoordreplace[MAX_TEX]; @@ -158,7 +161,7 @@ typedef struct { enable_state_t enable; map_state_t *map_grid; map_states_t map1, map2; - renderlist_t **lists; + khash_t(gllisthead) *headlists; texgen_state_t texgen[MAX_TEX]; texture_state_t texture; GLfloat color[4]; @@ -193,6 +196,7 @@ typedef struct { int emulatedWin; int shared_cnt; light_state_t light; + fog_t fog; material_state_t material; int immediateMV; } glstate_t; diff --git a/project/jni/gl4es/src/gl/texgen.c b/project/jni/gl4es/src/gl/texgen.c index 691145517..10bea82d5 100755 --- a/project/jni/gl4es/src/gl/texgen.c +++ b/project/jni/gl4es/src/gl/texgen.c @@ -167,12 +167,12 @@ void sphere_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint matrix_vector(ModelviewMatrix, verts+k*4, eye); vector4_normalize(eye); vector3_matrix((norm)?(norm+k*3):glstate->normal, InvModelview, eye_norm); - vector4_normalize(eye_norm); - a=dot4(eye, eye_norm)*2.0f; - for (int j=0; j<4; j++) + vector_normalize(eye_norm); + a=dot(eye, eye_norm)*2.0f; + for (int j=0; j<3; j++) reflect[j]=eye[j]-eye_norm[j]*a; reflect[2]+=1.0f; - a = 0.5f / sqrtf(dot4(reflect, reflect)); + a = 0.5f / sqrtf(dot(reflect, reflect)); out[k*4+0] = reflect[0]*a + 0.5f; out[k*4+1] = reflect[1]*a + 0.5f; out[k*4+2] = 0.0f; diff --git a/project/jni/gl4es/src/gl/texture.c b/project/jni/gl4es/src/gl/texture.c index 30802f8bc..995fd9162 100755 --- a/project/jni/gl4es/src/gl/texture.c +++ b/project/jni/gl4es/src/gl/texture.c @@ -300,7 +300,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height, if (convert) { GLvoid *pixels = (GLvoid *)data; if (! pixel_convert(data, &pixels, width, height, - *format, *type, dest_format, dest_type, 0)) { + *format, *type, dest_format, dest_type, 0, glstate->texture.unpack_align)) { printf("LIBGL: swizzle error: (%s, %s -> %s, %s)\n", PrintEnum(*format), PrintEnum(*type), PrintEnum(dest_format), PrintEnum(dest_type)); return NULL; @@ -311,7 +311,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height, GLvoid *pix2 = (GLvoid *)pixels; internal2format_type(internalformat, &dest_format, &dest_type); if (! pixel_convert(pixels, &pix2, width, height, - *format, *type, dest_format, dest_type, 0)) { + *format, *type, dest_format, dest_type, 0, glstate->texture.unpack_align)) { printf("LIBGL: swizzle error: (%s, %s -> %s, %s)\n", PrintEnum(dest_format), PrintEnum(dest_type), PrintEnum(internalformat), PrintEnum(dest_type)); return NULL; @@ -346,7 +346,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height, return (void *)data; } -GLenum swizzle_internalformat(GLenum *internalformat, GLenum format) { +GLenum swizzle_internalformat(GLenum *internalformat, GLenum format, GLenum type) { GLenum ret = *internalformat; GLenum sret; switch(*internalformat) { @@ -365,8 +365,12 @@ GLenum swizzle_internalformat(GLenum *internalformat, GLenum format) { case GL_RGB5: sret = GL_RGB5; break; - case GL_RGB8: case GL_RGB: + if(globals4es.avoid16bits==0 && format==GL_RGB && type==GL_UNSIGNED_SHORT_5_6_5) { + sret = ret = GL_RGB5; + break; + } + case GL_RGB8: case GL_BGR: case GL_RGB16: case GL_RGB16F: @@ -381,6 +385,14 @@ GLenum swizzle_internalformat(GLenum *internalformat, GLenum format) { sret = GL_RGB5_A1; break; case GL_RGBA: + if(globals4es.avoid16bits==0 && format==GL_RGBA && type==GL_UNSIGNED_SHORT_5_5_5_1) { + sret = ret = GL_RGB5_A1; + break; + } + if(globals4es.avoid16bits==0 && format==GL_RGBA && type==GL_UNSIGNED_SHORT_4_4_4_4) { + sret = ret = GL_RGBA4; + break; + } case GL_RGBA8: case GL_RGBA16: case GL_RGBA16F: @@ -564,20 +576,21 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, if (globals4es.texshrink>=8 && max1>8192) max1=8192; proxy_width = ((width<max1)?0:width; proxy_height = ((height<max1)?0:height; - proxy_intformat = swizzle_internalformat(&internalformat, format); + proxy_intformat = swizzle_internalformat(&internalformat, format, type); return; } - //PUSH_IF_COMPILING(glTexImage2D); GLuint old_glbatch = glstate->gl_batch; if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; + } else { + PUSH_IF_COMPILING(glTexImage2D); } - + GLvoid *datab = (GLvoid*)data; if (glstate->vao->unpack) - datab += (uintptr_t)glstate->vao->pack->data; + datab += (uintptr_t)glstate->vao->unpack->data; GLvoid *pixels = (GLvoid *)datab; border = 0; //TODO: something? @@ -594,7 +607,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, else bound->mipmap_need = 1; } - GLenum new_format = swizzle_internalformat(&internalformat, format); + GLenum new_format = swizzle_internalformat(&internalformat, format, type); if (bound && (level==0)) { bound->orig_internal = internalformat; bound->internalformat = new_format; @@ -675,7 +688,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, if (globals4es.texdump) { if (bound) { - pixel_to_ppm(pixels, width, height, format, type, bound->texture); + pixel_to_ppm(pixels, width, height, format, type, bound->texture, glstate->texture.pack_align); } } } else { @@ -861,7 +874,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, else bound->data = malloc(width*height*4); if (datab) { - if (!pixel_convert(pixels, &bound->data, width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE, 0)) + if (!pixel_convert(pixels, &bound->data, width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE, 0, glstate->texture.pack_align)) printf("LIBGL: Error on pixel_convert when TEXCOPY in glTexImage2D\n"); } else { //memset(bound->data, 0, width*height*4); @@ -877,16 +890,17 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) { - //PUSH_IF_COMPILING(glTexSubImage2D); GLuint old_glbatch = glstate->gl_batch; if (glstate->gl_batch || glstate->list.pending) { flush(); glstate->gl_batch = 0; + } else { + PUSH_IF_COMPILING(glTexSubImage2D); } GLvoid *datab = (GLvoid*)data; if (glstate->vao->unpack) - datab += (uintptr_t)glstate->vao->pack->data; + datab += (uintptr_t)glstate->vao->unpack->data; GLvoid *pixels = (GLvoid*)datab; const GLuint itarget = what_target(target); @@ -944,7 +958,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff GLvoid *tmp = GetStreamingBuffer(bound->streamingID); tmp += (yoffset*bound->width+xoffset)*2; if (! pixel_convert(old, &tmp, width, height, - format, type, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bound->width)) { + format, type, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bound->width, glstate->texture.pack_align)) { printf("LIBGL: swizzle error: (%#4x, %#4x -> GL_RGB, UNSIGNED_SHORT_5_6_5)\n", format, type); } @@ -956,7 +970,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff //pixels = (GLvoid *)swizzle_texture(width, height, &format, &type, old); GLenum dest_format, dest_type; internal2format_type(orig_internal, &dest_format, &dest_type); - if (!pixel_convert(old, &pixels, width, height, format, type, dest_format, dest_type, 0)) { + if (!pixel_convert(old, &pixels, width, height, format, type, dest_format, dest_type, 0, glstate->texture.pack_align)) { printf("LIBGL: Error in pixel_convert while glTexSubImage2D\n"); } else { format = dest_format; @@ -964,7 +978,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff if(orig_internal!=internalformat) { GLvoid* pix2 = pixels; internal2format_type(internalformat, &dest_format, &dest_type); - if (!pixel_convert(pixels, &pix2, width, height, format, type, dest_format, dest_type, 0)) { + if (!pixel_convert(pixels, &pix2, width, height, format, type, dest_format, dest_type, 0, glstate->texture.pack_align)) { printf("LIBGL: Error in pixel_convert while glTexSubImage2D\n"); } if (pixels != pix2 && pixels != old) @@ -1009,7 +1023,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff if (globals4es.texdump) { if (bound) { - pixel_to_ppm(pixels, width, height, format, type, bound->texture); + pixel_to_ppm(pixels, width, height, format, type, bound->texture, glstate->texture.pack_align); } } @@ -1082,7 +1096,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff //printf("*texcopy* glTexSubImage2D, xy=%i,%i, size=%i,%i=>%i,%i, format=%s, type=%s, tex=%u\n", xoffset, yoffset, width, height, bound->width, bound->height, PrintEnum(format), PrintEnum(type), bound->glname); GLvoid * tmp = bound->data; tmp += (yoffset*bound->width + xoffset)*4; - if (!pixel_convert(pixels, &tmp, width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE, bound->width)) + if (!pixel_convert(pixels, &tmp, width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE, bound->width, glstate->texture.pack_align)) printf("LIBGL: Error on pixel_convert while TEXCOPY in glTexSubImage2D\n"); } @@ -1152,45 +1166,62 @@ void gl4es_glPixelStorei(GLenum pname, GLint param) { switch (pname) { case GL_UNPACK_ROW_LENGTH: glstate->texture.unpack_row_length = param; - break; + return; case GL_UNPACK_SKIP_PIXELS: glstate->texture.unpack_skip_pixels = param; - break; + return; case GL_UNPACK_SKIP_ROWS: glstate->texture.unpack_skip_rows = param; - break; + return; case GL_UNPACK_LSB_FIRST: glstate->texture.unpack_lsb_first = param; - break; + return; case GL_UNPACK_IMAGE_HEIGHT: glstate->texture.unpack_image_height = param; - break; + return; case GL_UNPACK_SWAP_BYTES: case GL_PACK_SWAP_BYTES: // Fake... TODO? //glstate->texture.unpack_lsb_first = param; - break; + return; case GL_PACK_ROW_LENGTH: glstate->texture.pack_row_length = param; - break; + return; case GL_PACK_SKIP_PIXELS: glstate->texture.pack_skip_pixels = param; - break; + return; case GL_PACK_SKIP_ROWS: glstate->texture.pack_skip_rows = param; - break; + return; case GL_PACK_LSB_FIRST: glstate->texture.pack_lsb_first = param; - break; + return; case GL_PACK_IMAGE_HEIGHT: glstate->texture.pack_image_height = param; + return; + case GL_PACK_ALIGNMENT: + if(glstate->texture.pack_align==param) + return; + if (param!=1 && param!=2 && param!=4 && param!=8) { + errorShim(GL_INVALID_VALUE); + return; + } + glstate->texture.pack_align=param; break; - default: - errorGL(); - gles_glPixelStorei(pname, param); + case GL_UNPACK_ALIGNMENT: + if(glstate->texture.unpack_align==param) + return; + if (param!=1 && param!=2 && param!=4 && param!=8) { + errorShim(GL_INVALID_VALUE); + return; + } + glstate->texture.unpack_align=param; break; } + errorGL(); + gles_glPixelStorei(pname, param); } + GLboolean gl4es_glIsTexture(GLuint texture) { noerrorShim(); if (!texture) { @@ -1256,7 +1287,7 @@ gltexture_t* gl4es_getTexture(GLenum target, GLuint texture) { #define batch_activetex (glstate->statebatch.active_tex_changed?(glstate->statebatch.active_tex-GL_TEXTURE0):glstate->texture.active) void gl4es_glBindTexture(GLenum target, GLuint texture) { noerrorShim(); - //printf("glBindTexture(%s, %u), active=%i, client=%i\n", PrintEnum(target), texture, glstate->texture.active, glstate->texture.client); + //printf("glBindTexture(%s, %u), active=%i, client=%i, list.active=%p (compiling=%d, pending=%d)\n", PrintEnum(target), texture, glstate->texture.active, glstate->texture.client, glstate->list.active, glstate->list.compiling, glstate->list.pending); if(glstate->list.pending) flush(); if ((target!=GL_PROXY_TEXTURE_2D) && (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling))) { if ((glstate->statebatch.bound_targ[batch_activetex] == target) && (glstate->statebatch.bound_tex[batch_activetex] == texture)) @@ -1363,6 +1394,7 @@ void gl4es_glTexParameteri(GLenum target, GLenum pname, GLint param) { case GL_TEXTURE_WRAP_T: switch (param) { case GL_CLAMP: + case GL_CLAMP_TO_BORDER: param = GL_CLAMP_TO_EDGE; break; } @@ -1402,6 +1434,61 @@ void gl4es_glTexParameterf(GLenum target, GLenum pname, GLfloat param) { gl4es_glTexParameteri(target, pname, param); } +void gl4es_glTexParameterfv(GLenum target, GLenum pname, const GLfloat * params) { + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_LOD_BIAS: + case GL_GENERATE_MIPMAP: + gl4es_glTexParameteri(target, pname, params[0]); + return; + case GL_TEXTURE_BORDER_COLOR: + // not supported on GLES, + noerrorShim(); + return; + } + PUSH_IF_COMPILING(glTexParameterfv); + LOAD_GLES(glTexParameterfv); + errorGL(); + const GLuint rtarget = map_tex_target(target); + gles_glTexParameterfv(rtarget, pname, params); + +} + +void gl4es_glTexParameteriv(GLenum target, GLenum pname, const GLint * params) { + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_LOD_BIAS: + case GL_GENERATE_MIPMAP: + gl4es_glTexParameteri(target, pname, params[0]); + return; + case GL_TEXTURE_BORDER_COLOR: + // not supported on GLES, + noerrorShim(); + return; + } + PUSH_IF_COMPILING(glTexParameteriv); + LOAD_GLES(glTexParameteriv); + errorGL(); + const GLuint rtarget = map_tex_target(target); + gles_glTexParameteriv(rtarget, pname, params); +} + void gl4es_glDeleteTextures(GLsizei n, const GLuint *textures) { if (glstate->gl_batch || glstate->list.pending) flush(); noerrorShim(); @@ -1662,7 +1749,7 @@ void gl4es_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, #ifdef TEXSTREAM if (globals4es.texstream && bound->streamed) { noerrorShim(); - pixel_convert(GetStreamingBuffer(bound->streamingID), &dst, width, height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format, type, 0); + pixel_convert(GetStreamingBuffer(bound->streamingID), &dst, width, height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format, type, 0, glstate->texture.unpack_align); readfboEnd(); if (old_glbatch) glstate->gl_batch=old_glbatch; @@ -1672,7 +1759,7 @@ void gl4es_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, if (globals4es.texcopydata && bound->data) { //printf("texcopydata* glGetTexImage(0x%04X, %d, 0x%04x, 0x%04X, %p)\n", target, level, format, type, img); noerrorShim(); - if (!pixel_convert(bound->data, &dst, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) + if (!pixel_convert(bound->data, &dst, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0, glstate->texture.unpack_align)) printf("LIBGL: Error on pixel_convert while glGetTexImage\n"); } else { // Setup an FBO the same size of the texture @@ -1891,7 +1978,7 @@ void gl4es_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum GLvoid *pixels = malloc(width*height*4); gles_glReadPixels(x, y, width, height, use_bgra?GL_BGRA:GL_RGBA, GL_UNSIGNED_BYTE, pixels); if (! pixel_convert(pixels, &dst, width, height, - use_bgra?GL_BGRA:GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) { + use_bgra?GL_BGRA:GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0,glstate->texture.unpack_align)) { LOGE("LIBGL: ReadPixels error: (%s, UNSIGNED_BYTE -> %s, %s )\n", PrintEnum(use_bgra?GL_BGRA:GL_RGBA), PrintEnum(format), PrintEnum(type)); } @@ -2140,23 +2227,26 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor // automaticaly reduce the pixel size half=pixels; bound->alpha = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true; - if(globals4es.nodownsampling==1) { + if(globals4es.nodownsampling==1) { // will be removed soon, avoid16bits is better format = GL_RGBA; type = GL_UNSIGNED_BYTE; } else { - format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA; -#ifdef PANDORA - type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:(internalformat==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_5_5_1:GL_UNSIGNED_SHORT_4_4_4_4; -#else - type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4; -#endif - if (pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) - fact = 0; -// if (pixel_thirdscale(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE)) -// fact = 1; - else { + if(globals4es.avoid16bits) { format = GL_RGBA; type = GL_UNSIGNED_BYTE; + } else { + format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA; +#ifdef PANDORA + type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:(internalformat==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_5_5_1:GL_UNSIGNED_SHORT_4_4_4_4; +#else + type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4; +#endif + if (pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0, glstate->texture.pack_align)) + fact = 0; + else { + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + } } } bound->format = format; //internalformat; @@ -2251,7 +2341,7 @@ void gl4es_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, #else GLenum format = bound->format; GLenum type = bound->type; - pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0); + pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0, glstate->texture.pack_align); gl4es_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, half); #endif if (half!=pixels) @@ -2411,6 +2501,8 @@ void glGenTextures(GLsizei n, GLuint * textures) AliasExport("gl4es_glGenTexture void glDeleteTextures(GLsizei n, const GLuint * textures) AliasExport("gl4es_glDeleteTextures"); void glTexParameteri(GLenum target, GLenum pname, GLint param) AliasExport("gl4es_glTexParameteri"); void glTexParameterf(GLenum target, GLenum pname, GLfloat param) AliasExport("gl4es_glTexParameterf"); +void glTexParameterfv(GLenum target, GLenum pname, const GLfloat * params) AliasExport("gl4es_glTexParameterfv"); +void glTexParameteriv(GLenum target, GLenum pname, const GLint * params) AliasExport("gl4es_glTexParameteriv"); GLboolean glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences) AliasExport("gl4es_glAreTexturesResident"); void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) AliasExport("gl4es_glGetTexLevelParameteriv"); void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid * img) AliasExport("gl4es_glGetTexImage"); diff --git a/project/jni/gl4es/src/gl/wrap/gl.c b/project/jni/gl4es/src/gl/wrap/gl.c index 5dd79fd7f..718578535 100755 --- a/project/jni/gl4es/src/gl/wrap/gl.c +++ b/project/jni/gl4es/src/gl/wrap/gl.c @@ -55,7 +55,9 @@ void gl4es_glFogiv(GLenum pname, GLint *iparams) { case GL_FOG_START: case GL_FOG_END: case GL_FOG_MODE: - case GL_FOG_INDEX: { + case GL_FOG_INDEX: + case GL_FOG_COORD_SRC: + { gl4es_glFogf(pname, *iparams); break; } diff --git a/project/jni/gl4es/src/gl/wrap/gles.c b/project/jni/gl4es/src/gl/wrap/gles.c index fdb427cc1..803f10ef9 100644 --- a/project/jni/gl4es/src/gl/wrap/gles.c +++ b/project/jni/gl4es/src/gl/wrap/gles.c @@ -1580,14 +1580,14 @@ void gl4es_glTexGeni(GLenum coord, GLenum pname, GLint param) { void glTexGeni(GLenum coord, GLenum pname, GLint param) __attribute__((alias("gl4es_glTexGeni"))) __attribute__((visibility("default"))); #endif #ifndef skip_glTexImage2D -void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels) { +void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data) { LOAD_GLES(glTexImage2D); #ifndef direct_glTexImage2D PUSH_IF_COMPILING(glTexImage2D) #endif - gles_glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + gles_glTexImage2D(target, level, internalformat, width, height, border, format, type, data); } -void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels) __attribute__((alias("gl4es_glTexImage2D"))) __attribute__((visibility("default"))); +void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data) __attribute__((alias("gl4es_glTexImage2D"))) __attribute__((visibility("default"))); #endif #ifndef skip_glTexParameterf void gl4es_glTexParameterf(GLenum target, GLenum pname, GLfloat param) { @@ -1650,14 +1650,14 @@ void gl4es_glTexParameterxv(GLenum target, GLenum pname, const GLfixed * params) void glTexParameterxv(GLenum target, GLenum pname, const GLfixed * params) __attribute__((alias("gl4es_glTexParameterxv"))) __attribute__((visibility("default"))); #endif #ifndef skip_glTexSubImage2D -void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels) { +void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data) { LOAD_GLES(glTexSubImage2D); #ifndef direct_glTexSubImage2D PUSH_IF_COMPILING(glTexSubImage2D) #endif - gles_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + gles_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data); } -void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels) __attribute__((alias("gl4es_glTexSubImage2D"))) __attribute__((visibility("default"))); +void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data) __attribute__((alias("gl4es_glTexSubImage2D"))) __attribute__((visibility("default"))); #endif #ifndef skip_glTranslatef void gl4es_glTranslatef(GLfloat x, GLfloat y, GLfloat z) { diff --git a/project/jni/gl4es/src/gl/wrap/gles.h b/project/jni/gl4es/src/gl/wrap/gles.h old mode 100644 new mode 100755 index e1306a6ff..1f6c33c6e --- a/project/jni/gl4es/src/gl/wrap/gles.h +++ b/project/jni/gl4es/src/gl/wrap/gles.h @@ -1340,7 +1340,7 @@ typedef struct { int func; ARGS_void_GLenum_GLenum_const_GLint___GENPT__ args; } INDEXED_void_GLenum_GLenum_const_GLint___GENPT__; -typedef void (*FUNC_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels); +typedef void (*FUNC_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data); typedef struct { GLenum a1; GLint a2; @@ -1361,7 +1361,7 @@ typedef struct { int func; ARGS_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__ args; } INDEXED_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__; -typedef void (*FUNC_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels); +typedef void (*FUNC_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data); typedef struct { GLenum a1; GLint a2; @@ -2496,8 +2496,8 @@ packed_call_t* glCopyPackedCall(const packed_call_t *packed); #define glTexGeni_FORMAT FORMAT_void_GLenum_GLenum_GLint #define glTexImage2D_INDEX 159 #define glTexImage2D_RETURN void -#define glTexImage2D_ARG_NAMES target, level, internalformat, width, height, border, format, type, pixels -#define glTexImage2D_ARG_EXPAND GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels +#define glTexImage2D_ARG_NAMES target, level, internalformat, width, height, border, format, type, data +#define glTexImage2D_ARG_EXPAND GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data #define glTexImage2D_PACKED PACKED_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__ #define glTexImage2D_INDEXED INDEXED_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__ #define glTexImage2D_FORMAT FORMAT_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__ @@ -2545,8 +2545,8 @@ packed_call_t* glCopyPackedCall(const packed_call_t *packed); #define glTexParameterxv_FORMAT FORMAT_void_GLenum_GLenum_const_GLfixed___GENPT__ #define glTexSubImage2D_INDEX 166 #define glTexSubImage2D_RETURN void -#define glTexSubImage2D_ARG_NAMES target, level, xoffset, yoffset, width, height, format, type, pixels -#define glTexSubImage2D_ARG_EXPAND GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels +#define glTexSubImage2D_ARG_NAMES target, level, xoffset, yoffset, width, height, format, type, data +#define glTexSubImage2D_ARG_EXPAND GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data #define glTexSubImage2D_PACKED PACKED_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__ #define glTexSubImage2D_INDEXED INDEXED_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__ #define glTexSubImage2D_FORMAT FORMAT_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__ @@ -4597,7 +4597,7 @@ typedef void (*glViewport_PTR)(glViewport_ARG_EXPAND); } #endif #ifndef direct_glTexImage2D -#define push_glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels) { \ +#define push_glTexImage2D(target, level, internalformat, width, height, border, format, type, data) { \ glTexImage2D_PACKED *packed_data = malloc(sizeof(glTexImage2D_PACKED)); \ packed_data->format = glTexImage2D_FORMAT; \ packed_data->func = gl4es_glTexImage2D; \ @@ -4609,7 +4609,7 @@ typedef void (*glViewport_PTR)(glViewport_ARG_EXPAND); packed_data->args.a6 = (GLint)border; \ packed_data->args.a7 = (GLenum)format; \ packed_data->args.a8 = (GLenum)type; \ - packed_data->args.a9 = (GLvoid *)pixels; \ + packed_data->args.a9 = (GLvoid *)data; \ glPushCall((void *)packed_data); \ } #endif @@ -4680,7 +4680,7 @@ typedef void (*glViewport_PTR)(glViewport_ARG_EXPAND); } #endif #ifndef direct_glTexSubImage2D -#define push_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) { \ +#define push_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data) { \ glTexSubImage2D_PACKED *packed_data = malloc(sizeof(glTexSubImage2D_PACKED)); \ packed_data->format = glTexSubImage2D_FORMAT; \ packed_data->func = gl4es_glTexSubImage2D; \ @@ -4692,7 +4692,7 @@ typedef void (*glViewport_PTR)(glViewport_ARG_EXPAND); packed_data->args.a6 = (GLsizei)height; \ packed_data->args.a7 = (GLenum)format; \ packed_data->args.a8 = (GLenum)type; \ - packed_data->args.a9 = (GLvoid *)pixels; \ + packed_data->args.a9 = (GLvoid *)data; \ glPushCall((void *)packed_data); \ } #endif diff --git a/project/jni/gl4es/src/glx/glx.c b/project/jni/gl4es/src/glx/glx.c index 4459da6e3..dde49968a 100755 --- a/project/jni/gl4es/src/glx/glx.c +++ b/project/jni/gl4es/src/glx/glx.c @@ -29,6 +29,7 @@ #endif + //#define DEBUG #ifdef DEBUG #define DBG(a) a @@ -62,7 +63,6 @@ typedef struct { Display *dpy; int Type; GC gc; XImage* frame; - GLXContext glxcontext; } glx_buffSize; //PBuffer should work under ANDROID @@ -86,7 +86,7 @@ static GLXContext fbContext = NULL; #endif //ANDROID // hmm... -static EGLContext eglContext; +static EGLContext eglContext = EGL_NO_CONTEXT; static int fbcontext_count = 0; @@ -98,11 +98,24 @@ static int fbdev = -1; #endif static int g_width=0, g_height=0; -// RPI stuffs +// **** RPI stuffs **** static bool g_bcmhost = false; static bool g_bcm_active = false; void (*bcm_host_init)(); void (*bcm_host_deinit)(); +#ifndef ANDROID +#include "rpi.h" +#endif +// ***** end of RPI stuffs **** + +// Generic create native window to use with "LIBGL_FB=1" (so with EGL_DEFAULT_DISPLAY and without X11) +static void* create_native_window(int w, int h) { +#ifndef ANDROID + if(bcm_host) return create_rpi_window(w, h); +#endif + + return NULL; +} #define SHUT(a) if(!globals4es.nobanner) a @@ -219,7 +232,7 @@ static int get_config_default(Display *display, int attribute, int *value) { *value = GLX_WINDOW_BIT; break; case GLX_BUFFER_SIZE: - *value = 0; + *value = 16; break; case GLX_X_VISUAL_TYPE: case GLX_CONFIG_CAVEAT: @@ -348,8 +361,10 @@ void glx_init() { if (bcm_host) { bcm_host_init = dlsym(bcm_host, "bcm_host_init"); bcm_host_deinit = dlsym(bcm_host, "bcm_host_deinit"); - if (bcm_host_init && bcm_host_deinit) + if (bcm_host_init && bcm_host_deinit) { g_bcmhost = true; + rpi_init(); + } } if (globals4es.xrefresh || globals4es.stacktrace || g_bcmhost) { // TODO: a bit gross. Maybe look at this: http://stackoverflow.com/a/13290134/293352 @@ -394,7 +409,7 @@ GLXContext gl4es_glXCreateContext(Display *display, XVisualInfo *visual, GLXContext shareList, Bool isDirect) { - DBG(printf("glXCreateContext(%p, %p, %p, %i), latest_visual=%p\n", display, visual, shareList, isDirect, latest_visual);) + DBG(printf("glXCreateContext(%p, %p, %p, %i), latest_visual=%p, fbcontext_count=%d", display, visual, shareList, isDirect, latest_visual, fbcontext_count);) static struct __GLXFBConfigRec default_glxfbconfig; GLXFBConfig glxfbconfig; @@ -411,6 +426,11 @@ GLXContext gl4es_glXCreateContext(Display *display, default_glxfbconfig.depthBits = 16; default_glxfbconfig.stencilBits = 8; } + int depthBits = glxfbconfig->depthBits; +#ifdef PANDORA + if(depthBits==24 && glxfbconfig->stencilBits==8 && !(globals4es.usefbo || globals4es.usepbuffer)) + depthBits = 16; +#endif EGLint configAttribs[] = { #ifdef PANDORA @@ -429,7 +449,7 @@ GLXContext gl4es_glXCreateContext(Display *display, #else EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, #endif - EGL_BUFFER_SIZE, glxfbconfig->depthBits, + EGL_BUFFER_SIZE, depthBits, EGL_STENCIL_SIZE, glxfbconfig->stencilBits, EGL_SAMPLE_BUFFERS, glxfbconfig->nMultiSampleBuffers, @@ -438,10 +458,14 @@ GLXContext gl4es_glXCreateContext(Display *display, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_NONE }; - if (globals4es.usefb && fbcontext_count>0) { + if (globals4es.usefb && fbcontext_count++>0) { // don't create a new context, one FB is enough... - fbcontext_count++; - return fbContext; + GLXContext fake = malloc(sizeof(struct __GLXContextRec)); + memcpy(fake, fbContext, sizeof(struct __GLXContextRec)); + fake->glstate = NewGLState(fbContext->glstate); // let's create a new shared glsate + + DBG(printf(" => %p\n", fake);) + return fake; } #ifdef BCMHOST @@ -463,13 +487,12 @@ GLXContext gl4es_glXCreateContext(Display *display, GLXContext fake = malloc(sizeof(struct __GLXContextRec)); memset(fake, 0, sizeof(struct __GLXContextRec)); - if(globals4es.usefb) - fbContext = fake; // make an egl context here... EGLBoolean result; if (eglDisplay == NULL || eglDisplay == EGL_NO_DISPLAY) { init_display(display); if (eglDisplay == EGL_NO_DISPLAY) { + DBG(printf(" => %p\n", 0);) LOGE("LIBGL: Unable to create EGL display.\n"); free(fake); return 0; @@ -481,6 +504,7 @@ GLXContext gl4es_glXCreateContext(Display *display, egl_eglBindAPI(EGL_OPENGL_ES_API); result = egl_eglInitialize(eglDisplay, NULL, NULL); if (result != EGL_TRUE) { + DBG(printf(" => %p\n", 0);) LOGE("LIBGL: Unable to initialize EGL display.\n"); free(fake); return 0; @@ -495,7 +519,8 @@ GLXContext gl4es_glXCreateContext(Display *display, CheckEGLErrors(); if (result != EGL_TRUE || configsFound == 0) { - LOGE("LIBGL: No EGL configs found.\n"); + DBG(printf(" => %p\n", 0);) + LOGE("LIBGL: No EGL configs found (depth=%d, stencil=%d).\n", depthBits, glxfbconfig->stencilBits); free(fake); return 0; } @@ -529,7 +554,11 @@ GLXContext gl4es_glXCreateContext(Display *display, egl_eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT); } */ - + if(globals4es.usefb) { + fbContext = malloc(sizeof(struct __GLXContextRec)); + memcpy(fbContext, fake, sizeof(struct __GLXContextRec)); + } + DBG(printf(" => %p\n", fake);) return fake; } @@ -719,7 +748,7 @@ GLXContext gl4es_glXCreateContextAttribsARB(Display *display, GLXFBConfig config fake->display = (globals4es.usefb)?g_display:display; fake->direct = true; fake->xid = 1; //TODO: Proper handling of that id... - fake->contextType = 0; //Window + fake->contextType = (config->drawableType)==GLX_PIXMAP_BIT?2:0; //Pixmap:Window egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_RED_SIZE, &fake->rbits); egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_GREEN_SIZE, &fake->gbits); @@ -735,14 +764,17 @@ GLXContext gl4es_glXCreateContextAttribsARB(Display *display, GLXFBConfig config } void gl4es_glXDestroyContext(Display *display, GLXContext ctx) { - DBG(printf("glXDestroyContext(%p, %p)\n", display, ctx);) + DBG(printf("glXDestroyContext(%p, %p), fbcontext_count=%d, ctx_type=%d\n", display, ctx, fbcontext_count, (ctx)?ctx->contextType:0);) if (globals4es.usefb && ctx->contextType==0) { if (fbcontext_count==0) return; // Should not happens! - if (--fbcontext_count > 0) - return; // Nothing to do... + if (--fbcontext_count > 0) { + DeleteGLState(ctx->glstate); + free(ctx); + return; // Not much to do... + } } - if ((!globals4es.usefb && ctx->eglContext) || (globals4es.usefb && eglContext)) { + if (ctx->eglContext) { if (globals4es.usefbo && ctx->contextType==0) { deleteMainFBO(); } @@ -775,6 +807,7 @@ void gl4es_glXDestroyContext(Display *display, GLXContext ctx) { if (globals4es.usefb) fbContext = NULL; + free(ctx); return; } @@ -827,7 +860,7 @@ not set to EGL_NO_CONTEXT. Bool gl4es_glXMakeCurrent(Display *display, GLXDrawable drawable, GLXContext context) { - DBG(printf("glXMakeCurrent(%p, %p, %p) 'isPBuffer(drawable)=%d, context->drawable=%p, context->eglSurface=%p\n", display, drawable, context, isPBuffer(drawable), context?context->drawable:0, context?context->eglSurface:0);) + DBG(printf("glXMakeCurrent(%p, %p, %p), isPBuffer(drawable)=%d, context->drawable=%p, context->eglSurface=%p", display, drawable, context, isPBuffer(drawable), context?context->drawable:0, context?context->eglSurface:0);) LOAD_EGL(eglMakeCurrent); LOAD_EGL(eglDestroySurface); LOAD_EGL(eglCreateWindowSurface); @@ -842,6 +875,7 @@ Bool gl4es_glXMakeCurrent(Display *display, EGLSurface eglSurf = 0; EGLConfig eglConfig = 0; if(context && glxContext==context && context->drawable==drawable) { + DBG(printf(" => True\n");) //same context, all is done bye DBG(printf("Same context and drawable, doing nothing\n");) return true; @@ -857,16 +891,24 @@ Bool gl4es_glXMakeCurrent(Display *display, #ifndef ANDROID eglSurf = context->eglSurface = pbuffersize[created-1].Surface; //(EGLSurface)drawable; context->eglContext = eglContext = pbuffersize[created-1].Context; // this context is ok for the PBuffer + if (context->contextType != pbuffersize[created-1].Type) { // Context / buffer not aligned, create a new glstate tracker + DeleteGLState(context->glstate); + context->glstate = NewGLState(NULL); + } #endif } else { + unsigned int width = 0, height = 0, depth = 0; #ifndef ANDROID + if(globals4es.usefb && (bcm_host || globals4es.usepbuffer)) { + // Get Window size and all... + unsigned int border; + Window root; + int x, y; + XGetGeometry(display, drawable, &root, &x, &y, &width, &height, &border, &depth); + DBG(printf("XGetGeometry gives %dx%d for drawable %p\n", width, height, drawable);) + } if(globals4es.usefb) { if(globals4es.usepbuffer) { - // Get Window size and all... - unsigned int width, height, border, depth; - Window root; - int x, y; - XGetGeometry(display, drawable, &root, &x, &y, &width, &height, &border, &depth); //let's create a PBuffer attributes EGLint egl_attribs[10]; // should be enough int i = 0; @@ -897,7 +939,7 @@ Bool gl4es_glXMakeCurrent(Display *display, if(eglSurface) eglSurf = context->eglSurface = eglSurface; else - eglSurface = eglSurf = context->eglSurface = egl_eglCreateWindowSurface(eglDisplay, context->eglConfigs[0], 0, (globals4es.glx_surface_srgb)?sRGB:NULL); + eglSurface = eglSurf = context->eglSurface = egl_eglCreateWindowSurface(eglDisplay, context->eglConfigs[0], (EGLNativeWindowType)create_native_window(width,height), (globals4es.glx_surface_srgb)?sRGB:NULL); } else { if(context->eglSurface) egl_eglDestroySurface(eglDisplay, context->eglSurface); @@ -925,7 +967,6 @@ Bool gl4es_glXMakeCurrent(Display *display, map->surface = eglSurf; map->PBuffer = created; - if(created) pbuffersize[created-1].glxcontext = context; } if (context) { @@ -933,7 +974,7 @@ Bool gl4es_glXMakeCurrent(Display *display, ActivateGLState(context->glstate); #ifdef PANDORA - if(created) pandora_set_gamma(); + if(!created) pandora_set_gamma(); #endif glstate->emulatedPixmap = 0; glstate->emulatedWin = 0; @@ -944,7 +985,7 @@ Bool gl4es_glXMakeCurrent(Display *display, CheckEGLErrors(); if (result) { - if (globals4es.usefbo && created) { + if (globals4es.usefbo && !created) { // get size of the surface... egl_eglQuerySurface(eglDisplay,eglSurf,EGL_WIDTH,&g_width); egl_eglQuerySurface(eglDisplay,eglSurf,EGL_HEIGHT,&g_height); @@ -953,10 +994,13 @@ Bool gl4es_glXMakeCurrent(Display *display, createMainFBO(g_width, g_height); } // finished + DBG(printf(" => True\n");) return true; } + DBG(printf(" => False\n");) return false; } + DBG(printf(" => True\n");) return true; } @@ -1087,7 +1131,7 @@ const char *gl4es_glXQueryServerString(Display *display, int screen, int name) { } Bool gl4es_glXQueryExtension(Display *display, int *errorBase, int *eventBase) { - DBG(printf("glXQuesryExtension(%p, %p, %p)\n", display, errorBase, eventBase);) + DBG(printf("glXQueryExtension(%p, %p, %p)\n", display, errorBase, eventBase);) if (errorBase) *errorBase = 0; @@ -1499,24 +1543,36 @@ void gl4es_glXReleaseBuffersMESA() {} #ifndef ANDROID /* TODO proper implementation */ int gl4es_glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) { - DBG(printf("glXQueryDrawable(%p, %p, %d, %p)\n", dpy, draw, attribute, value);) + DBG(printf("glXQueryDrawable(%p, %p", dpy, draw);) int pbuf=isPBuffer(draw); *value = 0; switch(attribute) { case GLX_WIDTH: *value = (pbuf)?pbuffersize[pbuf-1].Width:800; + DBG(printf("(%d), GLX_WIDTH, %p = %d)\n", pbuf, value, *value);) return 1; case GLX_HEIGHT: *value = (pbuf)?pbuffersize[pbuf-1].Height:480; + DBG(printf("(%d), GLX_HEIGHT, %p = %d)\n", pbuf, value, *value);) return 1; case GLX_PRESERVED_CONTENTS: - return 0; + if(pbuf) *value = 1; + DBG(printf("(%d), GLX_PRESERVED_CONTENTS, %p = %d)\n", pbuf, value, *value);) + return 1; case GLX_LARGEST_PBUFFER: - return 0; + if(pbuf) *value = 0; + DBG(printf("(%d), GLX_LARGEST_PBUFFER, %p = %d)\n", pbuf, value, *value);) + return 1; case GLX_FBCONFIG_ID: *value = 1; + DBG(printf("(%d), GLX_FBCONFIG_ID, %p = %d)\n", pbuf, value, *value);) + return 1; + case GLX_SWAP_INTERVAL_EXT: + *value = 0; + DBG(printf("(%d), GLX_SWAP_INTERVAL_EXT, %p = %d)\n", pbuf, value, *value);) return 1; } + DBG(printf("(%d), %04x, %p)\n", pbuf, attribute, value);) return 0; } @@ -1551,12 +1607,14 @@ void gl4es_glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf) { DBG(printf("glxDestroyPBuffer(%p, %p)\n", dpy, pbuf);) LOAD_EGL(eglDestroySurface); int j=0; - while(jtexture.unpack_align); free(tmp); } else { gles_glReadPixels(0, 0, Width, Height, GL_BGRA, GL_UNSIGNED_BYTE, (void*)pix); @@ -1978,8 +2035,6 @@ void BlitEmulatedPixmap() { EGLSurface Surface = egl_eglCreatePbufferSurface(eglDisplay, pbufConfigs[0], egl_attribs); - buff->glxcontext->eglSurface = Surface; - egl_eglMakeCurrent(eglDisplay, Surface, Surface, eglContext); egl_eglDestroySurface(eglDisplay, buff->Surface); diff --git a/project/jni/gl4es/src/glx/glx.h b/project/jni/gl4es/src/glx/glx.h index b0533413d..4c2f81dab 100755 --- a/project/jni/gl4es/src/glx/glx.h +++ b/project/jni/gl4es/src/glx/glx.h @@ -125,6 +125,7 @@ #define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 +#define GLX_SWAP_INTERVAL_EXT 0x20F1 typedef int GLXDrawable; #ifndef ANDROID diff --git a/project/jni/gl4es/src/glx/hardext.c b/project/jni/gl4es/src/glx/hardext.c index f5d9dfd1e..46d9b0354 100755 --- a/project/jni/gl4es/src/glx/hardext.c +++ b/project/jni/gl4es/src/glx/hardext.c @@ -110,6 +110,14 @@ void GetHardwareExtensions(int notest) S("GL_OES_blend_equation_separate", blendeq, 1); S("GL_EXT_blend_minmax", blendminmax, 1); S("GL_EXT_blend_color", blendcolor, 1); + if(hardext.blendcolor==0) { + // try by just loading the function + LOAD_GLES_OR_OES(glBlendColor); + if(gles_glBlendColor != NULL) { + hardext.blendcolor = 1; + SHUT(LOGD("LIBGL: Extension glBlendColor found and used\n")); + } + } S("GL_OES_point_sprite", pointsprite, 1); S("GL_OES_point_size_array", pointsize, 0); S("GL_OES_element_index_uint", elementuint, 0); @@ -146,4 +154,4 @@ void GetHardwareExtensions(int notest) egl_eglMakeCurrent(eglDisplay, 0, 0, EGL_NO_CONTEXT); egl_eglDestroySurface(eglDisplay, eglSurface); egl_eglDestroyContext(eglDisplay, eglContext); -} \ No newline at end of file +} diff --git a/project/jni/gl4es/src/glx/rpi.c b/project/jni/gl4es/src/glx/rpi.c new file mode 100644 index 000000000..640b8faac --- /dev/null +++ b/project/jni/gl4es/src/glx/rpi.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include + +#include "rpi.h" + +// Code specific to RPI +// everything is dynamicaly linked, so this can be saffely compiled everywhere +extern void* bcm_host; +extern void* vcos; + +typedef uint32_t DISPMANX_DISPLAY_HANDLE_T; +typedef uint32_t DISPMANX_UPDATE_HANDLE_T; +typedef uint32_t DISPMANX_ELEMENT_HANDLE_T; +typedef uint32_t DISPMANX_RESOURCE_HANDLE_T; +typedef uint32_t DISPMANX_PROTECTION_T; +typedef struct tag_VC_RECT_T { + int32_t x; + int32_t y; + int32_t width; + int32_t height; +} VC_RECT_T; +typedef struct { + DISPMANX_ELEMENT_HANDLE_T element; + int width; + int height; +} EGL_DISPMANX_WINDOW_T; +int32_t (*graphics_get_display_size)(const uint16_t, uint32_t *, uint32_t*); +DISPMANX_DISPLAY_HANDLE_T (*vc_dispmanx_display_open)(uint32_t); +DISPMANX_UPDATE_HANDLE_T (*vc_dispmanx_update_start)(int32_t); +DISPMANX_ELEMENT_HANDLE_T (*vc_dispmanx_element_add)( + DISPMANX_UPDATE_HANDLE_T, DISPMANX_DISPLAY_HANDLE_T, int32_t, + VC_RECT_T *, DISPMANX_RESOURCE_HANDLE_T, + VC_RECT_T *, DISPMANX_PROTECTION_T, + /*VC_DISPMANX_ALPHA_T*/void*, /*DISPMANX_CLAMP_T*/void*, + /*DISPMANX_TRANSFORM_T*/ int32_t); +int (*vc_dispmanx_update_submit_sync)(DISPMANX_RESOURCE_HANDLE_T); +static DISPMANX_UPDATE_HANDLE_T dispman_update; +static DISPMANX_DISPLAY_HANDLE_T dispman_display; +static VC_RECT_T dst_rect; +static VC_RECT_T src_rect; + +void rpi_init() { + #define GO(A) A=dlsym(bcm_host, #A); if(A==NULL) A=dlsym(vcos, #A); if(A==NULL) printf("LIBGL: Warning, " #A " is null") + GO(graphics_get_display_size); + GO(vc_dispmanx_display_open); + GO(vc_dispmanx_update_start); + GO(vc_dispmanx_element_add); + GO(vc_dispmanx_update_submit_sync); + #undef GO +} + +void* create_rpi_window(int w, int h) { + static EGL_DISPMANX_WINDOW_T nativewindow; + if(!bcm_host) return NULL; + // create a simple RPI nativewindow of size w*h, on output 0 (i.e. LCD)... + // code heavily inspired from Allegro 5.2 + uint32_t screenwidth, screenheight; + graphics_get_display_size(/*LCD*/ 0, &screenwidth, & screenheight); + if(w==0) w=screenwidth; + if(h==0) h=screenheight; + DISPMANX_ELEMENT_HANDLE_T dispman_element; + VC_RECT_T dst_rect, src_rect; + dst_rect.x = 0; dst_rect.y = 0; + dst_rect.width = screenwidth; + dst_rect.height = screenheight; + src_rect.x = 0; src_rect.y = 0; + src_rect.width = w << 16; + src_rect.height = h << 16; + dispman_display = vc_dispmanx_display_open(/*LCD*/ 0); + dispman_update = vc_dispmanx_update_start(0); + dispman_element = vc_dispmanx_element_add( + dispman_update,dispman_display, 0, &dst_rect, + 0, &src_rect, /*DISPMANX_PROTECTION_NONE*/ 0, 0, 0, + /*DISPMAN_NO_ROTATE*/ 0); + nativewindow.element = dispman_element; + nativewindow.width = w; + nativewindow.height = h; + vc_dispmanx_update_submit_sync(dispman_update); + + return &nativewindow; +} diff --git a/project/jni/gl4es/src/glx/rpi.h b/project/jni/gl4es/src/glx/rpi.h new file mode 100644 index 000000000..3dbf5027c --- /dev/null +++ b/project/jni/gl4es/src/glx/rpi.h @@ -0,0 +1,10 @@ +#ifndef __RPI_H_ +#define __RPI_H_ + +// Code specific to RPI + +void rpi_init(); +void* create_rpi_window(int w, int h); + + +#endif //__RPI_H_ \ No newline at end of file diff --git a/project/jni/gl4es/version.h b/project/jni/gl4es/version.h index bafa84bdf..3e5601b76 100755 --- a/project/jni/gl4es/version.h +++ b/project/jni/gl4es/version.h @@ -3,6 +3,6 @@ #define MAJOR 0 #define MINOR 9 -#define REVISION 5 +#define REVISION 6 #endif //_GL4ES_VERSION_H