Merge branch 'sdl_android' into python3_testing

This commit is contained in:
Gerhard Stein
2017-02-05 15:19:18 +01:00
38 changed files with 771 additions and 509 deletions

View File

@@ -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() );

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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 )
{

View File

@@ -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 )
{

View File

@@ -163,6 +163,7 @@
<string name="display_size_mouse">Mouse emulation mode</string>
<string name="display_size">Display size for mouse emulation</string>
<string name="display_size_desktop">Desktop, no emulation</string>
<string name="display_size_large">Large (tablets)</string>
<string name="display_size_small">Small, magnifying glass</string>
<string name="display_size_small_touchpad">Small, touchpad mode</string>

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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)

View File

@@ -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 \

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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; i<hardext.maxtex; i++)
free(vao->tex[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; i<hardext.maxtex; i++)
vao->tex[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");

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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; i<hardext.maxtex; i++) {
TESTA(tex_coord,tex,i)
}
#undef TESTA
#undef TEST
#undef T2
return GL_TRUE;
}
static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
GLsizei skip, GLsizei count) {
if (! list)
@@ -378,30 +400,99 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
list->mode_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; i<hardext.maxtex; i++) {
if (glstate->vao->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; i<hardext.maxtex; i++)
list->tex[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; i<hardext.maxtex; i++) {
GOA(tex_coord,tex,i)
}
glstate->vao->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; i<hardext.maxtex; i++) {
if (glstate->vao->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; i<count; i++)
if (len<sindices[i]) len = sindices[i]; // get the len of the arrays
@@ -547,7 +643,7 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
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; aa<MAX_TEX; aa++) {
for (int aa=0; aa<hardext.maxtex; aa++) {
client_state(tex_coord_array[aa], GL_TEXTURE_COORD_ARRAY, TEXTURE(aa););
// get 1st enabled target
const GLint itarget = get_target(glstate->enable.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; aa<MAX_TEX; aa++) {
for (int aa=0; aa<hardext.maxtex; aa++) {
if (!IS_TEX2D(glstate->enable.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+3<indcnt; i+=4, j+=6) {
indices[j+0] = indfirst + i+0;
indices[j+1] = indfirst + i+1;
indices[j+2] = indfirst + i+2;
indices[j+3] = indfirst + i+0;
indices[j+4] = indfirst + i+2;
indices[j+5] = indfirst + i+3;
}
}
// take care of vao elements, just in case
glbuffer_t *old_vao_elements = glstate->vao->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; aa<MAX_TEX; aa++) {
for (int aa=0; aa<hardext.maxtex; aa++) {
client_state(tex_coord_array[aa], GL_TEXTURE_COORD_ARRAY, TEXTURE(aa););
// get 1st enabled target
const GLint itarget = get_target(glstate->enable.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; aa<MAX_TEX; aa++) {
for (int aa=0; aa<hardext.maxtex; aa++) {
if (!IS_TEX2D(glstate->enable.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; i<primcount; i++)
@@ -1565,7 +1702,7 @@ void glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GL
void gl4es_glMultiDrawElements( GLenum mode, GLsizei *count, GLenum type, const void * const *indices, GLsizei primcount)
{
LOAD_GLES_EXT(glMultiDrawElements);
if((!gles_glMultiDrawElements) || should_intercept_render(mode) || (glstate->list.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

View File

@@ -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);

View File

@@ -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)

View File

@@ -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;

View File

@@ -681,12 +681,13 @@ void adjust_renderlist(renderlist_t *list) {
list->stage = STAGE_LAST;
list->open = false;
for (int a=0; a<hardext.maxtex; a++) {
gltexture_t *bound = glstate->texture.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]<len) {free(texgened[A]); texgened[A]=malloc(4*sizeof(GLfloat)*len); texgenedsz[A]=len; } use_texgen[A]=1
GLint needclean[MAX_TEX];
GLint needclean[MAX_TEX] = {0};
for (int a=0; a<hardext.maxtex; a++) {
if(glstate->enable.texture[a]) {
const GLint itarget = get_target(glstate->enable.texture[a]);

View File

@@ -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->top<MAX_STACK_##B) { \
#define P(A, B) if(glstate->A->top+1<MAX_STACK_##B) { \
memcpy(TOP(A)+16, TOP(A), 16*sizeof(GLfloat)); \
glstate->A->top++; \
} else errorShim(GL_STACK_OVERFLOW)

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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:

View File

@@ -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;

View File

@@ -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)

View File

@@ -3,6 +3,6 @@
#define MAJOR 0
#define MINOR 9
#define REVISION 2
#define REVISION 3
#endif //_GL4ES_VERSION_H

View File

@@ -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

View File

@@ -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;