glshim updated, added latest changes by ptitSeb

This commit is contained in:
lubomyr
2016-11-02 20:21:36 +02:00
parent 1258d54afa
commit 21867b6ddc
31 changed files with 1884 additions and 715 deletions

View File

@@ -11,8 +11,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE := glshim
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \
$(LOCAL_PATH)/src/util \
$(LOCAL_PATH)/src/util/vectorial
$(LOCAL_PATH)/src/util
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) -DBCMHOST
@@ -43,10 +42,11 @@ LOCAL_SRC_FILES := \
src/gl/wrap/glstub.c \
src/gl/math/eval.c \
src/glx/glx.c \
src/glx/hardext.c \
src/glx/lookup.c \
src/glx/streaming.c
LOCAL_CFLAGS += -g -std=c99 -funwind-tables -O3 -DBCMHOST -include include/android_debug.h
LOCAL_CFLAGS += -g -std=c99 -funwind-tables -O3 -DBCMHOST -fvisibility=hidden -include include/android_debug.h
#LOCAL_LDLIBS := -ldl -llog -lEGL

View File

@@ -6,13 +6,13 @@ This is a shim providing OpenGL 1.x functionality to OpenGL ES accelerated cards
Most function of OpenGL up to 1.5 are supported, with some notable exceptions:
* Reading of Depth or Stencil buffer will not work
* GL_FEEDBACK mode is not implemented
* OcclusionQuery is not implemented
Some know limitations:
* GL_SELECT as some limitation in its implementation (for exemple, current Depth buffer or binded texture are not taken into account)
* NPOT texture are supported, but not with GL_REPEAT / GL_MIRRORED, only GL_CLAMP will work properly
* Framebuffer use FRAMEBUFFER_OES extension (that must be present in the GLES 1.1 stack)
* Multiple Color attachment on Framebuffer are not supported
* OcclusionQuery is implemented, but with a 0 bits precision
* Probably many other things
----
@@ -65,6 +65,7 @@ Controls the Framebuffer output
* 0 : Default, using standard x11 rendering
* 1 : Use Framebuffer output (x11 bypassed, only fullscreen)
* 2 : Use Framebuffer, but also an intermediary FBO
* 3 : Use PBuffer, allowing x11 rendering even if driver doesn't support it
##### LIBGL_XREFRESH
Debug helper in specific cases
@@ -194,7 +195,12 @@ Expose NPOT (Non Power of Two) Support
* 1 : Expose limited NPOT extension
* 2 : Expose GL_ARB_texture_non_power_of_two extension
##### LIBGL_QUERIES
##### LIBGL_GLQUERIES
Expose glQueries functions
* 0 : Default, don't expose the function (fake one will be used if called)
* 1 : Expose fake functions (always answer 0)
* 0 : Don't expose the function (fake one will be used if called)
* 1 : Default, expose fake functions (always answer 0)
##### LIBGL_NOTEST
Initial Hardware test
* 0 : Default, perform intial hardware testing (using a PBuffer)
* 1 : Do not perform test (no extensions tested or used)

8
project/jni/glshim/include/android_debug.h Normal file → Executable file
View File

@@ -29,14 +29,14 @@ namespace std
*((ostringstream*)this) << v;
if( this->str().find('\n') != ::std::string::npos )
{
__android_log_print(ANDROID_LOG_INFO, "glshim", "%s", this->str().c_str());
__android_log_print(ANDROID_LOG_INFO, "LIBGL", "%s", this->str().c_str());
this->str().clear();
}
return *this;
}
~android_cout()
{
__android_log_print(ANDROID_LOG_INFO, "glshim", "%s", this->str().c_str());
__android_log_print(ANDROID_LOG_INFO, "LIBGL", "%s", this->str().c_str());
this->str().clear();
}
};
@@ -48,7 +48,7 @@ namespace std
#endif
#define printf(...) __android_log_print(ANDROID_LOG_INFO, "glshim", __VA_ARGS__)
#define printf(...) __android_log_print(ANDROID_LOG_INFO, "LIBGL", __VA_ARGS__)
// Override fprintf(stderr, ...) constructs
static inline int __sdl_logged_fprintf(FILE *stream, const char *format, ...)
@@ -57,7 +57,7 @@ static inline int __sdl_logged_fprintf(FILE *stream, const char *format, ...)
va_list args;
va_start(args, format);
if( stream == stderr || stream == stdout )
ret = __android_log_vprint(ANDROID_LOG_INFO, "glshim", format, args);
ret = __android_log_vprint(ANDROID_LOG_INFO, "LIBGL", format, args);
else
ret = vfprintf(stream, format, args);
va_end(args);

View File

@@ -78,6 +78,12 @@
#define skip_glMultiTexCoord4f
#define skip_glTexGeni
#define skip_glTexGenfv
#define skip_glTexEnvf
#define skip_glTexEnvi
#define skip_glTexEnvfv
#define skip_glTexEnviv
#define skip_glGetTexEnvfv
#define skip_glGetTexEnviv
#define skip_glReadPixels
#define skip_glCompressedTexImage2D
#define skip_glCompressedTexSubImage2D

View File

@@ -59,7 +59,9 @@
#define GL_TEXTURE_GEN_STR 0x8D60
// GL_ARB_point_sprite
#define GL_POINT_SPRITE 0x8861
#define GL_COORD_REPLACE 0x8862
// GL_ARB_texture_rectangle
#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
@@ -564,4 +566,5 @@
#define GL_TEXTURE_INTENSITY_TYPE 0x8C15
#define GL_DEPTH_COMPONENT24 0x81A6
#define GL_DEPTH_COMPONENT16 0x81A5
#define GL_DEPTH_COMPONENT 0x1902
#define GL_MAX_DRAW_BUFFERS_ARB 0x8824

View File

