diff --git a/project/java/DataDownloader.java b/project/java/DataDownloader.java
index 5fa4a6a74..c0d276ae8 100644
--- a/project/java/DataDownloader.java
+++ b/project/java/DataDownloader.java
@@ -750,14 +750,19 @@ class DataDownloader extends Thread
ret = check.read(buf, 0, buf.length);
}
check.close();
+
+
+ // NOTE: For some reason this not work properly on older Android versions (4.4 and below).
+ // Setting this to become a warning
if( check.getChecksum().getValue() != entry.getCrc() || count != entry.getSize() )
{
- File ff = new File(path);
- ff.delete();
+ //File ff = new File(path);
+ //ff.delete();
Log.i("SDL", "Saving file '" + path + "' - CRC check failed, ZIP: " +
String.format("%x", entry.getCrc()) + " actual file: " + String.format("%x", check.getChecksum().getValue()) +
" file size in ZIP: " + entry.getSize() + " actual size " + count );
- throw new Exception();
+ Log.i("SDL", "If you still get problems try to reset the app or delete file at path " + path );
+ //throw new Exception();
}
} catch( Exception e ) {
Status.setText( res.getString(R.string.error_write, path) + ": " + e.getMessage() );
diff --git a/project/java/Globals.java b/project/java/Globals.java
index 2d8ca7d5b..b632eebc3 100644
--- a/project/java/Globals.java
+++ b/project/java/Globals.java
@@ -112,6 +112,7 @@ class Globals
public static int MoveMouseWithGyroscopeSpeed = 2;
public static boolean ClickMouseWithDpad = false;
public static boolean RelativeMouseMovement = ForceRelativeMouseMode; // Laptop touchpad mode
+ public static boolean ForceHardwareMouse = false;
public static int RelativeMouseMovementSpeed = 2;
public static int RelativeMouseMovementAccel = 0;
public static int ShowScreenUnderFinger = Mouse.ZOOM_NONE;
diff --git a/project/java/MainActivity.java b/project/java/MainActivity.java
index 8fd8caacc..eb13182c7 100644
--- a/project/java/MainActivity.java
+++ b/project/java/MainActivity.java
@@ -820,7 +820,6 @@ public class MainActivity extends Activity
_parent.hideScreenKeyboard();
return true;
}
- /*
if (keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_CLEAR)
{
// EditText deletes two characters at a time, here's a hacky fix
@@ -830,12 +829,12 @@ public class MainActivity extends Activity
int start = t.getSelectionStart(); //get cursor starting position
int end = t.getSelectionEnd(); //get cursor ending position
if ( start < 0 )
- return true;
+ return false;
if ( end < 0 || end == start )
{
start --;
if ( start < 0 )
- return true;
+ return false;
end = start + 1;
}
t.setText(t.getText().toString().substring(0, start) + t.getText().toString().substring(end));
@@ -843,7 +842,6 @@ public class MainActivity extends Activity
return true;
}
}
- */
//Log.i("SDL", "Key " + keyCode + " flags " + event.getFlags() + " action " + event.getAction());
return false;
}
diff --git a/project/java/Settings.java b/project/java/Settings.java
index da85b52b9..1ba99c6c8 100644
--- a/project/java/Settings.java
+++ b/project/java/Settings.java
@@ -186,6 +186,7 @@ public class Settings
out.writeBoolean(Globals.ImmersiveMode);
out.writeBoolean(Globals.AutoDetectOrientation);
out.writeBoolean(Globals.TvBorders);
+ out.writeBoolean(Globals.ForceHardwareMouse);
out.close();
settingsLoaded = true;
@@ -379,6 +380,7 @@ public class Settings
Globals.ImmersiveMode = settingsFile.readBoolean();
Globals.AutoDetectOrientation = settingsFile.readBoolean();
Globals.TvBorders = settingsFile.readBoolean();
+ Globals.ForceHardwareMouse = settingsFile.readBoolean();
settingsLoaded = true;
diff --git a/project/java/SettingsMenuMouse.java b/project/java/SettingsMenuMouse.java
index e1f5feeb1..cf5160070 100644
--- a/project/java/SettingsMenuMouse.java
+++ b/project/java/SettingsMenuMouse.java
@@ -124,21 +124,25 @@ class SettingsMenuMouse extends SettingsMenu
p.getResources().getString(R.string.display_size_small),
p.getResources().getString(R.string.display_size_small_touchpad),
p.getResources().getString(R.string.display_size_large),
+ p.getResources().getString(R.string.display_size_desktop),
};
int _size_small = 0;
int _size_small_touchpad = 1;
int _size_large = 2;
- int _more_options = 3;
+ int _size_desktop = 3;
+ int _more_options = 4;
if( ! Globals.SwVideoMode )
{
CharSequence[] items2 = {
p.getResources().getString(R.string.display_size_small_touchpad),
p.getResources().getString(R.string.display_size_large),
+ p.getResources().getString(R.string.display_size_desktop),
};
items = items2;
_size_small_touchpad = 0;
_size_large = 1;
+ _size_desktop = 2;
_size_small = 1000;
}
if( firstStart )
@@ -147,6 +151,7 @@ class SettingsMenuMouse extends SettingsMenu
p.getResources().getString(R.string.display_size_small),
p.getResources().getString(R.string.display_size_small_touchpad),
p.getResources().getString(R.string.display_size_large),
+ p.getResources().getString(R.string.display_size_desktop),
p.getResources().getString(R.string.show_more_options),
};
items = items2;
@@ -155,6 +160,7 @@ class SettingsMenuMouse extends SettingsMenu
CharSequence[] items3 = {
p.getResources().getString(R.string.display_size_small_touchpad),
p.getResources().getString(R.string.display_size_large),
+ p.getResources().getString(R.string.display_size_desktop),
p.getResources().getString(R.string.show_more_options),
};
items = items3;
@@ -165,6 +171,7 @@ class SettingsMenuMouse extends SettingsMenu
final int size_small = _size_small;
final int size_small_touchpad = _size_small_touchpad;
final int size_large = _size_large;
+ final int size_desktop = _size_desktop;
final int more_options = _more_options;
AlertDialog.Builder builder = new AlertDialog.Builder(p);
@@ -174,23 +181,33 @@ class SettingsMenuMouse extends SettingsMenu
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
+ if( item == size_desktop )
+ {
+ Globals.LeftClickMethod = Mouse.LEFT_CLICK_NORMAL;
+ Globals.RelativeMouseMovement = false;
+ Globals.ShowScreenUnderFinger = Mouse.ZOOM_NONE;
+ Globals.ForceHardwareMouse = true;
+ }
if( item == size_large )
{
Globals.LeftClickMethod = Mouse.LEFT_CLICK_NORMAL;
Globals.RelativeMouseMovement = false;
Globals.ShowScreenUnderFinger = Mouse.ZOOM_NONE;
+ Globals.ForceHardwareMouse = false;
}
if( item == size_small )
{
Globals.LeftClickMethod = Mouse.LEFT_CLICK_NEAR_CURSOR;
Globals.RelativeMouseMovement = false;
Globals.ShowScreenUnderFinger = Mouse.ZOOM_MAGNIFIER;
+ Globals.ForceHardwareMouse = false;
}
if( item == size_small_touchpad )
{
Globals.LeftClickMethod = Mouse.LEFT_CLICK_WITH_TAP_OR_TIMEOUT;
Globals.RelativeMouseMovement = true;
Globals.ShowScreenUnderFinger = Mouse.ZOOM_NONE;
+ Globals.ForceHardwareMouse = false;
}
if( item == more_options )
{
diff --git a/project/java/Video.java b/project/java/Video.java
index 3454ad472..cb0eb8761 100644
--- a/project/java/Video.java
+++ b/project/java/Video.java
@@ -106,8 +106,8 @@ abstract class DifferentTouchInput
public abstract void process(final MotionEvent event);
public abstract void processGenericEvent(final MotionEvent event);
- public static int ExternalMouseDetected = 0;
-
+ public static int ExternalMouseDetected = Mouse.MOUSE_HW_INPUT_FINGER;
+
public static DifferentTouchInput touchInput = getInstance();
public static DifferentTouchInput getInstance()
@@ -315,8 +315,8 @@ abstract class DifferentTouchInput
}
public void process(final MotionEvent event)
{
- int hwMouseEvent = ((event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS) ? Mouse.MOUSE_HW_INPUT_STYLUS :
- ((event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) ? Mouse.MOUSE_HW_INPUT_MOUSE :
+ int hwMouseEvent = ((event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE || Globals.ForceHardwareMouse) ? Mouse.MOUSE_HW_INPUT_MOUSE :
+ ((event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS) ? Mouse.MOUSE_HW_INPUT_STYLUS :
Mouse.MOUSE_HW_INPUT_FINGER;
if( ExternalMouseDetected != hwMouseEvent )
{
diff --git a/project/java/translations/values/strings.xml b/project/java/translations/values/strings.xml
index 834ce24d7..74ca529f0 100644
--- a/project/java/translations/values/strings.xml
+++ b/project/java/translations/values/strings.xml
@@ -163,6 +163,7 @@
Mouse emulation mode
Display size for mouse emulation
+ Desktop, no emulation
Large (tablets)
Small, magnifying glass
Small, touchpad mode
diff --git a/project/jni/application/Android.mk b/project/jni/application/Android.mk
index f162fbeea..2f8fdf47a 100644
--- a/project/jni/application/Android.mk
+++ b/project/jni/application/Android.mk
@@ -49,9 +49,6 @@ LOCAL_SHARED_LIBRARIES := sdl-$(SDL_VERSION) $(filter-out $(APP_AVAILABLE_STATIC
LOCAL_STATIC_LIBRARIES := $(filter $(APP_AVAILABLE_STATIC_LIBS), $(COMPILED_LIBRARIES))
-$(warning APP LOCAL_SHARED_LIBRARIES $(LOCAL_SHARED_LIBRARIES))
-$(warning APP LOCAL_STATIC_LIBRARIES $(LOCAL_STATIC_LIBRARIES))
-
APP_STL := gnustl_static
LOCAL_LDLIBS := $(APPLICATION_GLES_LIBRARY) -ldl -llog -lz # -lgnustl_static
diff --git a/project/jni/application/ballfield/ballfield.cpp b/project/jni/application/ballfield/ballfield.cpp
index 78cd94345..7756c6c72 100644
--- a/project/jni/application/ballfield/ballfield.cpp
+++ b/project/jni/application/ballfield/ballfield.cpp
@@ -689,11 +689,12 @@ int main(int argc, char* argv[])
if(evt.key.keysym.sym == SDLK_0)
{
SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, 1);
+ SDL_ANDROID_SetMouseEmulationMode(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
}
if(evt.key.keysym.sym == SDLK_1)
{
SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, 0);
- SDL_ANDROID_OpenExternalWebBrowser("http:/google.com/");
+ SDL_ANDROID_SetMouseEmulationMode(1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
}
if(evt.key.keysym.sym == SDLK_2)
{
diff --git a/project/jni/application/commandergenius/AndroidAppSettings.cfg b/project/jni/application/commandergenius/AndroidAppSettings.cfg
index 66fa305bc..0f1c7582e 100644
--- a/project/jni/application/commandergenius/AndroidAppSettings.cfg
+++ b/project/jni/application/commandergenius/AndroidAppSettings.cfg
@@ -7,10 +7,10 @@ AppName="Commander Genius"
AppFullName=net.sourceforge.clonekeenplus
# Application version code (integer)
-AppVersionCode=198300
+AppVersionCode=198600
# Application user-visible version name (string)
-AppVersionName="1.9.8.3 Beta"
+AppVersionName="1.9.8.6 Beta"
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
diff --git a/project/jni/application/commandergenius/commandergenius b/project/jni/application/commandergenius/commandergenius
index 3cadca295..2dc893395 160000
--- a/project/jni/application/commandergenius/commandergenius
+++ b/project/jni/application/commandergenius/commandergenius
@@ -1 +1 @@
-Subproject commit 3cadca29551ca2fa1f01a64120acf8f25b3cd1bd
+Subproject commit 2dc893395b6720d118dda626de8f09561758e66a
diff --git a/project/jni/application/ninslash/src b/project/jni/application/ninslash/src
index 721417db3..9b2cee79d 160000
--- a/project/jni/application/ninslash/src
+++ b/project/jni/application/ninslash/src
@@ -1 +1 @@
-Subproject commit 721417db327fc76628adcf673b068a7a75810d49
+Subproject commit 9b2cee79d1e00fb3a19953c43b2e8a1e55538d63
diff --git a/project/jni/application/openttd/src b/project/jni/application/openttd/src
index f03484e84..b394d53be 160000
--- a/project/jni/application/openttd/src
+++ b/project/jni/application/openttd/src
@@ -1 +1 @@
-Subproject commit f03484e84ba64a806d59da435d68398bda32caf9
+Subproject commit b394d53be82ec280e9c0909ce42779e6625c107c
diff --git a/project/jni/curl/lib/Makefile.inc b/project/jni/curl/lib/Makefile.inc
index b573e932e..a3e4a15c3 100644
--- a/project/jni/curl/lib/Makefile.inc
+++ b/project/jni/curl/lib/Makefile.inc
@@ -78,3 +78,4 @@ LIB_RCFILES = libcurl.rc
CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES)
HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES)
+
diff --git a/project/jni/fontconfig/Android.mk b/project/jni/fontconfig/Android.mk
index 7b447f214..ef941b83f 100644
--- a/project/jni/fontconfig/Android.mk
+++ b/project/jni/fontconfig/Android.mk
@@ -13,7 +13,7 @@ LOCAL_CFLAGS += -DHAVE_CONFIG_H
LOCAL_SHARED_LIBRARIES := freetype expat
-LOCAL_LDLIBS := -lz
+#LOCAL_LDLIBS := -lz
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
diff --git a/project/jni/gl4es/README.md b/project/jni/gl4es/README.md
index 353994af1..ee7094c94 100755
--- a/project/jni/gl4es/README.md
+++ b/project/jni/gl4es/README.md
@@ -134,6 +134,11 @@ Experimental: enable Alpha test only when using texture that contains an alpha c
* 0 : Default, nothing special
* 1 : Alpha Hack enabled
+##### LIBGL_NODOWNSAMPLING
+Texture downsampling control
+ * 0 : Default, DXTc texture are downsampled to 16bits
+ * 1 : DXTc texture are left as 32bits RGBA
+
##### LIBGL_STREAM
PANDORA only: enable Texture Streaming (works only on RGB textures)
* 0 : Default, nothing special
@@ -220,11 +225,21 @@ Initial Hardware test
* 0 : Default, perform intial hardware testing (using a PBuffer)
* 1 : Do not perform test (no extensions tested or used)
+##### LIBGL_NOVAOCACHE
+VAO Caching
+ * 0 : Default, tr to cache vao to avoid memcpy in render list
+ * 1 : Don't cache VAO
+
----
Version history
----
+##### current version
+ * Fixed (Added in fact) support for Multisampling on the GLX Context creation (a bit hacky, but seems to works)
+ * Added LIBGL_NODOWNSAMPLING and associated Hint
+ * Try to implement some caching on VAO to avoid some memcpy in renderlist (with a way to disable it just in case)
+
##### 0.9.3
* Added support for Cube Mapping (with hardware support)
* Improved Texture state tracking
diff --git a/project/jni/gl4es/include/gl4eshint.h b/project/jni/gl4es/include/gl4eshint.h
index 024845ed6..04c9ee0a0 100755
--- a/project/jni/gl4es/include/gl4eshint.h
+++ b/project/jni/gl4es/include/gl4eshint.h
@@ -23,5 +23,7 @@
#define GL_BATCH_HINT_GL4ES 0xA109
// same as using LIBGL_NOERROR=x
#define GL_NOERROR_HINT_GL4ES 0xA10A
+// same as using LIBGL_NODOWNSAMPLING=x
+#define GL_NODOWNSAMPLING_HINT_GL4ES 0xA10B
#endif
\ No newline at end of file
diff --git a/project/jni/gl4es/src/config.h b/project/jni/gl4es/src/config.h
index 76f996062..b6987af1c 100755
--- a/project/jni/gl4es/src/config.h
+++ b/project/jni/gl4es/src/config.h
@@ -1,6 +1,7 @@
#define SYS_proxy 9999
#define MAX_EVAL_ORDER 30
#define MAX_TEX 8
+#define MAX_LIGHT 8
#define MAX_STACK_PROJECTION 16
#define MAX_STACK_TEXTURE 16
#define MAX_STACK_MODELVIEW 64
diff --git a/project/jni/gl4es/src/gl/buffers.c b/project/jni/gl4es/src/gl/buffers.c
index 2735f4ba1..2ece32c9c 100755
--- a/project/jni/gl4es/src/gl/buffers.c
+++ b/project/jni/gl4es/src/gl/buffers.c
@@ -1,5 +1,6 @@
#include "buffers.h"
#include "debug.h"
+#include "../glx/hardext.h"
static GLuint lastbuffer = 1;
@@ -125,7 +126,11 @@ void gl4es_glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLe
}
if (buff->data) {
free(buff->data);
+
}
+ if(target==GL_ARRAY_BUFFER)
+ VaoSharedClear(glstate->vao);
+
buff->size = size;
buff->usage = usage;
buff->data = malloc(size);
@@ -147,6 +152,10 @@ void gl4es_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, cons
// printf("LIBGL: Warning, null buffer for target=0x%04X for glBufferSubData\n", target);
return;
}
+
+ if(target==GL_ARRAY_BUFFER)
+ VaoSharedClear(glstate->vao);
+
memcpy(buff->data + offset, data, size); //TODO, some check maybe?
noerrorShim();
}
@@ -157,6 +166,7 @@ void gl4es_glDeleteBuffers(GLsizei n, const GLuint * buffers) {
flush();
}
+ VaoSharedClear(glstate->vao);
khash_t(buff) *list = glstate->buffers;
if (list) {
khint_t k;
@@ -247,6 +257,10 @@ void *gl4es_glMapBuffer(GLenum target, GLenum access) {
errorShim(GL_INVALID_ENUM);
return (void*)NULL;
}
+
+ if(target==GL_ARRAY_BUFFER)
+ VaoSharedClear(glstate->vao);
+
glbuffer_t *buff = getbuffer_buffer(target);
if (buff==NULL)
return (void*)NULL; // Should generate an error!
@@ -262,6 +276,10 @@ GLboolean gl4es_glUnmapBuffer(GLenum target) {
errorShim(GL_INVALID_ENUM);
return GL_FALSE;
}
+
+ if(target==GL_ARRAY_BUFFER)
+ VaoSharedClear(glstate->vao);
+
glbuffer_t *buff = getbuffer_buffer(target);
if (buff==NULL)
return GL_FALSE; // Should generate an error!
@@ -280,10 +298,11 @@ void gl4es_glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, G
return;
}
glbuffer_t *buff = getbuffer_buffer(target);
+
if (buff==NULL)
return; // Should generate an error!
// TODO, check parameter consistancie
- memcpy(data, buff->data+offset, size);
+ memcpy(data, buff->data+offset, size);
noerrorShim();
}
@@ -406,6 +425,7 @@ void gl4es_glDeleteVertexArrays(GLsizei n, const GLuint *arrays) {
k = kh_get(glvao, list, t);
if (k != kh_end(list)) {
glvao = kh_value(list, k);
+ VaoSharedClear(glvao);
kh_del(glvao, list, k);
free(glvao);
}
@@ -428,7 +448,28 @@ GLboolean gl4es_glIsVertexArray(GLuint array) {
return GL_FALSE;
}
-//Dirzct wrapper
+void VaoSharedClear(glvao_t *vao) {
+ if(vao==NULL || vao->shared_arrays==NULL)
+ return;
+ if(!(--(*vao->shared_arrays))) {
+ free(vao->vert.ptr);
+ free(vao->color.ptr);
+ free(vao->secondary.ptr);
+ free(vao->normal.ptr);
+ for (int i=0; itex[i].ptr);
+ free(vao->shared_arrays);
+ }
+ vao->vert.ptr = NULL;
+ vao->color.ptr = NULL;
+ vao->secondary.ptr = NULL;
+ vao->normal.ptr = NULL;
+ for (int i=0; itex[i].ptr = NULL;
+ vao->shared_arrays = NULL;
+}
+
+//Direct wrapper
void glGenVertexArrays(GLsizei n, GLuint *arrays) AliasExport("gl4es_glGenVertexArrays");
void glBindVertexArray(GLuint array) AliasExport("gl4es_glBindVertexArray");
void glDeleteVertexArrays(GLsizei n, const GLuint *arrays) AliasExport("gl4es_glDeleteVertexArrays");
diff --git a/project/jni/gl4es/src/gl/buffers.h b/project/jni/gl4es/src/gl/buffers.h
index efd56013c..57503d70e 100755
--- a/project/jni/gl4es/src/gl/buffers.h
+++ b/project/jni/gl4es/src/gl/buffers.h
@@ -65,6 +65,12 @@ typedef struct {
pointer_state_t vertex, color, normal, tex_coord[MAX_TEX], secondary;
} pointer_states_t;
+typedef struct {
+ GLfloat *ptr;
+ pointer_state_t state;
+ GLboolean enabled;
+} pointer_cache_t;
+
// VAO ****************
typedef struct {
GLuint array;
@@ -81,8 +87,18 @@ typedef struct {
normal_array,
vertex_array,
tex_coord_array[MAX_TEX];
+ // VAO optimisation: keep a shared copy of the digested datas (unless the vao is the default one)
+ int *shared_arrays;
+ pointer_cache_t vert;
+ pointer_cache_t normal;
+ pointer_cache_t color;
+ pointer_cache_t secondary;
+ pointer_cache_t tex[MAX_TEX];
+ int cache_count;
} glvao_t;
+void VaoSharedClear(glvao_t *vao);
+
KHASH_MAP_INIT_INT(glvao, glvao_t*)
void gl4es_glGenVertexArrays(GLsizei n, GLuint *arrays);
diff --git a/project/jni/gl4es/src/gl/const.h b/project/jni/gl4es/src/gl/const.h
index b31b51a1f..a8705409e 100755
--- a/project/jni/gl4es/src/gl/const.h
+++ b/project/jni/gl4es/src/gl/const.h
@@ -17,6 +17,7 @@
#define GL_TEXTURE_GEN_T 0x0C61
#define GL_TEXTURE_GEN_MODE 0x2500
#define GL_TEXTURE_BORDER_COLOR 0x1004
+#define GL_TEXTURE_BORDER 0x1005
#define GL_TEXTURE_WIDTH 0x1000
#define GL_TEXTURE_HEIGHT 0x1001
#define GL_TEXTURE_BORDER 0x1005
diff --git a/project/jni/gl4es/src/gl/debug.c b/project/jni/gl4es/src/gl/debug.c
index 71d71f19c..0a7cb4692 100755
--- a/project/jni/gl4es/src/gl/debug.c
+++ b/project/jni/gl4es/src/gl/debug.c
@@ -82,6 +82,8 @@ const char* PrintEnum(GLenum what) {
p(GL_TEXTURE_WIDTH);
p(GL_TEXTURE_HEIGHT);
p(GL_TEXTURE_COMPRESSED);
+ p(GL_TEXTURE_BORDER);
+ p(GL_TEXTURE_INTERNAL_FORMAT);
// texture pack/unpack
p(GL_UNPACK_ALIGNMENT);
// framebuffer
diff --git a/project/jni/gl4es/src/gl/getter.c b/project/jni/gl4es/src/gl/getter.c
index 0c3f2ba29..ddc9cd50e 100755
--- a/project/jni/gl4es/src/gl/getter.c
+++ b/project/jni/gl4es/src/gl/getter.c
@@ -9,7 +9,8 @@ GLenum gl4es_glGetError() {
if(globals4es.noerror)
return GL_NO_ERROR;
if (glstate->shim_error) {
- GLenum tmp = glstate->last_error;
+ GLenum tmp = gles_glGetError(); // to purge GLES error stack
+ tmp = glstate->last_error;
glstate->last_error = GL_NO_ERROR;
return tmp;
}
@@ -488,6 +489,9 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) {
case GL_NOERROR_HINT_GL4ES:
*params=globals4es.noerror;
break;
+ case GL_NODOWNSAMPLING_HINT_GL4ES:
+ *params=globals4es.nodownsampling;
+ 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 81dd333f0..f3d3e27ad 100755
--- a/project/jni/gl4es/src/gl/gl.c
+++ b/project/jni/gl4es/src/gl/gl.c
@@ -276,13 +276,13 @@ void gl4es_glEnable(GLenum cap) {
}
}
PUSH_IF_COMPILING(glEnable)
-
+#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;
}
-
+#endif
LOAD_GLES(glEnable);
proxy_glEnable(cap, true, gles_glEnable);
}
@@ -369,6 +369,28 @@ GLboolean gl4es_glIsEnabled(GLenum cap) {
#undef clientisenabled
GLboolean glIsEnabled(GLenum cap) AliasExport("gl4es_glIsEnabled");
+static GLboolean is_cache_compatible(GLsizei count) {
+ #define T2(AA, A, B) \
+ if(glstate->vao->AA!=glstate->vao->B.enabled) return GL_FALSE; \
+ if(glstate->vao->B.enabled && memcmp(&glstate->vao->pointers.A, &glstate->vao->B.state, sizeof(pointer_state_t))) return GL_FALSE;
+ #define TEST(A,B) T2(A##_array, A, B)
+ #define TESTA(A,B,I) T2(A##_array[i], A[i], B[i])
+
+ if(glstate->vao == glstate->defaultvao) return GL_FALSE;
+ if(count > glstate->vao->cache_count) return GL_FALSE;
+ TEST(vertex, vert)
+ TEST(color, color)
+ TEST(secondary, secondary)
+ TEST(normal, normal)
+ for (int i=0; imode_init = mode;
list->len = count-skip;
list->cap = count-skip;
+
+ // check cache if any
+ if(glstate->vao->shared_arrays) {
+ if (!is_cache_compatible(count))
+ VaoSharedClear(glstate->vao);
+ }
- if (glstate->vao->vertex_array) {
- list->vert = copy_gl_pointer_tex(&glstate->vao->pointers.vertex, 4, skip, count);
- }
- if (glstate->vao->color_array) {
- if(glstate->vao->pointers.color.size==GL_BGRA)
- list->color = copy_gl_pointer_color_bgra(&glstate->vao->pointers.color, 4, skip, count);
- else
- list->color = copy_gl_pointer_color(&glstate->vao->pointers.color, 4, skip, count);
- }
- if (glstate->vao->secondary_array/* && glstate->enable.color_array*/) {
- if(glstate->vao->pointers.secondary.size==GL_BGRA)
- list->secondary = copy_gl_pointer_color_bgra(&glstate->vao->pointers.secondary, 4, skip, count);
- else
- list->secondary = copy_gl_pointer(&glstate->vao->pointers.secondary, 4, skip, count); // alpha chanel is always 0 for secondary...
- }
- if (glstate->vao->normal_array) {
- list->normal = copy_gl_pointer_raw(&glstate->vao->pointers.normal, 3, skip, count);
- }
- for (int i=0; ivao->tex_coord_array[i]) {
- list->tex[i] = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[i], 4, skip, count);
- }
- }
+ if(glstate->vao->shared_arrays) {
+ #define OP(A, N) (A)?A+skip*N:NULL
+ list->vert = OP(glstate->vao->vert.ptr,4);
+ list->color = OP(glstate->vao->color.ptr,4);
+ list->secondary = OP(glstate->vao->secondary.ptr,4);
+ list->normal = OP(glstate->vao->normal.ptr,3);
+ for (int i=0; itex[i] = OP(glstate->vao->tex[i].ptr,4);
+ #undef OP
+
+ list->shared_arrays = glstate->vao->shared_arrays;
+ (*glstate->vao->shared_arrays)++;
+ } else {
+ if(!globals4es.novaocache && glstate->vao != glstate->defaultvao) {
+ // prepare a vao cache object
+ list->shared_arrays = glstate->vao->shared_arrays = (int*)malloc(sizeof(int));
+ *glstate->vao->shared_arrays = 1;
+ #define G2(AA, A, B) \
+ glstate->vao->B.enabled = glstate->vao->AA; \
+ if (glstate->vao->B.enabled) memcpy(&glstate->vao->B.state, &glstate->vao->pointers.A, sizeof(pointer_state_t));
+ #define GO(A,B) G2(A##_array, A, B)
+ #define GOA(A,B,I) G2(A##_array[i], A[i], B[i])
+ GO(vertex, vert)
+ GO(color, color)
+ GO(secondary, secondary)
+ GO(normal, normal)
+ for (int i=0; ivao->cache_count = count;
+ #undef GOA
+ #undef GO
+ #undef G2
+ }
+ if (glstate->vao->vertex_array) {
+ if(glstate->vao->shared_arrays) {
+ glstate->vao->vert.ptr = copy_gl_pointer_tex(&glstate->vao->pointers.vertex, 4, 0, count);
+ list->vert = glstate->vao->vert.ptr + 4*skip;
+ } else
+ list->vert = copy_gl_pointer_tex(&glstate->vao->pointers.vertex, 4, skip, count);
+ }
+ if (glstate->vao->color_array) {
+ if(glstate->vao->shared_arrays) {
+ if(glstate->vao->pointers.color.size==GL_BGRA)
+ glstate->vao->color.ptr = copy_gl_pointer_color_bgra(&glstate->vao->pointers.color, 4, 0, count);
+ else
+ glstate->vao->color.ptr = copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, count);
+ list->color = glstate->vao->color.ptr + 4*skip;
+ } else {
+ if(glstate->vao->pointers.color.size==GL_BGRA)
+ list->color = copy_gl_pointer_color_bgra(&glstate->vao->pointers.color, 4, skip, count);
+ else
+ list->color = copy_gl_pointer_color(&glstate->vao->pointers.color, 4, skip, count);
+ }
+ }
+ if (glstate->vao->secondary_array/* && glstate->enable.color_array*/) {
+ if(glstate->vao->shared_arrays) {
+ if(glstate->vao->pointers.secondary.size==GL_BGRA)
+ glstate->vao->secondary.ptr = copy_gl_pointer_color_bgra(&glstate->vao->pointers.secondary, 4, 0, count);
+ else
+ glstate->vao->secondary.ptr = copy_gl_pointer(&glstate->vao->pointers.secondary, 4, 0, count); // alpha chanel is always 0 for secondary...
+ list->secondary = glstate->vao->secondary.ptr + 4*skip;
+ } else {
+ if(glstate->vao->pointers.secondary.size==GL_BGRA)
+ list->secondary = copy_gl_pointer_color_bgra(&glstate->vao->pointers.secondary, 4, skip, count);
+ else
+ list->secondary = copy_gl_pointer(&glstate->vao->pointers.secondary, 4, skip, count); // alpha chanel is always 0 for secondary...
+ }
+ }
+ if (glstate->vao->normal_array) {
+ if(glstate->vao->shared_arrays) {
+ glstate->vao->normal.ptr = copy_gl_pointer_raw(&glstate->vao->pointers.normal, 3, 0, count);
+ list->normal = glstate->vao->normal.ptr + 3*skip;
+ } else
+ list->normal = copy_gl_pointer_raw(&glstate->vao->pointers.normal, 3, skip, count);
+ }
+ for (int i=0; ivao->tex_coord_array[i]) {
+ if(glstate->vao->shared_arrays) {
+ glstate->vao->tex[i].ptr = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[i], 4, 0, count);
+ list->tex[i] = glstate->vao->tex[i].ptr + 4*skip;
+ } else
+ list->tex[i] = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[i], 4, skip, count);
+ }
+ }
+ }
return list;
}
@@ -411,6 +502,10 @@ static inline bool should_intercept_render(GLenum mode) {
if (glstate->enable.texture[aa]) {
if ((glstate->enable.texgen_s[aa] || glstate->enable.texgen_t[aa] || glstate->enable.texgen_r[aa] || glstate->enable.texgen_q[aa]))
return true;
+ if ((!glstate->vao->tex_coord_array[aa]) && !(mode==GL_POINT && glstate->texture.pscoordreplace[aa]))
+ return true;
+ if ((glstate->vao->tex_coord_array[aa]) && (glstate->vao->pointers.tex_coord[aa].size == 1))
+ return true;
}
}
if(glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES)
@@ -422,7 +517,7 @@ static inline bool should_intercept_render(GLenum mode) {
return (
(glstate->vao->vertex_array && ! valid_vertex_type(glstate->vao->pointers.vertex.type)) ||
(mode == GL_LINES && glstate->enable.line_stipple) ||
- (mode == GL_QUADS) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch))
+ /*(mode == GL_QUADS) ||*/ (glstate->list.active && (glstate->list.compiling || glstate->gl_batch))
);
}
@@ -477,7 +572,7 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
return;
}
- if (should_intercept_render(mode)) {
+ if (should_intercept_render(mode) || (mode==GL_QUADS)) {
renderlist_t *list = NULL;
GLsizei min, max;
@@ -508,6 +603,7 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
LOAD_GLES(glDisable);
LOAD_GLES(glEnableClientState);
LOAD_GLES(glDisableClientState);
+ LOAD_GLES(glMultiTexCoord4f);
GLuint len = 0;
for (int i=0; ivao->pointers.vertex.size, glstate->vao->pointers.vertex.type, glstate->vao->pointers.vertex.stride, glstate->vao->pointers.vertex.pointer);
GLuint old_tex = glstate->texture.client;
#define TEXTURE(A) gl4es_glClientActiveTexture(A+GL_TEXTURE0);
- for (int aa=0; aaenable.texture[aa]);
@@ -559,7 +655,13 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
if (glstate->vao->tex_coord_array[aa]) {
TEXTURE(aa);
tex_setup_texcoord(len, itarget);
- }
+ } else
+ gles_glMultiTexCoord4f(GL_TEXTURE0+aa, glstate->texcoord[aa][0], glstate->texcoord[aa][1], glstate->texcoord[aa][2], glstate->texcoord[aa][3]);
+ } else if (glstate->clientstate.tex_coord_array[aa]) {
+ // special case, Tex disable but CoordArray enabled... disabling it temporarly
+ TEXTURE(aa);
+ glstate->clientstate.tex_coord_array[aa] = 0;
+ gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
if (glstate->texture.client!=old_tex)
@@ -567,7 +669,7 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
// POLYGON mode as LINE is "intercepted" and drawn using list
gles_glDrawElements(mode, count, GL_UNSIGNED_SHORT, sindices);
- for (int aa=0; aaenable.texture[aa]) && (IS_ANYTEX(glstate->enable.texture[aa]))) {
TEXTURE(aa);
gles_glDisable(GL_TEXTURE_2D);
@@ -615,6 +717,7 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
LOAD_GLES(glDisable);
LOAD_GLES(glEnableClientState);
LOAD_GLES(glDisableClientState);
+ LOAD_GLES(glMultiTexCoord4f);
if (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) {
NewStage(glstate->list.active, STAGE_DRAW);
@@ -635,6 +738,35 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
draw_renderlist(list);
free_renderlist(list);
} else {
+ if (mode==GL_QUADS) {
+ static GLushort *indices = NULL;
+ static int indcnt = 0;
+ static int indfirst = 0;
+ if((indcnt < count) || (indfirst!=first)) {
+ if(indcnt < count) {
+ indcnt = count;
+ if (indices) free(indices);
+ indices = (GLushort*)malloc(sizeof(GLushort)*(indcnt*3/2));
+ }
+ indfirst = first;
+ for (int i=0, j=0; i+3vao->elements;
+ glstate->vao->elements = NULL;
+ gl4es_glDrawElements(GL_TRIANGLES, count*3/2, GL_UNSIGNED_SHORT, indices);
+ glstate->vao->elements = old_vao_elements;
+ return;
+ }
+
LOAD_GLES(glDrawArrays);
GLenum mode_init = mode;
@@ -658,7 +790,7 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
gles_glVertexPointer(glstate->vao->pointers.vertex.size, glstate->vao->pointers.vertex.type, glstate->vao->pointers.vertex.stride, glstate->vao->pointers.vertex.pointer);
GLuint old_tex = glstate->texture.client;
#define TEXTURE(A) gl4es_glClientActiveTexture(A+GL_TEXTURE0);
- for (int aa=0; aaenable.texture[aa]);
@@ -670,9 +802,13 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
if (glstate->vao->tex_coord_array[aa]) {
TEXTURE(aa);
tex_setup_texcoord(count+first, itarget);
- /*glClientActiveTexture(aa+GL_TEXTURE0);
- gles_glTexCoordPointer(glstate->pointers.tex_coord[aa].size, glstate->pointers.tex_coord[aa].type, glstate->pointers.tex_coord[aa].stride, glstate->pointers.tex_coord[aa].pointer);*/
- }
+ } else
+ gles_glMultiTexCoord4f(GL_TEXTURE0+aa, glstate->texcoord[aa][0], glstate->texcoord[aa][1], glstate->texcoord[aa][2], glstate->texcoord[aa][3]);
+ } else if (glstate->clientstate.tex_coord_array[aa]) {
+ // special case, Tex disable but CoordArray enabled... disabling it temporarly
+ TEXTURE(aa);
+ glstate->clientstate.tex_coord_array[aa] = 0;
+ gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
if (glstate->texture.client!=old_tex)
@@ -680,7 +816,7 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
gles_glDrawArrays(mode, first, count);
- for (int aa=0; aaenable.texture[aa]) && (IS_ANYTEX(glstate->enable.texture[aa]))) {
TEXTURE(aa);
gles_glDisable(GL_TEXTURE_2D);
@@ -1544,9 +1680,10 @@ void glPointParameterfv(GLenum pname, const GLfloat * params) AliasExport("gl4es
void gl4es_glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount)
{
LOAD_GLES_EXT(glMultiDrawArrays);
- if((!gles_glMultiDrawArrays) || should_intercept_render(mode) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch))
+ if((!gles_glMultiDrawArrays) || should_intercept_render(mode) || (mode==GL_QUADS) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch))
|| (glstate->render_mode == GL_SELECT) || ((glstate->polygon_mode == GL_LINE) || (glstate->polygon_mode == GL_POINT)) )
{
+ // GL_QUADS special case can probably by improved
// divide the call
// TODO optimize with forcing Batch mode
for (int i=0; ilist.active && (glstate->list.compiling || glstate->gl_batch))
+ if((!gles_glMultiDrawElements) || should_intercept_render(mode) || (mode==GL_QUADS) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch))
|| (glstate->render_mode == GL_SELECT) || ((glstate->polygon_mode == GL_LINE) || (glstate->polygon_mode == GL_POINT)) || (type != GL_UNSIGNED_SHORT) )
{
// divide the call
diff --git a/project/jni/gl4es/src/gl/hint.c b/project/jni/gl4es/src/gl/hint.c
index 0d24cc995..47c40ffc5 100755
--- a/project/jni/gl4es/src/gl/hint.c
+++ b/project/jni/gl4es/src/gl/hint.c
@@ -69,6 +69,12 @@ void gl4es_glHint(GLenum pname, GLenum mode) {
else
errorShim(GL_INVALID_ENUM);
break;
+ case GL_NODOWNSAMPLING_HINT_GL4ES:
+ if (mode<=1)
+ globals4es.nodownsampling = 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 ee6d82b68..5e399f10e 100755
--- a/project/jni/gl4es/src/gl/init.c
+++ b/project/jni/gl4es/src/gl/init.c
@@ -257,8 +257,14 @@ void initialize_gl4es() {
globals4es.queries = 0;
SHUT(LOGD("LIBGL: Dont't expose fake glQueries functions\n"));
}
+ char *env_nodownsampling = getenv("LIBGL_NODOWNSAMPLING");
+ if (env_nodownsampling && strcmp(env_nodownsampling, "1") == 0) {
+ globals4es.nodownsampling = 1;
+ SHUT(LOGD("LIBGL: No downsampling of DXTc textures\n"));
+ }
env(LIBGL_NOTEXMAT, globals4es.texmat, "Don't handle Texture Matrice internaly");
+ env(LIBGL_NOVAOCACHE, globals4es.novaocache, "Don't use VAO cache");
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 2c35a8089..dc3dd3219 100755
--- a/project/jni/gl4es/src/gl/init.h
+++ b/project/jni/gl4es/src/gl/init.h
@@ -33,10 +33,12 @@ typedef struct _globals4es {
int queries;
int silentstub;
int glx_surface_srgb;
+ int nodownsampling;
#ifdef PANDORA
float gamma;
#endif
int texmat;
+ int novaocache;
char version[50];
} globals4es_t;
diff --git a/project/jni/gl4es/src/gl/list.c b/project/jni/gl4es/src/gl/list.c
index f39122aa1..df33de80e 100755
--- a/project/jni/gl4es/src/gl/list.c
+++ b/project/jni/gl4es/src/gl/list.c
@@ -681,12 +681,13 @@ void adjust_renderlist(renderlist_t *list) {
list->stage = STAGE_LAST;
list->open = false;
for (int a=0; atexture.bound[a][ENABLED_TEX2D]; //TODO check if hardcoded TEX2D is ok
+ const GLint itarget = get_target(glstate->enable.texture[a]);
+ gltexture_t *bound = glstate->texture.bound[a][itarget];
// in case of Texture bounding inside a list
if (list->set_texture && (list->tmu == a))
bound = gl4es_getTexture(list->target_texture, list->texture);
// GL_ARB_texture_rectangle
- if ((list->tex[a]) && glstate->texture.rect_arb[a] && (bound)) {
+ if ((list->tex[a]) && (itarget == ENABLED_TEXTURE_RECTANGLE) && (bound)) {
tex_coord_rect_arb(list->tex[a], list->len, bound->width, bound->height);
}
}
@@ -935,7 +936,7 @@ void draw_renderlist(renderlist_t *list) {
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]);
diff --git a/project/jni/gl4es/src/gl/matrix.c b/project/jni/gl4es/src/gl/matrix.c
index 9fafd61ec..10eaa7319 100755
--- a/project/jni/gl4es/src/gl/matrix.c
+++ b/project/jni/gl4es/src/gl/matrix.c
@@ -56,6 +56,7 @@ static int send_to_hardware() {
}
void init_matrix(glstate_t* glstate) {
+DBG(printf("init_matrix(%p)\n", glstate);)
alloc_matrix(&glstate->projection_matrix, MAX_STACK_PROJECTION);
set_identity(TOP(projection_matrix));
glstate->projection_matrix->identity = 1;
@@ -93,7 +94,7 @@ DBG(printf("glPushMatrix(), list=%p\n", glstate->list.active);)
noerrorShim();
// go...
switch(matrix_mode) {
- #define P(A, B) if(glstate->A->topA->top+1A->top++; \
} else errorShim(GL_STACK_OVERFLOW)
diff --git a/project/jni/gl4es/src/gl/pixel.c b/project/jni/gl4es/src/gl/pixel.c
index 1c2fead8a..56326dfe2 100755
--- a/project/jni/gl4es/src/gl/pixel.c
+++ b/project/jni/gl4es/src/gl/pixel.c
@@ -73,58 +73,58 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst,
case GL_UNSIGNED_INT_8_8_8_8_REV:
type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f))
type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f))
- type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort,
- s = (GLushort[]){
- (v & 0x001f),
- ((v & 0x03e0) >> 5),
- ((v & 0x7c00) >> 10),
- ((v & 0x8000) >> 15)*31,
- };
- read_each(, / 31.0f);
- )
type_case(GL_UNSIGNED_SHORT_5_6_5_REV, GLushort,
- s = (GLushort[]){
- (v & 0x001f)*2,
- ((v & 0x07e0) >> 5),
- ((v & 0xF800) >> 11)*2,
+ s = (const GLushort[]) {
+ ((v ) & 0x1f)<<1,
+ ((v >> 5) & 0x3f),
+ ((v >> 11) & 0x1f)<<1,
};
read_each(, / 63.0f);
)
+ type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort,
+ s = (const GLushort[]) {
+ ((v ) & 0x1f),
+ ((v >> 5) & 0x1f),
+ ((v >> 10) & 0x1f),
+ ((v >> 15) & 0x01)*31,
+ };
+ read_each(, / 31.0f);
+ )
type_case(GL_UNSIGNED_SHORT_4_4_4_4_REV, GLushort,
- s = (GLushort[]){
- (v & 0x000f),
- ((v & 0x00f0) >> 4),
- ((v & 0x0f00) >> 8),
- ((v & 0xf000) >> 12)
+ s = (const GLushort[]) {
+ ((v ) & 0x0f),
+ ((v >> 4 ) & 0x0f),
+ ((v >> 8 ) & 0x0f),
+ ((v >> 12 ) & 0x0f)
};
read_each(, / 15.0f);
)
type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort,
- s = (GLushort[]){
- ((v & 0xF800) >>11)*2,
- ((v & 0x07e0) >> 5),
- ((v & 0x001f) )*2,
+ s = (const GLushort[]) {
+ ((v >> 11) & 0x1f)<<1,
+ ((v >> 5) & 0x3f),
+ ((v ) & 0x1f)<<1,
};
read_each(, / 63.0f);
)
- type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
- s = (GLushort[]){
- ((v & 0xf000) >>12),
- ((v & 0x0f00) >> 8),
- ((v & 0x00f0) >> 4),
- ((v & 0x000f) )
- };
- read_each(, / 15.0f);
- )
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
- s = (GLushort[]){
- ((v & 0xf800) >> 11),
- ((v & 0x07c0) >> 6),
- ((v & 0x003e) >> 1),
- ((v & 1))*31,
+ s = (const GLushort[]) {
+ ((v >> 11) & 0x1f),
+ ((v >> 6) & 0x1f),
+ ((v >> 1) & 0x1f),
+ ((v ) & 0x01)*31,
};
read_each(, / 31.0f);
)
+ type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
+ s = (const GLushort[]) {
+ ((v >> 12) & 0x0f),
+ ((v >> 8) & 0x0f),
+ ((v >> 4) & 0x0f),
+ ((v ) & 0x0f)
+ };
+ read_each(, / 15.0f);
+ )
default:
// TODO: add glSetError?
printf("LIBGL: Unsupported source data type: %s\n", PrintEnum(src_type));
@@ -149,35 +149,35 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst,
// TODO: force 565 to RGB? then we can change [4] -> 3
type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort,
GLfloat color[4];
- color[dst_color->red] = pixel.r;
- color[dst_color->green] = pixel.g;
- color[dst_color->blue] = pixel.b;
- *d = (((GLushort)(color[0] * 31.0f) & 0x1f) << 11) |
- (((GLushort)(color[1] * 63.0f) & 0x3f) << 5) |
- (((GLushort)(color[2] * 31.0f) & 0x1f));
+ color[src_color->red] = pixel.r;
+ color[src_color->green] = pixel.g;
+ color[src_color->blue] = pixel.b;
+ *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) |
+ (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) |
+ (((GLuint)(color[2] * 31.0f) & 0x1f) );
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
GLfloat color[4];
- color[dst_color->red] = pixel.r;
- color[dst_color->green] = pixel.g;
- color[dst_color->blue] = pixel.b;
- color[dst_color->alpha] = pixel.a;
+ color[src_color->red] = pixel.r;
+ color[src_color->green] = pixel.g;
+ color[src_color->blue] = pixel.b;
+ color[src_color->alpha] = pixel.a;
// TODO: can I macro this or something? it follows a pretty strict form.
- *d = (((GLushort)(color[0] * 31.0f) & 0x1f) ) |
- (((GLushort)(color[1] * 31.0f) & 0x1f) << 5) |
- (((GLushort)(color[2] * 31.0f) & 0x1f) << 10) |
- (((GLushort)(color[3] * 1) & 0x01) << 15);
+ *d = (((GLuint)(color[3] ) & 0x01) ) |
+ (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) |
+ (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) |
+ (((GLuint)(color[0] * 31.0f) & 0x1f) << 11);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
GLfloat color[4];
- color[dst_color->red] = pixel.r;
- color[dst_color->green] = pixel.g;
- color[dst_color->blue] = pixel.b;
- color[dst_color->alpha] = pixel.a;
- *d = (((GLushort)(color[0] * 15.0) & 0x0f) << 12) |
- (((GLushort)(color[1] * 15.0) & 0x0f) << 8) |
- (((GLushort)(color[2] * 15.0) & 0x0f) << 4) |
- (((GLushort)(color[3] * 15.0) & 0x0f));
+ color[src_color->red] = pixel.r;
+ color[src_color->green] = pixel.g;
+ color[src_color->blue] = pixel.b;
+ color[src_color->alpha] = pixel.a;
+ *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) |
+ (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) |
+ (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) |
+ (((GLushort)(color[3] * 15.0f) & 0x0f) );
)
default:
printf("LIBGL: Unsupported target data type: %s\n", PrintEnum(dst_type));
@@ -243,38 +243,29 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst,
case GL_UNSIGNED_INT_8_8_8_8_REV:
type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f))
type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f))
- type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort,
- s = (GLushort[]){
- (v & 31),
- ((v & 0x03e0) >> 5),
- ((v & 0x7c00) >> 10),
- ((v & 0x8000) >> 15)*31,
- };
- read_each(, / 31.0f);
- )
type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort,
- s = (GLushort[]){
- (v & 31)*2,
- ((v & 0x07e0) >> 5),
- ((v & 0xF800) >> 11)*2,
+ s = (const GLushort[]) {
+ ((v >> 11) & 0x1f)<<1,
+ ((v >> 5) & 0x3f),
+ ((v ) & 0x1f)<<1,
};
read_each(, / 63.0f);
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
- s = (GLushort[]){
- ((v & 0xf800) >> 11),
- ((v & 0x07c0) >> 6),
- ((v & 0x003e) >> 1),
- ((v & 1))*31,
+ s = (const GLushort[]) {
+ ((v >> 11) & 0x1f),
+ ((v >> 6) & 0x1f),
+ ((v >> 1) & 0x1f),
+ ((v ) & 0x01)*31,
};
read_each(, / 31.0f);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
- s = (GLushort[]){
- (v & 0x000f),
- ((v & 0x00f0) >> 4),
- ((v & 0x0f00) >> 8),
- ((v & 0xf000) >> 12)
+ s = (const GLushort[]) {
+ ((v >> 12) & 0x0f),
+ ((v >> 8) & 0x0f),
+ ((v >> 4) & 0x0f),
+ ((v ) & 0x0f)
};
read_each(, / 15.0f);
)
@@ -300,9 +291,9 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst,
color[src_color->red] = pixel.r;
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
- *d = ((GLuint)(color[2] * 31.0f) & 0x1f << 11) |
- ((GLuint)(color[1] * 63.0f) & 0x3f << 5) |
- ((GLuint)(color[0] * 31.0f) & 0x1f);
+ *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) |
+ (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) |
+ (((GLuint)(color[2] * 31.0f) & 0x1f) );
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
GLfloat color[4];
@@ -311,10 +302,10 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst,
color[src_color->blue] = pixel.b;
color[src_color->alpha] = pixel.a;
// TODO: can I macro this or something? it follows a pretty strict form.
- *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) |
- ((GLuint)(color[1] * 31.0f) & 0x1f << 5) |
- ((GLuint)(color[2] * 31.0f) & 0x1f << 10) |
- ((GLuint)(color[3] * 1) & 0x01 << 15);
+ *d = (((GLuint)(color[3] ) & 0x01) ) |
+ (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) |
+ (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) |
+ (((GLuint)(color[0] * 31.0f) & 0x1f) << 11);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
GLfloat color[4];
@@ -322,10 +313,10 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst,
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
color[src_color->alpha] = pixel.a;
- *d = ((GLushort)(color[3] * 15.0f) & 0x0f << 12) |
- ((GLushort)(color[2] * 15.0f) & 0x0f << 8) |
- ((GLushort)(color[1] * 15.0f) & 0x0f << 4) |
- ((GLushort)(color[0] * 15.0f) & 0x0f);
+ *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) |
+ (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) |
+ (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) |
+ (((GLushort)(color[3] * 15.0f) & 0x0f) );
)
default:
printf("LIBGL: Unsupported target data type: %s\n", PrintEnum(src_type));
@@ -402,59 +393,37 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1,
case GL_UNSIGNED_INT_8_8_8_8_REV:
type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f))
type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f))
- type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort,
- for (int ii=0; ii<4; ii++) {
- s[ii] = (GLushort[]) {
- (v[ii] & 31),
- ((v[ii] & 0x03e0) >> 5),
- ((v[ii] & 0x7c00) >> 10),
- ((v[ii] & 0x8000) >> 15)*31,
- };
- };
- read_each(, / 31.0f);
- )
- type_case(GL_UNSIGNED_SHORT_4_4_4_4_REV, GLushort,
- for (int ii=0; ii<4; ii++) {
- s[ii] = (GLushort[]) {
- ((v[ii] & 0x000f) ),
- ((v[ii] & 0x00f0) >> 4),
- ((v[ii] & 0x0f00) >> 8),
- ((v[ii] & 0xf000) >>12)
- };
- };
- read_each(, / 15.0f);
- )
type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort,
for (int ii=0; ii<4; ii++) {
- s[ii] = (GLushort[]) {
- ((v[ii] & 0x001f) )*2,
- ((v[ii] & 0x07e0) >> 5),
- ((v[ii] & 0xF800) >>11)*2,
+ s[ii] = (const GLushort[]) {
+ ((v[ii] >> 11) & 0x1f)<<1,
+ ((v[ii] >> 5) & 0x3f),
+ ((v[ii] ) & 0x1f)<<1,
};
+ read_i_each(, / 63.0f, ii);
};
- read_each(, / 63.0f);
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
for (int ii=0; ii<4; ii++) {
- s[ii] = (GLushort[]) {
- ((v[ii] & 0xf800) >>11),
- ((v[ii] & 0x07c0) >> 6),
- ((v[ii] & 0x003e) >> 1),
- ((v[ii] & 1) )*31,
+ s[ii] = (const GLushort[]) {
+ ((v[ii] >> 11) & 0x1f),
+ ((v[ii] >> 6) & 0x1f),
+ ((v[ii] >> 1) & 0x1f),
+ ((v[ii] ) & 0x01)*31,
};
+ read_i_each(, / 31.0f, ii);
};
- read_each(, / 31.0f);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
for (int ii=0; ii<4; ii++) {
- s[ii] = (GLushort[]) {
- ((v[ii] & 0xf000) >>12),
- ((v[ii] & 0x0f00) >> 8),
- ((v[ii] & 0x00f0) >> 4),
- ((v[ii] & 0x000f) )
+ s[ii] = (const GLushort[]) {
+ ((v[ii] >> 12) & 0x0f),
+ ((v[ii] >> 8) & 0x0f),
+ ((v[ii] >> 4) & 0x0f),
+ ((v[ii] ) & 0x0f)
};
+ read_i_each(, / 15.0f, ii);
};
- read_each(, / 15.0f);
)
default:
// TODO: add glSetError?
@@ -478,9 +447,9 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1,
color[src_color->red] = pixel.r;
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
- *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 11) |
- ((GLuint)(color[1] * 63.0f) & 0x3f << 5) |
- ((GLuint)(color[2] * 31.0f) & 0x1f);
+ *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) |
+ (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) |
+ (((GLuint)(color[2] * 31.0f) & 0x1f) );
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
GLfloat color[4];
@@ -489,10 +458,10 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1,
color[src_color->blue] = pixel.b;
color[src_color->alpha] = pixel.a;
// TODO: can I macro this or something? it follows a pretty strict form.
- *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) |
- ((GLuint)(color[1] * 31.0f) & 0x1f << 5) |
- ((GLuint)(color[2] * 31.0f) & 0x1f << 10) |
- ((GLuint)(color[3] * 1) & 0x01 << 15);
+ *d = (((GLuint)(color[3] ) & 0x01) ) |
+ (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) |
+ (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) |
+ (((GLuint)(color[0] * 31.0f) & 0x1f) << 11);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
GLfloat color[4];
@@ -500,10 +469,10 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1,
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
color[src_color->alpha] = pixel.a;
- *d = ((GLushort)(color[0] * 15.0f) & 0x0f << 12) |
- ((GLushort)(color[1] * 15.0f) & 0x0f << 8) |
- ((GLushort)(color[2] * 15.0f) & 0x0f << 4) |
- ((GLushort)(color[3] * 15.0f) & 0x0f);
+ *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) |
+ (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) |
+ (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) |
+ (((GLushort)(color[3] * 15.0f) & 0x0f) );
)
default:
printf("LIBGL: half_pixel: Unsupported target data type: %s\n", PrintEnum(src_type));
@@ -588,27 +557,37 @@ bool quarter_pixel(const GLvoid *src[16],
case GL_UNSIGNED_INT_8_8_8_8_REV:
type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f))
type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f))
- type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort,
- for (int ii=0; ii<16; ii++) {
+ type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
+ for (int ii=0; ii<4; ii++) {
s[ii] = (GLushort[]) {
- (v[ii] & 31),
- ((v[ii] & 0x03e0) >> 5),
- ((v[ii] & 0x7c00) >> 10),
- ((v[ii] & 0x8000) >> 15)*31,
+ ((v[ii] & 0xf800) >>11),
+ ((v[ii] & 0x07c0) >> 6),
+ ((v[ii] & 0x003e) >> 1),
+ ((v[ii] & 1) )*31,
};
+ read_i_each(, / 31.0f, ii);
+ };
+ )
+ type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort,
+ for (int ii=0; ii<4; ii++) {
+ s[ii] = (GLushort[]) {
+ ((v[ii] & 0xF800) >>11)*2,
+ ((v[ii] & 0x07e0) >> 5),
+ ((v[ii] & 0x001f) )*2,
+ };
+ read_i_each(, / 63.0f, ii);
};
- read_each(, / 31.0f);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
for (int ii=0; ii<16; ii++) {
s[ii] = (GLushort[]) {
- (v[ii] & 0x000f),
- ((v[ii] & 0x00f0) >> 4),
+ ((v[ii] & 0xf000) >> 12),
((v[ii] & 0x0f00) >> 8),
- ((v[ii] & 0xf000) >> 12)
+ ((v[ii] & 0x00f0) >> 4),
+ (v[ii] & 0x000f)
};
+ read_i_each(, / 15.0f, ii);
};
- read_each(, / 15.0f);
)
default:
// TODO: add glSetError?
@@ -632,9 +611,21 @@ bool quarter_pixel(const GLvoid *src[16],
color[src_color->red] = pixel.r;
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
- *d = ((GLuint)(color[0] * 31) & 0x1f << 11) |
- ((GLuint)(color[1] * 63) & 0x3f << 5) |
- ((GLuint)(color[2] * 31) & 0x1f);
+ *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) |
+ (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) |
+ (((GLuint)(color[2] * 31.0f) & 0x1f) );
+ )
+ type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
+ GLfloat color[4];
+ color[src_color->red] = pixel.r;
+ color[src_color->green] = pixel.g;
+ color[src_color->blue] = pixel.b;
+ color[src_color->alpha] = pixel.a;
+ // TODO: can I macro this or something? it follows a pretty strict form.
+ *d = (((GLuint)(color[3] ) & 0x01) ) |
+ (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) |
+ (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) |
+ (((GLuint)(color[0] * 31.0f) & 0x1f) << 11);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
GLfloat color[4];
@@ -642,10 +633,10 @@ bool quarter_pixel(const GLvoid *src[16],
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
color[src_color->alpha] = pixel.a;
- *d = ((GLushort)(color[0] * 15.0) & 0x0f << 12) |
- ((GLushort)(color[1] * 15.0) & 0x0f << 8) |
- ((GLushort)(color[2] * 15.0) & 0x0f << 4) |
- ((GLushort)(color[3] * 15.0) & 0x0f);
+ *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) |
+ (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) |
+ (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) |
+ (((GLushort)(color[3] * 15.0f) & 0x0f) );
)
default:
printf("LIBGL: quarter_pixel Unsupported target data type: %s\n", PrintEnum(src_type));
@@ -1021,13 +1012,13 @@ bool pixel_halfscale(const GLvoid *old, GLvoid **new,
GLuint width, GLuint height,
GLenum format, GLenum type) {
GLuint pixel_size, new_width, new_height;
- new_width = width / 2; if(new_width==0) new_width=1;
- new_height = height / 2; if(new_height==0) new_height==1;
+ new_width = width / 2; if(!new_width) ++new_width;
+ new_height = height / 2; if(!new_height) ++new_height;
/* if (new_width*2!=width || new_height*2!=height) {
printf("LIBGL: halfscaling %ux%u failed\n", width, height);
return false;
}*/
-// printf("LIBGL: halfscaling %ux%u -> %ux%u\n", width, height, new_width, new_height);
+ //printf("LIBGL: halfscaling %ux%u -> %ux%u (%s / %s)\n", width, height, new_width, new_height, PrintEnum(format), PrintEnum(type));
const colorlayout_t *src_color;
src_color = get_color_map(format);
GLvoid *dst;
@@ -1037,16 +1028,18 @@ bool pixel_halfscale(const GLvoid *old, GLvoid **new,
dst = malloc(pixel_size * new_width * new_height);
src = (uintptr_t)old;
pos = (uintptr_t)dst;
+ const int dx = (width>1)?1:0;
+ const int dy = (height>1)?1:0;
for (int y = 0; y < new_height; y++) {
for (int x = 0; x < new_width; x++) {
pix0 = src + ((x * 2) +
(y * 2) * width) * pixel_size;
- pix1 = src + ((x * 2 + 1) +
+ pix1 = src + ((x * 2 + dx) +
(y * 2) * width) * pixel_size;
pix2 = src + ((x * 2) +
- (y * 2 + 1) * width) * pixel_size;
- pix3 = src + ((x * 2 + 1) +
- (y * 2 + 1) * width) * pixel_size;
+ (y * 2 + dy) * width) * pixel_size;
+ pix3 = src + ((x * 2 + dx) +
+ (y * 2 + dy) * width) * pixel_size;
half_pixel((GLvoid *)pix0, (GLvoid *)pix1, (GLvoid *)pix2, (GLvoid *)pix3, (GLvoid *)pos, src_color, type);
pos += pixel_size;
}
@@ -1059,8 +1052,8 @@ bool pixel_thirdscale(const GLvoid *old, GLvoid **new,
GLuint width, GLuint height,
GLenum format, GLenum type) {
GLuint pixel_size, new_width, new_height, dest_size;
- new_width = width / 2;
- new_height = height / 2;
+ new_width = width / 2; if(!new_width) ++new_width;
+ new_height = height / 2; if(!new_height) ++new_height;
if (new_width*2!=width || new_height*2!=height || format!=GL_RGBA || type!=GL_UNSIGNED_BYTE) {
//printf("LIBGL: thirdscaling %ux%u failed\n", width, height);
return false;
@@ -1076,17 +1069,19 @@ bool pixel_thirdscale(const GLvoid *old, GLvoid **new,
dst = malloc(dest_size * new_width * new_height);
src = (uintptr_t)old;
pos = (uintptr_t)dst;
+ const int dx = (width>1)?1:0;
+ const int dy = (height>1)?1:0;
GLubyte tmp[4];
for (int y = 0; y < new_height; y++) {
for (int x = 0; x < new_width; x++) {
pix0 = src + ((x * 2) +
(y * 2) * width) * pixel_size;
- pix1 = src + ((x * 2 + 1) +
+ pix1 = src + ((x * 2 + dx) +
(y * 2) * width) * pixel_size;
pix2 = src + ((x * 2) +
- (y * 2 + 1) * width) * pixel_size;
- pix3 = src + ((x * 2 + 1) +
- (y * 2 + 1) * width) * pixel_size;
+ (y * 2 + dy) * width) * pixel_size;
+ pix3 = src + ((x * 2 + dx) +
+ (y * 2 + dy) * width) * pixel_size;
half_pixel((GLvoid *)pix0, (GLvoid *)pix1, (GLvoid *)pix2, (GLvoid *)pix3, (GLvoid *)tmp, src_color, type);
*((GLushort*)pos) = (((GLushort)tmp[0])&0xf0)<<8 | (((GLushort)tmp[1])&0xf0)<<4 | (((GLushort)tmp[2])&0xf0) | (((GLushort)tmp[3])>>4);
pos += dest_size;
@@ -1100,8 +1095,8 @@ bool pixel_quarterscale(const GLvoid *old, GLvoid **new,
GLuint width, GLuint height,
GLenum format, GLenum type) {
GLuint pixel_size, new_width, new_height;
- new_width = width / 4;
- new_height = height / 4;
+ new_width = width / 4; if(!new_width) ++new_width;
+ new_height = height / 4; if(!new_height) ++new_height;
/* if (new_width*4!=width || new_height*4!=height) {
printf("LIBGL: quarterscaling %ux%u failed\n", width, height);
return false;
@@ -1116,12 +1111,14 @@ bool pixel_quarterscale(const GLvoid *old, GLvoid **new,
dst = malloc(pixel_size * new_width * new_height);
src = (uintptr_t)old;
pos = (uintptr_t)dst;
+ const int dxs[4] = {0, width>1?1:0, width>2?2:0, width>3?3:width>1?1:0};
+ const int dys[4] = {0, height>1?1:0, height>2?2:0, height>3?3:height>1?1:0};
for (int y = 0; y < new_height; y++) {
for (int x = 0; x < new_width; x++) {
for (int dx=0; dx<4; dx++) {
for (int dy=0; dy<4; dy++) {
- pix[dx+dy*4] = src + ((x * 4 + dx) +
- (y * 4 + dy) * width) * pixel_size;
+ pix[dx+dy*4] = src + ((x * 4 + dxs[dx]) +
+ (y * 4 + dys[dy]) * width) * pixel_size;
}
}
quarter_pixel((const GLvoid **)pix, (GLvoid *)pos, src_color, type);
diff --git a/project/jni/gl4es/src/gl/state.h b/project/jni/gl4es/src/gl/state.h
index d3a6489de..f148393bc 100755
--- a/project/jni/gl4es/src/gl/state.h
+++ b/project/jni/gl4es/src/gl/state.h
@@ -51,8 +51,6 @@ typedef struct {
pack_skip_rows,
pack_image_height;
GLboolean pack_lsb_first;
- // TODO: do we only need to worry about GL_TEXTURE_2D?
- GLboolean rect_arb[MAX_TEX];
gltexture_t *bound[MAX_TEX][ENABLED_TEXTURE_LAST];
GLboolean pscoordreplace[MAX_TEX];
khash_t(tex) *list;
diff --git a/project/jni/gl4es/src/gl/texture.c b/project/jni/gl4es/src/gl/texture.c
index 1bde96aa6..4f6547de9 100755
--- a/project/jni/gl4es/src/gl/texture.c
+++ b/project/jni/gl4es/src/gl/texture.c
@@ -25,6 +25,12 @@ int npot(int n) {
return i;
}
+static int inline nlevel(int size, int level) {
+ size>>=level;
+ if(!size) size=1;
+ return size;
+}
+
// conversions for GL_ARB_texture_rectangle
void tex_coord_rect_arb(GLfloat *tex, GLsizei len,
GLsizei width, GLsizei height) {
@@ -82,7 +88,7 @@ void tex_setup_texcoord(GLuint len, GLuint itarget) {
// check if some changes are needed
int changes = 0;
- if ((glstate->texture.rect_arb[texunit])
+ if ((itarget == ENABLED_TEXTURE_RECTANGLE)
|| (bound && ((bound->width!=bound->nwidth)||(bound->height!=bound->nheight)
)) || !(globals4es.texmat || glstate->texture_matrix[texunit]->identity)
)
@@ -96,7 +102,7 @@ void tex_setup_texcoord(GLuint len, GLuint itarget) {
}
copy_gl_pointer_tex_noalloc(tex[texunit], &glstate->vao->pointers.tex_coord[texunit], 4, 0, len);
// Normalize if needed
- if ((glstate->texture.rect_arb[texunit]))
+ if (itarget == ENABLED_TEXTURE_RECTANGLE)
tex_coord_rect_arb(tex[texunit], len, bound->width, bound->height);
// Apply transformation matrix if any
if (!(globals4es.texmat || glstate->texture_matrix[texunit]->identity))
@@ -435,6 +441,86 @@ GLenum swizzle_internalformat(GLenum *internalformat) {
return sret;
}
+static int get_shrinklevel(int width, int height, int level) {
+ int shrink = 0;
+ int mipwidth = width << level;
+ int mipheight = height << level;
+ switch(globals4es.texshrink) {
+ case 0: // nothing
+ break;
+ case 1: //everything / 2
+ if ((mipwidth > 1) && (mipheight > 1)) {
+ shrink = 1;
+ }
+ break;
+ case 2: //only > 512 /2
+ case 7: //only > 512 /2 , but not for empty texture
+ if (((mipwidth%2==0) && (mipheight%2==0)) &&
+ ((mipwidth > 512) && (mipheight > 8)) || ((mipheight > 512) && (mipwidth > 8))) {
+ shrink = 1;
+ }
+ break;
+ case 3: //only > 256 /2
+ if (((mipwidth%2==0) && (mipheight%2==0)) &&
+ ((mipwidth > 256) && (mipheight > 8)) || ((mipheight > 256) && (mipwidth > 8))) {
+ shrink = 1;
+ }
+ break;
+ case 4: //only > 256 /2, >=1024 /4
+ case 5: //every > 256 is downscaled to 256, but not for empty texture (as there is no downscale stronger than 4, there are the same)
+ if (((mipwidth%4==0) && (mipheight%4==0)) &&
+ ((mipwidth > 256) && (mipheight > 8)) || ((mipheight > 256) && (mipwidth > 8))) {
+ if ((mipwidth>=1024) || (mipheight>=1024)) {
+ shrink = 2;
+ } else {
+ shrink = 1;
+ }
+ }
+ break;
+ case 6: //only > 128 /2, >=512 is downscaled to 256, but not for empty texture
+ if (((mipwidth%2==0) && (mipheight%2==0)) &&
+ ((mipwidth > 128) && (mipheight > 8)) || ((mipheight > 128) && (mipwidth > 8))) {
+ if (((mipwidth%2==0) && (mipheight%2==0)) && (mipwidth>=512) || (mipheight>=512)) {
+ while (((mipwidth > 256) && (mipheight > 8)) || ((mipheight > 256) && (mipwidth > 8))) {
+ width /= 2;
+ height /= 2;
+ mipwidth /= 2;
+ mipheight /= 2;
+ shrink+=1;
+ }
+ } else {
+ shrink = 1;
+ }
+ }
+ break;
+ case 8: //advertise 8192 max texture size, but >2048 are shrinked to 2048
+ if ((mipwidth>4096) || (mipheight>4096)) {
+ shrink=2;
+ } else
+ if ((mipwidth>2048) || (mipheight>2048)) {
+ shrink=1;
+ }
+ break;
+ case 9: //advertise 8192 max texture size, but >4096 are quadshrinked and >512 are shrinked, but not for empty texture
+ if ((mipwidth>4096) || (mipheight>4096)) {
+ shrink=2;
+ } else
+ if ((mipwidth>512) || (mipheight>512)) {
+ shrink=1;
+ }
+ break;
+ case 10://advertise 8192 max texture size, but >2048 are quadshrinked and >512 are shrinked, but not for empty texture
+ if ((mipwidth>2048) || (mipheight>2048)) {
+ shrink=2;
+ } else
+ if ((mipwidth>512) || (mipheight>512)) {
+ shrink=1;
+ }
+ break;
+ }
+ return shrink;
+}
+
static int default_tex_mipmap = 0;
static int proxy_width = 0;
@@ -487,6 +573,14 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat,
bound->orig_internal = internalformat;
bound->internalformat = new_format;
}
+ // shrink checking
+ int mipwidth = width << level;
+ int mipheight = height << level;
+ int shrink = 0;
+ if(bound) {
+ bound->shrink = shrink = get_shrinklevel(width, height, level);
+ }
+ if(width>>shrink==0 && height>>shrink==0) return; // nothing to do
if (datab) {
// implements GL_UNPACK_ROW_LENGTH
@@ -511,13 +605,12 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat,
free(old);
}
- if (bound) {
- bound->shrink = 0;
- switch(globals4es.texshrink) {
- case 0: // nothing
+ if (bound && bound->shrink!=0) {
+ switch(globals4es.texshrink) {
+ case 0: // nothing ???
break;
case 1: //everything / 2
- if ((width > 1) && (height > 1)) {
+ if ((mipwidth > 1) && (mipheight > 1)) {
GLvoid *out = pixels;
GLfloat ratio = 0.5;
pixel_scale(pixels, &out, width, height, ratio, format, type);
@@ -529,163 +622,28 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat,
bound->shrink = 1;
}
break;
- case 2: //only > 512 /2
- case 7: //only > 512 /2 , but not for empty texture
- if (((width%2==0) && (height%2==0)) &&
- ((width > 512) && (height > 8)) || ((height > 512) && (width > 8))) {
- GLvoid *out = pixels;
- pixel_halfscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 2;
- height /= 2;
- bound->shrink = 1;
- }
- break;
- case 3: //only > 256 /2
- if (((width%2==0) && (height%2==0)) &&
- ((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) {
- GLvoid *out = pixels;
- pixel_halfscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 2;
- height /= 2;
- bound->shrink = 1;
- }
- break;
- case 4: //only > 256 /2, >=1024 /4
- case 5: //every > 256 is downscaled to 256, but not for empty texture (as there is no downscale stronger than 4, there are the same)
- if (((width%4==0) && (height%4==0)) &&
- ((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) {
- if ((width>=1024) || (height>=1024)) {
+ default:
+ while(shrink) {
+ if (shrink>1) { // quarterscale
GLvoid *out = pixels;
pixel_quarterscale(pixels, &out, width, height, format, type);
if (out != pixels && pixels!=datab)
free(pixels);
pixels = out;
- width /= 4;
- height /= 4;
- bound->shrink = 2;
- } else {
+ width = nlevel(width, 2);
+ height = nlevel(height, 2);
+ shrink-=2;
+ } else { //halfscale
GLvoid *out = pixels;
pixel_halfscale(pixels, &out, width, height, format, type);
if (out != pixels && pixels!=datab)
free(pixels);
pixels = out;
- width /= 2;
- height /= 2;
- bound->shrink = 1;
+ width = nlevel(width, 1);
+ height = nlevel(height, 1);
+ shrink--;
}
}
- break;
- /*case 5: //every > 256 is downscaled to 256, but not for empty texture
- while (((width%2==0) && (height%2==0)) &&
- ((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) {
- GLvoid *out = pixels;
- pixel_halfscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 2;
- height /= 2;
- bound->shrink+=1;
- }
- break;*/
- case 6: //only > 128 /2, >=512 is downscaled to 256, but not for empty texture
- if (((width%2==0) && (height%2==0)) &&
- ((width > 128) && (height > 8)) || ((height > 128) && (width > 8))) {
- if (((width%2==0) && (height%2==0)) && (width>=512) || (height>=512)) {
- while (((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) {
- GLvoid *out = pixels;
- pixel_halfscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 2;
- height /= 2;
- bound->shrink=1;
- }
- } else {
- GLvoid *out = pixels;
- pixel_halfscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 2;
- height /= 2;
- bound->shrink = 1;
- }
- }
- break;
- case 8: //advertise 8192 max texture size, but >2048 are shrinked to 2048
- if ((width>4096) || (height>4096)) {
- GLvoid *out = pixels;
- pixel_quarterscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 4;
- height /= 4;
- bound->shrink=2;
- } else
- if ((width>2048) || (height>2048)) {
- GLvoid *out = pixels;
- pixel_halfscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 2;
- height /= 2;
- bound->shrink=1;
- }
- break;
- case 9: //advertise 8192 max texture size, but >4096 are quadshrinked and >512 are shrinked, but not for empty texture
- if ((width>4096) || (height>4096)) {
- GLvoid *out = pixels;
- pixel_quarterscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 4;
- height /= 4;
- bound->shrink=2;
- } else
- if ((width>512) || (height>512)) {
- GLvoid *out = pixels;
- pixel_halfscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 2;
- height /= 2;
- bound->shrink=1;
- }
- break;
- case 10://advertise 8192 max texture size, but >2048 are quadshrinked and >512 are shrinked, but not for empty texture
- if ((width>2048) || (height>2048)) {
- GLvoid *out = pixels;
- pixel_quarterscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 4;
- height /= 4;
- bound->shrink=2;
- } else
- if ((width>512) || (height>512)) {
- GLvoid *out = pixels;
- pixel_halfscale(pixels, &out, width, height, format, type);
- if (out != pixels && pixels!=datab)
- free(pixels);
- pixels = out;
- width /= 2;
- height /= 2;
- bound->shrink=1;
- }
- break;
}
}
@@ -700,6 +658,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat,
((internalformat==GL_RGB) || (internalformat==3) || (internalformat==GL_RGB8) || (internalformat==GL_BGR) || (internalformat==GL_RGB5)) || (globals4es.texstream==2) ) {
bound->streamingID = AddStreamed(width, height, bound->texture);
if (bound->streamingID>-1) { // success
+ bound->shrink = 0; // no shrink on Stream texture
bound->streamed = true;
ApplyFilterID(bound->streamingID, bound->min_filter, bound->mag_filter);
GLboolean tmp = IS_TEX2D(glstate->enable.texture[glstate->texture.active]);
@@ -716,62 +675,10 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat,
}
#endif
if (bound) {
- bound->shrink = 0;
if (!bound->streamed)
swizzle_texture(width, height, &format, &type, internalformat, new_format, NULL); // convert format even if data is NULL
- if ((globals4es.texshrink>0) && !bound->streamed) {
- switch(globals4es.texshrink) {
- case 1: //everything / 2
- width /= 2;
- height /= 2;
- bound->shrink = 1;
- break;
- case 2: //only > 512 /2
- if((width>512) || (height>512)) {
- width /= 2;
- height /= 2;
- bound->shrink = 1;
- }
- break;
- case 3: //only > 256 /2
- if((width>256) || (height>256)) {
- width /= 2;
- height /= 2;
- bound->shrink = 1;
- }
- break;
- case 4: //only > 256 /2, >=1024 /4
- if((width>1024) || (height>1024)) {
- width /= 4;
- height /= 4;
- bound->shrink = 2;
- } else if((width>256) || (height>256)) {
- width /= 2;
- height /= 2;
- bound->shrink = 1;
- }
- break;
- case 5: //every > 256 is downscaled to 256, but not for empty texture
- break;
- case 6: //only > 128 /2, >=512 is downscaled to 256 ), but not for empty texture
- break;
- case 7: //only > 512 /2, but not for empty texture
- break;
- case 8: //advertise 8192 max texture size, but >2048 are shrinked to 2048
- case 9: //advertise 8192 max texture size, but >4096 are quadshrinked and >512 are shrinked, but not for empty texture (but >2048 are not supported anyway)
- case 10://advertise 8192 max texture size, but >2048 are quadshrinked and >512 are shrinked, but not for empty texture (but >2048 are not supported anyway)
- if((width>4096) || (height>4096)) {
- width /= 4;
- height /= 4;
- bound->shrink = 2;
- } else if((width>2048) || (height>2048)) {
- width /= 2;
- height /= 2;
- bound->shrink = 1;
- }
- break;
- }
- }
+ width = nlevel(width, bound->shrink);
+ height = nlevel(height, bound->shrink);
}
}
@@ -1033,8 +940,8 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff
errorGL();
}
- if (bound && bound->mipmap_need && !bound->mipmap_auto && (globals4es.automipmap!=3) && (!globals4es.texstream || (globals4es.texstream && !bound->streamed)))
- gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE );
+ /*if (bound && bound->mipmap_need && !bound->mipmap_auto && (globals4es.automipmap!=3) && (!globals4es.texstream || (globals4es.texstream && !bound->streamed)))
+ gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE );*/
if ((target==GL_TEXTURE_2D) && globals4es.texcopydata && bound && ((globals4es.texstream && !bound->streamed) || !globals4es.texstream)) {
//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);
@@ -1203,6 +1110,7 @@ gltexture_t* gl4es_getTexture(GLenum target, GLuint texture) {
tex->type = GL_UNSIGNED_BYTE;
tex->orig_internal = GL_RGBA;
tex->internalformat = GL_RGBA;
+ tex->shrink = 0;
tex->data = NULL;
} else {
tex = kh_value(list, k);
@@ -1265,7 +1173,6 @@ tex_changed=1; // seems buggy, temporary disabling that...
}
#endif
- glstate->texture.rect_arb[glstate->texture.active] = (target == GL_TEXTURE_RECTANGLE_ARB);
target = map_tex_target(target);
glstate->texture.bound[glstate->texture.active][itarget] = tex;
@@ -1436,6 +1343,7 @@ void gl4es_glGenTextures(GLsizei n, GLuint * textures) {
tex->min_filter = tex->mag_filter = GL_NEAREST;
tex->format = GL_RGBA;
tex->type = GL_UNSIGNED_BYTE;
+ tex->shrink = 0;
tex->data = NULL;
} else {
tex = kh_value(list, k);
@@ -1463,28 +1371,20 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL
switch (pname) {
case GL_TEXTURE_WIDTH:
if (target==GL_PROXY_TEXTURE_2D)
- (*params) = proxy_width>>level;
- else
- (*params) = ((bound)?bound->width:2048)>>level;
- if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) {
- if (*params<4) // minimum size of a compressed block is 4
- *params = 0;
- } else {
- if (*params<=0) // 1 is the minimum, not 0
- *params = 1;
+ (*params) = nlevel(proxy_width,level);
+ else {
+ (*params) = nlevel((bound)?bound->width:2048,level);
+ if(level && (!bound || (bound && !(bound->mipmap_auto || bound->mipmap_need))))
+ (*params) = 0; // Mipmap level not loaded
}
break;
case GL_TEXTURE_HEIGHT:
if (target==GL_PROXY_TEXTURE_2D)
- (*params) = proxy_height>>level;
- else
- (*params) = ((bound)?bound->height:2048)>>level;
- if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) {
- if (*params<4) // minimum size of a compressed block is 4
- *params = 0;
- } else {
- if (*params<=0) // 1 is the minimum, not 0, but only on uncompressed textures
- *params = 1;
+ (*params) = nlevel(proxy_height,level);
+ else {
+ (*params) = nlevel((bound)?bound->height:2048,level);
+ if(level && (!bound || (bound && !(bound->mipmap_auto || bound->mipmap_need))))
+ (*params) = 0; // Mipmap level not loaded
}
break;
case GL_TEXTURE_INTERNAL_FORMAT:
@@ -1492,7 +1392,7 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL
(*params) = proxy_intformat;
else {
if (bound && bound->compressed)
- (*params) = bound->format;
+ (*params) = bound->internalformat;
else {
if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) {
if(bound->orig_internal==GL_COMPRESSED_RGB)
@@ -1535,9 +1435,9 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL
break;
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) {
- int w = bound->width>>level;
- int h = bound->height>>level;
- w = ((w>>2)+1) << 2; h = ((h>>2)+1) << 2; //DXT works on 4x4 blocks...
+ int w = nlevel((bound->width>>level),2); //DXT works on 4x4 blocks...
+ int h = nlevel((bound->height>>level),2);
+ w<<=2; h<<=2;
if (bound->orig_internal==GL_COMPRESSED_RGB) //DXT1, 64bits (i.e. size=8) for a 4x4 block
(*params) = (w*h)/2;
else //DXT5, 64+64 (i.e. size = 16) for a 4x4 block
@@ -1545,9 +1445,25 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL
} else
(*params) = (bound)?(bound->width*bound->height*4):0;
break;
+ case GL_TEXTURE_BORDER:
+ (*params) = 0;
+ break;
+ case GL_TEXTURE_INTENSITY_SIZE:
+ if(bound)
+ (*params) = 32; // is it correct ? GLES doesn't store Intensity... Shall I return 0 instead? Or fake it and return 8?
+ else
+ (*params) = 0;
+ break;
+ case GL_TEXTURE_LUMINANCE_SIZE:
+ if(bound)
+ (*params) = (bound->orig_internal==GL_LUMINANCE || bound->orig_internal==GL_LUMINANCE_ALPHA)?8:0;
+ else
+ (*params) = 0;
+ break;
+ break;
default:
errorShim(GL_INVALID_ENUM); //Wrong here...
- printf("Stubbed glGetTexLevelParameteriv(%04x, %i, %04x, %p)\n", target, level, pname, params);
+ printf("Stubbed glGetTexLevelParameteriv(%s, %i, %s, %p)\n", PrintEnum(target), level, PrintEnum(pname), params);
}
}
@@ -1582,8 +1498,8 @@ void gl4es_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type,
pixel_halfscale(tmp, &tmp2, width, height, format, type);
free(tmp);
tmp = tmp2;
- if(width>1) width>>=1;
- if(height>1) height>>=1;
+ width = nlevel(width, 1);
+ height = nlevel(height, 1);
}
memcpy(img, tmp, width*height*pixel_sizeof(format, type));
free(tmp);
@@ -2038,12 +1954,6 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor
if (internalformat==GL_RGBA8)
internalformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
// test if internalformat is not a compressed one
- if (level != 0) {
- noerrorShim();
- //TODO
- //printf("STUBBED glCompressedTexImage2D with level=%i\n", level);
- //return;
- }
if ((width<=0) || (height<=0)) {
noerrorShim();
return; // nothing to do...
@@ -2089,19 +1999,29 @@ 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;
- format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA;
- type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4;
- 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.nodownsampling==1) {
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 {
+ format = GL_RGBA;
+ type = GL_UNSIGNED_BYTE;
+ }
}
bound->format = format; //internalformat;
bound->type = type;
bound->compressed = true;
+ bound->internalformat = internalformat;
} else {
fact = 0;
}
@@ -2109,7 +2029,10 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor
gl4es_glGetIntegerv(GL_UNPACK_ALIGNMENT, &oldalign);
if (oldalign!=1)
gl4es_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- gl4es_glTexImage2D(target, level, format, width>>fact, height>>fact, border, format, type, half);
+ gl4es_glTexImage2D(target, level, format==GL_RGBA?GL_COMPRESSED_RGBA:GL_COMPRESSED_RGB, nlevel(width,fact), nlevel(height,fact), border, format, type, half);
+ // re-update bounded texture info
+ bound->compressed = true;
+ bound->internalformat = internalformat;
if (oldalign!=1)
gl4es_glPixelStorei(GL_UNPACK_ALIGNMENT, oldalign);
if (half!=pixels)
@@ -2120,6 +2043,7 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor
bound->alpha = true;
bound->format = internalformat;
bound->type = GL_UNSIGNED_BYTE;
+ bound->internalformat = internalformat;
bound->compressed = true;
gles_glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, datab);
}
@@ -2210,10 +2134,10 @@ void gl4es_glGetCompressedTexImage(GLenum target, GLint lod, GLvoid *img) {
return;
if(bound->orig_internal!=GL_COMPRESSED_RGB && bound->orig_internal!=GL_COMPRESSED_RGBA)
return;
- int width = bound->width>>lod;
- int height = bound->height>>lod;
- int w = ((width>>2)+1)<<2;
- int h = ((height>>2)+1)<<2;
+ int width = nlevel(bound->width,lod);
+ int height = nlevel(bound->height,lod);
+ int w = nlevel(width,2); w<<=2;
+ int h = nlevel(height,2); h<<=2;
int alpha = (bound->orig_internal==GL_COMPRESSED_RGBA)?1:0;
diff --git a/project/jni/gl4es/src/gl/texture.h b/project/jni/gl4es/src/gl/texture.h
index ea5bc615c..9ddcef64e 100755
--- a/project/jni/gl4es/src/gl/texture.h
+++ b/project/jni/gl4es/src/gl/texture.h
@@ -97,6 +97,7 @@ typedef enum {
ENABLED_TEX1D = 0,
ENABLED_TEX2D,
ENABLED_TEX3D,
+ ENABLED_TEXTURE_RECTANGLE,
ENABLED_CUBE_MAP,
ENABLED_TEXTURE_LAST
} texture_enabled_t;
@@ -161,6 +162,7 @@ static inline GLuint what_target(GLenum target) {
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
return ENABLED_CUBE_MAP;
case GL_TEXTURE_RECTANGLE_ARB:
+ return ENABLED_TEXTURE_RECTANGLE;
case GL_TEXTURE_2D:
default:
return ENABLED_TEX2D;
@@ -172,6 +174,8 @@ static inline GLenum to_target(GLuint itarget) {
return GL_TEXTURE_1D;
case ENABLED_TEX3D:
return GL_TEXTURE_3D;
+ case ENABLED_TEXTURE_RECTANGLE:
+ return GL_TEXTURE_RECTANGLE_ARB;
case ENABLED_CUBE_MAP:
return GL_TEXTURE_CUBE_MAP;
case ENABLED_TEX2D:
diff --git a/project/jni/gl4es/src/glx/glx.c b/project/jni/gl4es/src/glx/glx.c
index 9a1e95eea..17ee72938 100755
--- a/project/jni/gl4es/src/glx/glx.c
+++ b/project/jni/gl4es/src/glx/glx.c
@@ -388,34 +388,58 @@ void glx_init() {
#endif
}
-#ifndef ANDROID
+#ifndef ANDROID
+static XVisualInfo *latest_visual = NULL;
+static GLXFBConfig latest_glxfbconfig = NULL;
+
GLXContext gl4es_glXCreateContext(Display *display,
XVisualInfo *visual,
GLXContext shareList,
Bool isDirect) {
- DBG(printf("glXCreateContext(%p, %p, %p, %i)\n", display, visual, shareList, isDirect);)
+ DBG(printf("glXCreateContext(%p, %p, %p, %i), latest_visual=%p\n", display, visual, shareList, isDirect, latest_visual);)
+
+ static struct __GLXFBConfigRec default_glxfbconfig;
+ GLXFBConfig glxfbconfig;
+
+ if(visual==latest_visual)
+ glxfbconfig = latest_glxfbconfig;
+ else {
+ glxfbconfig = &default_glxfbconfig;
+ memset(glxfbconfig, 0, sizeof(struct __GLXFBConfigRec));
+ default_glxfbconfig.redBits = (visual==0)?0:(visual->depth==16)?5:8;
+ default_glxfbconfig.greenBits = (visual==0)?0:(visual->depth==16)?6:8;
+ default_glxfbconfig.blueBits = (visual==0)?0:(visual->depth==16)?5:8;
+ default_glxfbconfig.alphaBits = (visual==0)?0:(visual->depth!=32)?0:8;
+ default_glxfbconfig.depthBits = 16;
+ default_glxfbconfig.stencilBits = 8;
+ }
+
EGLint configAttribs[] = {
#ifdef PANDORA
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
#else
- EGL_RED_SIZE, (visual==0)?0:(visual->depth==16)?5:8,
- EGL_GREEN_SIZE, (visual==0)?0:(visual->depth==16)?6:8,
- EGL_BLUE_SIZE, (visual==0)?0:(visual->depth==16)?5:8,
- EGL_ALPHA_SIZE, (visual==0)?0:(visual->depth!=32)?0:8,
+ EGL_RED_SIZE, glxfbconfig->redBits,
+ EGL_GREEN_SIZE, glxfbconfig->greenBits,
+ EGL_BLUE_SIZE, glxfbconfig->blueBits,
+ EGL_ALPHA_SIZE, glxfbconfig->alphaBits,
#endif
EGL_DEPTH_SIZE, 16,
#ifdef USE_ES2
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#else
- EGL_BUFFER_SIZE, (visual==0)?16:visual->depth,
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
#endif
+ EGL_BUFFER_SIZE, glxfbconfig->depthBits,
+ EGL_STENCIL_SIZE, glxfbconfig->stencilBits,
+
+ EGL_SAMPLE_BUFFERS, glxfbconfig->nMultiSampleBuffers,
+ EGL_SAMPLES, glxfbconfig->multiSampleSize,
+
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
EGL_NONE
};
-
if (globals4es.usefb && fbcontext_count>0) {
// don't create a new context, one FB is enough...
fbcontext_count++;
@@ -615,12 +639,14 @@ GLXContext gl4es_glXCreateContextAttribsARB(Display *display, GLXFBConfig config
#endif
EGL_DEPTH_SIZE, config->depthBits,
EGL_STENCIL_SIZE, config->stencilBits,
+ EGL_SAMPLES, config->multiSampleSize,
+ EGL_SAMPLE_BUFFERS, config->nMultiSampleBuffers,
#ifdef USE_ES2
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#else
- EGL_SURFACE_TYPE, (config->drawableType)==GLX_PIXMAP_BIT?EGL_PIXMAP_BIT:(EGL_WINDOW_BIT | EGL_PBUFFER_BIT),
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
#endif
+ EGL_SURFACE_TYPE, (config->drawableType)==GLX_PIXMAP_BIT?EGL_PIXMAP_BIT:(EGL_WINDOW_BIT | EGL_PBUFFER_BIT),
EGL_NONE
};
@@ -785,6 +811,11 @@ XVisualInfo *gl4es_glXChooseVisual(Display *display,
return NULL;
}
+ // create and store the glxConfig that goes with thoses attributes
+ latest_visual = visual;
+ int count = 1;
+ latest_glxfbconfig = gl4es_glXChooseFBConfig(display, screen, attributes, &count)[0];
+
return visual;
}
@@ -1124,6 +1155,7 @@ GLXFBConfig *gl4es_glXChooseFBConfig(Display *display, int screen,
configs[0]->maxPbufferWidth = configs[0]->maxPbufferHeight = 2048;
configs[0]->redBits = configs[0]->greenBits = configs[0]->blueBits = configs[0]->alphaBits = 0;
configs[0]->nMultiSampleBuffers = 0; configs[0]->multiSampleSize = 0;
+ configs[0]->depthBits = 16; configs[0]->stencilBits = 8;
if(attrib_list) {
int i = 0;
while(attrib_list[i]!=0) {
@@ -1131,35 +1163,44 @@ GLXFBConfig *gl4es_glXChooseFBConfig(Display *display, int screen,
case GLX_RED_SIZE:
configs[0]->redBits = attrib_list[i++];
if(configs[0]->redBits==GLX_DONT_CARE) configs[0]->redBits = 0;
+ DBG(printf("FBConfig redBits=%d\n", configs[0]->redBits);)
break;
case GLX_GREEN_SIZE:
configs[0]->greenBits = attrib_list[i++];
if(configs[0]->greenBits==GLX_DONT_CARE) configs[0]->greenBits = 0;
+ DBG(printf("FBConfig greenBits=%d\n", configs[0]->greenBits);)
break;
case GLX_BLUE_SIZE:
configs[0]->blueBits = attrib_list[i++];
if(configs[0]->blueBits==GLX_DONT_CARE) configs[0]->blueBits = 0;
+ DBG(printf("FBConfig blueBits=%d\n", configs[0]->blueBits);)
break;
case GLX_ALPHA_SIZE:
configs[0]->alphaBits = attrib_list[i++];
if(configs[0]->alphaBits==GLX_DONT_CARE) configs[0]->alphaBits = 0;
+ DBG(printf("FBConfig alphaBits=%d\n", configs[0]->alphaBits);)
break;
case GLX_DEPTH_SIZE:
configs[0]->depthBits = attrib_list[i++];
if(configs[0]->depthBits==GLX_DONT_CARE) configs[0]->depthBits = 0;
+ DBG(printf("FBConfig depthBits=%d\n", configs[0]->depthBits);)
break;
case GLX_STENCIL_SIZE:
configs[0]->stencilBits = attrib_list[i++];
if(configs[0]->stencilBits==GLX_DONT_CARE) configs[0]->stencilBits = 0;
+ DBG(printf("FBConfig stencilBits=%d\n", configs[0]->stencilBits);)
break;
case GLX_DRAWABLE_TYPE:
configs[0]->drawableType = attrib_list[i++];
+ DBG(printf("FBConfig drawableType=%d\n", configs[0]->drawableType);)
break;
case GLX_SAMPLE_BUFFERS:
configs[0]->nMultiSampleBuffers = attrib_list[i++];
+ DBG(printf("FBConfig multisampleBuffers=%d\n", configs[0]->nMultiSampleBuffers);)
break;
case GLX_SAMPLES:
configs[0]->multiSampleSize = attrib_list[i++];
+ DBG(printf("FBConfig multiSampleSize=%d\n", configs[0]->multiSampleSize);)
break;
default:
++i;
diff --git a/project/jni/gl4es/src/glx/hardext.c b/project/jni/gl4es/src/glx/hardext.c
index be6997a9c..177e3b52d 100755
--- a/project/jni/gl4es/src/glx/hardext.c
+++ b/project/jni/gl4es/src/glx/hardext.c
@@ -128,6 +128,7 @@ void GetHardwareExtensions(int notest)
gles_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &hardext.maxtex);
gles_glGetIntegerv(GL_MAX_LIGHTS, &hardext.maxlights);
if(hardext.maxtex>MAX_TEX) hardext.maxtex=MAX_TEX; // caping, as there are some fixed-sized array...
+ if(hardext.maxlights>MAX_LIGHT) hardext.maxlights=MAX_LIGHT; // caping lights too
SHUT(LOGD("LIBGL: Texture Units: %d, Max lights: %d\n", hardext.maxtex, hardext.maxlights));
#ifndef PANDORA
// The IMPLEMENTATION_COLOR_READ is pretty buggy on the Pandora, so disabling it (it's just use to blit PBuffer to Drawable in glx.c)
diff --git a/project/jni/gl4es/version.h b/project/jni/gl4es/version.h
index d72f1a932..422ec3521 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 2
+#define REVISION 3
#endif //_GL4ES_VERSION_H
\ No newline at end of file
diff --git a/project/jni/sdl-1.2/include/SDL_android.h b/project/jni/sdl-1.2/include/SDL_android.h
index 2a120e5b0..7cd48cf01 100644
--- a/project/jni/sdl-1.2/include/SDL_android.h
+++ b/project/jni/sdl-1.2/include/SDL_android.h
@@ -134,9 +134,23 @@ enum {
/* TODO: more options, see Globals.java */
};
-/* Set SDL Android-specifc option, such as video depth or mouse emulation mode. Most options require restarting the app. */
+/* Set SDL Android-specifc option, and save it to SDL config file, such as video depth or mouse emulation mode. Most options require restarting the app. */
extern DECLSPEC void SDLCALL SDL_ANDROID_SetConfigOption(int option, int value);
+/* Change mouse emulation mode, pass -1 to any option to keep the current value, this does not change SDL config file.
+ Currently only relativeMovement is processed, other options are ignored */
+extern DECLSPEC void SDLCALL SDL_ANDROID_SetMouseEmulationMode(
+ int relativeMovement, int relativeMovementSpeed, int relativeMovementAcceleration,
+ int leftClickMode, int leftClickKey, int leftClickTimeout,
+ int rightClickMode, int rightClickKey, int rightClickTimeout,
+ int moveMouseWithJoystick, int moveMouseWithJoystickSpeed, int moveMouseWithJoystickAcceleration,
+ int moveMouseWithGyroscope, int moveMouseWithGyroscopeSpeed,
+ int forceHardwareMouse, int showScreenUnderFinger,
+ int fingerHover, int fingerHoverJitterFilter, int generateSubframeTouchEvents
+);
+
+extern DECLSPEC int SDLCALL SDL_ANDROID_GetMouseEmulationMode();
+
#ifdef __cplusplus
}
#endif
diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c
index 1f1aaf18a..056183910 100644
--- a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c
+++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c
@@ -1179,6 +1179,31 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz,
}
}
+void SDLCALL SDL_ANDROID_SetMouseEmulationMode(
+ int _relativeMovement, int _relativeMovementSpeed, int _relativeMovementAcceleration,
+ int _leftClickMode, SDLKey _leftClickKey, int _leftClickTimeout,
+ int _rightClickMode, SDLKey _rightClickKey, int _rightClickTimeout,
+ int _moveMouseWithJoystick, int _moveMouseWithJoystickSpeed, int _moveMouseWithJoystickAcceleration,
+ int _moveMouseWithGyroscope, int _moveMouseWithGyroscopeSpeed,
+ int _forceHardwareMouse, int _showScreenUnderFinger,
+ int _fingerHover, int _fingerHoverJitterFilter, int _generateSubframeTouchEvents
+)
+{
+ relativeMovement = _relativeMovement;
+ if (relativeMovement)
+ {
+ leftClickMethod = LEFT_CLICK_WITH_TAP_OR_TIMEOUT;
+ }
+ else
+ {
+ leftClickMethod = LEFT_CLICK_NORMAL;
+ }
+}
+
+int SDLCALL SDL_ANDROID_GetMouseEmulationMode() {
+ return relativeMovement;
+}
+
typedef struct
{
int leftClickMethod;