@@ -57,6 +57,7 @@ const char* PrintEnum(GLenum what) {
p(GL_COMPRESSED_RGB);
p(GL_COMPRESSED_RGBA);
// type
p(GL_BYTE);
p(GL_UNSIGNED_BYTE);
p(GL_UNSIGNED_BYTE_2_3_3_REV);
p(GL_UNSIGNED_BYTE_3_3_2);

View File

@@ -1,6 +1,6 @@
#include "framebuffers.h"
#include "debug.h"
#include "../glx/hardext.h"
#ifndef ANDROID
#include <execinfo.h>
#endif
@@ -197,17 +197,17 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text
k = kh_get(tex, list, texture);
if (k == kh_end(list)){
printf("*WARNING* texture for FBO not found, name=%u\n", texture);
LOGE("LIBGL: texture for FBO not found, name=%u\n", texture);
} else {
tex = kh_value(list, k);
texture = tex->glname;
// check if texture is shrinked...
if (tex->shrink) {
printf("LIBGL: unshrinking shrinked texture for FBO\n");
LOGD("LIBGL: unshrinking shrinked texture for FBO\n");
tex->width *= 2*tex->shrink;
tex->height *= 2*tex->shrink;
tex->nwidth = npot(tex->width);
tex->nheight = npot(tex->height);
tex->nwidth = hardext.npot==2?tex->width:npot(tex->width);
tex->nheight = hardext.npot==2?tex->height:npot(tex->height);
tex->shrink = 0;
gltexture_t *bound = glstate->texture.bound[glstate->texture.active];
GLuint oldtex = (bound)?bound->glname:0;
@@ -232,10 +232,9 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text
}
}
if(attachment==GL_DEPTH_ATTACHMENT) {
if(attachment==GL_DEPTH_ATTACHMENT /*&& hardext.depthtex==0*/) {
noerrorShim();
if (level!=0) return;
// glshim doesn't support DEPTH Texture. So instead of ending with an incomplete FBO
// let's create a renderbuffer and attach it instead of the (presumably) depth texture
GLuint render_depth; // memory leak here...
glshim_glGenRenderbuffers(1, &render_depth);
@@ -353,14 +352,16 @@ void glshim_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei
//printf("glRenderbufferStorage(0x%04X, 0x%04X, %i, %i)\n", target, internalformat, width, height);
errorGL();
width = npot(width);
height = npot(height);
width = hardext.npot==2?width:npot(width);
height = hardext.npot==2?height:npot(height);
// check if internal format is GL_DEPTH_STENCIL_EXT
if (internalformat == GL_DEPTH_STENCIL)
internalformat = GL_DEPTH24_STENCIL8;
// in that case, create first a STENCIL one then a DEPTH one....
if ((internalformat == GL_DEPTH_STENCIL) || (internalformat == GL_DEPTH24_STENCIL8)) {
if ((internalformat == GL_DEPTH24_STENCIL8) && (hardext.depthstencil==0)) {
khint_t k;
int ret;
internalformat = GL_DEPTH_COMPONENT24;
internalformat = (hardext.depth24)?GL_DEPTH_COMPONENT24:GL_DEPTH_COMPONENT16;
GLuint old_rb = current_rb;
GLuint stencil;
if (!depthstencil) {
@@ -386,10 +387,13 @@ void glshim_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei
gles_glRenderbufferStorage(target, GL_STENCIL_INDEX8, width, height);
gles_glBindRenderbuffer(GL_RENDERBUFFER, current_rb);
}
else if (internalformat == GL_DEPTH_COMPONENT) { // Not much is supported on GLES...
else if (internalformat == GL_DEPTH_COMPONENT) // Not much is supported on GLES...
internalformat = GL_DEPTH_COMPONENT16;
}
else if (internalformat == GL_RGB8 && hardext.rgba8==0)
internalformat = GL_RGB565_OES;
else if (internalformat == GL_RGBA8 && hardext.rgba8==0)
internalformat = GL_RGBA4_OES;
gles_glRenderbufferStorage(target, internalformat, width, height);
}
@@ -430,7 +434,7 @@ void glshim_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachme
LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv);
// hack to return DEPTH size
if(target==GL_FRAMEBUFFER && attachment==GL_DEPTH_ATTACHMENT && pname==GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) {
if(target==GL_FRAMEBUFFER && attachment==GL_DEPTH_ATTACHMENT && pname==GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE && hardext.depthtex==0) {
noerrorShim();
glshim_glGetFramebufferAttachmentParameteriv(target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, params);
if (params)
@@ -481,8 +485,8 @@ void createMainFBO(int width, int height) {
mainfbo_width = width;
mainfbo_height = height;
mainfbo_nwidth = width = npot(width);
mainfbo_nheight = height = npot(height);
mainfbo_nwidth = width = hardext.npot==2?width:npot(width);
mainfbo_nheight = height = hardext.npot==2?width:npot(height);
// create the texture
gles_glGenTextures(1, &mainfbo_tex);

View File

@@ -1,5 +1,6 @@
#include "gl.h"
#include "debug.h"
#include "../glx/hardext.h"
/*
glstate_t state = {.color = {1.0f, 1.0f, 1.0f, 1.0f},
.secondary = {0.0f, 0.0f, 0.0f, 0.0f},
@@ -88,6 +89,13 @@ void* NewGLState(void* shared_glstate) {
glstate->gl_batch = gl_batch;
//raster & viewport
glstate->raster.raster_zoomx=1.0f;
glstate->raster.raster_zoomy=1.0f;
for(int i=0; i<4; i++)
glstate->raster.raster_scale[i] = 1.0f;
LOAD_GLES(glGetFloatv);
gles_glGetFloatv(GL_VIEWPORT, (GLfloat*)&glstate->raster.viewport);
return (void*)glstate;
}
@@ -161,48 +169,56 @@ void DeleteGLState(void* oldstate) {
void ActivateGLState(void* new_glstate) {
if(glstate == (glstate_t*)new_glstate) return; // same state, nothing to do
if (glstate && glstate->gl_batch) flush();
glstate = (glstate_t*)new_glstate;
glstate = (new_glstate)?(glstate_t*)new_glstate:default_glstate;
// check if viewport is correct
if(glstate->raster.viewport.width==0.0f || glstate->raster.viewport.height==0.0f) {
LOAD_GLES(glGetFloatv);
gles_glGetFloatv(GL_VIEWPORT, (GLfloat*)&glstate->raster.viewport);
}
if (gl_batch && glstate->init_batch==0) init_batch();
}
void scan_env();
__attribute__((constructor))
void initialize_glshim() {
char *env_nobanner = getenv("LIBGL_NOBANNER");
if (env_nobanner && strcmp(env_nobanner, "1") == 0)
glshim_nobanner = 1;
if(!glshim_nobanner) printf("LIBGL: Initialising glshim\n");
if(!glshim_nobanner) LOGD("LIBGL: Initialising glshim\n");
// init read hack
char *env_readhack = getenv("LIBGL_READHACK");
if (env_readhack && strcmp(env_readhack, "1") == 0) {
readhack = 1;
printf("LIBGL: glReadPixel Hack (for other-life, 1x1 reading multiple time)\n");
LOGD("LIBGL: glReadPixel Hack (for other-life, 1x1 reading multiple time)\n");
}
if (env_readhack && strcmp(env_readhack, "2") == 0) {
readhack = 2;
printf("LIBGL: glReadPixel Depth Hack (for games that read GLDepth always at the same place, same 1x1 size)\n");
LOGD("LIBGL: glReadPixel Depth Hack (for games that read GLDepth always at the same place, same 1x1 size)\n");
}
char *env_batch = getenv("LIBGL_BATCH");
if (env_batch && strcmp(env_batch, "1") == 0) {
gl_batch = 1;
printf("LIBGL: Batch mode enabled\n");
LOGD("LIBGL: Batch mode enabled\n");
}
if (env_batch && strcmp(env_batch, "0") == 0) {
gl_batch = 0;
printf("LIBGL: Batch mode disabled\n");
LOGD("LIBGL: Batch mode disabled\n");
}
if (env_batch && strcmp(env_batch, "2") == 0) {
gl_batch = 0;
gl_mergelist = 0;
printf("LIBGL: Batch mode disabled, merging of list disabled too\n");
LOGD("LIBGL: Batch mode disabled, merging of list disabled too\n");
}
default_glstate = (glstate_t*)NewGLState(NULL);
ActivateGLState(default_glstate);
initialized = 1;
#ifdef ANDROID
scan_env();
#endif
}
// config functions
@@ -216,6 +232,7 @@ const GLubyte *glshim_glGetString(GLenum name) {
strcpy(extensions,
"GL_EXT_abgr "
"GL_EXT_packed_pixels "
"GL_EXT_compiled_vertex_array "
"GL_ARB_vertex_buffer_object "
"GL_ARB_vertex_array_object "
"GL_ARB_vertex_buffer "
@@ -241,31 +258,42 @@ const GLubyte *glshim_glGetString(GLenum name) {
"GL_EXT_texture_compression_dxt3 "
"GL_EXT_texture_compression_dxt5 "
"GL_EXT_texture_compression_dxt1 "
"GL_ARB_framebuffer_object "
"GL_EXT_framebuffer_object "
"GL_EXT_packed_depth_stencil "
"GL_ARB_point_parameters "
"GL_EXT_point_parameters "
"GL_EXT_stencil_wrap "
"SGIS_texture_edge_clamp "
"GL_EXT_texture_edge_clamp "
#ifndef ODROID
"GL_EXT_blend_subtract "
"GL_EXT_blend_func_separate "
"GL_EXT_blend_equation_separate "
#endif
"GL_ARB_draw_buffers "
"GL_EXT_direct_state_access "
"GL_EXT_multi_draw_arrays "
"GL_SUN_multi_draw_arrays "
"GL_ARB_multisample "
"GL_EXT_texture_object "
"GL_EXT_polygon_offset "
// "GL_EXT_blend_logic_op "
// "GL_EXT_blend_color "
// "GL_ARB_texture_cube_map "
);
if(glshim_npot>=1)
strcat(extensions, "GL_APPLE_texture_2D_limited_npot ");
if(glshim_npot>=2)
strcat(extensions, "GL_ARB_texture_non_power_of_two ");
if(hardext.blendcolor)
strcat(extensions, "GL_EXT_blend_color ");
if(hardext.blendminmax)
strcat(extensions, "GL_EXT_blend_minmax ");
if(hardext.blendeq)
strcat(extensions, "GL_EXT_blend_equation_separate ");
if(hardext.blendfunc)
strcat(extensions, "GL_EXT_blend_func_separate ");
if(hardext.blendsub)
strcat(extensions, "GL_EXT_blend_subtract ");
if(hardext.fbo)
strcat(extensions,
"GL_ARB_framebuffer_object "
"GL_EXT_framebuffer_object "
"GL_EXT_packed_depth_stencil "
"GL_ARB_draw_buffers ");
if(hardext.pointsprite)
strcat(extensions, "GL_ARB_point_sprite ");
}
switch (name) {
case GL_VERSION:
@@ -295,10 +323,6 @@ void transposeMatrix(float *matrix)
}
// glGet
extern float raster_zoomx, raster_zoomy;
extern GLfloat raster_scale[4];
extern GLfloat raster_bias[4];
void glshim_glGetIntegerv(GLenum pname, GLint *params) {
if (params==NULL) {
errorShim(GL_INVALID_OPERATION);
@@ -356,6 +380,28 @@ void glshim_glGetIntegerv(GLenum pname, GLint *params) {
//Fake, *TODO* ?
*params = 0;
break;
case GL_ZOOM_X:
*params = glstate->raster.raster_zoomx;
break;
case GL_ZOOM_Y:
*params = glstate->raster.raster_zoomy;
break;
case GL_RED_SCALE:
*params = glstate->raster.raster_scale[0];
break;
case GL_RED_BIAS:
*params = glstate->raster.raster_bias[0];
break;
case GL_GREEN_SCALE:
case GL_BLUE_SCALE:
case GL_ALPHA_SCALE:
*params = glstate->raster.raster_scale[(pname-GL_GREEN_SCALE)/2+1];
break;
case GL_GREEN_BIAS:
case GL_BLUE_BIAS:
case GL_ALPHA_BIAS:
*params = glstate->raster.raster_bias[(pname-GL_GREEN_BIAS)/2+1];
break;
case GL_POINT_SIZE_RANGE:
gles_glGetIntegerv(GL_POINT_SIZE_MIN, params);
gles_glGetIntegerv(GL_POINT_SIZE_MAX, params+1);
@@ -466,26 +512,26 @@ void glshim_glGetFloatv(GLenum pname, GLfloat *params) {
*params = glstate->texture.pack_lsb_first;
break;
case GL_ZOOM_X:
*params = raster_zoomx;
*params = glstate->raster.raster_zoomx;
break;
case GL_ZOOM_Y:
*params = raster_zoomy;
*params = glstate->raster.raster_zoomy;
break;
case GL_RED_SCALE:
*params = raster_scale[0];
*params = glstate->raster.raster_scale[0];
break;
case GL_RED_BIAS:
*params = raster_bias[0];
*params = glstate->raster.raster_bias[0];
break;
case GL_GREEN_SCALE:
case GL_BLUE_SCALE:
case GL_ALPHA_SCALE:
*params = raster_scale[(pname-GL_GREEN_SCALE)/2+1];
*params = glstate->raster.raster_scale[(pname-GL_GREEN_SCALE)/2+1];
break;
case GL_GREEN_BIAS:
case GL_BLUE_BIAS:
case GL_ALPHA_BIAS:
*params = raster_bias[(pname-GL_GREEN_BIAS)/2+1];
*params = glstate->raster.raster_bias[(pname-GL_GREEN_BIAS)/2+1];
break;
case GL_POINT_SIZE_RANGE:
gles_glGetFloatv(GL_POINT_SIZE_MIN, params);
@@ -594,7 +640,11 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) {
enable(GL_TEXTURE_GEN_S, texgen_s[glstate->texture.active]);
enable(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active]);
enable(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active]);
enable(GL_TEXTURE_GEN_Q, texgen_q[glstate->texture.active]);
enable(GL_LINE_STIPPLE, line_stipple);
// point sprite
proxy_enable(GL_POINT_SPRITE, pointsprite);
// Secondary color
enable(GL_COLOR_SUM, color_sum);
@@ -636,11 +686,9 @@ void glshim_glEnable(GLenum cap) {
if (which_cap!=ENABLED_LAST) {
if ((glstate->statebatch.enabled[which_cap] == 1))
return; // nothing to do...
if (!glstate->statebatch.enabled[which_cap]) {
glstate->statebatch.enabled[which_cap] = 1;
} else {
if (glstate->statebatch.enabled[which_cap])
flush();
}
glstate->statebatch.enabled[which_cap] = 1;
}
}
PUSH_IF_COMPILING(glEnable)
@@ -662,11 +710,9 @@ void glshim_glDisable(GLenum cap) {
if (which_cap!=ENABLED_LAST) {
if ((glstate->statebatch.enabled[which_cap] == 2))
return; // nothing to do...
if (!glstate->statebatch.enabled[which_cap]) {
glstate->statebatch.enabled[which_cap] = 2;
} else {
if (glstate->statebatch.enabled[which_cap])
flush();
}
glstate->statebatch.enabled[which_cap] = 2;
}
}
PUSH_IF_COMPILING(glDisable)
@@ -683,12 +729,18 @@ void glshim_glDisable(GLenum cap) {
void glDisable(GLenum cap) AliasExport("glshim_glDisable");
void glshim_glEnableClientState(GLenum cap) {
// should flush for now... to be optimized later!
if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling))
flush();
LOAD_GLES(glEnableClientState);
proxy_glEnable(cap, true, gles_glEnableClientState);
}
void glEnableClientState(GLenum cap) AliasExport("glshim_glEnableClientState");
void glshim_glDisableClientState(GLenum cap) {
// should flush for now... to be optimized later!
if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling))
flush();
LOAD_GLES(glDisableClientState);
proxy_glEnable(cap, false, gles_glDisableClientState);
}
@@ -702,7 +754,8 @@ void glDisableClientState(GLenum cap) AliasExport("glshim_glDisableClientState")
GLboolean glshim_glIsEnabled(GLenum cap) {
// should flush for now... to be optimized later!
if (glstate->gl_batch) flush();
if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling))
flush();
LOAD_GLES(glIsEnabled);
noerrorShim();
switch (cap) {
@@ -711,7 +764,9 @@ GLboolean glshim_glIsEnabled(GLenum cap) {
isenabled(GL_TEXTURE_GEN_S, texgen_s[glstate->texture.active]);
isenabled(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active]);
isenabled(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active]);
isenabled(GL_TEXTURE_GEN_Q, texgen_q[glstate->texture.active]);
isenabled(GL_COLOR_SUM, color_sum);
isenabled(GL_POINT_SPRITE, pointsprite);
clientisenabled(GL_SECONDARY_COLOR_ARRAY, secondary_array);
isenabled(GL_TEXTURE_1D, texture_1d[glstate->texture.active]);
isenabled(GL_TEXTURE_3D, texture_3d[glstate->texture.active]);
@@ -732,7 +787,7 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
GLsizei skip, GLsizei count) {
if (! list)
list = alloc_renderlist();
//if (glstate->list.compiling) printf("arrary_to_renderlist while compiling list, skip=%d, count=%d\n", skip, count);
//if (glstate->list.compiling) LOGD("arrary_to_renderlist while compiling list, skip=%d, count=%d\n", skip, count);
list->mode = mode;
list->mode_init = mode;
list->len = count-skip;
@@ -750,7 +805,7 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
if (glstate->vao->normal_array) {
list->normal = copy_gl_pointer_raw(&glstate->vao->pointers.normal, 3, skip, count);
}
for (int i=0; i<MAX_TEX; i++) {
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);
}
@@ -760,22 +815,25 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
static inline bool should_intercept_render(GLenum mode) {
// check bounded tex that will be used if one need some transformations
for (int aa=0; aa<MAX_TEX; aa++) {
for (int aa=0; aa<hardext.maxtex; aa++) {
if (glstate->enable.texture_2d[aa] || glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa]) {
if(glstate->texture.rect_arb[aa])
return true;
gltexture_t *bound = glstate->texture.bound[aa];
if (bound && (bound->width!=bound->nwidth || bound->height!=bound->height))
if (bound && (bound->width!=bound->nwidth || bound->height!=bound->nheight))
return true;
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->polygon_mode == GL_LINE && mode>=GL_TRIANGLES)
return true;
if ((glstate->vao->secondary_array) && (glstate->vao->color_array))
return true;
if (glstate->vao->color_array && (glstate->vao->pointers.color.size != 4))
return true;
return (
(glstate->vao->vertex_array && ! valid_vertex_type(glstate->vao->pointers.vertex.type)) ||
(/*glstate->enable.texture_2d[0] && */(glstate->enable.texgen_s[0] || glstate->enable.texgen_t[0] || glstate->enable.texgen_r[0])) ||
(/*glstate->enable.texture_2d[1] && */(glstate->enable.texgen_s[1] || glstate->enable.texgen_t[1] || glstate->enable.texgen_r[1])) ||
(/*glstate->enable.texture_2d[2] && */(glstate->enable.texgen_s[2] || glstate->enable.texgen_t[2] || glstate->enable.texgen_r[2])) ||
(/*glstate->enable.texture_2d[3] && */(glstate->enable.texgen_s[3] || glstate->enable.texgen_t[3] || glstate->enable.texgen_r[3])) ||
(mode == GL_LINES && glstate->enable.line_stipple) ||
(mode == GL_QUADS) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch))
);
@@ -814,9 +872,16 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
NewStage(glstate->list.active, STAGE_DRAW);
list = glstate->list.active;
normalize_indices(sindices, &max, &min, count);
list = arrays_to_renderlist(list, mode, min, max + 1);
list->indices = (need_free)?sindices:copy_gl_array(sindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count);
if(need_free) {
normalize_indices(sindices, &max, &min, count);
list = arrays_to_renderlist(list, mode, min, max + 1);
list->indices = sindices;
} else {
getminmax_indices(sindices, &max, &min, count);
list = arrays_to_renderlist(list, mode, min, max + 1);
list->indices = copy_gl_array(sindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count);
if(min) normalize_indices(list->indices, &max, &min, count);
}
list->ilen = count;
list->indice_cap = count;
//end_renderlist(list);
@@ -829,9 +894,16 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
renderlist_t *list = NULL;
GLsizei min, max;
normalize_indices(sindices, &max, &min, count);
list = arrays_to_renderlist(list, mode, min, max + 1);
list->indices = (need_free)?sindices:copy_gl_array(sindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count);
if(need_free) {
normalize_indices(sindices, &max, &min, count);
list = arrays_to_renderlist(list, mode, min, max + 1);
list->indices = sindices;
} else {
getminmax_indices(sindices, &max, &min, count);
list = arrays_to_renderlist(list, mode, min, max + 1);
list->indices = copy_gl_array(sindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count);
if(min) normalize_indices(list->indices, &max, &min, count);
}
list->ilen = count;
list->indice_cap = count;
list = end_renderlist(list);
@@ -864,8 +936,8 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
GLenum mode_init = mode;
if (glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES)
mode = GL_LINE_LOOP;
/*if (glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES)
mode = GL_LINE_LOOP;*/
if (glstate->polygon_mode == GL_POINT && mode>=GL_TRIANGLES)
mode = GL_POINTS;
@@ -876,27 +948,9 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
if (glstate->render_mode == GL_SELECT) {
select_glDrawElements(&glstate->vao->pointers.vertex, mode, count, GL_UNSIGNED_SHORT, sindices);
} else {
// secondary color...
GLfloat *final_colors = NULL;
pointer_state_t old_color;
// secondry color and color sizef != 4 are "intercepted" and draw using a list
client_state(color_array, GL_COLOR_ARRAY, );
if (/*glstate->enable.color_sum && */(glstate->vao->secondary_array) && (glstate->vao->color_array)) {
final_colors=copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, len);
GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&glstate->vao->pointers.secondary, 4, 0, len);
for (int i=0; i<len*4; i++)
final_colors[i]+=seconds_colors[i];
gles_glColorPointer(4, GL_FLOAT, 0, final_colors);
free(seconds_colors);
} else if (glstate->vao->color_array && (glstate->vao->pointers.color.size != 4)) {
// Pandora doesn't like Color Pointer with size != 4
if(glstate->vao->pointers.color.type == GL_UNSIGNED_BYTE) {
final_colors=copy_gl_pointer_bytecolor(&glstate->vao->pointers.color, 4, 0, len);
gles_glColorPointer(4, GL_UNSIGNED_BYTE, 0, final_colors);
} else {
final_colors=copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, len);
gles_glColorPointer(4, GL_FLOAT, 0, final_colors);
}
} else if (glstate->vao->color_array)
if (glstate->vao->color_array)
gles_glColorPointer(glstate->vao->pointers.color.size, glstate->vao->pointers.color.type, glstate->vao->pointers.color.stride, glstate->vao->pointers.color.pointer);
client_state(normal_array, GL_NORMAL_ARRAY, );
if (glstate->vao->normal_array)
@@ -905,8 +959,7 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
if (glstate->vao->vertex_array)
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;
GLuint cur_tex = old_tex;
#define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;}
#define TEXTURE(A) glshim_glClientActiveTexture(A+GL_TEXTURE0);
for (int aa=0; aa<MAX_TEX; aa++) {
client_state(tex_coord_array[aa], GL_TEXTURE_COORD_ARRAY, TEXTURE(aa););
if (!glstate->enable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) {
@@ -920,46 +973,9 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
}
if (glstate->texture.client!=old_tex)
TEXTURE(old_tex);
#undef TEXTURE
if (glstate->polygon_mode == GL_LINE && mode_init>=GL_TRIANGLES) {
int n, s;
switch (mode_init) {
case GL_TRIANGLES:
n = 3;
s = 3;
break;
case GL_TRIANGLE_STRIP:
n = 3;
s = 1;
break;
case GL_TRIANGLE_FAN: // wrong here...
n = count;
s = count;
break;
case GL_QUADS:
n = 4;
s = 4;
break;
case GL_QUAD_STRIP:
n = 4;
s = 1;
break;
default: // Polygon and other?
n = count;
s = count;
break;
}
for (int i=n; i<count; i+=s)
gles_glDrawElements(mode, n, GL_UNSIGNED_SHORT, sindices+i-n);
} else
gles_glDrawElements(mode, count, GL_UNSIGNED_SHORT, sindices);
// POLYGON mode as LINE is "intercepted" and drawn using list
gles_glDrawElements(mode, count, GL_UNSIGNED_SHORT, sindices);
// secondary color
if (final_colors) {
free(final_colors);
}
#define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;}
for (int aa=0; aa<MAX_TEX; aa++) {
if (!glstate->enable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) {
TEXTURE(aa);
@@ -1016,8 +1032,8 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
return;
}
if (glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES)
mode = GL_LINE_LOOP;
/*if (glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES)
mode = GL_LINE_LOOP;*/
if (glstate->polygon_mode == GL_POINT && mode>=GL_TRIANGLES)
mode = GL_POINTS;
@@ -1028,8 +1044,6 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
draw_renderlist(list);
free_renderlist(list);
} else {
// TODO: some draw states require us to use the full pipeline here
// like texgen, stipple, npot
LOAD_GLES(glDrawArrays);
GLenum mode_init = mode;
@@ -1042,27 +1056,8 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
select_glDrawArrays(&glstate->vao->pointers.vertex, mode, first, count);
} else {
// setup the Array Pointers
// secondary color...
GLfloat *final_colors = NULL;
client_state(color_array, GL_COLOR_ARRAY, );
if (/*glstate->enable.color_sum && */(glstate->vao->secondary_array) && (glstate->vao->color_array)) {
final_colors=copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, count+first);
GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&glstate->vao->pointers.secondary, 4, first, count+first);
for (int i=0; i<(count+first)*4; i++)
final_colors[i]+=seconds_colors[i];
gles_glColorPointer(4, GL_FLOAT, 0, final_colors);
free(seconds_colors);
} else if ((glstate->vao->color_array && (glstate->vao->pointers.color.size != 4))
|| (glstate->vao->color_array && (glstate->vao->pointers.color.stride!=0) && (glstate->vao->pointers.color.type != GL_FLOAT))) {
// Pandora doesn't like Color Pointer with size != 4
if(glstate->vao->pointers.color.type == GL_UNSIGNED_BYTE) {
final_colors=copy_gl_pointer_bytecolor(&glstate->vao->pointers.color, 4, 0, count+first);
gles_glColorPointer(4, GL_UNSIGNED_BYTE, 0, final_colors);
} else {
final_colors=copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, count+first);
gles_glColorPointer(4, GL_FLOAT, 0, final_colors);
}
} else if (glstate->vao->color_array)
client_state(color_array, GL_COLOR_ARRAY, );
if (glstate->vao->color_array)
gles_glColorPointer(glstate->vao->pointers.color.size, glstate->vao->pointers.color.type, glstate->vao->pointers.color.stride, glstate->vao->pointers.color.pointer);
client_state(normal_array, GL_NORMAL_ARRAY, );
if (glstate->vao->normal_array)
@@ -1071,8 +1066,7 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
if (glstate->vao->vertex_array)
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;
GLuint cur_tex = old_tex;
#define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;}
#define TEXTURE(A) glshim_glClientActiveTexture(A+GL_TEXTURE0);
for (int aa=0; aa<MAX_TEX; aa++) {
client_state(tex_coord_array[aa], GL_TEXTURE_COORD_ARRAY, TEXTURE(aa););
if (!glstate->enable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) {
@@ -1088,53 +1082,18 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
}
if (glstate->texture.client!=old_tex)
TEXTURE(old_tex);
#undef TEXTURE
if (glstate->polygon_mode == GL_LINE && mode_init>=GL_TRIANGLES) {
int n, s;
switch (mode_init) {
case GL_TRIANGLES:
n = 3;
s = 3;
break;
case GL_TRIANGLE_STRIP:
n = 3;
s = 1;
break;
case GL_TRIANGLE_FAN: // wrong here...
n = count;
s = count;
break;
case GL_QUADS:
n = 4;
s = 4;
break;
case GL_QUAD_STRIP:
n = 4;
s = 1;
break;
default: // Polygon and other?
n = count;
s = count;
break;
}
for (int i=n; i<count; i+=s)
gles_glDrawArrays(mode, i-n, n);
} else
gles_glDrawArrays(mode, first, count);
gles_glDrawArrays(mode, first, count);
// secondary color
if (final_colors) {
free(final_colors);
}
for (int aa=0; aa<MAX_TEX; aa++) {
if (!glstate->enable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) {
glshim_glClientActiveTexture(aa+GL_TEXTURE0);
TEXTURE(aa);
gles_glDisable(GL_TEXTURE_2D);
}
}
if (glstate->texture.client!=old_tex)
glshim_glClientActiveTexture(old_tex+GL_TEXTURE0);
TEXTURE(old_tex);
#undef TEXTURE
}
}
}
@@ -1292,7 +1251,7 @@ void glshim_glEnd() {
if (!glstate->list.active) return;
// check if TEXTUREx is activate and no TexCoord (or texgen), in that case, create a dummy one base on glstate->..
for (int a=0; a<MAX_TEX; a++)
if (glstate->enable.texture_2d[a] && ((glstate->list.active->tex[a]==0) && (!glstate->enable.texgen_s[a])))
if (glstate->enable.texture_2d[a] && ((glstate->list.active->tex[a]==0) && !(glstate->enable.texgen_s[a] || glstate->texture.pscoordreplace[a])))
rlMultiTexCoord4f(glstate->list.active, GL_TEXTURE0+a, glstate->texcoord[a][0], glstate->texcoord[a][1], glstate->texcoord[a][2], glstate->texcoord[a][3]);
// render if we're not in a display list
if (!(glstate->list.compiling || glstate->gl_batch)) {
@@ -1757,7 +1716,7 @@ void glshim_glPushMatrix() {
default:
//Warning?
errorShim(GL_INVALID_OPERATION);
//printf("LIBGL: PushMatrix with Unrecognise matrix mode (0x%04X)\n", matrix_mode);
//LOGE("LIBGL: PushMatrix with Unrecognise matrix mode (0x%04X)\n", matrix_mode);
//gles_glPushMatrix();
}
}
@@ -1804,7 +1763,7 @@ void glshim_glPopMatrix() {
default:
//Warning?
errorShim(GL_INVALID_OPERATION);
//printf("LIBGL: PopMatrix withUnrecognise matrix mode (0x%04X)\n", matrix_mode);
//LOGE("LIBGL: PopMatrix with Unrecognise matrix mode (0x%04X)\n", matrix_mode);
//gles_glPopMatrix();
}
}
@@ -1831,7 +1790,7 @@ void glshim_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf a
else {
static int test = 1;
if (test) {
printf("stub glBlendColor(%f, %f, %f, %f)\n", red, green, blue, alpha);
LOGD("stub glBlendColor(%f, %f, %f, %f)\n", red, green, blue, alpha);
test = 0;
}
}
@@ -1954,7 +1913,6 @@ void init_statebatch() {
void flush() {
// flush internal list
//printf("flush glstate->list.active=%p, gl_batch=%i(%i)\n", glstate->list.active, glstate->gl_batch, gl_batch);
renderlist_t *mylist = glstate->list.active;
if (mylist) {
GLuint old = glstate->gl_batch;
@@ -1965,7 +1923,7 @@ void flush() {
free_renderlist(mylist);
glstate->gl_batch = old;
}
if (glstate->gl_batch) init_statebatch();
init_statebatch();
glstate->list.active = (glstate->gl_batch)?alloc_renderlist():NULL;
}
@@ -1975,7 +1933,9 @@ void init_batch() {
glstate->gl_batch = 1;
glstate->init_batch = 1;
}
#ifndef ANDROID
extern void BlitEmulatedPixmap();
#endif
void glshim_glFlush() {
LOAD_GLES(glFlush);
@@ -1988,6 +1948,11 @@ void glshim_glFlush() {
gles_glFlush();
errorGL();
#ifndef ANDROID
if(glstate->emulatedPixmap && !glstate->emulatedWin)
BlitEmulatedPixmap();
#endif
}
void glFlush() AliasExport("glshim_glFlush");
@@ -2050,7 +2015,7 @@ void glFogfv(GLenum pname, const GLfloat* params) AliasExport("glshim_glFogfv");
void glshim_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) {
static bool warning = false;
if(!warning) {
printf("Warning, stubbed glIndexPointer\n");
LOGD("Warning, stubbed glIndexPointer\n");
warning = true;
}
}
@@ -2059,7 +2024,7 @@ void glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) AliasEx
void glshim_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer) {
static bool warning = false;
if(!warning) {
printf("Warning, stubbed glEdgeFlagPointer\n");
LOGD("Warning, stubbed glEdgeFlagPointer\n");
warning = true;
}
}
@@ -2117,7 +2082,7 @@ void glPointParameteriv(GLenum pname, const GLint * params) AliasExport("glshim_
void glshim_glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount)
{
LOAD_GLES_OES(glMultiDrawArrays);
LOAD_GLES_EXT(glMultiDrawArrays);
if((!gles_glMultiDrawArrays) || should_intercept_render(mode) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch))
|| (glstate->render_mode == GL_SELECT) || ((glstate->polygon_mode == GL_LINE) || (glstate->polygon_mode == GL_POINT)) )
{
@@ -2138,7 +2103,7 @@ void glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GL
void glshim_glMultiDrawElements( GLenum mode, GLsizei *count, GLenum type, const void * const *indices, GLsizei primcount)
{
LOAD_GLES_OES(glMultiDrawElements);
LOAD_GLES_EXT(glMultiDrawElements);
if((!gles_glMultiDrawElements) || should_intercept_render(mode) || (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) )
{

View File

@@ -12,6 +12,7 @@
#include <stdlib.h>
#include <string.h>
#include "khash.h"
#include "logs.h"
#ifdef __ARM_NEON__
#include <arm_neon.h>
@@ -235,10 +236,11 @@ static const GLsizei gl_sizeof(GLenum type) {
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_BYTE_2_3_3_REV:
case GL_UNSIGNED_BYTE_3_3_2:
case GL_DEPTH_COMPONENT:
return 1;
}
// formats
printf("libGL: Unsupported pixel data type: %s\n", PrintEnum(type));
LOGD("LIBGL: Unsupported pixel data type: %s\n", PrintEnum(type));
return 0;
}
@@ -256,7 +258,7 @@ static const GLuint gl_max_value(GLenum type) {
case GL_INT: return 2147483647;
case GL_UNSIGNED_INT: return 4294967295;
}
printf("libGL: unknown gl max value type: %s\n", PrintEnum(type));
LOGD("LIBGL: unknown gl max value type: %s\n", PrintEnum(type));
return 0;
}
@@ -288,6 +290,7 @@ static const GLsizei pixel_sizeof(GLenum format, GLenum type) {
case GL_RED:
case GL_ALPHA:
case GL_LUMINANCE:
case GL_DEPTH_COMPONENT:
width = 1;
break;
case GL_RG:
@@ -305,7 +308,7 @@ static const GLsizei pixel_sizeof(GLenum format, GLenum type) {
width = 4;
break;
default:
printf("libGL: unsupported pixel format %s\n", PrintEnum(format));
LOGD("LIBGL: unsupported pixel format %s\n", PrintEnum(format));
return 0;
}
@@ -329,6 +332,7 @@ static const GLboolean pixel_hasalpha(GLenum format) {
case GL_RGB:
case GL_BGR:
case GL_RGB8:
case GL_DEPTH_COMPONENT:
return false;
default:
return true;

View File

@@ -1,6 +1,7 @@
#include "gl.h"
#include "list.h"
#include "debug.h"
#include "../glx/hardext.h"
#define alloc_sublist(n, cap) \
(GLfloat *)malloc(n * sizeof(GLfloat) * cap)
@@ -43,12 +44,10 @@ bool ispurerender_renderlist(renderlist_t *list) {
return false;
if (list->popattribute)
return false;
if (list->material || list->light || list->lightmodel || list->texgen)
if (list->material || list->light || list->lightmodel || list->texgen || list->texenv)
return false;
if (list->fog_op)
return false;
if (list->texgen)
return false;
if (list->mode_init == 0)
return false;
if (list->set_texture || list->set_tmu)
@@ -115,7 +114,7 @@ bool islistscompatible_renderlist(renderlist_t *a, renderlist_t *b) {
if ((a->secondary==NULL) != (b->secondary==NULL))
return false;
// check the textures
for (int i=0; i<MAX_TEX; i++)
for (int i=0; i<hardext.maxtex; i++)
if ((a->tex[i]==NULL) != (b->tex[i]==NULL))
return false;
if ((a->set_texture==b->set_texture) && ((a->texture != b->texture) || (a->target_texture != b->target_texture)))
@@ -292,7 +291,7 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) {
a->secondary = alloc_sublist(4, cap);
memcpy(a->secondary, tmp, 4*a->len*sizeof(GLfloat));
}
for (int i=0; i<MAX_TEX; i++) {
for (int i=0; i<hardext.maxtex; i++) {
tmp = a->tex[i];
if (tmp) {
a->tex[i] = alloc_sublist(4, cap);
@@ -306,7 +305,7 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) {
realloc_sublist(a->normal, 3, cap);
realloc_sublist(a->color, 4, cap);
realloc_sublist(a->secondary, 4, cap);
for (int i=0; i<MAX_TEX; i++)
for (int i=0; i<hardext.maxtex; i++)
realloc_sublist(a->tex[i], 4, cap);
}
}
@@ -326,7 +325,7 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) {
if (a->normal) memcpy(a->normal+a->len*3, b->normal, b->len*3*sizeof(GLfloat));
if (a->color) memcpy(a->color+a->len*4, b->color, b->len*4*sizeof(GLfloat));
if (a->secondary) memcpy(a->secondary+a->len*4, b->secondary, b->len*4*sizeof(GLfloat));
for (int i=0; i<MAX_TEX; i++)
for (int i=0; i<hardext.maxtex; i++)
if (a->tex[i]) memcpy(a->tex[i]+a->len*4, b->tex[i], b->len*4*sizeof(GLfloat));
// indices
if (ilen_a + ilen_b)
@@ -507,7 +506,7 @@ renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a)
if(glstate->gl_batch) {
if (list->popattribute) {
// invalidate all batchstate
for (int i=0; i<MAX_TEX; i++) {
for (int i=0; i<hardext.maxtex; i++) {
glstate->statebatch.bound_targ[i] = 0xffff;
glstate->statebatch.bound_tex[i] = 0xffffffff;
}
@@ -559,6 +558,7 @@ renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a)
PROCESS(material, rendermaterial_t, m->pname);
PROCESS(light, renderlight_t, m->pname | ((m->which-GL_LIGHT0)<<16));
PROCESS(texgen, rendertexgen_t, m->pname | ((m->coord-GL_S)<<16));
PROCESS(texenv, rendertexenv_t, m->pname | ((m->target)<<16));
#undef PROCESS
if (list->lightmodel) {
list->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat));
@@ -609,7 +609,7 @@ void free_renderlist(renderlist_t *list) {
if (list->normal) free(list->normal);
if (list->color) free(list->color);
if (list->secondary) free(list->secondary);
for (a=0; a<MAX_TEX; a++)
for (a=0; a<hardext.maxtex; a++)
if (list->tex[a]) free(list->tex[a]);
}
if (!list->shared_indices || ((*list->shared_indices)--)==0) {
@@ -639,6 +639,13 @@ void free_renderlist(renderlist_t *list) {
)
kh_destroy(texgen, list->texgen);
}
if (list->texenv) {
rendertexenv_t *m;
kh_foreach_value(list->texenv, m,
free(m);
)
kh_destroy(texenv, list->texenv);
}
if (list->lightmodel)
free(list->lightmodel);
@@ -660,7 +667,7 @@ void resize_renderlist(renderlist_t *list) {
realloc_sublist(list->normal, 3, list->cap);
realloc_sublist(list->color, 4, list->cap);
realloc_sublist(list->secondary, 4, list->cap);
for (int a=0; a<MAX_TEX; a++)
for (int a=0; a<hardext.maxtex; a++)
realloc_sublist(list->tex[a], 4, list->cap);
}
}
@@ -671,7 +678,7 @@ void adjust_renderlist(renderlist_t *list) {
list->stage = STAGE_LAST;
list->open = false;
for (int a=0; a<MAX_TEX; a++) {
for (int a=0; a<hardext.maxtex; a++) {
gltexture_t *bound = glstate->texture.bound[a];
// in case of Texture bounding inside a list
if (list->set_texture && (list->tmu == a))
@@ -829,6 +836,14 @@ void draw_renderlist(renderlist_t *list) {
glshim_glLightModelfv(list->lightmodelparam, list->lightmodel);
}
if (list->texenv) {
khash_t(texenv) *tgn = list->texenv;
rendertexenv_t *m;
kh_foreach_value(tgn, m,
glshim_glTexEnvfv(m->target, m->pname, m->params);
)
}
if (list->texgen) {
khash_t(texgen) *tgn = list->texgen;
rendertexgen_t *m;
@@ -910,23 +925,25 @@ void draw_renderlist(renderlist_t *list) {
}
GLfloat *texgened[MAX_TEX];
GLint needclean[MAX_TEX];
for (int a=0; a<MAX_TEX; a++) {
for (int a=0; a<hardext.maxtex; a++) {
texgened[a]=NULL;
needclean[a]=0;
if ((glstate->enable.texgen_s[a] || glstate->enable.texgen_t[a] || glstate->enable.texgen_r[a])) {
if ((glstate->enable.texgen_s[a] || glstate->enable.texgen_t[a] || glstate->enable.texgen_r[a] || glstate->enable.texgen_q[a])) {
gen_tex_coords(list->vert, list->normal, &texgened[a], list->len, &needclean[a], a, (list->ilen<list->len)?indices:NULL, (list->ilen<list->len)?list->ilen:0);
} else if (glstate->enable.texture_2d[a] && (list->tex[a]==NULL)) {
} else if (glstate->enable.texture_2d[a] && (list->tex[a]==NULL) && !(list->mode==GL_POINT && glstate->texture.pscoordreplace[a])) {
gen_tex_coords(list->vert, list->normal, &texgened[a], list->len, &needclean[a], a, (list->ilen<list->len)?indices:NULL, (list->ilen<list->len)?list->ilen:0);
}
}
old_tex = glstate->texture.client;
GLuint cur_tex = old_tex;
#define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;}
for (int a=0; a<MAX_TEX; a++) {
for (int a=0; a<hardext.maxtex; a++) {
if ((list->tex[a] || texgened[a])/* && glstate->enable.texture_2d[a]*/) {
TEXTURE(a);
gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glstate->clientstate.tex_coord_array[a] = 1;
if(!glstate->clientstate.tex_coord_array[a]) {
gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glstate->clientstate.tex_coord_array[a] = 1;
}
gles_glTexCoordPointer(4, GL_FLOAT, 0, (texgened[a])?texgened[a]:list->tex[a]);
} else {
if (glstate->clientstate.tex_coord_array[a]) {
@@ -1137,7 +1154,7 @@ void draw_renderlist(renderlist_t *list) {
}
}
#define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;}
for (int a=0; a<MAX_TEX; a++) {
for (int a=0; a<hardext.maxtex; a++) {
if (needclean[a]) {
TEXTURE(a);
gen_tex_clean(needclean[a], a);
@@ -1189,7 +1206,7 @@ void FASTMATH rlVertex4f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z, GL
memcpy(secondary, glstate->secondary, sizeof(GLfloat) * 4);
}
for (int a=0; a<MAX_TEX; a++) {
for (int a=0; a<hardext.maxtex; a++) {
if (list->tex[a]) {
GLfloat * const tex = list->tex[a] + (list->len * 4);
memcpy(tex, glstate->texcoord[a], sizeof(GLfloat) * 4);
@@ -1415,5 +1432,59 @@ renderlist_t* GetFirst(renderlist_t* list) {
return list;
}
void rlTexEnvfv(renderlist_t *list, GLenum target, GLenum pname, const GLfloat * params) {
int n = 1;
switch(target) {
case GL_POINT_SPRITE: n = 1; break;
default:
switch(pname) {
case GL_TEXTURE_ENV_MODE: n=4; break;
case GL_TEXTURE_ENV_COLOR: n=4; break;
case GL_TEXTURE_LOD_BIAS: n=4; break;
}
}
rendertexenv_t *m;
khash_t(texenv) *map;
khint_t k;
int ret;
if (! list->texenv) {
list->texenv = map = kh_init(texenv);
// segfaults if we don't do a single put
kh_put(texenv, map, 1, &ret);
kh_del(texenv, map, 1);
} else {
map = list->texenv;
}
int key = pname | ((target)<<16);
k = kh_get(texenv, map, key);
if (k == kh_end(map)) {
k = kh_put(texenv, map, key, &ret);
m = kh_value(map, k) = malloc(sizeof(rendertexenv_t));
} else {
m = kh_value(map, k);
}
m->target = target;
m->pname = pname;
memcpy(m->params, params, n*sizeof(GLfloat));
}
void rlTexEnviv(renderlist_t *list, GLenum target, GLenum pname, const GLint * params) {
GLfloat fparams[4];
int n = 1;
switch(target) {
case GL_POINT_SPRITE: n = 1; break;
default:
switch(pname) {
case GL_TEXTURE_ENV_MODE: n=4; break;
case GL_TEXTURE_ENV_COLOR: n=4; break;
case GL_TEXTURE_LOD_BIAS: n=4; break;
}
}
for (int i=0; i<n; i++) fparams[i] = params[i];
rlTexEnvfv(list, target, pname, fparams);
}
#undef alloc_sublist
#undef realloc_sublist

View File

@@ -17,6 +17,7 @@ typedef enum {
STAGE_MATERIAL,
STAGE_LIGHT,
STAGE_LIGHTMODEL,
STAGE_TEXENV,
STAGE_TEXGEN,
STAGE_POLYGON,
STAGE_DRAW,
@@ -37,6 +38,7 @@ static int StageExclusive[STAGE_LAST] = {
0, // STAGE_MATERIAL
0, // STAGE_LIGHT
1, // STAGE_LIGTMODEL
0, // STAGE_TEXENV
0, // STAGE_TEXGEN
1, // STAGE_POLYGON
1 // STAGE_DRAW
@@ -63,6 +65,13 @@ typedef struct {
int count;
} rendertexgen_t;
typedef struct {
int target;
int pname;
GLfloat params[4];
int count;
} rendertexenv_t;
typedef struct {
GLfloat xmove;
GLfloat ymove;
@@ -80,6 +89,7 @@ typedef struct {
KHASH_MAP_INIT_INT(material, rendermaterial_t *)
KHASH_MAP_INIT_INT(light, renderlight_t *)
KHASH_MAP_INIT_INT(texgen, rendertexgen_t *)
KHASH_MAP_INIT_INT(texenv, rendertexenv_t *)
typedef struct _call_list_t {
unsigned long len;
@@ -131,6 +141,7 @@ typedef struct _renderlist_t {
khash_t(material) *material;
khash_t(light) *light;
khash_t(texgen) *texgen;
khash_t(texenv) *texenv;
GLfloat *lightmodel;
GLenum lightmodelparam;
GLenum polygon_mode;
@@ -163,6 +174,8 @@ void rlColor4f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b, GLfloat a) F
void rlMaterialfv(renderlist_t *list, GLenum face, GLenum pname, const GLfloat * params);
void rlLightfv(renderlist_t *list, GLenum which, GLenum pname, const GLfloat * params);
void rlTexGenfv(renderlist_t *list, GLenum coord, GLenum pname, const GLfloat * params);
void rlTexEnvfv(renderlist_t *list, GLenum target, GLenum pname, const GLfloat * params);
void rlTexEnviv(renderlist_t *list, GLenum target, GLenum pname, const GLint * params);
void rlNormal3f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z) FASTMATH;
void rlPushCall(renderlist_t *list, packed_call_t *data);
void rlTexCoord4f(renderlist_t *list, GLfloat s, GLfloat t, GLfloat r, GLfloat q) FASTMATH;

View File

@@ -1,4 +1,5 @@
#include "loader.h"
#include "logs.h"
#include <linux/limits.h>
void *gles = NULL, *egl = NULL, *bcm_host = NULL, *vcos = NULL;
@@ -47,10 +48,10 @@ void *open_lib(const char **names, const char *override) {
if (override) {
if ((lib = dlopen(override, flags))) {
strncpy(path_name, override, PATH_MAX);
printf("libGL:loaded: %s\n", path_name);
LOGD("LIBGL:loaded: %s\n", path_name);
return lib;
} else {
printf("LIBGL_GLES override failed: %s\n", dlerror());
LOGE("LIBGL_GLES override failed: %s\n", dlerror());
}
}
for (int p = 0; path_prefix[p]; p++) {
@@ -58,7 +59,7 @@ void *open_lib(const char **names, const char *override) {
for (int e = 0; lib_ext[e]; e++) {
snprintf(path_name, PATH_MAX, "%s%s.%s", path_prefix[p], names[i], lib_ext[e]);
if ((lib = dlopen(path_name, flags))) {
printf("libGL:loaded: %s\n", path_name);
LOGD("LIBGL:loaded: %s\n", path_name);
return lib;
}
}

View File

@@ -15,7 +15,7 @@ extern void *open_lib(const char **names, const char *override);
extern void load_libs();
#ifndef WARN_NULL
#define WARN_NULL(name) if (name == NULL) printf("libGL: warning, " #name " is NULL\n");
#define WARN_NULL(name) if (name == NULL) LOGD("libGL: warning, " #name " is NULL\n");
#endif
#ifndef LOAD_RAW
@@ -52,4 +52,11 @@ extern void load_libs();
LOAD_RAW(gles, name, egl_eglGetProcAddress(#name"OES")); \
}
#define LOAD_GLES_EXT(name) \
DEFINE_RAW(gles, name); \
{ \
LOAD_EGL(eglGetProcAddress); \
LOAD_RAW(gles, name, egl_eglGetProcAddress(#name"EXT")); \
}
#endif

View File

@@ -0,0 +1,2 @@
#define LOGD(...) printf(__VA_ARGS__)
#define LOGE(...) fprintf(stderr, __VA_ARGS__)

View File

@@ -17,6 +17,7 @@ static const colorlayout_t *get_color_map(GLenum format) {
map(GL_LUMINANCE_ALPHA, 0, 0, 0, 1);
map(GL_LUMINANCE, 0, 0, 0, -1);
map(GL_ALPHA,-1, -1, -1, 0);
map(GL_DEPTH_COMPONENT, 0, -1, -1, -1);
default:
printf("LIBGL: unknown pixel format %s\n", PrintEnum(format));
break;
@@ -676,7 +677,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
dst_color = get_color_map(dst_format);
if (!dst_size || !pixel_sizeof(src_format, src_type)
|| !src_color->type || !dst_color->type) {
printf("pixel conversion, anticipated abort\n");
LOGE("LIBGL: pixel conversion, anticipated abort\n");
return false;
}
@@ -699,7 +700,10 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
uintptr_t src_pos = (uintptr_t)src;
uintptr_t dst_pos = (uintptr_t)*dst;
// fast optimized loop for common conversion cases first...
if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
// TODO: Rewrite that with some Macro, it's obviously doable to simplify the reading (and writting) of all this
// simple BGRA <-> RGBA / UNSIGNED_BYTE
if ((((src_format == GL_BGRA) && (dst_format == GL_RGBA)) || ((src_format == GL_RGBA) && (dst_format == GL_BGRA)))
&& (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
GLuint tmp;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -713,6 +717,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// BGRA1555 -> RGBA5551
if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && (src_type == GL_UNSIGNED_SHORT_1_5_5_5_REV)) {
GLuint tmp;
unsigned short *wtexmemp = NULL, wtexmem;
@@ -730,6 +735,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// RGBA -> LA
if ((src_format == GL_RGBA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
GLuint tmp;
for (int i = 0; i < height; i++) {
@@ -745,6 +751,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// BGRA -> LA
if ((src_format == GL_BGRA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
GLuint tmp;
for (int i = 0; i < height; i++) {
@@ -760,6 +767,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// RGB(A) -> L
if (((src_format == GL_RGBA)||(src_format == GL_RGB)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
GLuint tmp;
for (int i = 0; i < height; i++) {
@@ -775,6 +783,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// BGR(A) -> L
if (((src_format == GL_BGRA)||(src_format == GL_BGR)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
GLuint tmp;
for (int i = 0; i < height; i++) {
@@ -790,6 +799,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// BGR(A) -> RGB
if (((src_format == GL_BGR)||(src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -804,6 +814,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// RGBA -> RGB
if ((src_format == GL_RGBA) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -818,6 +829,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// RGB(A) -> RGB565
if (((src_format == GL_RGB)||(src_format == GL_RGBA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -830,6 +842,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// BGR(A) -> RGB565
if (((src_format == GL_BGR) || (src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -842,6 +855,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// RGBA -> RGBA5551
if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -854,6 +868,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// BGRA -> RGBA5551
if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -866,6 +881,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// RGBA -> RGBA4444
if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -878,6 +894,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// BGRA -> RGBA4444
if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -890,6 +907,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// BGRA4444 -> RGBA
if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_BYTE) && (src_type == GL_UNSIGNED_SHORT_4_4_4_4_REV)) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -906,6 +924,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
// RGBA5551 -> RGBA
if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_BYTE) && (src_type == GL_UNSIGNED_SHORT_5_5_5_1)) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {

View File

@@ -1,11 +1,7 @@
#include "raster.h"
#include "debug.h"
static rasterpos_t rPos = {0, 0, 0};
static viewport_t viewport = {0, 0, 0, 0};
static GLubyte *raster = NULL;
GLfloat raster_zoomx=1.0f;
GLfloat raster_zoomy=1.0f;
static GLuint raster_texture=0;
static GLsizei raster_width=0;
static GLsizei raster_height=0;
@@ -15,10 +11,8 @@ static GLsizei raster_realheight=0;
static GLint raster_x1, raster_x2, raster_y1, raster_y2;
#define min(a, b) ((a)<b)?(a):(b)
#define max(a, b) ((a)>(b))?(a):(b)
GLfloat raster_scale[4] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat raster_bias[4] = {0.0f, 0.0f, 0.0f, 0.0f};
void matrix_column_row(const GLfloat *a, GLfloat *b);
void matrix_transpose(const GLfloat *a, GLfloat *b);
void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c);
void glshim_glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) {
@@ -28,28 +22,21 @@ void glshim_glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) {
noerrorShim();
return;
}
#if 1
// Transform xyz coordinates with current modelview and projection matrix...
GLfloat glmatrix[16], projection[16], modelview[16];
GLfloat t[4], transl[4] = {x, y, z, 1.0f};
glshim_glGetFloatv(GL_PROJECTION_MATRIX, glmatrix);
matrix_column_row(glmatrix, projection);
matrix_transpose(glmatrix, projection);
glshim_glGetFloatv(GL_MODELVIEW_MATRIX, glmatrix);
matrix_column_row(glmatrix, modelview);
matrix_transpose(glmatrix, modelview);
matrix_vector(modelview, transl, t);
matrix_vector(projection, t, transl);
GLfloat w2, h2;
w2=viewport.width/2.0f;
h2=viewport.height/2.0f;
rPos.x = transl[0]*w2+w2;
rPos.y = transl[1]*h2+h2;
rPos.z = transl[2];
#else
rPos.x = x;
rPos.y = y;
rPos.z = z;
#endif
w2=glstate->raster.viewport.width/2.0f;
h2=glstate->raster.viewport.height/2.0f;
glstate->raster.rPos.x = transl[0]*w2+w2;
glstate->raster.rPos.y = transl[1]*h2+h2;
glstate->raster.rPos.z = transl[2];
}
void glshim_glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {
@@ -59,19 +46,21 @@ void glshim_glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {
noerrorShim();
return;
}
rPos.x = x;
rPos.y = y;
rPos.z = z;
glstate->raster.rPos.x = x;
glstate->raster.rPos.y = y;
glstate->raster.rPos.z = z;
}
void glshim_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
PUSH_IF_COMPILING(glViewport);
LOAD_GLES(glViewport);
gles_glViewport(x, y, width, height);
viewport.x = x;
viewport.y = y;
viewport.width = width;
viewport.height = height;
if(glstate->raster.viewport.x!=x || glstate->raster.viewport.y!=y || glstate->raster.viewport.width!=width || glstate->raster.viewport.height!=height) {
gles_glViewport(x, y, width, height);
glstate->raster.viewport.x = x;
glstate->raster.viewport.y = y;
glstate->raster.viewport.width = width;
glstate->raster.viewport.height = height;
}
}
// hacky viewport temporary changes
@@ -81,7 +70,7 @@ void pushViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
}
void popViewport() {
LOAD_GLES(glViewport);
gles_glViewport(viewport.x, viewport.y, viewport.width, viewport.height);
gles_glViewport(glstate->raster.viewport.x, glstate->raster.viewport.y, glstate->raster.viewport.width, glstate->raster.viewport.height);
}
@@ -92,8 +81,8 @@ void glshim_glPixelZoom(GLfloat xfactor, GLfloat yfactor) {
noerrorShim();
return;
}
raster_zoomx = xfactor;
raster_zoomy = yfactor;
glstate->raster.raster_zoomx = xfactor;
glstate->raster.raster_zoomy = yfactor;
//printf("LIBGL: glPixelZoom(%f, %f)\n", xfactor, yfactor);
}
@@ -107,20 +96,20 @@ void glshim_glPixelTransferf(GLenum pname, GLfloat param) {
//printf("LIBGL: glPixelTransferf(%04x, %f)\n", pname, param);
switch(pname) {
case GL_RED_SCALE:
raster_scale[0]=param;
glstate->raster.raster_scale[0]=param;
break;
case GL_RED_BIAS:
raster_bias[0]=param;
glstate->raster.raster_bias[0]=param;
break;
case GL_GREEN_SCALE:
case GL_BLUE_SCALE:
case GL_ALPHA_SCALE:
raster_scale[(pname-GL_GREEN_SCALE)/2+1]=param;
glstate->raster.raster_scale[(pname-GL_GREEN_SCALE)/2+1]=param;
break;
case GL_GREEN_BIAS:
case GL_BLUE_BIAS:
case GL_ALPHA_BIAS:
raster_bias[(pname-GL_GREEN_BIAS)/2+1]=param;
glstate->raster.raster_bias[(pname-GL_GREEN_BIAS)/2+1]=param;
break;
/*default:
printf("LIBGL: stubbed glPixelTransferf(%04x, %f)\n", pname, param);*/
@@ -154,21 +143,21 @@ void init_raster(int width, int height) {
GLubyte raster_transform(GLubyte pix, GLubyte number) {
GLfloat a = (GLfloat)pix*(1.0f/255.0f);
a=a*raster_scale[number]+raster_bias[number];
a=a*glstate->raster.raster_scale[number]+glstate->raster.raster_bias[number];
if (a<0.0) a=0.0;
if (a>1.0) a=1.0;
return (GLubyte)(a*255.0f);
}
GLfloat FASTMATH raster_transformf(GLfloat pix, GLubyte number) {
pix=pix*raster_scale[number]+raster_bias[number];
pix=pix*glstate->raster.raster_scale[number]+glstate->raster.raster_bias[number];
if (pix<0.0) pix=0.0;
if (pix>1.0) pix=1.0;
return pix;
}
int raster_need_transform() {
for (int i=0; i<4; i++) if (raster_scale[i]!=1.0f) return 1;
for (int i=0; i<4; i++) if (raster_bias[i]!=0.0f) return 1;
for (int i=0; i<4; i++) if (glstate->raster.raster_scale[i]!=1.0f) return 1;
for (int i=0; i<4; i++) if (glstate->raster.raster_bias[i]!=0.0f) return 1;
return 0;
}
@@ -234,7 +223,7 @@ GLuint raster_to_texture()
void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig,
GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) {
/*printf("glBitmap, xy={%f, %f}, xyorig={%f, %f}, size={%u, %u}, zoom={%f, %f}, viewport={%i, %i, %i, %i}\n",
rPos.x, rPos.y, xorig, yorig, width, height, raster_zoomx, raster_zoomy, viewport.x, viewport.y, viewport.width, viewport.height);*/
glstate->raster.rPos.x, glstate->raster.rPos.y, xorig, yorig, width, height, glstate->raster.raster_zoomx, glstate->raster.raster_zoomy, glstate->raster.viewport.x, glstate->raster.viewport.y, glstate->raster.viewport.width, glstate->raster.viewport.height);*/
// TODO: shouldn't be drawn if the raster pos is outside the viewport?
// TODO: negative width/height mirrors bitmap?
noerrorShim();
@@ -254,8 +243,8 @@ void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig
r->ymove = ymove;
} else {
rPos.x += xmove;
rPos.y += ymove;
glstate->raster.rPos.x += xmove;
glstate->raster.rPos.y += ymove;
}
return;
}
@@ -314,8 +303,8 @@ void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig
r->width = width;
r->height = height;
r->bitmap = true;
r->zoomx = raster_zoomx;
r->zoomy = raster_zoomy;
r->zoomx = glstate->raster.raster_zoomx;
r->zoomy = glstate->raster.raster_zoomy;
LOAD_GLES(glDeleteTextures);
if (!(glstate->list.compiling || glstate->gl_batch)) {
render_raster_list(r);
@@ -333,7 +322,7 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format,
noerrorShim();
/*printf("glDrawPixels, xy={%f, %f}, size={%i, %i}, format=%s, type=%s, zoom={%f, %f}, viewport={%i, %i, %i, %i}\n",
rPos.x, rPos.y, width, height, PrintEnum(format), PrintEnum(type), raster_zoomx, raster_zoomy, viewport.x, viewport.y, viewport.width, viewport.height);*/
glstate->raster.rPos.x, glstate->raster.rPos.y, width, height, PrintEnum(format), PrintEnum(type), glstate->raster.raster_zoomx, glstate->raster.raster_zoomy, glstate->raster.viewport.x, glstate->raster.viewport.y, glstate->raster.viewport.width, glstate->raster.viewport.height);*/
// check of unsuported format...
if ((format == GL_STENCIL_INDEX) || (format == GL_DEPTH_COMPONENT)) {
errorShim(GL_INVALID_ENUM);
@@ -399,8 +388,8 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format,
r->width = width;
r->height = height;
r->bitmap = false;
r->zoomx = raster_zoomx;
r->zoomy = raster_zoomy;
r->zoomx = glstate->raster.raster_zoomx;
r->zoomy = glstate->raster.raster_zoomy;
if (!(glstate->list.compiling || glstate->gl_batch)) {
render_raster_list(r);
/* gles_glDeleteTextures(1, &r->texture);
@@ -409,7 +398,7 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format,
}
void render_raster_list(rasterlist_t* rast) {
//printf("render_raster_list, rast->x/y=%f/%f rast->width/height=%i/%i, rPos.x/y/z=%f/%f/%f, rast->zoomxy=%f/%f raster->texture=%u\n", rast->xorig, rast->yorig, rast->width, rast->height, rPos.x, rPos.y, rPos.z, rast->zoomx, rast->zoomy, rast->texture);
//printf("render_raster_list, rast->x/y=%f/%f rast->width/height=%i/%i, rPos.x/y/z=%f/%f/%f, rast->zoomxy=%f/%f raster->texture=%u\n", rast->xorig, rast->yorig, rast->width, rast->height, glstate->raster.rPos.x, glstate->raster.rPos.y, glstate->raster.rPos.z, rast->zoomx, rast->zoomy, rast->texture);
#ifdef USE_DRAWTEX
LOAD_GLES_OES(glDrawTexf);
LOAD_GLES(glEnable);
@@ -444,7 +433,7 @@ void render_raster_list(rasterlist_t* rast) {
glshim_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
gles_glDrawTexf(rPos.x-rast->xorig, rPos.y-rast->yorig, rPos.z, rast->width * rast->zoomx, rast->height * rast->zoomy);
gles_glDrawTexf(glstate->raster.rPos.x-rast->xorig, glstate->raster.rPos.y-rast->yorig, glstate->raster.rPos.z, rast->width * rast->zoomx, rast->height * rast->zoomy);
if (!glstate->enable.texture_2d[0]) glshim_glDisable(GL_TEXTURE_2D);
if (old_tex!=0) gles_glActiveTexture(GL_TEXTURE0+old_tex);
if (old_cli!=0) gles_glClientActiveTexture(GL_TEXTURE0+old_cli);
@@ -465,12 +454,12 @@ void render_raster_list(rasterlist_t* rast) {
glshim_glLoadIdentity();
glshim_glMatrixMode(GL_MODELVIEW);
glshim_glLoadIdentity();
float w2 = 2.0f / viewport.width;
float h2 = 2.0f / viewport.height;
float raster_x1=rPos.x-rast->xorig;
float raster_x2=rPos.x-rast->xorig + rast->width * rast->zoomx ;
float raster_y1=rPos.y-rast->yorig;
float raster_y2=rPos.y-rast->yorig + rast->height * rast->zoomy ;
float w2 = 2.0f / glstate->raster.viewport.width;
float h2 = 2.0f / glstate->raster.viewport.height;
float raster_x1=glstate->raster.rPos.x-rast->xorig;
float raster_x2=glstate->raster.rPos.x-rast->xorig + rast->width * rast->zoomx ;
float raster_y1=glstate->raster.rPos.y-rast->yorig;
float raster_y2=glstate->raster.rPos.y-rast->yorig + rast->height * rast->zoomy ;
GLfloat rast_vert[] = {
raster_x1*w2-1.0f, raster_y1*h2-1.0f,
raster_x2*w2-1.0f, raster_y1*h2-1.0f,
@@ -547,8 +536,8 @@ void render_raster_list(rasterlist_t* rast) {
#endif
glshim_glPopAttrib();
}
rPos.x += rast->xmove;
rPos.y += rast->ymove;
glstate->raster.rPos.x += rast->xmove;
glstate->raster.rPos.y += rast->ymove;
}
//Direct wrapper

View File

@@ -22,9 +22,6 @@ typedef struct {
GLsizei height;
} viewport_t;
extern GLfloat raster_scale[4];
extern GLfloat raster_bias[4];
int raster_need_transform();
void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig,

View File

@@ -4,8 +4,11 @@ void push_hit() {
// push current hit to hit list, and re-init current hit
if (glstate->selectbuf.hit) {
if (!glstate->selectbuf.overflow) {
if (glstate->selectbuf.zmin<0.0f) glstate->selectbuf.zmin=0.0f; // not really normalized...
if (glstate->selectbuf.zmax>1.0f) glstate->selectbuf.zmax=1.0f; // TODO, normalize for good?
//Normalize zmin/zmax
if((glstate->selectbuf.zmaxoverall - glstate->selectbuf.zminoverall)!=0.0f) {
glstate->selectbuf.zmin = (glstate->selectbuf.zmin-glstate->selectbuf.zminoverall)/(glstate->selectbuf.zmaxoverall - glstate->selectbuf.zminoverall);
glstate->selectbuf.zmax = (glstate->selectbuf.zmax-glstate->selectbuf.zminoverall)/(glstate->selectbuf.zmaxoverall - glstate->selectbuf.zminoverall);
}
int tocopy = glstate->namestack.top + 3;
if (tocopy+glstate->selectbuf.pos > glstate->selectbuf.size) {
glstate->selectbuf.overflow = 1;
@@ -25,8 +28,10 @@ void push_hit() {
}
glstate->selectbuf.hit = 0;
}
glstate->selectbuf.zmin = 1.0f;
glstate->selectbuf.zmax = 0.0f;
glstate->selectbuf.zmin = 1e10f;
glstate->selectbuf.zmax = -1e10f;
glstate->selectbuf.zminoverall = 1e10f;
glstate->selectbuf.zmaxoverall = -1e10f;
}
@@ -50,8 +55,10 @@ GLint glshim_glRenderMode(GLenum mode) {
glstate->selectbuf.count = 0;
glstate->selectbuf.pos = 0;
glstate->selectbuf.overflow = 0;
glstate->selectbuf.zmin = 1.0f;
glstate->selectbuf.zmax = 0.0f;
glstate->selectbuf.zmin = 1e10f;
glstate->selectbuf.zmax = -1e10f;
glstate->selectbuf.zminoverall = 1e10f;
glstate->selectbuf.zmaxoverall = -1e10f;
glstate->selectbuf.hit = 0;
}
@@ -124,9 +131,9 @@ void init_select() {
*/
GLfloat tmp[16];
glshim_glGetFloatv(GL_PROJECTION_MATRIX, tmp);
matrix_column_row(tmp, projection);
matrix_transpose(tmp, projection);
glshim_glGetFloatv(GL_MODELVIEW_MATRIX, tmp);
matrix_column_row(tmp, modelview);
matrix_transpose(tmp, modelview);
}
void select_transform(GLfloat *a) {
@@ -218,6 +225,12 @@ GLboolean select_triangle_in_viewscreen(const GLfloat *a, const GLfloat *b, cons
return false;
}
static void FASTMATH ZMinMax(GLfloat *zmin, GLfloat *zmax, GLfloat *vtx) {
if (vtx[2]<*zmin) *zmin=vtx[2];
if (vtx[2]>*zmax) *zmax=vtx[2];
}
void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first, GLuint count) {
if (count == 0) return;
if (vtx->pointer == NULL) return;
@@ -225,59 +238,77 @@ void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first,
GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type,
vtx->size, vtx->stride,
GL_FLOAT, 4, 0, count+first);
GLfloat zmin=1.0f, zmax=0.0f;
GLfloat zmin=1e10f, zmax=-1e10f;
init_select();
int found = 0;
#define FOUND() { \
found = 1; \
glstate->selectbuf.hit = 1; \
}
#define FOUND() { \
if (zmin<glstate->selectbuf.zmin) glstate->selectbuf.zmin=zmin; \
if (zmax>glstate->selectbuf.zmax) glstate->selectbuf.zmax=zmax; \
glstate->selectbuf.hit = 1; \
free(vert); \
return; \
}
// transform the points
for (int i=first; i<count+first; i++) {
select_transform(vert+i*4);
if (vert[i*4+2]<zmin) zmin=vert[i*4+2];
if (vert[i*4+2]>zmax) zmax=vert[i*4+2];
ZMinMax(&glstate->selectbuf.zminoverall, &glstate->selectbuf.zmaxoverall, vert+i*4);
}
// intersect with screen now
GLfloat *vert2 = vert + first*4;
for (int i=0; i<count; i++) {
switch (mode) {
case GL_POINTS:
if (select_point_in_viewscreen(vert2+i*4))
if (select_point_in_viewscreen(vert2+i*4)) {
ZMinMax(&zmin, &zmax, vert+i*4);
FOUND();
}
break;
case GL_LINES:
if (i%2==1) {
if (select_segment_in_viewscreen(vert2+(i-1)*4, vert2+i*4))
if (select_segment_in_viewscreen(vert2+(i-1)*4, vert2+i*4)) {
ZMinMax(&zmin, &zmax, vert+(i-1)*4);
ZMinMax(&zmin, &zmax, vert+i*4);
FOUND();
}
}
break;
case GL_LINE_STRIP:
case GL_LINE_LOOP: //FIXME: the last "loop" segment is missing here
if (i>0) {
if (select_segment_in_viewscreen(vert2+(i-1)*4, vert2+i*4))
if (select_segment_in_viewscreen(vert2+(i-1)*4, vert2+i*4)) {
ZMinMax(&zmin, &zmax, vert+(i-1)*4);
ZMinMax(&zmin, &zmax, vert+i*4);
FOUND();
}
}
break;
case GL_TRIANGLES:
if (i%3==2) {
if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4))
if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4)) {
ZMinMax(&zmin, &zmax, vert+(i-2)*4);
ZMinMax(&zmin, &zmax, vert+(i-1)*4);
ZMinMax(&zmin, &zmax, vert+i*4);
FOUND();
}
}
break;
case GL_TRIANGLE_STRIP:
if (i>1) {
if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4))
if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4)) {
ZMinMax(&zmin, &zmax, vert+(i-2)*4);
ZMinMax(&zmin, &zmax, vert+(i-1)*4);
ZMinMax(&zmin, &zmax, vert+i*4);
FOUND();
}
}
break;
case GL_TRIANGLE_FAN:
if (i>1) {
if (select_triangle_in_viewscreen(vert2, vert2+(i-1)*4, vert2+i*4))
if (select_triangle_in_viewscreen(vert2, vert2+(i-1)*4, vert2+i*4)) {
ZMinMax(&zmin, &zmax, vert);
ZMinMax(&zmin, &zmax, vert+(i-1)*4);
ZMinMax(&zmin, &zmax, vert+i*4);
FOUND();
}
}
break;
default:
@@ -285,6 +316,10 @@ void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first,
}
}
free(vert);
if(found) {
if (zmin<glstate->selectbuf.zmin) glstate->selectbuf.zmin=zmin;
if (zmax>glstate->selectbuf.zmax) glstate->selectbuf.zmax=zmax;
}
#undef FOUND
}
@@ -301,57 +336,71 @@ void select_glDrawElements(const pointer_state_t* vtx, GLenum mode, GLuint count
vtx->size, vtx->stride,
GL_FLOAT, 4, 0, max);
init_select();
GLfloat zmin=1.0f, zmax=0.0f;
GLfloat zmin=1e10f, zmax=-10e6f;
int found = 0;
for (int i=min; i<max; i++) {
select_transform(vert+i*3);
if (vert[i*4+2]<zmin) zmin=vert[i*4+2];
if (vert[i*4+2]>zmax) zmax=vert[i*4+2];
select_transform(vert+i*4);
ZMinMax(&glstate->selectbuf.zminoverall, &glstate->selectbuf.zmaxoverall, vert+i*4);
}
if (zmin<0.0f) zmin = 0.0f;
if (zmax>1.0f) zmax = 1.0f;
#define FOUND() { \
if (zmin<glstate->selectbuf.zmin) glstate->selectbuf.zmin=zmin; \
if (zmax>glstate->selectbuf.zmax) glstate->selectbuf.zmax=zmax; \
#define FOUND() { \
found = 1; \
glstate->selectbuf.hit = 1; \
free(vert); \
return; \
}
for (int i=0; i<count; i++) {
switch (mode) {
case GL_POINTS:
if (select_point_in_viewscreen(vert+ind[i]*4))
if (select_point_in_viewscreen(vert+ind[i]*4)) {
ZMinMax(&zmin, &zmax, vert+ind[i]*4);
FOUND();
}
break;
case GL_LINES:
if (i%2==1) {
if (select_segment_in_viewscreen(vert+ind[(i-1)]*4, vert+ind[i]*4))
if (select_segment_in_viewscreen(vert+ind[(i-1)]*4, vert+ind[i]*4)) {
ZMinMax(&zmin, &zmax, vert+ind[i-1]*4);
ZMinMax(&zmin, &zmax, vert+ind[i]*4);
FOUND();
}
}
break;
case GL_LINE_STRIP:
case GL_LINE_LOOP: //FIXME: the last "loop" segment is missing here
if (i>0) {
if (select_segment_in_viewscreen(vert+ind[(i-1)]*4, vert+ind[i]*4))
if (select_segment_in_viewscreen(vert+ind[(i-1)]*4, vert+ind[i]*4)) {
ZMinMax(&zmin, &zmax, vert+ind[i-1]*4);
ZMinMax(&zmin, &zmax, vert+ind[i]*4);
FOUND();
}
}
break;
case GL_TRIANGLES:
if (i%3==2) {
if (select_triangle_in_viewscreen(vert+ind[(i-2)]*4, vert+ind[(i-1)]*4, vert+ind[i]*4))
if (select_triangle_in_viewscreen(vert+ind[(i-2)]*4, vert+ind[(i-1)]*4, vert+ind[i]*4)) {
ZMinMax(&zmin, &zmax, vert+ind[i-2]*4);
ZMinMax(&zmin, &zmax, vert+ind[i-1]*4);
ZMinMax(&zmin, &zmax, vert+ind[i]*4);
FOUND();
}
}
break;
case GL_TRIANGLE_STRIP:
if (i>1) {
if (select_triangle_in_viewscreen(vert+ind[(i-2)]*4, vert+ind[(i-1)]*4, vert+ind[i]*4))
if (select_triangle_in_viewscreen(vert+ind[(i-2)]*4, vert+ind[(i-1)]*4, vert+ind[i]*4)) {
ZMinMax(&zmin, &zmax, vert+ind[i-2]*4);
ZMinMax(&zmin, &zmax, vert+ind[i-1]*4);
ZMinMax(&zmin, &zmax, vert+ind[i]*4);
FOUND();
}
}
break;
case GL_TRIANGLE_FAN:
if (i>1) {
if (select_triangle_in_viewscreen(vert+ind[0]*4, vert+ind[(i-1)]*4, vert+ind[i]*4))
ZMinMax(&zmin, &zmax, vert+ind[0]*4);
ZMinMax(&zmin, &zmax, vert+ind[i-1]*4);
ZMinMax(&zmin, &zmax, vert+ind[i]*4);
FOUND();
}
break;
@@ -360,6 +409,11 @@ void select_glDrawElements(const pointer_state_t* vtx, GLenum mode, GLuint count
}
}
free(vert);
if(found) {
if (zmin<glstate->selectbuf.zmin) glstate->selectbuf.zmin=zmin;
if (zmax>glstate->selectbuf.zmax) glstate->selectbuf.zmax=zmax;
}
#undef FOUND
}

View File

@@ -1,4 +1,5 @@
#include "stack.h"
#include "../glx/hardext.h"
void glshim_glPushAttrib(GLbitfield mask) {
//printf("glPushAttrib(0x%04X)\n", mask);
@@ -23,6 +24,7 @@ void glshim_glPushAttrib(GLbitfield mask) {
cur->clip_planes = NULL;
cur->lights_enabled = NULL;
cur->lights = NULL;
cur->materials = NULL;
// TODO: GL_ACCUM_BUFFER_BIT
@@ -77,10 +79,8 @@ void glshim_glPushAttrib(GLbitfield mask) {
cur->dither = glshim_glIsEnabled(GL_DITHER);
cur->fog = glshim_glIsEnabled(GL_FOG);
GLint max_lights;
glshim_glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
cur->lights_enabled = (GLboolean *)malloc(max_lights * sizeof(GLboolean));
for (i = 0; i < max_lights; i++) {
cur->lights_enabled = (GLboolean *)malloc(hardext.maxlights * sizeof(GLboolean));
for (i = 0; i < hardext.maxlights; i++) {
*(cur->lights_enabled + i) = glshim_glIsEnabled(GL_LIGHT0 + i);
}
@@ -105,15 +105,16 @@ void glshim_glPushAttrib(GLbitfield mask) {
cur->scissor_test = glshim_glIsEnabled(GL_SCISSOR_TEST);
cur->stencil_test = glshim_glIsEnabled(GL_STENCIL_TEST);
int a;
for (a=0; a<MAX_TEX; a++) {
for (a=0; a<hardext.maxtex; a++) {
cur->texture_1d[a] = glstate->enable.texture_1d[a];
cur->texture_2d[a] = glstate->enable.texture_2d[a];
cur->texture_3d[a] = glstate->enable.texture_3d[a];
cur->texgen_s[a] = glstate->enable.texgen_s[a];
cur->texgen_r[a] = glstate->enable.texgen_r[a];
cur->texgen_t[a] = glstate->enable.texgen_t[a];
cur->texgen_q[a] = glstate->enable.texgen_q[a];
}
cur->pointsprite = glshim_glIsEnabled(GL_POINT_SPRITE);
}
// TODO: GL_EVAL_BIT
@@ -137,20 +138,33 @@ void glshim_glPushAttrib(GLbitfield mask) {
if (mask & GL_LIGHTING_BIT) {
cur->lighting = glshim_glIsEnabled(GL_LIGHTING);
glshim_glGetIntegerv(GL_LIGHT_MODEL_AMBIENT, cur->light_model_ambient);
glshim_glGetFloatv(GL_LIGHT_MODEL_AMBIENT, cur->light_model_ambient);
glshim_glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &cur->light_model_two_side);
int i;
GLint max_lights;
glshim_glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
cur->lights_enabled = (GLboolean *)malloc(max_lights * sizeof(GLboolean));
cur->lights = (GLfloat *)malloc(max_lights * sizeof(GLfloat));
for (i = 0; i < max_lights; i++) {
int j=0;
cur->lights_enabled = (GLboolean *)malloc(hardext.maxlights * sizeof(GLboolean));
cur->lights = (GLfloat *)malloc(hardext.maxlights * sizeof(GLfloat)*(10*4));
for (i = 0; i < hardext.maxlights; i++) {
*(cur->lights_enabled + i) = glshim_glIsEnabled(GL_LIGHT0 + i);
/* TODO: record all data about the lights
glGetFloatv(GL_LIGHT0 + i, cur->lights + i);
*/
#define L(A) glshim_glGetLightfv(GL_LIGHT0 + i, A, cur->lights+j); j+=4
L(GL_AMBIENT);
L(GL_DIFFUSE);
L(GL_SPECULAR);
L(GL_POSITION);
L(GL_SPOT_CUTOFF);
L(GL_SPOT_DIRECTION);
L(GL_SPOT_EXPONENT);
L(GL_CONSTANT_ATTENUATION);
L(GL_LINEAR_ATTENUATION);
L(GL_QUADRATIC_ATTENUATION);
#undef L
}
j=0;
cur->materials = (GLfloat *)malloc(1 * sizeof(GLfloat)*(5*4));
#define M(A) glshim_glGetMaterialfv(GL_FRONT, A, cur->materials+j); j+=4
M(GL_AMBIENT); M(GL_DIFFUSE); M(GL_SPECULAR); M(GL_EMISSION); M(GL_SHININESS); // handle both face at some point?
#undef M
glshim_glGetIntegerv(GL_SHADE_MODEL, &cur->shade_model);
}
@@ -188,6 +202,13 @@ void glshim_glPushAttrib(GLbitfield mask) {
if (mask & GL_POINT_BIT) {
cur->point_smooth = glshim_glIsEnabled(GL_POINT_SMOOTH);
glshim_glGetFloatv(GL_POINT_SIZE, &cur->point_size);
if(hardext.pointsprite) {
cur->pointsprite = glshim_glIsEnabled(GL_POINT_SPRITE);
int a;
for (a=0; a<hardext.maxtex; a++) {
cur->pscoordreplace[a] = glstate->texture.pscoordreplace[a];
}
}
}
// TODO: GL_POLYGON_BIT
@@ -219,10 +240,11 @@ void glshim_glPushAttrib(GLbitfield mask) {
if (mask & GL_TEXTURE_BIT) {
cur->active=glstate->texture.active;
int a;
for (a=0; a<MAX_TEX; a++) {
for (a=0; a<hardext.maxtex; a++) {
cur->texgen_r[a] = glstate->enable.texgen_r[a];
cur->texgen_s[a] = glstate->enable.texgen_s[a];
cur->texgen_t[a] = glstate->enable.texgen_t[a];
cur->texgen_q[a] = glstate->enable.texgen_q[a];
cur->texgen[a] = glstate->texgen[a]; // all mode and planes per texture in 1 line
cur->texture[a] = (glstate->texture.bound[a])?glstate->texture.bound[a]->texture:0;
}
@@ -289,7 +311,7 @@ void glshim_glPushClientAttrib(GLbitfield mask) {
cur->secondary_enable = glstate->vao->secondary_array;
cur->normal_enable = glstate->vao->normal_array;
int a;
for (a=0; a<MAX_TEX; a++) {
for (a=0; a<hardext.maxtex; a++) {
cur->tex_enable[a] = glstate->vao->tex_coord_array[a];
}
memcpy(&(cur->pointers), &glstate->vao->pointers, sizeof(pointer_states_t));
@@ -374,9 +396,7 @@ void glshim_glPopAttrib() {
enable_disable(GL_DITHER, cur->dither);
enable_disable(GL_FOG, cur->fog);
GLint max_lights;
glshim_glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
for (i = 0; i < max_lights; i++) {
for (i = 0; i < hardext.maxlights; i++) {
enable_disable(GL_LIGHT0 + i, *(cur->lights_enabled + i));
}
@@ -400,9 +420,10 @@ void glshim_glPopAttrib() {
enable_disable(GL_SAMPLE_COVERAGE, cur->sample_coverage);
enable_disable(GL_SCISSOR_TEST, cur->scissor_test);
enable_disable(GL_STENCIL_TEST, cur->stencil_test);
enable_disable(GL_POINT_SPRITE, cur->pointsprite);
int a;
int old_tex = glstate->texture.active;
for (a=0; a<MAX_TEX; a++) {
for (a=0; a<hardext.maxtex; a++) {
if (glstate->enable.texture_1d[a] != cur->texture_1d[a]) {
glshim_glActiveTexture(GL_TEXTURE0+a);
enable_disable(GL_TEXTURE_1D, cur->texture_1d[a]);
@@ -418,6 +439,7 @@ void glshim_glPopAttrib() {
glstate->enable.texgen_r[a] = cur->texgen_r[a];
glstate->enable.texgen_s[a] = cur->texgen_s[a];
glstate->enable.texgen_t[a] = cur->texgen_t[a];
glstate->enable.texgen_q[a] = cur->texgen_q[a];
}
if (glstate->texture.active != old_tex) glshim_glActiveTexture(GL_TEXTURE0+old_tex);
}
@@ -432,12 +454,43 @@ void glshim_glPopAttrib() {
}
if (cur->mask & GL_HINT_BIT) {
enable_disable(GL_PERSPECTIVE_CORRECTION_HINT, cur->perspective_hint);
enable_disable(GL_POINT_SMOOTH_HINT, cur->point_smooth_hint);
enable_disable(GL_LINE_SMOOTH_HINT, cur->line_smooth_hint);
enable_disable(GL_FOG_HINT, cur->fog_hint);
enable_disable(GL_GENERATE_MIPMAP_HINT, cur->mipmap_hint);
glshim_glHint(GL_PERSPECTIVE_CORRECTION_HINT, cur->perspective_hint);
glshim_glHint(GL_POINT_SMOOTH_HINT, cur->point_smooth_hint);
glshim_glHint(GL_LINE_SMOOTH_HINT, cur->line_smooth_hint);
glshim_glHint(GL_FOG_HINT, cur->fog_hint);
glshim_glHint(GL_GENERATE_MIPMAP_HINT, cur->mipmap_hint);
}
if (cur->mask & GL_LIGHTING_BIT) {
enable_disable(GL_LIGHTING, cur->lighting);
glshim_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, cur->light_model_ambient);
glshim_glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, cur->light_model_two_side);
int i;
int j=0;
for (i = 0; i < hardext.maxlights; i++) {
enable_disable(GL_LIGHT0 + i, *(cur->lights_enabled + i));
#define L(A) glshim_glLightfv(GL_LIGHT0 + i, A, cur->lights+j); j+=4
L(GL_AMBIENT);
L(GL_DIFFUSE);
L(GL_SPECULAR);
L(GL_POSITION);
L(GL_SPOT_CUTOFF);
L(GL_SPOT_DIRECTION);
L(GL_SPOT_EXPONENT);
L(GL_CONSTANT_ATTENUATION);
L(GL_LINEAR_ATTENUATION);
L(GL_QUADRATIC_ATTENUATION);
#undef L
}
j=0;
#define M(A) glshim_glMaterialfv(GL_FRONT_AND_BACK, A, cur->materials+j); j+=4
M(GL_AMBIENT); M(GL_DIFFUSE); M(GL_SPECULAR); M(GL_EMISSION); M(GL_SHININESS); // handle both face at some point?
#undef M
glshim_glShadeModel(cur->shade_model);
}
// GL_LIST_BIT
if (cur->mask & GL_LIST_BIT) {
glshim_glListBase(cur->list_base);
@@ -459,6 +512,17 @@ void glshim_glPopAttrib() {
if (cur->mask & GL_POINT_BIT) {
enable_disable(GL_POINT_SMOOTH, cur->point_smooth);
glshim_glPointSize(cur->point_size);
if(hardext.pointsprite) {
enable_disable(GL_POINT_SPRITE, cur->pointsprite);
int a;
for (a=0; a<hardext.maxtex; a++) {
if(glstate->texture.pscoordreplace[a]!=cur->pscoordreplace[a]) {
glshim_glActiveTexture(GL_TEXTURE0+a);
glshim_glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, cur->pscoordreplace[a]);
}
}
if (glstate->texture.active!= cur->active) glshim_glActiveTexture(GL_TEXTURE0+cur->active);
}
}
if (cur->mask & GL_SCISSOR_BIT) {
@@ -478,10 +542,11 @@ void glshim_glPopAttrib() {
if (cur->mask & GL_TEXTURE_BIT) {
int a;
//TODO: Enable bit for the 4 texture coordinates
for (a=0; a<MAX_TEX; a++) {
for (a=0; a<hardext.maxtex; a++) {
glstate->enable.texgen_r[a] = cur->texgen_r[a];
glstate->enable.texgen_s[a] = cur->texgen_s[a];
glstate->enable.texgen_t[a] = cur->texgen_t[a];
glstate->enable.texgen_q[a] = cur->texgen_q[a];
glstate->texgen[a] = cur->texgen[a]; // all mode and planes per texture in 1 line
if ((cur->texture[a]==0 && glstate->texture.bound[a] != 0) || (cur->texture[a]!=0 && glstate->texture.bound[a]==0)) {
glshim_glActiveTexture(GL_TEXTURE0+a);
@@ -525,6 +590,7 @@ void glshim_glPopAttrib() {
maybe_free(cur->clip_planes);
maybe_free(cur->lights_enabled);
maybe_free(cur->lights);
maybe_free(cur->materials);
glstate->stack->len--;
}
@@ -571,7 +637,7 @@ void glshim_glPopClientAttrib() {
enable_disable(GL_COLOR_ARRAY, cur->color_enable);
if (glstate->vao->secondary_array != cur->secondary_enable)
enable_disable(GL_SECONDARY_COLOR_ARRAY, cur->secondary_enable);
for (int a=0; a<MAX_TEX; a++) {
for (int a=0; a<hardext.maxtex; a++) {
if (glstate->vao->tex_coord_array[a] != cur->tex_enable[a]) {
glshim_glClientActiveTexture(GL_TEXTURE0+a);
enable_disable(GL_TEXTURE_COORD_ARRAY, cur->tex_enable[a]);

View File

@@ -20,6 +20,10 @@ typedef struct _glstack_t {
GLboolean dither;
// point sprite
GLboolean pointsprite;
GLint pscoordreplace[MAX_TEX];
GLboolean color_logic_op;
GLint logic_op;
@@ -56,6 +60,7 @@ typedef struct _glstack_t {
GLboolean texgen_s[MAX_TEX];
GLboolean texgen_r[MAX_TEX];
GLboolean texgen_t[MAX_TEX];
GLboolean texgen_q[MAX_TEX];
GLboolean colormaterial;
GLboolean autonormal;
@@ -78,8 +83,9 @@ typedef struct _glstack_t {
GLboolean lighting;
GLboolean *lights_enabled;
GLfloat *lights;
GLint light_model_ambient[4];
GLfloat light_model_ambient[4];
GLint light_model_two_side;
GLfloat *materials;
GLint shade_model;
// GL_LINE_BIT

View File

@@ -16,9 +16,11 @@ typedef struct {
auto_normal,
blend,
color_sum,
pointsprite,
texgen_s[MAX_TEX],
texgen_t[MAX_TEX],
texgen_r[MAX_TEX],
texgen_q[MAX_TEX],
texture_2d[MAX_TEX],
texture_3d[MAX_TEX],
texture_1d[MAX_TEX];
@@ -29,12 +31,15 @@ typedef struct {
GLenum S;
GLenum T;
GLenum R;
GLenum Q;
GLfloat S_E[4]; // Eye Plane
GLfloat T_E[4];
GLfloat R_E[4];
GLfloat Q_E[4];
GLfloat S_O[4]; // Object Plane
GLfloat T_O[4];
GLfloat R_O[4];
GLfloat Q_O[4];
} texgen_state_t;
typedef struct {
@@ -52,6 +57,7 @@ typedef struct {
// TODO: do we only need to worry about GL_TEXTURE_2D?
GLboolean rect_arb[MAX_TEX];
gltexture_t *bound[MAX_TEX];
GLboolean pscoordreplace[MAX_TEX];
khash_t(tex) *list;
GLuint active; // active texture
GLuint client; // client active texture
@@ -69,6 +75,15 @@ typedef struct {
GLuint cap;
} displaylist_state_t;
typedef struct {
rasterpos_t rPos;
viewport_t viewport;
GLfloat raster_scale[4];
GLfloat raster_bias[4];
GLfloat raster_zoomx;
GLfloat raster_zoomy;
} raster_state_t;
typedef struct {
map_state_t *vertex3,
@@ -93,6 +108,8 @@ typedef struct {
GLuint size;
GLfloat zmin;
GLfloat zmax;
GLfloat zminoverall;
GLfloat zmaxoverall;
GLuint overflow;
GLuint pos;
GLboolean hit;
@@ -171,6 +188,9 @@ typedef struct {
khash_t(queries) *queries;
glstack_t *stack;
glclientstack_t *clientStack;
raster_state_t raster;
int emulatedPixmap;
int emulatedWin;
int shared_cnt;
} glstate_t;

View File

@@ -35,6 +35,7 @@ void glshim_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) {
case GL_S: glstate->texgen[glstate->texture.active].S = param[0]; break;
case GL_T: glstate->texgen[glstate->texture.active].T = param[0]; break;
case GL_R: glstate->texgen[glstate->texture.active].R = param[0]; break;
case GL_Q: glstate->texgen[glstate->texture.active].Q = param[0]; break;
default:
errorShim(GL_INVALID_ENUM);
return;
@@ -50,6 +51,9 @@ void glshim_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) {
case GL_R:
memcpy(glstate->texgen[glstate->texture.active].R_O, param, 4 * sizeof(GLfloat));
break;
case GL_Q:
memcpy(glstate->texgen[glstate->texture.active].Q_O, param, 4 * sizeof(GLfloat));
break;
default:
errorShim(GL_INVALID_ENUM);
return;
@@ -65,6 +69,9 @@ void glshim_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) {
case GL_R:
memcpy(glstate->texgen[glstate->texture.active].R_E, param, 4 * sizeof(GLfloat));
break;
case GL_Q:
memcpy(glstate->texgen[glstate->texture.active].Q_E, param, 4 * sizeof(GLfloat));
break;
default:
errorShim(GL_INVALID_ENUM);
return;
@@ -82,6 +89,7 @@ void glshim_glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) {
case GL_S: *params = glstate->texgen[glstate->texture.active].S; break;
case GL_T: *params = glstate->texgen[glstate->texture.active].T; break;
case GL_R: *params = glstate->texgen[glstate->texture.active].R; break;
case GL_Q: *params = glstate->texgen[glstate->texture.active].Q; break;
default: *params = GL_EYE_LINEAR;
}
break;
@@ -96,6 +104,9 @@ void glshim_glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) {
case GL_R:
memcpy(params, glstate->texgen[glstate->texture.active].R_O, 4 * sizeof(GLfloat));
break;
case GL_Q:
memcpy(params, glstate->texgen[glstate->texture.active].Q_O, 4 * sizeof(GLfloat));
break;
default:
errorShim(GL_INVALID_ENUM);
}
@@ -110,6 +121,9 @@ void glshim_glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) {
case GL_R:
memcpy(params, glstate->texgen[glstate->texture.active].R_E, 4 * sizeof(GLfloat));
break;
case GL_Q:
memcpy(params, glstate->texgen[glstate->texture.active].Q_E, 4 * sizeof(GLfloat));
break;
default:
errorShim(GL_INVALID_ENUM);
}
@@ -125,7 +139,22 @@ GLfloat FASTMATH dot(const GLfloat *a, const GLfloat *b) {
}
GLfloat FASTMATH dot4(const GLfloat *a, const GLfloat *b) {
#ifdef __ARM_NEON__
register float ret;
asm volatile (
"vld1.f32 {d0-d1}, [%1] \n" //q0 = a(0..3)
"vld1.f32 {d2-d3}, [%2] \n" //q1 = b(0..3)
"vmul.f32 q0, q0, q1 \n" //q0 = a(0)*b(0),a(1)*b(1),a(2)*b(2),a(3)*b(3)
"vadd.f32 d0, d0, d1 \n" //d0 = a(0)*b(0)+a(2)*b(2),a(1)*b(1)+a(3)*b(3)
"vpadd.f32 d0,d0 \n" //d0 = a(0)*b(0)+a(2)*b(2)+a(1)*b(1)+a(3)*b(3),a(0)*b(0)+a(2)*b(2)+a(1)*b(1)+a(3)*b(3)
"vmov.f32 %0, s0 \n"
:"=w"(ret): "r"(a), "r"(b)
: "q0", "q1"
);
return ret;
#else
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3];
#endif
}
void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c) {
@@ -133,13 +162,13 @@ void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c) {
const float* a1 = a+8;
asm volatile (
"vld4.f32 {d0,d2,d4,d6}, [%1] \n"
"vld4.f32 {d1,d3,d5,d7}, [%2] \n" // %q0-%q3 = a(0,4,8,12/1,5,9,13/2,6,10,14/3,7,11,15)
"vld1.f32 {q4}, [%3] \n" // %q4 = b
"vmul.f32 q0, q0, d8[0] \n" // %q0 = a(0,4,8,12)*b[0]
"vmla.f32 q0, q1, d8[1] \n" // %q0 = %q0 + a(1,5,9,13)*b[1]
"vmla.f32 q0, q2, d9[0] \n" // %q0 = %q0 + a(2,6,10,14)*b[2]
"vmla.f32 q0, q3, d9[1] \n" // %q0 = %q0 + a(3,7,11,15)*b[3]
"vst1.f32 {q0}, [%0] \n"
"vld4.f32 {d1,d3,d5,d7}, [%2] \n" // q0-q3 = a(0,4,8,12/1,5,9,13/2,6,10,14/3,7,11,15)
"vld1.f32 {q4}, [%3] \n" // q4 = b
"vmul.f32 q0, q0, d8[0] \n" // q0 = a(0,4,8,12)*b[0]
"vmla.f32 q0, q1, d8[1] \n" // q0 = q0 + a(1,5,9,13)*b[1]
"vmla.f32 q0, q2, d9[0] \n" // q0 = q0 + a(2,6,10,14)*b[2]
"vmla.f32 q0, q3, d9[1] \n" // q0 = q0 + a(3,7,11,15)*b[3]
"vst1.f32 {q0}, [%0] \n"
::"r"(c), "r"(a), "r"(a1), "r"(b)
: "q0", "q1", "q2", "q3", "q4", "memory"
);
@@ -184,7 +213,10 @@ void vector3_matrix(const GLfloat *a, const GLfloat *b, GLfloat *c) {
const float* b3=b+8;
const float* b4=b+12;
asm volatile (
"vld1.f32 {q0}, [%1] \n" // %q0 = a(0..3)
//"vld1.f32 {q0}, [%1] \n" // %q0 = a(0..2)
"vld1.32 {d4}, [%1] \n"
"flds s10, [%1, #8] \n"
"vsub.f32 s11, s11, s11 \n"
"vld1.f32 {q1}, [%2] \n" // %q1 = b(0..3)
"vmul.f32 q1, q1, d0[0] \n" // %q1 = b(0..3)*a[0]
"vld1.f32 {q2}, [%3] \n" // %q2 = b(4..7)
@@ -210,6 +242,7 @@ void vector_normalize(GLfloat *a) {
asm volatile (
"vld1.32 {d4}, [%0] \n\t" //d4={x0,y0}
"flds s10, [%0, #8] \n\t" //d5[0]={z0}
"vsub.f32 s11, s11, s11 \n\t"
"vmul.f32 d0, d4, d4 \n\t" //d0= d4*d4
"vpadd.f32 d0, d0 \n\t" //d0 = d[0] + d[1]
@@ -225,7 +258,7 @@ void vector_normalize(GLfloat *a) {
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4 */ // 1 iteration should be enough
"vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4
"vst1.32 d4, [%0] \n\t" //
"vst1.32 {d4}, [%0] \n\t" //
"fsts s10, [%0, #8] \n\t" //
:"+&r"(a):
@@ -239,18 +272,58 @@ void vector_normalize(GLfloat *a) {
#endif
}
void matrix_column_row(const GLfloat *a, GLfloat *b) {
void vector4_normalize(GLfloat *a) {
#ifdef __ARM_NEON__
asm volatile (
"vld1.32 {q2}, [%0] \n\t" //q2={x0,y0,z0,00}
"vmul.f32 d0, d4, d4 \n\t" //d0= d4*d4
"vpadd.f32 d0, d0 \n\t" //d0 = d[0] + d[1]
"vmla.f32 d0, d5, d5 \n\t" //d0 = d0 + d5*d5
"vmov.f32 d1, d0 \n\t" //d1 = d0
"vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0)
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3
/* "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d4 = (3 - d0 * d3) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4 */ // 1 iteration should be enough
"vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4
"vst1.32 {q2}, [%0] \n\t" //
:"+&r"(a):
: "d0", "d1", "d2", "d3", "d4", "d5", "memory"
);
#else
float det=1.0f/sqrtf(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
a[0]*=det;
a[1]*=det;
a[2]*=det;
// a[3] is ignored and left as 0.0f
#endif
}
void FASTMATH matrix_transpose(const GLfloat *a, GLfloat *b) {
// column major -> row major
// a(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) -> b(0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15)
#ifdef __ARM_NEON__
const float* a1 = a+8;
float* b1=b+8;
asm volatile (
"vld4.f32 {d0,d2,d4,d6}, [%1] \n"
"vld4.f32 {d1,d3,d5,d7}, [%2] \n" // %q0-%q3 = a(0,4,8,12/1,5,9,13/2,6,10,14/3,7,11,15)
"vst1.f32 {d0-d3}, [%0] \n"
"vst1.f32 {d4-d7}, [%3] \n"
::"r"(b), "r"(a), "r"(a1), "r"(b1)
: "q0", "q1", "q2", "q3", "memory"
);
#else
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
b[i*4+j]=a[i+j*4];
}
void matrix_row_column(const GLfloat *a, GLfloat *b) {
// row major -> column major
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
b[i+j*4]=a[i*4+j];
#endif
}
void matrix_inverse(const GLfloat *m, GLfloat *r) {
@@ -318,14 +391,14 @@ void sphere_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint
for (int i=0; i<count; i++) {
GLushort k = indices?indices[i]:i;
matrix_vector(ModelviewMatrix, verts+k*4, eye);
vector_normalize(eye);
vector4_normalize(eye);
vector3_matrix((norm)?(norm+k*3):glstate->normal, InvModelview, eye_norm);
vector_normalize(eye_norm);
a=dot(eye, eye_norm)*2.0f;
vector4_normalize(eye_norm);
a=dot4(eye, eye_norm)*2.0f;
for (int j=0; j<4; j++)
reflect[j]=eye[j]-eye_norm[j]*a;
reflect[2]+=1.0f;
a = 1.0f / (2.0f*sqrtf(dot(reflect, reflect)));
a = 0.5f / sqrtf(dot4(reflect, reflect));
out[k*4+0] = reflect[0]*a + 0.5f;
out[k*4+1] = reflect[1]*a + 0.5f;
out[k*4+2] = 0.0f;
@@ -340,7 +413,7 @@ void eye_loop(const GLfloat *verts, const GLfloat *param, GLfloat *out, GLint co
GLfloat ModelviewMatrix[16], InvModelview[16];
glGetFloatv(GL_MODELVIEW_MATRIX, InvModelview);
// column major -> row major
matrix_column_row(InvModelview, ModelviewMatrix);
matrix_transpose(InvModelview, ModelviewMatrix);
// And get the inverse
matrix_inverse(ModelviewMatrix, InvModelview);
GLfloat plane[4], tmp[4];
@@ -368,22 +441,22 @@ static inline void tex_coord_loop(GLfloat *verts, GLfloat *norm, GLfloat *out, G
}
void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count, GLint *needclean, int texture, GLushort *indices, GLuint ilen) {
//printf("gen_tex_coords(%p, %p, %p, %d, %p, %d, %p, %d) texgen = S:%s T:%s R:%s\n", verts, norm, *coords, count, needclean, texture, indices, ilen, (glstate->enable.texgen_s[texture])?PrintEnum(glstate->texgen[texture].S):"-", (glstate->enable.texgen_t[texture])?PrintEnum(glstate->texgen[texture].T):"-", (glstate->enable.texgen_r[texture])?PrintEnum(glstate->texgen[texture].R):"-");
//printf("gen_tex_coords(%p, %p, %p, %d, %p, %d, %p, %d) texgen = S:%s T:%s R:%s Q:%s\n", verts, norm, *coords, count, needclean, texture, indices, ilen, (glstate->enable.texgen_s[texture])?PrintEnum(glstate->texgen[texture].S):"-", (glstate->enable.texgen_t[texture])?PrintEnum(glstate->texgen[texture].T):"-", (glstate->enable.texgen_r[texture])?PrintEnum(glstate->texgen[texture].R):"-", (glstate->enable.texgen_q[texture])?PrintEnum(glstate->texgen[texture].Q):"-");
// TODO: do less work when called from glDrawElements?
(*needclean) = 0;
// special case : no texgen but texture activated, create a simple 1 repeated element
if (!glstate->enable.texgen_s[texture] && !glstate->enable.texgen_t[texture] && !glstate->enable.texgen_r[texture]) {
if ((*coords)==NULL)
*coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat));
if (indices)
for (int i=0; i<ilen; i++) {
memcpy((*coords)+indices[i]*4, glstate->texcoord[texture], sizeof(GLfloat)*4);
}
else
for (int i=0; i<count*4; i+=4) {
memcpy((*coords)+i, glstate->texcoord[texture], sizeof(GLfloat)*4);
}
return;
if (!glstate->enable.texgen_s[texture] && !glstate->enable.texgen_t[texture] && !glstate->enable.texgen_r[texture] && !glstate->enable.texgen_q[texture]) {
if ((*coords)==NULL)
*coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat));
if (indices)
for (int i=0; i<ilen; i++) {
memcpy((*coords)+indices[i]*4, glstate->texcoord[texture], sizeof(GLfloat)*4);
}
else
for (int i=0; i<count*4; i+=4) {
memcpy((*coords)+i, glstate->texcoord[texture], sizeof(GLfloat)*4);
}
return;
}
// special case: SPHERE_MAP needs both texgen to make sense
if ((glstate->enable.texgen_s[texture] && (glstate->texgen[texture].S==GL_SPHERE_MAP)) && (glstate->enable.texgen_t[texture] && (glstate->texgen[texture].T==GL_SPHERE_MAP)))
@@ -446,14 +519,23 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count
if ((*coords)==NULL)
*coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat));
if (glstate->enable.texgen_s[texture])
tex_coord_loop(verts, norm, *coords, (indices)?ilen:count, glstate->texgen[texture].S, glstate->texgen[texture].S_O, glstate->texgen[texture].S_E, indices);
tex_coord_loop(verts, norm, (*coords), (indices)?ilen:count, glstate->texgen[texture].S, glstate->texgen[texture].S_O, glstate->texgen[texture].S_E, indices);
if (glstate->enable.texgen_t[texture])
tex_coord_loop(verts, norm, *coords+1, (indices)?ilen:count, glstate->texgen[texture].T, glstate->texgen[texture].T_O, glstate->texgen[texture].T_E, indices);
for (int i=0; i<((indices)?ilen:count); i++) {
GLushort k = indices?indices[i]:i;
(*coords)[k*4+2] = 0.0f;
(*coords)[k*4+3] = 1.0f;
}
tex_coord_loop(verts, norm, (*coords)+1, (indices)?ilen:count, glstate->texgen[texture].T, glstate->texgen[texture].T_O, glstate->texgen[texture].T_E, indices);
if (glstate->enable.texgen_r[texture])
tex_coord_loop(verts, norm, (*coords)+2, (indices)?ilen:count, glstate->texgen[texture].R, glstate->texgen[texture].R_O, glstate->texgen[texture].R_E, indices);
else
for (int i=0; i<((indices)?ilen:count); i++) {
GLushort k = indices?indices[i]:i;
(*coords)[k*4+2] = 0.0f;
}
if (glstate->enable.texgen_q[texture])
tex_coord_loop(verts, norm, (*coords)+3, (indices)?ilen:count, glstate->texgen[texture].Q, glstate->texgen[texture].Q_O, glstate->texgen[texture].Q_E, indices);
else
for (int i=0; i<((indices)?ilen:count); i++) {
GLushort k = indices?indices[i]:i;
(*coords)[k*4+3] = 1.0f;
}
}
void gen_tex_clean(GLint cleancode, int texture) {
@@ -469,7 +551,7 @@ void gen_tex_clean(GLint cleancode, int texture) {
void glshim_glLoadTransposeMatrixf(const GLfloat *m) {
GLfloat mf[16];
matrix_row_column(m, mf);
matrix_transpose(m, mf);
glshim_glLoadMatrixf(mf);
errorGL();
}
@@ -489,7 +571,7 @@ void glshim_glMultTransposeMatrixd(const GLdouble *m) {
}
void glshim_glMultTransposeMatrixf(const GLfloat *m) {
GLfloat mf[16];
matrix_row_column(m, mf);
matrix_transpose(m, mf);
glshim_glMultMatrixf(mf);
errorGL();
}

View File

@@ -11,8 +11,7 @@ GLfloat dot(const GLfloat *a, const GLfloat *b);
void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c);
void vector_matrix(const GLfloat *a, const GLfloat *b, GLfloat *c);
void vector_normalize(GLfloat *a);
void matrix_column_row(const GLfloat *a, GLfloat *b);
void matrix_row_column(const GLfloat *a, GLfloat *b);
void matrix_transpose(const GLfloat *a, GLfloat *b);
void matrix_inverse(const GLfloat *m, GLfloat *r);
void matrix_mul(const GLfloat *a, const GLfloat *b, GLfloat *c);

View File

@@ -7,6 +7,7 @@
#include <EGL/eglext.h>
#include "gles.h"
#include "../glx/streaming.h"
#include "../glx/hardext.h"
#ifndef GL_TEXTURE_STREAM_IMG
#define GL_TEXTURE_STREAM_IMG 0x8C0D
@@ -151,6 +152,9 @@ void internal2format_type(GLenum internalformat, GLenum *format, GLenum *type)
*format = GL_RGBA;
*type = GL_UNSIGNED_BYTE;
break;
case GL_DEPTH_COMPONENT:
*format = GL_DEPTH_COMPONENT;
*type = GL_UNSIGNED_SHORT;
default:
printf("LIBGL: Warning, unknown Internalformat (%s)\n", PrintEnum(internalformat));
*format = GL_RGBA;
@@ -298,7 +302,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height,
GLvoid *pix2 = pixels;
if (raster_need_transform())
if (!pixel_transform(data, &pixels, width, height,
*format, *type, raster_scale, raster_bias)) {
*format, *type, glstate->raster.raster_scale, glstate->raster.raster_bias)) {
printf("LIBGL: swizzle/convert error: (%s, %s -> %s, %s)\n",
PrintEnum(*format), PrintEnum(*type), PrintEnum(dest_format), PrintEnum(dest_type));
pix2 = pixels;
@@ -786,11 +790,16 @@ void glshim_glTexImage2D(GLenum target, GLint level, GLint internalformat,
case GL_PROXY_TEXTURE_2D:
break;
default: {
GLsizei nheight = npot(height), nwidth = npot(width);
GLsizei nheight = (hardext.npot==2)?height:npot(height), nwidth = (hardext.npot==2)?width:npot(width);
#ifdef PANDORA
#define NO_1x1
#endif
#ifdef NO_1x1
#define MIN_SIZE 2
if(nwidth < MIN_SIZE) nwidth=MIN_SIZE;
if(nheight < MIN_SIZE) nheight=MIN_SIZE;
if(level==0) {
if(nwidth < MIN_SIZE) nwidth=MIN_SIZE;
if(nheight < MIN_SIZE) nheight=MIN_SIZE;
}
#undef MIN_SIZE
#endif
if (texstream && bound && bound->streamed) {
@@ -828,6 +837,18 @@ void glshim_glTexImage2D(GLenum target, GLint level, GLint internalformat,
if (pixels) gles_glTexSubImage2D(target, level, 0, 0, width, height,
format, type, pixels);
errorGL();
#ifdef NO_1x1
if(level==0 && (width==1 || height==1 && pixels)) {
// complete the texture, juste in ase it use GL_REPEAT
// also, don't keep the fact we have resized, the non-adjusted coordinates will work (as the texture is enlarged)
if(width==1) {gles_glTexSubImage2D(target, level, 1, 0, width, height, format, type, pixels); nwidth=1;}
if(height==1) {gles_glTexSubImage2D(target, level, 0, 1, width, height, format, type, pixels); nheight=1;}
if(width==1 && height==1) { // create a manual mipmap just in case_state
gles_glTexSubImage2D(target, level, 1, 1, width, height, format, type, pixels);
gles_glTexImage2D(target, 1, format, 1, 1, 0, format, type, pixels);
}
}
#endif
} else {
gles_glTexImage2D(target, level, format, width, height, border,
format, type, pixels);
@@ -1764,9 +1785,8 @@ void glshim_glClientActiveTexture( GLenum texture ) {
gles_glClientActiveTexture(texture);
errorGL();
}
void glshim_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * data) {
//printf("glReadPixels(%i, %i, %i, %i, 0x%04X, 0x%04X, 0x%p)\n", x, y, width, height, format, type, data);
//printf("glReadPixels(%i, %i, %i, %i, %s, %s, 0x%p)\n", x, y, width, height, PrintEnum(format), PrintEnum(type), data);
GLuint old_glbatch = glstate->gl_batch;
if (glstate->gl_batch) {
flush();
@@ -1784,20 +1804,26 @@ void glshim_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
dst += (uintptr_t)glstate->vao->pack->data;
readfboBegin();
if (format == GL_RGBA && format == GL_UNSIGNED_BYTE) {
if ((format == GL_RGBA && type == GL_UNSIGNED_BYTE) // should not use default GL_RGBA on Pandora as it's very slow...
|| (format == hardext.readf && type == hardext.readt) // use the IMPLEMENTATION_READ too...
|| (format == GL_DEPTH_COMPONENT && type == GL_FLOAT)) // this one will probably fail, as DEPTH is not readable on most GLES hardware
{
// easy passthru
gles_glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst);
gles_glReadPixels(x, y, width, height, format, type, dst);
readfboEnd();
glstate->gl_batch = old_glbatch;
return;
}
// grab data in GL_RGBA format
int use_bgra = 0;
if(hardext.readf==GL_BGRA && hardext.readt==GL_UNSIGNED_BYTE)
use_bgra = 1; // if IMPLEMENTATION_READ is BGRA, then use it as it's probably faster then RGBA.
GLvoid *pixels = malloc(width*height*4);
gles_glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
gles_glReadPixels(x, y, width, height, use_bgra?GL_BGRA:GL_RGBA, GL_UNSIGNED_BYTE, pixels);
if (! pixel_convert(pixels, &dst, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) {
printf("LIBGL: ReadPixels error: (GL_RGBA, UNSIGNED_BYTE -> %s, %s )\n",
PrintEnum(format), PrintEnum(type));
use_bgra?GL_BGRA:GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) {
LOGE("LIBGL: ReadPixels error: (%s, UNSIGNED_BYTE -> %s, %s )\n",
PrintEnum(use_bgra?GL_BGRA:GL_RGBA), PrintEnum(format), PrintEnum(type));
}
free(pixels);
readfboEnd();
@@ -2036,20 +2062,28 @@ void glshim_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfo
} else {
pixels = uncompressDXTc(width, height, internalformat, imageSize, datab);
}
// if RGBA / DXT1, then RGB 000 needs to have 0 alpha too
if(internalformat==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
GLuint *p = (GLuint*)pixels;
for(int i=0; i<width*height; i++, p++)
if(*p==0xff000000) *p=0;
}
// automaticaly reduce the pixel size
half=pixels;
glstate->texture.bound[glstate->texture.active]->alpha = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true;
format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA;
glstate->texture.bound[glstate->texture.active]->format = format; //internalformat;
type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4;
glstate->texture.bound[glstate->texture.active]->type = type;
glstate->texture.bound[glstate->texture.active]->compressed = true;
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
glstate->texture.bound[glstate->texture.active]->type = GL_UNSIGNED_BYTE;
else {
format = GL_RGBA;
type = GL_UNSIGNED_BYTE;
}
glstate->texture.bound[glstate->texture.active]->format = format; //internalformat;
glstate->texture.bound[glstate->texture.active]->type = type;
glstate->texture.bound[glstate->texture.active]->compressed = true;
} else {
fact = 0;
}
@@ -2057,7 +2091,7 @@ void glshim_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfo
glshim_glGetIntegerv(GL_UNPACK_ALIGNMENT, &oldalign);
if (oldalign!=1)
glshim_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glshim_glTexImage2D(target, level, GL_RGBA, width>>fact, height>>fact, border, format, type, half);
glshim_glTexImage2D(target, level, format, width>>fact, height>>fact, border, format, type, half);
if (oldalign!=1)
glshim_glPixelStorei(GL_UNPACK_ALIGNMENT, oldalign);
if (half!=pixels)
@@ -2223,6 +2257,60 @@ void glshim_glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,
}
void glshim_glTexEnvf(GLenum target, GLenum pname, GLfloat param) {
LOAD_GLES(glTexEnvf);
PUSH_IF_COMPILING(glTexEnvf);
if(target==GL_POINT_SPRITE && pname==GL_COORD_REPLACE)
glstate->texture.pscoordreplace[glstate->texture.active] = (param!=0.0f)?1:0;
gles_glTexEnvf(target, pname, param);
}
void glshim_glTexEnvi(GLenum target, GLenum pname, GLint param) {
LOAD_GLES(glTexEnvi);
PUSH_IF_COMPILING(glTexEnvi);
if(target==GL_POINT_SPRITE && pname==GL_COORD_REPLACE)
glstate->texture.pscoordreplace[glstate->texture.active] = (param!=0)?1:0;
gles_glTexEnvi(target, pname, param);
}
void glshim_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *param) {
if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) {
NewStage(glstate->list.active, STAGE_TEXENV);
rlTexEnvfv(glstate->list.active, target, pname, param);
noerrorShim();
return;
}
LOAD_GLES(glTexEnvfv);
gles_glTexEnvfv(target, pname, param);
}
void glshim_glTexEnviv(GLenum target, GLenum pname, const GLint *param) {
if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) {
NewStage(glstate->list.active, STAGE_TEXENV);
rlTexEnviv(glstate->list.active, target, pname, param);
noerrorShim();
return;
}
LOAD_GLES(glTexEnviv);
gles_glTexEnviv(target, pname, param);
}
void glshim_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params) {
LOAD_GLES(glGetTexEnvfv);
if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush();
if(target==GL_POINT_SPRITE && pname==GL_COORD_REPLACE)
*params = glstate->texture.pscoordreplace[glstate->texture.active];
else
gles_glGetTexEnvfv(target, pname, params);
}
void glshim_glGetTexEnviv(GLenum target, GLenum pname, GLint * params) {
LOAD_GLES(glGetTexEnviv);
if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush();
if(target==GL_POINT_SPRITE && pname==GL_COORD_REPLACE)
*params = glstate->texture.pscoordreplace[glstate->texture.active];
else
gles_glGetTexEnviv(target, pname, params);
}
//Direct wrapper
void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *data) AliasExport("glshim_glTexImage2D");
void glTexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *data) AliasExport("glshim_glTexImage1D");
@@ -2255,6 +2343,11 @@ void glActiveTexture( GLenum texture ) AliasExport("glshim_glActiveTexture");
void glClientActiveTexture( GLenum texture ) AliasExport("glshim_glClientActiveTexture");
GLboolean glIsTexture( GLuint texture ) AliasExport("glshim_glIsTexture");
void glPixelStorei(GLenum pname, GLint param) AliasExport("glshim_glPixelStorei");
void glTexEnvf(GLenum target, GLenum pname, GLfloat param) AliasExport("glshim_glTexEnvf");
void glTexEnvi(GLenum target, GLenum pname, GLint param) AliasExport("glshim_glTexEnvi");
void glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params) AliasExport("glshim_glGetTexEnvfv");
void glGetTexEnviv(GLenum target, GLenum pname, GLint * params) AliasExport("glshim_glGetTexEnviv");
//EXT mapper
void glTexSubImage3DEXT(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *data) AliasExport("glshim_glTexSubImage3D");
void glCompressedTexImage2DEXT(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) AliasExport("glshim_glCompressedTexImage2D");

View File

@@ -74,7 +74,14 @@ void glshim_glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint
void glshim_glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height);
void glshim_glTexEnvf(GLenum target, GLenum pname, GLfloat param);
void glshim_glTexEnvi(GLenum target, GLenum pname, GLint param);
void glshim_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *param);
void glshim_glTexEnviv(GLenum target, GLenum pname, const GLint *param);
void glshim_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params);
void glshim_glGetTexEnviv(GLenum target, GLenum pname, GLint * params);
void tex_coord_rect_arb(GLfloat *tex, GLsizei len,
GLsizei width, GLsizei height);

File diff suppressed because it is too large Load Diff

View File

@@ -138,12 +138,18 @@ struct __GLXContextRec {
EGLSurface eglSurface;
EGLConfig eglConfigs[1];
EGLContext eglContext;
int samples;
int samplebuffers;
int depth;
int stencil;
int rbits, gbits, bbits, abits;
void* glstate;
int contextType; // 0 = Window, 1 = PBuffer
int contextType; // 0 = Window, 1 = PBuffer, 2 = PixmapBuffer, 3 = Emulated PixmapBuffer (with PBuffer)
};
typedef struct __GLXContextRec *GLXContext;
typedef XID GLXPbuffer;
typedef XID GLXPixmap;
#endif //ANDROID
struct __GLXFBConfigRec {
int visualType;
@@ -226,11 +232,9 @@ const char *glXQueryServerString(Display *display, int screen, int name);
#endif //ANDROID
GLXDrawable glXGetCurrentDrawable();
#ifndef ANDROID
void glXCreateGLXPixmap(Display *display, XVisualInfo * visual, Pixmap pixmap);
int glXGetConfig(Display *display, XVisualInfo *visual, int attribute, int *value);
void glXCopyContext(Display *display, GLXContext src, GLXContext dst, GLuint mask);
void glXDestroyContext(Display *display, GLXContext ctx);
void glXDestroyGLXPixmap(Display *display, void *pixmap);
void glXSwapBuffers(Display *display, int drawable);
void glXUseXFont(Font font, int first, int count, int listBase);
#endif //ANDROID
@@ -260,4 +264,9 @@ GLXContext glXCreateNewContext(Display *display, GLXFBConfig config, int render_
void glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf);
GLXPbuffer glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int * attrib_list);
GLXPixmap glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int * attrib_list);
void glXDestroyPixmap(Display *display, void *pixmap);
GLXPixmap glXCreateGLXPixmap(Display *display, XVisualInfo * visual, Pixmap pixmap);
void glXDestroyGLXPixmap(Display *display, void *pixmap);
#endif //ANDROID

View File

@@ -0,0 +1,147 @@
#include "../gl/gl.h"
#include "hardext.h"
static int tested = 0;
hardext_t hardext;
extern int glshim_nobanner;
#define SHUT(a) if(!glshim_nobanner) a
void GetHardwareExtensions(int notest)
{
// used EGL & GLES functions
LOAD_EGL(eglBindAPI);
LOAD_EGL(eglInitialize);
LOAD_EGL(eglGetDisplay);
LOAD_EGL(eglCreatePbufferSurface);
LOAD_EGL(eglDestroySurface);
LOAD_EGL(eglDestroyContext);
LOAD_EGL(eglMakeCurrent);
LOAD_EGL(eglChooseConfig);
LOAD_EGL(eglCreateContext);
LOAD_EGL(eglQueryString);
LOAD_GLES(glGetString);
LOAD_GLES(glGetIntegerv);
EGLDisplay eglDisplay;
EGLSurface eglSurface;
EGLContext eglContext;
if(tested) return;
// put some default values
memset(&hardext, 0, sizeof(hardext));
hardext.maxtex = 1;
hardext.maxsize = 2048;
hardext.readf = GL_RGBA;
hardext.readt = GL_UNSIGNED_BYTE;
if(notest) {
SHUT(LOGD("LIBGL: Hardware test disabled, nothing activated...\n"));
}
// Create a PBuffer first...
EGLint egl_context_attrib[] = {
#ifdef USE_ES2
EGL_CONTEXT_CLIENT_VERSION, 2,
#endif
EGL_NONE
};
//let's create a PBuffer attributes
EGLint egl_attribs[10]; // should be enough
int i = 0;
egl_attribs[i++] = EGL_WIDTH;
egl_attribs[i++] = 32;
egl_attribs[i++] = EGL_HEIGHT;
egl_attribs[i++] = 32;
egl_attribs[i++] = EGL_NONE;
EGLint configAttribs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
EGL_NONE
};
int configsFound;
static EGLConfig pbufConfigs[1];
eglDisplay = egl_eglGetDisplay(EGL_DEFAULT_DISPLAY);
egl_eglBindAPI(EGL_OPENGL_ES_API);
if (egl_eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE) {
LOGE("LIBGL: Error while gathering supported extension (Init issue), default to none\n");
return;
}
egl_eglChooseConfig(eglDisplay, configAttribs, pbufConfigs, 1, &configsFound);
if(!configsFound) {
SHUT(LOGE("LIBGL: Error while gathering supported extension (Config issue), default to none\n"));
return;
}
eglContext = egl_eglCreateContext(eglDisplay, pbufConfigs[0], EGL_NO_CONTEXT, egl_context_attrib);
if(!eglContext) {
SHUT(LOGE("LIBGL: Error while gathering supported extension (Context issue), default to none\n"));
return;
}
eglSurface = egl_eglCreatePbufferSurface(eglDisplay, pbufConfigs[0], egl_attribs);
if(!eglSurface) {
SHUT(LOGE("LIBGL: Error while gathering supported extension (Surface issue), default to none\n"));
egl_eglDestroyContext(eglDisplay, eglContext);
return;
}
egl_eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
// Now get extensions
const char* Exts = gles_glGetString(GL_EXTENSIONS);
// Parse them!
#define S(A, B, C) if(strstr(Exts, A)) { hardext.B = 1; SHUT(LOGD("LIBGL: Extension %s detected%s",A, C?" and used\n":"\n")); }
if(strstr(Exts, "GL_APPLE_texture_2D_limited_npot")) hardext.npot = 1;
if(strstr(Exts, "GL_ARB_texture_non_power_of_two ")) hardext.npot = 2;
if(hardext.npot>0) {
SHUT(LOGD("LIBGL: Hardware %s NPOT detected and used\n", hardext.npot==2?"Full":"Limited"));
}
S("GL_OES_blend_subtract", blendsub, 1);
S("GL_OES_blend_func_separate", blendfunc, 1);
S("GL_OES_blend_equation_separate", blendeq, 1);
S("GL_EXT_blend_minmax", blendminmax, 1);
S("GL_EXT_blend_color", blendcolor, 1);
S("GL_OES_point_sprite", pointsprite, 1);
S("GL_OES_point_size_array", pointsize, 0);
S("GL_OES_element_index_uint", elementuint, 0);
S("GL_OES_framebuffer_object", fbo, 1);
S("GL_OES_packed_depth_stencil", depthstencil, 1);
S("GL_OES_depth24", depth24, 1);
S("GL_OES_rgb8_rgba8", rgba8, 1);
S("GL_EXT_multi_draw_arrays", multidraw, 1);
S("GL_EXT_texture_format_BGRA8888", bgra8888, 0);
S("GL_OES_depth_texture", depthtex, 1);
// Now get some max stuffs
gles_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &hardext.maxsize);
SHUT(LOGD("LIBGL: Max texture size: %d\n", hardext.maxsize));
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...
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)
gles_glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &hardext.readf);
gles_glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &hardext.readt);
SHUT(LOGD("LIBGL: Implementation Read is %s/%s\n", PrintEnum(hardext.readf), PrintEnum(hardext.readt)));
#endif
if(strstr(egl_eglQueryString(eglDisplay, EGL_EXTENSIONS), "EGL_KHR_gl_colorspace")) {
LOGD("LIBGL: sRGB surface supported\n");
hardext.srgb = 1;
}
// End, cleanup
egl_eglMakeCurrent(eglDisplay, 0, 0, EGL_NO_CONTEXT);
egl_eglDestroySurface(eglDisplay, eglSurface);
egl_eglDestroyContext(eglDisplay, eglContext);
}

View File

@@ -0,0 +1,33 @@
#ifndef _GLX_HARDEXT_H_
#define _GLX_HARDEXT_H_
typedef struct _hardext {
int npot; // 0 = no npot capability, 1 = limited npot, 2 = full npot
int maxtex; // maximum number of texture
int maxlights; // maximum number of light
int maxsize; // maximum texture size
int blendsub; // GL_OES_blend_subtract
int blendfunc; // GL_OES_blend_func_separate
int blendeq; // GL_OES_blend_equation_separate
int blendminmax; // GL_EXT_blend_minmax
int blendcolor; // GL_EXT_blend_color
int pointsprite; // GL_OES_point_sprite (not used yet)
int pointsize; // GL_OES_point_size_array (not used yet)
int elementuint; // GL_OES_element_index_uint (not used yet)
int fbo; // GL_OES_framebuffer_object
int depthstencil; // GL_OES_packed_depth_stencil
int depth24; // GL_OES_depth24
int rgba8; // GL_OES_rgb8_rgba8
int multidraw; // GL_EXT_multi_draw_arrays
int bgra8888; // GL_EXT_texture_format_BGRA8888 (not used yet)
int depthtex; // GL_OES_depth_texture
unsigned int readf; // implementation Read Format
unsigned int readt; // implementation Read Type
int srgb; // EGL_KHR_gl_colorspace
} hardext_t;
extern hardext_t hardext;
void GetHardwareExtensions(int test);
#endif

View File

@@ -2,6 +2,7 @@
#include "../gl/gl.h"
#endif
#include "glx.h"
#include "hardext.h"
#include "../gl/directstate.h"
@@ -37,7 +38,7 @@ extern int export_silentstub;
#define STUB(func_name) \
if (strcmp(name, #func_name) == 0) { \
if(!export_silentstub) printf("glX stub: %s\n", #func_name); \
if(!export_silentstub) LOGD("glX stub: %s\n", #func_name); \
return (void *)glXStub; \
}
@@ -67,9 +68,7 @@ EXPORT void *glXGetProcAddressARB(const char *name) {
EX(glXCreateContext);
EX(glXCreateNewContext);
EX(glXCreateContextAttribsARB);
EX(glXCreateGLXPixmap);
EX(glXDestroyContext);
EX(glXDestroyGLXPixmap);
EX(glXGetConfig);
EX(glXGetCurrentDisplay);
EX(glXGetCurrentDrawable);
@@ -103,13 +102,25 @@ EXPORT void *glXGetProcAddressARB(const char *name) {
EX(glXCreatePbuffer);
EX(glXDestroyPbuffer);
STUB(glXCreatePixmap);
STUB(glXDestroyPixmap);
EX(glXCreatePixmap);
EX(glXDestroyPixmap);
EX(glXCreateGLXPixmap);
EX(glXDestroyGLXPixmap);
STUB(glXGetCurrentReadDrawable);
STUB(glXGetSelectedEvent);
STUB(glXSelectEvent);
#endif //ANDROID
// GL_EXT_texture_object (yeah, super old!)
_EXT(glGenTextures);
_EXT(glBindTexture);
_EXT(glDeleteTextures);
_EXT(glIsTexture);
_EXT(glAreTexturesResident);
_EXT(glPrioritizeTextures);
// GL_EXT_polygonoffset
_EXT(glPolygonOffset);
// GL_ARB_vertex_buffer_object
_ARB(glBindBuffer);
_ARB(glBufferData);
@@ -138,52 +149,54 @@ EXPORT void *glXGetProcAddressARB(const char *name) {
_ARB(glIsVertexArray);
// GL_ARB_frameBuffer_ext
_EX(glFramebufferTexture1D);
_EX(glFramebufferTexture3D);
_EX(glFramebufferTextureLayer);
_EX(glRenderbufferStorageMultisample);
_EX(glBlitFramebuffer);
_EXT(glGenFramebuffers);
_EXT(glDeleteFramebuffers);
_EXT(glIsFramebuffer);
_EXT(glCheckFramebufferStatus);
_EXT(glBindFramebuffer);
_EXT(glFramebufferTexture2D);
_EXT(glFramebufferTexture1D);
_EXT(glFramebufferTexture3D);
_EXT(glGenRenderbuffers);
_EXT(glFramebufferRenderbuffer);
_EXT(glDeleteRenderbuffers);
_EXT(glRenderbufferStorage);
_EXT(glRenderbufferStorageMultisample);
_EXT(glBindRenderbuffer);
_EXT(glIsRenderbuffer);
_EXT(glGenerateMipmap);
_EXT(glGetFramebufferAttachmentParameteriv);
_EXT(glGetRenderbufferParameteriv);
_EXT(glFramebufferTextureLayer);
_EXT(glBlitFramebuffer);
_ARB(glGenFramebuffers);
_ARB(glDeleteFramebuffers);
_ARB(glIsFramebuffer);
_ARB(glCheckFramebufferStatus);
_ARB(glBindFramebuffer);
_ARB(glFramebufferTexture2D);
_ARB(glFramebufferTexture1D);
_ARB(glFramebufferTexture3D);
_ARB(glGenRenderbuffers);
_ARB(glFramebufferRenderbuffer);
_ARB(glDeleteRenderbuffers);
_ARB(glRenderbufferStorage);
_ARB(glRenderbufferStorageMultisample);
_ARB(glBindRenderbuffer);
_ARB(glIsRenderbuffer);
_ARB(glGenerateMipmap);
_ARB(glGetFramebufferAttachmentParameteriv);
_ARB(glGetRenderbufferParameteriv);
_ARB(glFramebufferTextureLayer);
_ARB(glBlitFramebuffer);
STUB(glDrawBuffersARB);
if(hardext.fbo) {
_EX(glFramebufferTexture1D);
_EX(glFramebufferTexture3D);
_EX(glFramebufferTextureLayer);
_EX(glRenderbufferStorageMultisample);
_EX(glBlitFramebuffer);
_EXT(glGenFramebuffers);
_EXT(glDeleteFramebuffers);
_EXT(glIsFramebuffer);
_EXT(glCheckFramebufferStatus);
_EXT(glBindFramebuffer);
_EXT(glFramebufferTexture2D);
_EXT(glFramebufferTexture1D);
_EXT(glFramebufferTexture3D);
_EXT(glGenRenderbuffers);
_EXT(glFramebufferRenderbuffer);
_EXT(glDeleteRenderbuffers);
_EXT(glRenderbufferStorage);
_EXT(glRenderbufferStorageMultisample);
_EXT(glBindRenderbuffer);
_EXT(glIsRenderbuffer);
_EXT(glGenerateMipmap);
_EXT(glGetFramebufferAttachmentParameteriv);
_EXT(glGetRenderbufferParameteriv);
_EXT(glFramebufferTextureLayer);
_EXT(glBlitFramebuffer);
_ARB(glGenFramebuffers);
_ARB(glDeleteFramebuffers);
_ARB(glIsFramebuffer);
_ARB(glCheckFramebufferStatus);
_ARB(glBindFramebuffer);
_ARB(glFramebufferTexture2D);
_ARB(glFramebufferTexture1D);
_ARB(glFramebufferTexture3D);
_ARB(glGenRenderbuffers);
_ARB(glFramebufferRenderbuffer);
_ARB(glDeleteRenderbuffers);
_ARB(glRenderbufferStorage);
_ARB(glRenderbufferStorageMultisample);
_ARB(glBindRenderbuffer);
_ARB(glIsRenderbuffer);
_ARB(glGenerateMipmap);
_ARB(glGetFramebufferAttachmentParameteriv);
_ARB(glGetRenderbufferParameteriv);
_ARB(glFramebufferTextureLayer);
_ARB(glBlitFramebuffer);
STUB(glDrawBuffersARB);
}
/*
MAP_EGL(glGenFramebuffersARB, glGenFramebuffersOES);
@@ -317,7 +330,7 @@ EXPORT void *glXGetProcAddressARB(const char *name) {
_EX(glArrayElement);
_EX(glBegin);
_EX(glBitmap);
if(export_blendcolor) {
if(export_blendcolor || hardext.blendcolor) {
_EX(glBlendColor);
_EXT(glBlendColor);
_ARB(glBlendColor);
@@ -326,18 +339,21 @@ EXPORT void *glXGetProcAddressARB(const char *name) {
_ARB(glBlendEquation);
_EXT(glBlendFunc);
_ARB(glBlendFunc);
#ifndef ODROID
_EXT(glBlendEquationSeparate);
_ARB(glBlendEquationSeparate);
_EX(glBlendEquationSeparatei);
_EXT(glBlendEquationSeparatei);
_ARB(glBlendEquationSeparatei);
_EXT(glBlendFuncSeparate);
_ARB(glBlendFuncSeparate);
_EX(glBlendFuncSeparatei);
_EXT(glBlendFuncSeparatei);
_ARB(glBlendFuncSeparatei);
#endif
if(hardext.blendeq) {
_EXT(glBlendEquationSeparate);
_ARB(glBlendEquationSeparate);
_EX(glBlendEquationSeparatei);
_EXT(glBlendEquationSeparatei);
_ARB(glBlendEquationSeparatei);
}
if(hardext.blendfunc) {
_EXT(glBlendFuncSeparate);
_ARB(glBlendFuncSeparate);
_EX(glBlendFuncSeparatei);
_EXT(glBlendFuncSeparatei);
_ARB(glBlendFuncSeparatei);
}
_EX(glStencilMaskSeparate);
_EXT(glStencilMaskSeparate);
_EX(glCallList);
@@ -444,6 +460,8 @@ EXPORT void *glXGetProcAddressARB(const char *name) {
_EX(glTexImage3D);
_EX(glTexSubImage1D);
_EX(glTexSubImage3D);
_EXT(glTexImage3D);
_EXT(glTexSubImage3D);
_EX(glCompressedTexImage1D);
_EX(glCompressedTexSubImage1D);
_EX(glCompressedTexImage3D);
@@ -478,7 +496,7 @@ EXPORT void *glXGetProcAddressARB(const char *name) {
STUB(glClearAccum);
STUB(glColorMaterial);
STUB(glCopyTexImage3D);
STUB(glCopyTexSubImage3D);
_EX(glCopyTexSubImage3D); // It's a stub, calling the 2D one
STUB(glFeedbackBuffer);
STUB(glGetClipPlane);
STUB(glGetLightiv);
@@ -627,7 +645,10 @@ EXPORT void *glXGetProcAddressARB(const char *name) {
_EX(glGetQueryObjectuiv);
}
if (!export_silentstub) printf("glXGetProcAddress: %s not found.\n", name);
// GL_ARB_multisample
_ARB(glSampleCoverage);
if (!export_silentstub) LOGD("glXGetProcAddress: %s not found.\n", name);
return NULL;
}