glshim updated, added latest changes by ptitSeb

This commit is contained in:
lubomyr
2015-11-03 21:47:36 +02:00
parent cc98874948
commit ad9bbd68f3
16 changed files with 718 additions and 289 deletions

View File

@@ -201,7 +201,7 @@ GLfloat *gl_pointer_index(pointer_state_t *p, GLint index) {
GLsizei size = gl_sizeof(p->type);
GLsizei stride = p->stride ? p->stride : size * p->size;
uintptr_t ptr = (uintptr_t)(p->pointer) + (stride * index)
+ (uintptr_t)((state.buffers.vertex)?state.buffers.vertex->data:0);
+ (uintptr_t)((state.vao->vertex)?state.vao->vertex->data:0);
GL_TYPE_SWITCH(src, ptr, p->type,
for (int i = 0; i < p->size; i++) {

View File

@@ -1,22 +1,23 @@
#include "buffers.h"
#include "debug.h"
static GLuint lastbuffer = 1;
// Utility function to bond / unbind a particular buffer
// Utility function to bind / unbind a particular buffer
glbuffer_t** BUFF(GLenum target) {
switch(target) {
case GL_ARRAY_BUFFER:
return &state.buffers.vertex;
return &state.vao->vertex;
break;
case GL_ELEMENT_ARRAY_BUFFER:
return &state.buffers.elements;
return &state.vao->elements;
break;
case GL_PIXEL_PACK_BUFFER:
return &state.buffers.pack;
return &state.vao->pack;
break;
case GL_PIXEL_UNPACK_BUFFER:
return &state.buffers.unpack;
return &state.vao->unpack;
break;
default:
printf("LIBGL: Warning, unknown buffer target 0x%04X\n", target);
@@ -66,13 +67,16 @@ void glGenBuffers(GLsizei n, GLuint * buffers) {
}
void glBindBuffer(GLenum target, GLuint buffer) {
//printf("glBindBuffer(0x%04X, %u)\n", target, buffer);
//printf("glBindBuffer(%s, %u)\n", PrintEnum(target), buffer);
if (state.gl_batch) {
flush();
}
khint_t k;
int ret;
khash_t(buff) *list = state.buffers.list;
khash_t(buff) *list = state.buffers;
if (! list) {
list = state.buffers.list = kh_init(buff);
list = state.buffers = kh_init(buff);
// segfaults if we don't do a single put
kh_put(buff, list, 1, &ret);
kh_del(buff, list, 1);
@@ -108,7 +112,7 @@ void glBindBuffer(GLenum target, GLuint buffer) {
}
void glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
//printf("glBufferData(0x%04X, %i, %p, 0x%04X)\n", target, size, data, usage);
//printf("glBufferData(%s, %i, %p, %s)\n", PrintEnum(target), size, data, PrintEnum(usage));
if (!buffer_target(target)) {
errorShim(GL_INVALID_ENUM);
return;
@@ -132,7 +136,7 @@ void glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum us
}
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
//printf("glBufferSubData(0x%04X, %p, %i, %p)\n", target, offset, size, data);
//printf("glBufferSubData(%s, %p, %i, %p)\n", PrintEnum(target), offset, size, data);
if (!buffer_target(target)) {
errorShim(GL_INVALID_ENUM);
return;
@@ -149,26 +153,32 @@ void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvo
void glDeleteBuffers(GLsizei n, const GLuint * buffers) {
//printf("glDeleteBuffers(%i, %p)\n", n, buffers);
khash_t(buff) *list = state.buffers.list;
if (state.gl_batch) {
flush();
}
khash_t(buff) *list = state.buffers;
if (list) {
khint_t k;
glbuffer_t *buff;
for (int i = 0; i < n; i++) {
GLuint t = buffers[i];
k = kh_get(buff, list, t);
if (k != kh_end(list)) {
buff = kh_value(list, k);
if (state.buffers.vertex == buff)
state.buffers.vertex = NULL;
if (state.buffers.elements == buff)
state.buffers.elements = NULL;
if (state.buffers.pack == buff)
state.buffers.pack = NULL;
if (state.buffers.unpack == buff)
state.buffers.unpack = NULL;
if (buff->data) free(buff->data);
kh_del(buff, list, k);
free(buff);
if (t) { // don't allow to remove default one
k = kh_get(buff, list, t);
if (k != kh_end(list)) {
buff = kh_value(list, k);
if (state.vao->vertex == buff)
state.vao->vertex = NULL;
if (state.vao->elements == buff)
state.vao->elements = NULL;
if (state.vao->pack == buff)
state.vao->pack = NULL;
if (state.vao->unpack == buff)
state.vao->unpack = NULL;
if (buff->data) free(buff->data);
kh_del(buff, list, k);
free(buff);
}
}
}
}
@@ -177,7 +187,7 @@ void glDeleteBuffers(GLsizei n, const GLuint * buffers) {
GLboolean glIsBuffer(GLuint buffer) {
//printf("glIsBuffer(%u)\n", buffer);
khash_t(buff) *list = state.buffers.list;
khash_t(buff) *list = state.buffers;
khint_t k;
noerrorShim();
if (list) {
@@ -192,7 +202,7 @@ GLboolean glIsBuffer(GLuint buffer) {
void glGetBufferParameteriv(GLenum target, GLenum value, GLint * data) {
//printf("glGetBufferParameteriv(0x%04X, 0x%04X, %p)\n", target, value, data);
//printf("glGetBufferParameteriv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(value), data);
if (!buffer_target(target)) {
errorShim(GL_INVALID_ENUM);
return;
@@ -232,7 +242,7 @@ void glGetBufferParameteriv(GLenum target, GLenum value, GLint * data) {
}
void *glMapBuffer(GLenum target, GLenum access) {
//printf("glMapBuffer(0x%04X, 0x%04X)\n", target, access);
//printf("glMapBuffer(%s, %s)\n", PrintEnum(target), PrintEnum(access));
if (!buffer_target(target)) {
errorShim(GL_INVALID_ENUM);
return (void*)NULL;
@@ -247,7 +257,7 @@ void *glMapBuffer(GLenum target, GLenum access) {
}
GLboolean glUnmapBuffer(GLenum target) {
//printf("glUnmapBuffer(0x%04X)\n", target);
//printf("glUnmapBuffer(%s)\n", PrintEnum(target));
if (!buffer_target(target)) {
errorShim(GL_INVALID_ENUM);
return GL_FALSE;
@@ -264,7 +274,7 @@ GLboolean glUnmapBuffer(GLenum target) {
}
void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid * data) {
//printf("glGetBufferSubData(0x%04X, %p, %i, %p)\n", target, offset, size, data);
//printf("glGetBufferSubData(%s, %p, %i, %p)\n", PrintEnum(target), offset, size, data);
if (!buffer_target(target)) {
errorShim(GL_INVALID_ENUM);
return;
@@ -278,7 +288,7 @@ void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid
}
void glGetBufferPointerv(GLenum target, GLenum pname, GLvoid ** params) {
//printf("glGetBufferPointerv(0x%04X, 0x%04X, %p)\n", target, pname, params);
//printf("glGetBufferPointerv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(pname), params);
if (!buffer_target(target)) {
errorShim(GL_INVALID_ENUM);
return;
@@ -348,6 +358,9 @@ void glGenVertexArrays(GLsizei n, GLuint *arrays) {
}
void glBindVertexArray(GLuint array) {
//printf("glBindVertexArray(%u)\n", array);
if (state.gl_batch) {
flush();
}
khint_t k;
int ret;
@@ -358,25 +371,10 @@ void glBindVertexArray(GLuint array) {
kh_put(glvao, list, 1, &ret);
kh_del(glvao, list, 1);
}
// check if needs to copy the data to current vao
if ((state.bindedvao!=NULL) && (state.bindedvao->array!=array))
{
memcpy(&state.bindedvao->pointers, &state.pointers, sizeof(pointer_states_t));
state.bindedvao->vertex = state.buffers.vertex;
state.bindedvao->elements = state.buffers.elements;
state.bindedvao->pack = state.buffers.pack;
state.bindedvao->unpack = state.buffers.unpack;
state.bindedvao->secondary_array = state.enable.secondary_array;
state.bindedvao->color_array = state.enable.color_array;
state.bindedvao->normal_array = state.enable.normal_array;
state.bindedvao->vertex_array = state.enable.vertex_array;
memcpy(state.bindedvao->tex_coord_array, state.enable.tex_coord_array, MAX_TEX*sizeof(GLboolean));
}
// if array = 0 => unbind buffer!
if (array == 0) {
// unbind buffer
state.bindedvao = NULL;
state.vao = state.defaultvao;
} else {
// search for an existing buffer
k = kh_get(glvao, list, array);
@@ -386,38 +384,40 @@ void glBindVertexArray(GLuint array) {
glvao = kh_value(list, k) = malloc(sizeof(glvao_t));
// new vao is binded to nothing
memset(glvao, 0, sizeof(glvao_t));
/*
state.vao->vertex = state.defaultvbo;
state.vao->elements = state.defaultvbo;
state.vao->pack = state.defaultvbo;
state.vao->unpack = state.defaultvbo;
*/
// just put is number
glvao->array = array;
} else {
glvao = kh_value(list, k);
}
state.bindedvao = glvao;
memcpy(&state.pointers, &glvao->pointers, sizeof(pointer_states_t));
state.buffers.vertex = glvao->vertex;
state.buffers.elements = glvao->elements;
state.buffers.pack = glvao->pack;
state.buffers.unpack = glvao->unpack;
state.enable.secondary_array = glvao->secondary_array;
state.enable.color_array = glvao->color_array;
state.enable.normal_array = glvao->normal_array;
state.enable.vertex_array = glvao->vertex_array;
memcpy(state.enable.tex_coord_array, glvao->tex_coord_array, MAX_TEX*sizeof(GLboolean));
state.vao = glvao;
}
noerrorShim();
}
void glDeleteVertexArrays(GLsizei n, const GLuint *arrays) {
//printf("glDeleteVertexArrays(%i, %p)\n", n, arrays);
if (state.gl_batch) {
flush();
}
khash_t(glvao) *list = state.vaos;
if (list) {
khint_t k;
glvao_t *glvao;
for (int i = 0; i < n; i++) {
GLuint t = arrays[i];
k = kh_get(glvao, list, t);
if (k != kh_end(list)) {
glvao = kh_value(list, k);
kh_del(glvao, list, k);
free(glvao);
if (t) { // don't allow to remove the default one
k = kh_get(glvao, list, t);
if (k != kh_end(list)) {
glvao = kh_value(list, k);
kh_del(glvao, list, k);
free(glvao);
}
}
}
}

View File

@@ -122,6 +122,7 @@
// pixel formats
#define GL_RED 0x1903
#define GL_R3_G3_B2 0x2A10
#define GL_RG 0x8227
#define GL_BGR 0x80E0
#define GL_BGRA 0x80E1
@@ -140,7 +141,21 @@
#define GL_RGB8 0x8051
#define GL_RGB5 0x8050
#define GL_RGBA8 0x8058
#define GL_LUMINANCE8_ALPHA8 0x8045
#define GL_RGBA16 0x805B
#define GL_LUMINANCE8 0x8040
#define GL_LUMINANCE16 0x8042
#define GL_ALPHA8 0x803C
#define GL_LUMINANCE4_ALPHA4 0x8043
#define GL_RGB10_A2 0x8059
#define GL_RGBA16F 0x881A
#define GL_RGB16F 0x881B
#define GL_RGBA32F 0x8814
#define GL_RGB32F 0x8815
#define GL_LUMINANCE16_ALPHA16 0x8048
#define GL_RGB16 0x8054
#define GL_RGBA4 0x8056
#define GL_RGB5_A1 0x8057
// types
#define GL_BYTE 0x1400
#define GL_UNSIGNED_BYTE 0x1401
@@ -252,8 +267,11 @@
#define GL_UNPACK_SKIP_PIXELS 0x0CF4
#define GL_UNPACK_SKIP_ROWS 0x0CF3
#define GL_UNPACK_SWAP_BYTES 0x0CF0
#define GL_UNPACK_IMAGE_HEIGHT 0x806E
#define GL_PACK_IMAGE_HEIGHT 0x806C
#define GL_ZOOM_X 0x0D16
#define GL_ZOOM_Y 0x0D17
#define GL_TEXTURE_BASE_LEVEL 0x813C
// blending
#define GL_BLEND 0x0BE2

View File

@@ -20,14 +20,36 @@ const char* PrintEnum(GLenum what) {
p(GL_DRAW_FRAMEBUFFER);
// format
p(GL_RED);
p(GL_R3_G3_B2);
p(GL_RGB);
p(GL_RGBA);
p(GL_RGBA8);
p(GL_BGR);
p(GL_RGB8);
p(GL_RGB5);
p(GL_RGB16);
p(GL_RGB16F);
p(GL_RGB32F);
p(GL_BGRA);
p(GL_RGBA);
p(GL_RGBA4);
p(GL_RGB5_A1);
p(GL_RGB10_A2);
p(GL_RGBA8);
p(GL_RGBA16);
p(GL_RGBA16F);
p(GL_RGBA32F);
p(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
p(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
p(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
p(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
p(GL_LUMINANCE8_ALPHA8);
p(GL_LUMINANCE_ALPHA);
p(GL_LUMINANCE4_ALPHA4);
p(GL_LUMINANCE16_ALPHA16);
p(GL_LUMINANCE);
p(GL_ALPHA);
p(GL_LUMINANCE8);
p(GL_LUMINANCE16);
p(GL_ALPHA8);
// type
p(GL_UNSIGNED_BYTE);
p(GL_UNSIGNED_BYTE_2_3_3_REV);
@@ -52,6 +74,13 @@ const char* PrintEnum(GLenum what) {
p(GL_COLOR_ATTACHMENT4);
p(GL_DEPTH_ATTACHMENT);
p(GL_STENCIL_ATTACHMENT);
// VBO
p(GL_STATIC_DRAW);
p(GL_READ_WRITE);
p(GL_ARRAY_BUFFER);
p(GL_ELEMENT_ARRAY_BUFFER);
p(GL_PIXEL_PACK_BUFFER);
p(GL_PIXEL_UNPACK_BUFFER);
default:
sprintf(fallback, "0x%04X", what);
}

View File

@@ -581,13 +581,31 @@ void blitMainFBO() {
glDisable(GL_BLEND);
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
if(!state.clientstate.vertex_array) {
gles_glEnableClientState(GL_VERTEX_ARRAY);
state.clientstate.vertex_array = 1;
}
gles_glVertexPointer(2, GL_FLOAT, 0, vert);
if(!state.clientstate.tex_coord_array[0]) {
gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
state.clientstate.tex_coord_array[0] = 1;
}
gles_glTexCoordPointer(2, GL_FLOAT, 0, tex);
for (int a=1; a <MAX_TEX; a++)
if(state.clientstate.tex_coord_array[a]) {
glClientActiveTexture(GL_TEXTURE0 + a);
gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
state.clientstate.tex_coord_array[a] = 0;
}
if(state.clientstate.color_array) {
gles_glDisableClientState(GL_COLOR_ARRAY);
state.clientstate.color_array = 0;
}
if(state.clientstate.normal_array) {
gles_glDisableClientState(GL_NORMAL_ARRAY);
state.clientstate.normal_array = 0;
}
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

View File

@@ -42,6 +42,44 @@ void initialize_glshim() {
state.last_error = GL_NO_ERROR;
state.normal[3] = 1.0f; // default normal is 0/0/1
// add default VBO
{
khint_t k;
int ret;
khash_t(buff) *list = state.buffers;
if (! list) {
list = state.buffers = kh_init(buff);
}
k = kh_put(buff, list, 0, &ret);
glbuffer_t *buff = kh_value(list, k) = malloc(sizeof(glbuffer_t));
buff->buffer = 0;
buff->type = 0;
buff->data = NULL;
buff->usage = GL_STATIC_DRAW;
buff->size = 0;
buff->access = GL_READ_WRITE;
buff->mapped = 0;
state.defaultvbo = buff;
}
// add default VAO
{
khint_t k;
int ret;
khash_t(glvao) *list = state.vaos;
if (! list) {
list = state.vaos = kh_init(glvao);
}
k = kh_put(glvao, list, 0, &ret);
glvao_t *glvao = kh_value(list, k) = malloc(sizeof(glvao_t));
// new vao is binded to default vbo
memset(glvao, 0, sizeof(glvao_t));
// just put is number
glvao->array = 0;
state.defaultvao = glvao;
}
// Bind defaults...
state.vao = state.defaultvao;
// init read hack
char *env_readhack = getenv("LIBGL_READHACK");
if (env_readhack && strcmp(env_readhack, "1") == 0) {
@@ -183,6 +221,9 @@ void glGetIntegerv(GLenum pname, GLint *params) {
case GL_UNPACK_LSB_FIRST:
*params = state.texture.unpack_lsb_first;
break;
case GL_UNPACK_IMAGE_HEIGHT:
*params = state.texture.unpack_image_height;
break;
case GL_PACK_ROW_LENGTH:
*params = state.texture.pack_row_length;
break;
@@ -195,6 +236,9 @@ void glGetIntegerv(GLenum pname, GLint *params) {
case GL_PACK_LSB_FIRST:
*params = state.texture.pack_lsb_first;
break;
case GL_PACK_IMAGE_HEIGHT:
*params = state.texture.pack_image_height;
break;
case GL_UNPACK_SWAP_BYTES:
case GL_PACK_SWAP_BYTES:
//Fake, *TODO* ?
@@ -253,16 +297,16 @@ void glGetIntegerv(GLenum pname, GLint *params) {
*params=64; // fake, no limit in fact
break;
case GL_ARRAY_BUFFER_BINDING:
*params=(state.buffers.vertex)?state.buffers.vertex->buffer:0;
*params=(state.vao->vertex)?state.vao->vertex->buffer:0;
break;
case GL_ELEMENT_ARRAY_BUFFER_BINDING:
*params=(state.buffers.elements)?state.buffers.elements->buffer:0;
*params=(state.vao->elements)?state.vao->elements->buffer:0;
break;
case GL_PIXEL_PACK_BUFFER_BINDING:
*params=(state.buffers.pack)?state.buffers.pack->buffer:0;
*params=(state.vao->pack)?state.vao->pack->buffer:0;
break;
case GL_PIXEL_UNPACK_BUFFER_BINDING:
*params=(state.buffers.unpack)?state.buffers.unpack->buffer:0;
*params=(state.vao->unpack)?state.vao->unpack->buffer:0;
break;
default:
errorGL();
@@ -364,16 +408,16 @@ void glGetFloatv(GLenum pname, GLfloat *params) {
*params=64; // fake, no limit in fact
break;
case GL_ARRAY_BUFFER_BINDING:
*params=(state.buffers.vertex)?state.buffers.vertex->buffer:0;
*params=(state.vao->vertex)?state.vao->vertex->buffer:0;
break;
case GL_ELEMENT_ARRAY_BUFFER_BINDING:
*params=(state.buffers.elements)?state.buffers.elements->buffer:0;
*params=(state.vao->elements)?state.vao->elements->buffer:0;
break;
case GL_PIXEL_PACK_BUFFER_BINDING:
*params=(state.buffers.pack)?state.buffers.pack->buffer:0;
*params=(state.vao->pack)?state.vao->pack->buffer:0;
break;
case GL_PIXEL_UNPACK_BUFFER_BINDING:
*params=(state.buffers.unpack)?state.buffers.unpack->buffer:0;
*params=(state.vao->unpack)?state.vao->unpack->buffer:0;
break;
case GL_TRANSPOSE_PROJECTION_MATRIX:
gles_glGetFloatv(GL_PROJECTION_MATRIX, params);
@@ -405,6 +449,10 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) {
case constant: state.enable.name = enable; next(cap); break
#define enable(constant, name) \
case constant: state.enable.name = enable; break;
#define proxy_clientenable(constant, name) \
case constant: state.vao->name = enable; next(cap); break
#define clientenable(constant, name) \
case constant: state.vao->name = enable; break;
// TODO: maybe could be weird behavior if someone tried to:
// 1. enable GL_TEXTURE_1D
@@ -434,13 +482,13 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) {
// Secondary color
enable(GL_COLOR_SUM, color_sum);
enable(GL_SECONDARY_COLOR_ARRAY, secondary_array);
clientenable(GL_SECONDARY_COLOR_ARRAY, secondary_array);
// for glDrawArrays
proxy_enable(GL_VERTEX_ARRAY, vertex_array);
proxy_enable(GL_NORMAL_ARRAY, normal_array);
proxy_enable(GL_COLOR_ARRAY, color_array);
proxy_enable(GL_TEXTURE_COORD_ARRAY, tex_coord_array[state.texture.client]);
clientenable(GL_VERTEX_ARRAY, vertex_array);
clientenable(GL_NORMAL_ARRAY, normal_array);
clientenable(GL_COLOR_ARRAY, color_array);
clientenable(GL_TEXTURE_COORD_ARRAY, tex_coord_array[state.texture.client]);
// Texture 1D and 3D
enable(GL_TEXTURE_1D, texture_1d[state.texture.active]);
@@ -450,6 +498,8 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) {
}
#undef proxy_enable
#undef enable
#undef proxy_clientenable
#undef clientenable
}
void glEnable(GLenum cap) {
@@ -518,7 +568,6 @@ void glDisable(GLenum cap) {
proxy_glEnable(cap, false, gles_glDisable);
}
#ifndef USE_ES2
void glEnableClientState(GLenum cap) {
LOAD_GLES(glEnableClientState);
proxy_glEnable(cap, true, gles_glEnableClientState);
@@ -528,10 +577,11 @@ void glDisableClientState(GLenum cap) {
LOAD_GLES(glDisableClientState);
proxy_glEnable(cap, false, gles_glDisableClientState);
}
#endif
#define isenabled(what, where) \
case what: return state.enable.where
#define clientisenabled(what, where) \
case what: return state.vao->where
GLboolean glIsEnabled(GLenum cap) {
// should flush for now... to be optimized later!
@@ -545,19 +595,20 @@ GLboolean glIsEnabled(GLenum cap) {
isenabled(GL_TEXTURE_GEN_T, texgen_t[state.texture.active]);
isenabled(GL_TEXTURE_GEN_R, texgen_r[state.texture.active]);
isenabled(GL_COLOR_SUM, color_sum);
isenabled(GL_SECONDARY_COLOR_ARRAY, secondary_array);
clientisenabled(GL_SECONDARY_COLOR_ARRAY, secondary_array);
isenabled(GL_TEXTURE_1D, texture_1d[state.texture.active]);
isenabled(GL_TEXTURE_3D, texture_3d[state.texture.active]);
isenabled(GL_VERTEX_ARRAY, vertex_array);
isenabled(GL_NORMAL_ARRAY, normal_array);
isenabled(GL_COLOR_ARRAY, color_array);
isenabled(GL_TEXTURE_COORD_ARRAY, tex_coord_array[state.texture.client]);
clientisenabled(GL_VERTEX_ARRAY, vertex_array);
clientisenabled(GL_NORMAL_ARRAY, normal_array);
clientisenabled(GL_COLOR_ARRAY, color_array);
clientisenabled(GL_TEXTURE_COORD_ARRAY, tex_coord_array[state.texture.client]);
default:
errorGL();
return gles_glIsEnabled(cap);
}
}
#undef isenabled
#undef clientisenabled
static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
GLsizei skip, GLsizei count) {
@@ -569,21 +620,21 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
list->len = count-skip;
list->cap = count-skip;
if (state.enable.vertex_array) {
list->vert = copy_gl_pointer_raw(&state.pointers.vertex, 3, skip, count, state.pointers.vertex.buffer); //TODO, what if size == 4
if (state.vao->vertex_array) {
list->vert = copy_gl_pointer_raw(&state.vao->pointers.vertex, 3, skip, count, state.vao->pointers.vertex.buffer); //TODO, what if size == 4
}
if (state.enable.color_array) {
list->color = copy_gl_pointer_color(&state.pointers.color, 4, skip, count, state.pointers.color.buffer);
if (state.vao->color_array) {
list->color = copy_gl_pointer_color(&state.vao->pointers.color, 4, skip, count, state.vao->pointers.color.buffer);
}
if (state.enable.secondary_array/* && state.enable.color_array*/) {
list->secondary = copy_gl_pointer(&state.pointers.secondary, 4, skip, count, state.pointers.secondary.buffer); // alpha chanel is always 0 for secondary...
if (state.vao->secondary_array/* && state.enable.color_array*/) {
list->secondary = copy_gl_pointer(&state.vao->pointers.secondary, 4, skip, count, state.vao->pointers.secondary.buffer); // alpha chanel is always 0 for secondary...
}
if (state.enable.normal_array) {
list->normal = copy_gl_pointer_raw(&state.pointers.normal, 3, skip, count, state.pointers.normal.buffer);
if (state.vao->normal_array) {
list->normal = copy_gl_pointer_raw(&state.vao->pointers.normal, 3, skip, count, state.vao->pointers.normal.buffer);
}
for (int i=0; i<MAX_TEX; i++) {
if (state.enable.tex_coord_array[i]) {
list->tex[i] = copy_gl_pointer_raw(&state.pointers.tex_coord[i], 2, skip, count, state.pointers.tex_coord[i].buffer);
if (state.vao->tex_coord_array[i]) {
list->tex[i] = copy_gl_pointer_raw(&state.vao->pointers.tex_coord[i], 2, skip, count, state.vao->pointers.tex_coord[i].buffer);
}
}
@@ -593,7 +644,7 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
static inline bool should_intercept_render(GLenum mode) {
return (
(state.enable.vertex_array && ! valid_vertex_type(state.pointers.vertex.type)) ||
(state.vao->vertex_array && ! valid_vertex_type(state.vao->pointers.vertex.type)) ||
(/*state.enable.texture_2d[0] && */(state.enable.texgen_s[0] || state.enable.texgen_t[0] || state.enable.texgen_r[0])) ||
(/*state.enable.texture_2d[1] && */(state.enable.texgen_s[1] || state.enable.texgen_t[1] || state.enable.texgen_r[1])) ||
(/*state.enable.texture_2d[2] && */(state.enable.texgen_s[2] || state.enable.texgen_t[2] || state.enable.texgen_r[2])) ||
@@ -620,7 +671,7 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic
}
noerrorShim();
GLushort *sindices = copy_gl_array((state.buffers.elements)?state.buffers.elements->data + (uintptr_t)indices:indices,
GLushort *sindices = copy_gl_array((state.vao->elements)?state.vao->elements->data + (uintptr_t)indices:indices,
type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count);
bool compiling = (state.list.active && (state.list.compiling || state.gl_batch));
@@ -659,12 +710,14 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic
LOAD_GLES(glTexCoordPointer);
LOAD_GLES(glEnable);
LOAD_GLES(glDisable);
LOAD_GLES(glEnableClientState);
LOAD_GLES(glDisableClientState);
GLuint len = 0;
for (int i=0; i<count; i++)
if (len<sindices[i]) len = sindices[i]; // get the len of the arrays
len++; // lenght is max(indices) + 1 !
#define shift_pointer(a, b) \
if (state.enable.b && state.pointers.a.buffer) state.pointers.a.pointer += (uintptr_t)state.pointers.a.buffer->data;
if (state.vao->b && state.vao->pointers.a.buffer) state.vao->pointers.a.pointer += (uintptr_t)state.vao->pointers.a.buffer->data;
shift_pointer(color, color_array);
shift_pointer(secondary, secondary_array);
@@ -672,7 +725,16 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic
for (int aa=0; aa<MAX_TEX; aa++)
shift_pointer(tex_coord[aa], tex_coord_array[aa]);
shift_pointer(normal, normal_array);
#undef shift_pointer
#undef shift_pointer
#define client_state(A, B, C) \
if(state.vao->A != state.clientstate.A) { \
C \
if((state.clientstate.A = state.vao->A)==true) \
gles_glEnableClientState(B); \
else \
gles_glDisableClientState(B); \
}
GLenum mode_init = mode;
@@ -686,44 +748,47 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic
if (mode == GL_POLYGON)
mode = GL_TRIANGLE_FAN;
if (state.render_mode == GL_SELECT) {
select_glDrawElements(&state.pointers.vertex, mode, count, GL_UNSIGNED_SHORT, sindices);
select_glDrawElements(&state.vao->pointers.vertex, mode, count, GL_UNSIGNED_SHORT, sindices);
} else {
// secondary color...
GLfloat *final_colors = NULL;
pointer_state_t old_color;
if (/*state.enable.color_sum && */(state.enable.secondary_array) && (state.enable.color_array)) {
final_colors=copy_gl_pointer_color(&state.pointers.color, 4, 0, len, 0);
GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&state.pointers.secondary, 4, 0, len, 0);
client_state(color_array, GL_COLOR_ARRAY, );
if (/*state.enable.color_sum && */(state.vao->secondary_array) && (state.vao->color_array)) {
final_colors=copy_gl_pointer_color(&state.vao->pointers.color, 4, 0, len, 0);
GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&state.vao->pointers.secondary, 4, 0, len, 0);
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 (state.enable.color_array && (state.pointers.color.size != 4)) {
} else if (state.vao->color_array && (state.vao->pointers.color.size != 4)) {
// Pandora doesn't like Color Pointer with size != 4
if(state.pointers.color.type == GL_UNSIGNED_BYTE) {
final_colors=copy_gl_pointer_bytecolor(&state.pointers.color, 4, 0, len, 0);
if(state.vao->pointers.color.type == GL_UNSIGNED_BYTE) {
final_colors=copy_gl_pointer_bytecolor(&state.vao->pointers.color, 4, 0, len, 0);
gles_glColorPointer(4, GL_UNSIGNED_BYTE, 0, final_colors);
} else {
final_colors=copy_gl_pointer_color(&state.pointers.color, 4, 0, len, 0);
final_colors=copy_gl_pointer_color(&state.vao->pointers.color, 4, 0, len, 0);
gles_glColorPointer(4, GL_FLOAT, 0, final_colors);
}
} else if (state.enable.color_array)
gles_glColorPointer(state.pointers.color.size, state.pointers.color.type, state.pointers.color.stride, state.pointers.color.pointer);
if (state.enable.normal_array)
gles_glNormalPointer(state.pointers.normal.type, state.pointers.normal.stride, state.pointers.normal.pointer);
if (state.enable.vertex_array)
gles_glVertexPointer(state.pointers.vertex.size, state.pointers.vertex.type, state.pointers.vertex.stride, state.pointers.vertex.pointer);
} else if (state.vao->color_array)
gles_glColorPointer(state.vao->pointers.color.size, state.vao->pointers.color.type, state.vao->pointers.color.stride, state.vao->pointers.color.pointer);
client_state(normal_array, GL_NORMAL_ARRAY, );
if (state.vao->normal_array)
gles_glNormalPointer(state.vao->pointers.normal.type, state.vao->pointers.normal.stride, state.vao->pointers.normal.pointer);
client_state(vertex_array, GL_VERTEX_ARRAY, );
if (state.vao->vertex_array)
gles_glVertexPointer(state.vao->pointers.vertex.size, state.vao->pointers.vertex.type, state.vao->pointers.vertex.stride, state.vao->pointers.vertex.pointer);
GLuint old_tex = state.texture.client;
for (int aa=0; aa<MAX_TEX; aa++) {
for (int aa=0; aa<MAX_TEX; aa++)
client_state(tex_coord_array[aa], GL_TEXTURE_COORD_ARRAY, glClientActiveTexture(aa+GL_TEXTURE0););
for (int aa=0; aa<MAX_TEX; aa++) {
if (!state.enable.texture_2d[aa] && (state.enable.texture_1d[aa] || state.enable.texture_3d[aa])) {
glClientActiveTexture(aa+GL_TEXTURE0);
gles_glEnable(GL_TEXTURE_2D);
}
if (state.enable.tex_coord_array[aa]) {
if (state.vao->tex_coord_array[aa]) {
tex_setup_texcoord(aa, len);
/*glClientActiveTexture(aa+GL_TEXTURE0);
gles_glTexCoordPointer(state.pointers.tex_coord[aa].size, state.pointers.tex_coord[aa].type, state.pointers.tex_coord[aa].stride, state.pointers.tex_coord[aa].pointer);*/
}
}
}
if (state.texture.client!=old_tex)
glClientActiveTexture(old_tex+GL_TEXTURE0);
@@ -776,7 +841,7 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic
glClientActiveTexture(old_tex+GL_TEXTURE0);
}
#define shift_pointer(a, b) \
if (state.enable.b && state.pointers.a.buffer) state.pointers.a.pointer -= (uintptr_t)state.pointers.a.buffer->data;
if (state.vao->b && state.vao->pointers.a.buffer) state.vao->pointers.a.pointer -= (uintptr_t)state.vao->pointers.a.buffer->data;
shift_pointer(color, color_array);
shift_pointer(secondary, secondary_array);
@@ -819,6 +884,8 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
LOAD_GLES(glTexCoordPointer);
LOAD_GLES(glEnable);
LOAD_GLES(glDisable);
LOAD_GLES(glEnableClientState);
LOAD_GLES(glDisableClientState);
renderlist_t *list;
if (state.list.active && (state.list.compiling || state.gl_batch)) {
@@ -843,7 +910,7 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
LOAD_GLES(glDrawArrays);
#define shift_pointer(a, b) \
if (state.enable.b && state.pointers.a.buffer) state.pointers.a.pointer = state.pointers.a.buffer->data + (uintptr_t)state.pointers.a.pointer;
if (state.vao->b && state.vao->pointers.a.buffer) state.vao->pointers.a.pointer = state.vao->pointers.a.buffer->data + (uintptr_t)state.vao->pointers.a.pointer;
shift_pointer(color, color_array);
shift_pointer(secondary, secondary_array);
@@ -861,41 +928,46 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
mode = GL_TRIANGLE_FAN;
if (state.render_mode == GL_SELECT) {
select_glDrawArrays(&state.pointers.vertex, mode, first, count);
select_glDrawArrays(&state.vao->pointers.vertex, mode, first, count);
} else {
// setup the Array Pointers
// secondary color...
GLfloat *final_colors = NULL;
if (/*state.enable.color_sum && */(state.enable.secondary_array) && (state.enable.color_array)) {
final_colors=copy_gl_pointer_color(&state.pointers.color, 4, 0, count+first, 0);
GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&state.pointers.secondary, 4, first, count+first, 0);
client_state(color_array, GL_COLOR_ARRAY, );
if (/*state.enable.color_sum && */(state.vao->secondary_array) && (state.vao->color_array)) {
final_colors=copy_gl_pointer_color(&state.vao->pointers.color, 4, 0, count+first, 0);
GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&state.vao->pointers.secondary, 4, first, count+first, 0);
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 ((state.enable.color_array && (state.pointers.color.size != 4))
|| (state.enable.color_array && (state.pointers.color.stride!=0) && (state.pointers.color.type != GL_FLOAT))) {
} else if ((state.vao->color_array && (state.vao->pointers.color.size != 4))
|| (state.vao->color_array && (state.vao->pointers.color.stride!=0) && (state.vao->pointers.color.type != GL_FLOAT))) {
// Pandora doesn't like Color Pointer with size != 4
if(state.pointers.color.type == GL_UNSIGNED_BYTE) {
final_colors=copy_gl_pointer_bytecolor(&state.pointers.color, 4, 0, count+first, 0);
if(state.vao->pointers.color.type == GL_UNSIGNED_BYTE) {
final_colors=copy_gl_pointer_bytecolor(&state.vao->pointers.color, 4, 0, count+first, 0);
gles_glColorPointer(4, GL_UNSIGNED_BYTE, 0, final_colors);
} else {
final_colors=copy_gl_pointer_color(&state.pointers.color, 4, 0, count+first, 0);
final_colors=copy_gl_pointer_color(&state.vao->pointers.color, 4, 0, count+first, 0);
gles_glColorPointer(4, GL_FLOAT, 0, final_colors);
}
} else if (state.enable.color_array)
gles_glColorPointer(state.pointers.color.size, state.pointers.color.type, state.pointers.color.stride, state.pointers.color.pointer);
if (state.enable.normal_array)
gles_glNormalPointer(state.pointers.normal.type, state.pointers.normal.stride, state.pointers.normal.pointer);
if (state.enable.vertex_array)
gles_glVertexPointer(state.pointers.vertex.size, state.pointers.vertex.type, state.pointers.vertex.stride, state.pointers.vertex.pointer);
} else if (state.vao->color_array)
gles_glColorPointer(state.vao->pointers.color.size, state.vao->pointers.color.type, state.vao->pointers.color.stride, state.vao->pointers.color.pointer);
client_state(normal_array, GL_NORMAL_ARRAY, );
if (state.vao->normal_array)
gles_glNormalPointer(state.vao->pointers.normal.type, state.vao->pointers.normal.stride, state.vao->pointers.normal.pointer);
client_state(vertex_array, GL_VERTEX_ARRAY, );
if (state.vao->vertex_array)
gles_glVertexPointer(state.vao->pointers.vertex.size, state.vao->pointers.vertex.type, state.vao->pointers.vertex.stride, state.vao->pointers.vertex.pointer);
GLuint old_tex = state.texture.client;
for (int aa=0; aa<MAX_TEX; aa++) {
for (int aa=0; aa<MAX_TEX; aa++)
client_state(tex_coord_array[aa], GL_TEXTURE_COORD_ARRAY, glClientActiveTexture(aa+GL_TEXTURE0););
for (int aa=0; aa<MAX_TEX; aa++) {
if (!state.enable.texture_2d[aa] && (state.enable.texture_1d[aa] || state.enable.texture_3d[aa])) {
glClientActiveTexture(aa+GL_TEXTURE0);
gles_glEnable(GL_TEXTURE_2D);
}
if (state.enable.tex_coord_array[aa]) {
if (state.vao->tex_coord_array[aa]) {
tex_setup_texcoord(aa, count+first);
/*glClientActiveTexture(aa+GL_TEXTURE0);
gles_glTexCoordPointer(state.pointers.tex_coord[aa].size, state.pointers.tex_coord[aa].type, state.pointers.tex_coord[aa].stride, state.pointers.tex_coord[aa].pointer);*/
@@ -950,7 +1022,7 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
if (state.texture.client!=old_tex)
glClientActiveTexture(old_tex+GL_TEXTURE0);
#define shift_pointer(a, b) \
if (state.enable.b && state.pointers.a.buffer) state.pointers.a.pointer = state.pointers.a.pointer - (uintptr_t)state.pointers.a.buffer->data;
if (state.vao->b && state.vao->pointers.a.buffer) state.vao->pointers.a.pointer = state.vao->pointers.a.pointer - (uintptr_t)state.vao->pointers.a.buffer->data;
shift_pointer(color, color_array);
shift_pointer(secondary, secondary_array);
@@ -962,34 +1034,35 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
}
}
}
#undef client_state
#ifndef USE_ES2
#define clone_gl_pointer(t, s)\
t.size = s; t.type = type; t.stride = stride; t.pointer = pointer; t.buffer = state.buffers.vertex
t.size = s; t.type = type; t.stride = stride; t.pointer = pointer; t.buffer = state.vao->vertex
void glVertexPointer(GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer) {
noerrorShim();
clone_gl_pointer(state.pointers.vertex, size);
clone_gl_pointer(state.vao->pointers.vertex, size);
}
void glColorPointer(GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer) {
noerrorShim();
clone_gl_pointer(state.pointers.color, size);
clone_gl_pointer(state.vao->pointers.color, size);
}
void glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) {
noerrorShim();
clone_gl_pointer(state.pointers.normal, 3);
clone_gl_pointer(state.vao->pointers.normal, 3);
}
void glTexCoordPointer(GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer) {
noerrorShim();
clone_gl_pointer(state.pointers.tex_coord[state.texture.client], size);
clone_gl_pointer(state.vao->pointers.tex_coord[state.texture.client], size);
}
void glSecondaryColorPointer(GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer) {
if (size!=3)
return; // Size must be 3...
clone_gl_pointer(state.pointers.secondary, size);
clone_gl_pointer(state.vao->pointers.secondary, size);
noerrorShim();
}
@@ -1240,8 +1313,8 @@ void glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) {
void glArrayElement(GLint i) {
GLfloat *v;
pointer_state_t *p;
p = &state.pointers.color;
if (state.enable.color_array) {
p = &state.vao->pointers.color;
if (state.vao->color_array) {
v = gl_pointer_index(p, i);
GLfloat scale = gl_max_value(p->type);
// color[3] defaults to 1.0f
@@ -1254,8 +1327,8 @@ void glArrayElement(GLint i) {
}
glColor4fv(v);
}
p = &state.pointers.secondary;
if (state.enable.secondary_array) {
p = &state.vao->pointers.secondary;
if (state.vao->secondary_array) {
v = gl_pointer_index(p, i);
GLfloat scale = gl_max_value(p->type);
// color[3] defaults to 0.0f
@@ -1268,26 +1341,26 @@ void glArrayElement(GLint i) {
}
glSecondaryColor3fv(v);
}
p = &state.pointers.normal;
if (state.enable.normal_array) {
p = &state.vao->pointers.normal;
if (state.vao->normal_array) {
v = gl_pointer_index(p, i);
glNormal3fv(v);
}
p = &state.pointers.tex_coord[0];
if (state.enable.tex_coord_array[0]) {
p = &state.vao->pointers.tex_coord[0];
if (state.vao->tex_coord_array[0]) {
v = gl_pointer_index(p, i);
glTexCoord2fv(v);
}
int a;
for (a=1; a<MAX_TEX; a++) {
p = &state.pointers.tex_coord[a];
if (state.enable.tex_coord_array[a]) {
p = &state.vao->pointers.tex_coord[a];
if (state.vao->tex_coord_array[a]) {
v = gl_pointer_index(p, i);
glMultiTexCoord2fv(GL_TEXTURE0+a, v);
}
}
p = &state.pointers.vertex;
if (state.enable.vertex_array) {
p = &state.vao->pointers.vertex;
if (state.vao->vertex_array) {
v = gl_pointer_index(p, i);
if (p->size == 4) {
glVertex4fv(v);
@@ -1797,7 +1870,7 @@ void glGetPointerv(GLenum pname, GLvoid* *params) {
noerrorShim();
switch(pname) {
case GL_COLOR_ARRAY_POINTER:
*params = state.pointers.color.pointer;
*params = (void*)state.vao->pointers.color.pointer;
break;
case GL_EDGE_FLAG_ARRAY_POINTER:
*params = NULL;
@@ -1808,16 +1881,16 @@ void glGetPointerv(GLenum pname, GLvoid* *params) {
case GL_INDEX_ARRAY_POINTER:
*params = NULL;
case GL_NORMAL_ARRAY_POINTER:
*params = state.pointers.normal.pointer;
*params = (void*)state.vao->pointers.normal.pointer;
break;
case GL_TEXTURE_COORD_ARRAY_POINTER:
*params = state.pointers.tex_coord[state.texture.client].pointer;
*params = (void*)state.vao->pointers.tex_coord[state.texture.client].pointer;
break;
case GL_SELECTION_BUFFER_POINTER:
*params = state.selectbuf.buffer;
break;
case GL_VERTEX_ARRAY_POINTER :
*params = state.pointers.vertex.pointer;
*params = (void*)state.vao->pointers.vertex.pointer;
break;
default:
errorShim(GL_INVALID_ENUM);

View File

@@ -385,6 +385,7 @@ static const GLsizei pixel_sizeof(GLenum format, GLenum type) {
static const GLboolean pixel_hasalpha(GLenum format) {
switch (format) {
case GL_ALPHA:
case GL_LUMINANCE_ALPHA:
case GL_RGBA:
case GL_BGRA:
case GL_RGBA8:

View File

@@ -643,6 +643,8 @@ void draw_renderlist(renderlist_t *list) {
#endif
LOAD_GLES(glEnable);
LOAD_GLES(glDisable);
LOAD_GLES(glEnableClientState);
LOAD_GLES(glDisableClientState);
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
GLfloat *final_colors;
@@ -754,24 +756,29 @@ void draw_renderlist(renderlist_t *list) {
gles_glDrawArrays(list->mode, 0, list->len);
#else
if (list->vert) {
glEnableClientState(GL_VERTEX_ARRAY);
gles_glEnableClientState(GL_VERTEX_ARRAY);
gles_glVertexPointer(3, GL_FLOAT, 0, list->vert);
state.clientstate.vertex_array = 1;
} else {
glDisableClientState(GL_VERTEX_ARRAY);
gles_glDisableClientState(GL_VERTEX_ARRAY);
state.clientstate.vertex_array = false;
}
if (list->normal) {
glEnableClientState(GL_NORMAL_ARRAY);
gles_glEnableClientState(GL_NORMAL_ARRAY);
gles_glNormalPointer(GL_FLOAT, 0, list->normal);
state.clientstate.normal_array = 1;
} else {
glDisableClientState(GL_NORMAL_ARRAY);
gles_glDisableClientState(GL_NORMAL_ARRAY);
state.clientstate.normal_array = 0;
}
indices = list->indices;
final_colors = NULL;
if (list->color) {
glEnableClientState(GL_COLOR_ARRAY);
gles_glEnableClientState(GL_COLOR_ARRAY);
state.clientstate.color_array = 1;
if (state.enable.color_sum && (list->secondary)) {
final_colors=(GLfloat*)malloc(list->len * 4 * sizeof(GLfloat));
if (indices) {
@@ -788,7 +795,8 @@ void draw_renderlist(renderlist_t *list) {
} else
gles_glColorPointer(4, GL_FLOAT, 0, list->color);
} else {
glDisableClientState(GL_COLOR_ARRAY);
gles_glDisableClientState(GL_COLOR_ARRAY);
state.clientstate.color_array = 0;
}
GLuint texture;
bool stipple;
@@ -819,13 +827,15 @@ void draw_renderlist(renderlist_t *list) {
for (int a=0; a<MAX_TEX; a++) {
if ((list->tex[a] || texgened[a])/* && state.enable.texture_2d[a]*/) {
glClientActiveTexture(GL_TEXTURE0+a);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
state.clientstate.tex_coord_array[a] = 1;
gles_glTexCoordPointer(2, GL_FLOAT, 0, (texgened[a])?texgened[a]:list->tex[a]);
} else {
if (state.enable.tex_coord_array[a]) {
glClientActiveTexture(GL_TEXTURE0+a);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (state.clientstate.tex_coord_array[a]) {
glClientActiveTexture(GL_TEXTURE0+a);
gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
state.clientstate.tex_coord_array[a] = 0;
}
//else if (!state.enable.texgen_s[a] && state.enable.texture_2d[a]) printf("LIBGL: texture_2d[%i] without TexCoord, mode=0x%04X (init=0x%04X), listlen=%i\n", a, list->mode, list->mode_init, list->len);
}

View File

@@ -1,4 +1,5 @@
#include "pixel.h"
#include "debug.h"
static const colorlayout_t *get_color_map(GLenum format) {
#define map(fmt, ...) \
@@ -79,7 +80,7 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst,
};
read_each(, / 31.0f);
)
type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort,
type_case(GL_UNSIGNED_SHORT_5_6_5_REV, GLushort,
s = (GLushort[]){
(v & 31)*2,
((v & 0x07e0) >> 5),
@@ -87,7 +88,7 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst,
};
read_each(, / 63.0f);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
type_case(GL_UNSIGNED_SHORT_4_4_4_4_REV, GLushort,
s = (GLushort[]){
(v & 0x000f),
((v & 0x00f0) >> 4),
@@ -96,6 +97,32 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst,
};
read_each(, / 15.0f);
)
type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort,
s = (GLushort[]){
((v & 0xF800) >>11)*2,
((v & 0x07e0) >> 5),
((v & 0x0031) )*2,
};
read_each(, / 63.0f);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
s = (GLushort[]){
((v & 0xf000) >>12),
((v & 0x0f00) >> 8),
((v & 0x00f0) >> 4),
((v & 0x000f) )
};
read_each(, / 15.0f);
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
s = (GLushort[]){
((v & 0xf800) >> 11),
((v & 0x07c0) >> 6),
((v & 0x003e) >> 1),
((v & 1))*31,
};
read_each(, / 31.0f);
)
default:
// TODO: add glSetError?
printf("libGL: Unsupported source data type: %04X\n", src_type);
@@ -123,9 +150,9 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst,
color[dst_color->red] = pixel.r;
color[dst_color->green] = pixel.g;
color[dst_color->blue] = pixel.b;
*d = ((GLushort)(color[0] * 31.0) & 0x1f << 11) |
((GLushort)(color[1] * 63.0) & 0x3f << 5) |
((GLushort)(color[2] * 31.0) & 0x1f);
*d = ((GLushort)(color[0] * 31.0f) & 0x1f << 11) |
((GLushort)(color[1] * 63.0f) & 0x3f << 5) |
((GLushort)(color[2] * 31.0f) & 0x1f);
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
GLfloat color[4];
@@ -134,9 +161,9 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst,
color[dst_color->blue] = pixel.b;
color[dst_color->alpha] = pixel.a;
// TODO: can I macro this or something? it follows a pretty strict form.
*d = ((GLuint)(color[0] * 31) & 0x1f << 0) |
((GLuint)(color[1] * 31) & 0x1f << 5) |
((GLuint)(color[2] * 31) & 0x1f << 10) |
*d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) |
((GLuint)(color[1] * 31.0f) & 0x1f << 5) |
((GLuint)(color[2] * 31.0f) & 0x1f << 10) |
((GLuint)(color[3] * 1) & 0x01 << 15);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
@@ -231,6 +258,15 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst,
};
read_each(, / 63.0f);
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
s = (GLushort[]){
((v & 0xf800) >> 11),
((v & 0x07c0) >> 6),
((v & 0x003e) >> 1),
((v & 1))*31,
};
read_each(, / 31.0f);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
s = (GLushort[]){
(v & 0x000f),
@@ -262,9 +298,21 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst,
color[src_color->red] = pixel.r;
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
*d = ((GLuint)(color[2] * 31) & 0x1f << 11) |
((GLuint)(color[1] * 63) & 0x3f << 5) |
((GLuint)(color[0] * 31) & 0x1f);
*d = ((GLuint)(color[2] * 31.0f) & 0x1f << 11) |
((GLuint)(color[1] * 63.0f) & 0x3f << 5) |
((GLuint)(color[0] * 31.0f) & 0x1f);
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
GLfloat color[4];
color[src_color->red] = pixel.r;
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
color[src_color->alpha] = pixel.a;
// TODO: can I macro this or something? it follows a pretty strict form.
*d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) |
((GLuint)(color[1] * 31.0f) & 0x1f << 5) |
((GLuint)(color[2] * 31.0f) & 0x1f << 10) |
((GLuint)(color[3] * 1) & 0x01 << 15);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
GLfloat color[4];
@@ -272,10 +320,10 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst,
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
color[src_color->alpha] = pixel.a;
*d = ((GLushort)(color[3] * 15.0) & 0x0f << 12) |
((GLushort)(color[2] * 15.0) & 0x0f << 8) |
((GLushort)(color[1] * 15.0) & 0x0f << 4) |
((GLushort)(color[0] * 15.0) & 0x0f);
*d = ((GLushort)(color[3] * 15.0f) & 0x0f << 12) |
((GLushort)(color[2] * 15.0f) & 0x0f << 8) |
((GLushort)(color[1] * 15.0f) & 0x0f << 4) |
((GLushort)(color[0] * 15.0f) & 0x0f);
)
default:
printf("libGL: Unsupported target data type: %04X\n", src_type);
@@ -363,13 +411,45 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1,
};
read_each(, / 31.0f);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4_REV, GLushort,
for (int ii=0; ii<4; ii++) {
s[ii] = (GLushort[]) {
((v[ii] & 0x000f) ),
((v[ii] & 0x00f0) >> 4),
((v[ii] & 0x0f00) >> 8),
((v[ii] & 0xf000) >>12)
};
};
read_each(, / 15.0f);
)
type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort,
for (int ii=0; ii<4; ii++) {
s[ii] = (GLushort[]) {
((v[ii] & 0x001f) )*2,
((v[ii] & 0x07e0) >> 5),
((v[ii] & 0xF800) >>11)*2,
};
};
read_each(, / 63.0f);
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
for (int ii=0; ii<4; ii++) {
s[ii] = (GLushort[]) {
((v[ii] & 0xf800) >>11),
((v[ii] & 0x07c0) >> 6),
((v[ii] & 0x003e) >> 1),
((v[ii] & 1) )*31,
};
};
read_each(, / 31.0f);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
for (int ii=0; ii<4; ii++) {
s[ii] = (GLushort[]) {
(v[ii] & 0x000f),
((v[ii] & 0x00f0) >> 4),
((v[ii] & 0xf000) >>12),
((v[ii] & 0x0f00) >> 8),
((v[ii] & 0xf000) >> 12)
((v[ii] & 0x00f0) >> 4),
((v[ii] & 0x000f) )
};
};
read_each(, / 15.0f);
@@ -396,9 +476,21 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1,
color[src_color->red] = pixel.r;
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
*d = ((GLuint)(color[0] * 31) & 0x1f << 11) |
((GLuint)(color[1] * 63) & 0x3f << 5) |
((GLuint)(color[2] * 31) & 0x1f);
*d = ((GLuint)(color[0] * 31.0f) & 0x1f << 11) |
((GLuint)(color[1] * 63.0f) & 0x3f << 5) |
((GLuint)(color[2] * 31.0f) & 0x1f);
)
type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort,
GLfloat color[4];
color[src_color->red] = pixel.r;
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
color[src_color->alpha] = pixel.a;
// TODO: can I macro this or something? it follows a pretty strict form.
*d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) |
((GLuint)(color[1] * 31.0f) & 0x1f << 5) |
((GLuint)(color[2] * 31.0f) & 0x1f << 10) |
((GLuint)(color[3] * 1) & 0x01 << 15);
)
type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort,
GLfloat color[4];
@@ -406,10 +498,10 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1,
color[src_color->green] = pixel.g;
color[src_color->blue] = pixel.b;
color[src_color->alpha] = pixel.a;
*d = ((GLushort)(color[0] * 15.0) & 0x0f << 12) |
((GLushort)(color[1] * 15.0) & 0x0f << 8) |
((GLushort)(color[2] * 15.0) & 0x0f << 4) |
((GLushort)(color[3] * 15.0) & 0x0f);
*d = ((GLushort)(color[0] * 15.0f) & 0x0f << 12) |
((GLushort)(color[1] * 15.0f) & 0x0f << 8) |
((GLushort)(color[2] * 15.0f) & 0x0f << 4) |
((GLushort)(color[3] * 15.0f) & 0x0f);
)
default:
printf("libGL: half_pixel: Unsupported target data type: %04X\n", src_type);
@@ -576,16 +668,18 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
GLuint pixels = width * height;
GLuint dst_size = pixels * pixel_sizeof(dst_format, dst_type);
GLuint dst_width = ((stride?stride:width) - width) * pixel_sizeof(dst_format, dst_type);
GLuint src_width = width * pixel_sizeof(dst_format, dst_type);
GLuint src_width = width * pixel_sizeof(src_format, src_type);
//printf("pixel conversion: %ix%i - %04x, %04x -> %04x, %04x, transform=%i\n", width, height, src_format, src_type, dst_format, dst_type, raster_need_transform());
//printf("pixel conversion: %ix%i - %s, %s (%d) ==> %s, %s (%d), transform=%i\n", width, height, PrintEnum(src_format), PrintEnum(src_type),pixel_sizeof(src_format, src_type), PrintEnum(dst_format), PrintEnum(dst_type), pixel_sizeof(dst_format, dst_type), raster_need_transform());
src_color = get_color_map(src_format);
dst_color = get_color_map(dst_format);
if (!dst_size || !pixel_sizeof(src_format, src_type)
|| !src_color->type || !dst_color->type)
|| !src_color->type || !dst_color->type) {
printf("pixel conversion, anticipated abort\n");
return false;
}
if (src_type == dst_type && src_color->type == dst_color->type) {
if ((src_type == dst_type) && (src_color->type == dst_color->type)) {
if (*dst == src)
return true;
if (*dst == NULL) // alloc dst only if dst==NULL
@@ -618,6 +712,35 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
}
return true;
}
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++) {
for (int j = 0; j < width; j++) {
tmp = *(const GLuint*)src_pos;
*(GLushort*)dst_pos = (tmp&0x0000ff00) | (tmp&0x000000ff);
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
}
return true;
}
if ((src_format == GL_BGR) && (dst_format == GL_RGB) && (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++) {
((char*)dst_pos)[0] = ((char*)src_pos)[2];
((char*)dst_pos)[1] = ((char*)src_pos)[1];
((char*)dst_pos)[2] = ((char*)src_pos)[0];
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
}
return true;
}
if ((src_format == GL_RGB) && (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))) {
GLuint tmp;
for (int i = 0; i < height; i++) {

View File

@@ -425,12 +425,30 @@ void render_raster_list(rasterlist_t* rast) {
gles_glBindTexture(GL_TEXTURE_2D, rast->texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
gles_glEnableClientState(GL_VERTEX_ARRAY);
gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
gles_glDisableClientState(GL_COLOR_ARRAY);
gles_glDisableClientState(GL_NORMAL_ARRAY);
if(!state.clientstate.vertex_array) {
gles_glEnableClientState(GL_VERTEX_ARRAY);
state.clientstate.vertex_array = 1;
}
gles_glVertexPointer(3, GL_FLOAT, 0, vert);
if(!state.clientstate.tex_coord_array[0]) {
gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
state.clientstate.tex_coord_array[0] = 1;
}
gles_glTexCoordPointer(2, GL_FLOAT, 0, tex);
for (int a=1; a <MAX_TEX; a++)
if(state.clientstate.tex_coord_array[a]) {
glClientActiveTexture(GL_TEXTURE0 + a);
gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
state.clientstate.tex_coord_array[a] = 0;
}
if(state.clientstate.color_array) {
gles_glDisableClientState(GL_COLOR_ARRAY);
state.clientstate.color_array = 0;
}
if(state.clientstate.normal_array) {
gles_glDisableClientState(GL_NORMAL_ARRAY);
state.clientstate.normal_array = 0;
}
//glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

View File

@@ -282,15 +282,15 @@ void glPushClientAttrib(GLbitfield mask) {
}
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
cur->vert_enable = state.enable.vertex_array;
cur->color_enable = state.enable.color_array;
cur->secondary_enable = state.enable.secondary_array;
cur->normal_enable = state.enable.normal_array;
cur->vert_enable = state.vao->vertex_array;
cur->color_enable = state.vao->color_array;
cur->secondary_enable = state.vao->secondary_array;
cur->normal_enable = state.vao->normal_array;
int a;
for (a=0; a<MAX_TEX; a++) {
cur->tex_enable[a] = state.enable.tex_coord_array[a];
cur->tex_enable[a] = state.vao->tex_coord_array[a];
}
memcpy(&(cur->pointers), &state.pointers, sizeof(pointer_states_t));
memcpy(&(cur->pointers), &state.vao->pointers, sizeof(pointer_states_t));
cur->client = state.texture.client;
}
@@ -555,22 +555,22 @@ void glPopClientAttrib() {
}
if (cur->mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
if (state.enable.vertex_array != cur->vert_enable)
if (state.vao->vertex_array != cur->vert_enable)
enable_disable(GL_VERTEX_ARRAY, cur->vert_enable);
if (state.enable.normal_array != cur->normal_enable)
if (state.vao->normal_array != cur->normal_enable)
enable_disable(GL_NORMAL_ARRAY, cur->normal_enable);
if (state.enable.color_array != cur->color_enable)
if (state.vao->color_array != cur->color_enable)
enable_disable(GL_COLOR_ARRAY, cur->color_enable);
if (state.enable.secondary_array != cur->secondary_enable)
if (state.vao->secondary_array != cur->secondary_enable)
enable_disable(GL_SECONDARY_COLOR_ARRAY, cur->secondary_enable);
for (int a=0; a<MAX_TEX; a++) {
if (state.enable.tex_coord_array[a] != cur->tex_enable[a]) {
if (state.vao->tex_coord_array[a] != cur->tex_enable[a]) {
glClientActiveTexture(GL_TEXTURE0+a);
enable_disable(GL_TEXTURE_COORD_ARRAY, cur->tex_enable[a]);
}
}
memcpy(&state.pointers, &(cur->pointers), sizeof(pointer_states_t));
memcpy(&state.vao->pointers, &(cur->pointers), sizeof(pointer_states_t));
if (state.texture.client != cur->client) glClientActiveTexture(GL_TEXTURE0+cur->client);
}

View File

@@ -12,11 +12,6 @@ typedef struct {
auto_normal,
blend,
color_sum,
secondary_array,
color_array,
normal_array,
vertex_array,
tex_coord_array[MAX_TEX],
texgen_s[MAX_TEX],
texgen_t[MAX_TEX],
texgen_r[MAX_TEX],
@@ -41,12 +36,14 @@ typedef struct {
typedef struct {
GLuint unpack_row_length,
unpack_skip_pixels,
unpack_skip_rows;
unpack_skip_rows,
unpack_image_height;
GLboolean unpack_lsb_first;
// TODO: use those values
GLuint pack_row_length,
pack_skip_pixels,
pack_skip_rows;
pack_skip_rows,
pack_image_height;
GLboolean pack_lsb_first;
// TODO: do we only need to worry about GL_TEXTURE_2D?
GLboolean rect_arb[MAX_TEX];
@@ -102,14 +99,6 @@ typedef struct {
GLfloat *stack;
} matrixstack_t;
typedef struct {
glbuffer_t *vertex;
glbuffer_t *elements;
glbuffer_t *pack;
glbuffer_t *unpack;
khash_t(buff) *list;
} buffers_t;
typedef enum {
ENABLED_ALPHA,
ENABLED_BLEND,
@@ -128,13 +117,18 @@ typedef struct {
GLenum blendfunc_d;
} statebatch_t;
typedef struct {
GLboolean vertex_array,
color_array,
normal_array,
tex_coord_array[MAX_TEX];
} clientstate_t;
typedef struct {
displaylist_state_t list;
enable_state_t enable;
map_state_t *map_grid;
map_states_t map1, map2;
pointer_states_t pointers;
renderlist_t **lists;
texgen_state_t texgen[MAX_TEX];
texture_state_t texture;
@@ -149,14 +143,17 @@ typedef struct {
matrixstack_t *projection_matrix;
matrixstack_t **texture_matrix;
selectbuf_t selectbuf;
buffers_t buffers;
khash_t(glvao) *vaos;
glvao_t *bindedvao;
khash_t(buff) *buffers;
glvao_t *vao;
glbuffer_t *defaultvbo;
glvao_t *defaultvao;
int shim_error;
GLenum last_error;
GLuint gl_batch;
GLint vp[4];
statebatch_t statebatch;
clientstate_t clientstate;
} glstate_t;
#endif

View File

@@ -75,27 +75,27 @@ void tex_setup_texcoord(GLuint texunit, GLuint len) {
int changes = 0;
if ((state.texture.rect_arb[texunit]) ||
(bound && ((bound->width!=bound->nwidth)||(bound->height!=bound->nheight)||
(bound->shrink && (state.pointers.tex_coord[texunit].type!=GL_FLOAT) && (state.pointers.tex_coord[texunit].type!=GL_DOUBLE)))))
(bound->shrink && (state.vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (state.vao->pointers.tex_coord[texunit].type!=GL_DOUBLE)))))
changes = 1;
if (old!=texunit) glClientActiveTexture(texunit+GL_TEXTURE0);
if (changes) {
// first convert to GLfloat, without normalization
tex[texunit] = copy_gl_pointer_raw(&state.pointers.tex_coord[texunit], 2, 0, len, state.pointers.tex_coord[texunit].buffer);
tex[texunit] = copy_gl_pointer_raw(&state.vao->pointers.tex_coord[texunit], 2, 0, len, state.vao->pointers.tex_coord[texunit].buffer);
if (!tex[texunit]) {
printf("LibGL: Error with Texture tranform\n");
gles_glTexCoordPointer(len, state.pointers.tex_coord[texunit].type, state.pointers.tex_coord[texunit].stride, state.pointers.tex_coord[texunit].pointer);
gles_glTexCoordPointer(len, state.vao->pointers.tex_coord[texunit].type, state.vao->pointers.tex_coord[texunit].stride, state.vao->pointers.tex_coord[texunit].pointer);
if (old!=texunit) glClientActiveTexture(old+GL_TEXTURE0);
return;
}
// Normalize if needed
if ((state.texture.rect_arb[texunit]) || ((state.pointers.tex_coord[texunit].type!=GL_FLOAT) && (state.pointers.tex_coord[texunit].type!=GL_DOUBLE)))
if ((state.texture.rect_arb[texunit]) || ((state.vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (state.vao->pointers.tex_coord[texunit].type!=GL_DOUBLE)))
tex_coord_rect_arb(tex[texunit], len, bound->width, bound->height);
if ((bound->width!=bound->nwidth) || (bound->height!=bound->nheight))
tex_coord_npot(tex[texunit], len, bound->width, bound->height, bound->nwidth, bound->nheight);
// All done, setup the texcoord array now
gles_glTexCoordPointer(2, GL_FLOAT, 0, tex[texunit]);
} else {
gles_glTexCoordPointer(state.pointers.tex_coord[texunit].size, state.pointers.tex_coord[texunit].type, state.pointers.tex_coord[texunit].stride, state.pointers.tex_coord[texunit].pointer);
gles_glTexCoordPointer(state.vao->pointers.tex_coord[texunit].size, state.vao->pointers.tex_coord[texunit].type, state.vao->pointers.tex_coord[texunit].stride, state.vao->pointers.tex_coord[texunit].pointer);
}
if (old!=texunit) glClientActiveTexture(old+GL_TEXTURE0);
}
@@ -104,6 +104,7 @@ int nolumalpha = 0;
static void *swizzle_texture(GLsizei width, GLsizei height,
GLenum *format, GLenum *type,
GLenum intermediaryformat, GLenum internalformat,
const GLvoid *data) {
bool convert = false;
GLenum dest_format = GL_RGBA;
@@ -114,11 +115,22 @@ static void *swizzle_texture(GLsizei width, GLsizei height,
dest_format = GL_RGB;
break;
case GL_ALPHA:
dest_format = GL_ALPHA;
case GL_RGBA:
break;
case GL_LUMINANCE8_ALPHA8:
if(nolumalpha)
convert = true;
else {
dest_format = GL_LUMINANCE_ALPHA;
*format = GL_LUMINANCE_ALPHA;
}
break;
case GL_LUMINANCE_ALPHA:
if(nolumalpha)
convert = true;
else
dest_format = GL_LUMINANCE_ALPHA;
break;
case GL_RGB5:
dest_type = GL_UNSIGNED_SHORT_5_6_5;
@@ -127,7 +139,6 @@ static void *swizzle_texture(GLsizei width, GLsizei height,
case GL_RGB8:
dest_format = GL_RGB;
*format = GL_RGB;
//convert = true;
break;
case GL_RGBA8:
dest_format = GL_RGBA;
@@ -138,14 +149,36 @@ static void *swizzle_texture(GLsizei width, GLsizei height,
break;
}
switch (*type) {
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
if(dest_format==GL_RGBA)
dest_type = GL_UNSIGNED_SHORT_4_4_4_4;
convert = true;
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
if(dest_format==GL_RGBA)
dest_type = GL_UNSIGNED_SHORT_4_4_4_4;
convert = true;
break;
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
if(dest_format==GL_RGBA)
dest_type = GL_UNSIGNED_SHORT_5_5_5_1;
convert = true;
break;
case GL_UNSIGNED_SHORT_5_5_5_1:
if(dest_format==GL_RGBA)
dest_type = GL_UNSIGNED_SHORT_5_5_5_1;
convert = true;
break;
case GL_UNSIGNED_SHORT_5_6_5_REV:
if (dest_format==GL_RGB)
dest_type = GL_UNSIGNED_SHORT_5_6_5;
convert = true;
break;
case GL_UNSIGNED_SHORT_5_6_5:
if (dest_format==GL_RGB)
dest_type = GL_UNSIGNED_SHORT_5_6_5;
break;
//case GL_FLOAT:
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
break;
case GL_UNSIGNED_INT_8_8_8_8_REV:
*type = GL_UNSIGNED_BYTE;
@@ -153,24 +186,46 @@ static void *swizzle_texture(GLsizei width, GLsizei height,
default:
convert = true;
break;
}
if(*format != intermediaryformat || intermediaryformat!=internalformat) {
dest_format = intermediaryformat;
dest_type = GL_UNSIGNED_BYTE;
convert = true;
}
if (data) {
if (convert) {
GLvoid *pixels = (GLvoid *)data;
if (! pixel_convert(data, &pixels, width, height,
*format, *type, dest_format, dest_type, 0)) {
printf("libGL swizzle error: (%#4x, %#4x -> %#4x, %#4x)\n",
*format, *type, dest_format, dest_type);
printf("libGL swizzle error: (%s, %s -> %s, %s)\n",
PrintEnum(*format), PrintEnum(*type), PrintEnum(dest_format), PrintEnum(dest_type));
return NULL;
}
*type = dest_type;
*format = dest_format;
if(dest_format!=internalformat) {
GLvoid *pix2 = (GLvoid *)pixels;
if (! pixel_convert(pixels, &pix2, width, height,
dest_format, dest_type, internalformat, dest_type, 0)) {
printf("libGL swizzle error: (%s, %s -> %s, %s)\n",
PrintEnum(dest_format), PrintEnum(dest_type), PrintEnum(internalformat), PrintEnum(dest_type));
return NULL;
}
if(pix2!=pixels) {
if (pixels!=data)
free(pixels);
pixels = pix2;
}
dest_format = internalformat;
*type = internalformat;
*format = dest_format;
}
GLvoid *pix2 = pixels;
if (raster_need_transform())
if (!pixel_transform(data, &pixels, width, height,
*format, *type, raster_scale, raster_bias)) {
printf("libGL swizzle/convert error: (%#4x, %#4x -> %#4x, %#4x)\n",
*format, *type, dest_format, dest_type);
printf("libGL swizzle/convert error: (%s, %s -> %s, %s)\n",
PrintEnum(*format), PrintEnum(*type), PrintEnum(dest_format), PrintEnum(dest_type));
pix2 = pixels;
}
if (pix2!=pixels && pixels!=data)
@@ -180,12 +235,74 @@ static void *swizzle_texture(GLsizei width, GLsizei height,
} else {
if (convert) {
*type = dest_type;
*format = dest_format;
*format = internalformat;
}
}
return (void *)data;
}
GLenum swizzle_internalformat(GLenum *internalformat) {
GLenum ret;
GLenum sret;
switch(*internalformat) {
case GL_R:
case 1:
ret = GL_R; sret = GL_RGB;
break;
case GL_RG:
case 2:
ret = GL_RG; sret = GL_RGB;
break;
case GL_RGB5:
case GL_RGB8:
case GL_RGB:
case GL_BGR:
case GL_RGB16:
case GL_RGB16F:
case GL_RGB32F:
case 3:
ret = GL_RGB; sret = GL_RGB;
break;
case GL_RGBA8:
case GL_RGBA4:
case GL_BGRA:
case GL_RGBA16:
case GL_RGBA16F:
case GL_RGBA32F:
case GL_RGB5_A1:
case GL_RGB10_A2:
case 4:
ret = GL_RGBA; sret = GL_RGBA;
break;
case GL_ALPHA8:
case GL_ALPHA:
ret = GL_ALPHA; sret = GL_ALPHA;
break;
case GL_LUMINANCE8:
case GL_LUMINANCE16:
case GL_LUMINANCE:
ret = GL_LUMINANCE; sret = GL_LUMINANCE;
break;
case GL_LUMINANCE4_ALPHA4:
case GL_LUMINANCE8_ALPHA8:
case GL_LUMINANCE16_ALPHA16:
case GL_LUMINANCE_ALPHA:
ret = GL_LUMINANCE_ALPHA;
if (nolumalpha)
sret = GL_RGBA;
else
sret = GL_LUMINANCE_ALPHA;
break;
default:
ret = GL_RGBA;
sret = GL_RGBA;
break;
// Default...RGBA / RGBA will be fine....
}
*internalformat = ret;
return sret;
}
int automipmap = 0;
int texcopydata = 0;
int tested_env = 0;
@@ -220,8 +337,8 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat,
GLvoid *datab = (GLvoid*)data;
if (state.buffers.unpack)
datab += (uintptr_t)state.buffers.pack->data;
if (state.vao->unpack)
datab += (uintptr_t)state.vao->pack->data;
GLvoid *pixels = (GLvoid *)datab;
border = 0; //TODO: something?
@@ -238,6 +355,11 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat,
else
bound->mipmap_need = 1;
}
GLenum new_format = swizzle_internalformat(&internalformat);
if (bound) {
bound->orig_internal = internalformat;
bound->internalformat = new_format;
}
if (datab) {
// implements GL_UNPACK_ROW_LENGTH
@@ -257,7 +379,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat,
}
GLvoid *old = pixels;
pixels = (GLvoid *)swizzle_texture(width, height, &format, &type, old);
pixels = (GLvoid *)swizzle_texture(width, height, &format, &type, internalformat, new_format, old);
if (old != pixels && old != datab) {
free(old);
}
@@ -469,7 +591,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat,
if (bound) {
bound->shrink = 0;
if (!bound->streamed)
swizzle_texture(width, height, &format, &type, NULL); // convert format even if data is NULL
swizzle_texture(width, height, &format, &type, internalformat, new_format, NULL); // convert format even if data is NULL
if ((texshrink>0) && !bound->streamed) {
switch(texshrink) {
case 1: //everything / 2
@@ -623,8 +745,8 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
}
GLvoid *datab = (GLvoid*)data;
if (state.buffers.unpack)
datab += (uintptr_t)state.buffers.pack->data;
if (state.vao->unpack)
datab += (uintptr_t)state.vao->pack->data;
GLvoid *pixels = (GLvoid*)datab;
LOAD_GLES(glTexSubImage2D);
@@ -680,10 +802,19 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
#endif
{
//pixels = (GLvoid *)swizzle_texture(width, height, &format, &type, old);
if (!pixel_convert(old, &pixels, width, height, format, type, bound->format, bound->type, 0)) {
if (!pixel_convert(old, &pixels, width, height, format, type, bound->orig_internal, bound->type, 0)) {
printf("LIBGL: Error in pixel_convert while glTexSubImage2D\n");
} else {
format = bound->format;
if(bound->orig_internal!=bound->internalformat) {
GLvoid* pix2 = pixels;
if (!pixel_convert(pixels, &pix2, width, height, bound->orig_internal, bound->type, bound->internalformat, bound->type, 0)) {
printf("LIBGL: Error in pixel_convert while glTexSubImage2D\n");
}
if (pixels != pix2 && pixels != old)
free(pixels);
pixels = pix2;
}
format = bound->internalformat;
type = bound->type;
}
@@ -827,6 +958,9 @@ void glPixelStorei(GLenum pname, GLint param) {
case GL_UNPACK_LSB_FIRST:
state.texture.unpack_lsb_first = param;
break;
case GL_UNPACK_IMAGE_HEIGHT:
state.texture.unpack_image_height = param;
break;
case GL_UNPACK_SWAP_BYTES:
case GL_PACK_SWAP_BYTES:
// Fake... TODO?
@@ -844,6 +978,9 @@ void glPixelStorei(GLenum pname, GLint param) {
case GL_PACK_LSB_FIRST:
state.texture.pack_lsb_first = param;
break;
case GL_PACK_IMAGE_HEIGHT:
state.texture.pack_image_height = param;
break;
default:
errorGL();
gles_glPixelStorei(pname, param);
@@ -902,6 +1039,8 @@ gltexture_t* getTexture(GLenum target, GLuint texture) {
tex->min_filter = tex->mag_filter = GL_LINEAR;
tex->format = GL_RGBA;
tex->type = GL_UNSIGNED_BYTE;
tex->orig_internal = GL_RGBA;
tex->internalformat = GL_RGBA;
tex->data = NULL;
} else {
tex = kh_value(list, k);
@@ -1028,6 +1167,7 @@ void glTexParameteri(GLenum target, GLenum pname, GLint param) {
if (texture)
texture->mipmap_auto = (param)?1:0;
return; // not on GLES
case GL_TEXTURE_BASE_LEVEL:
case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD:
case GL_TEXTURE_LOD_BIAS:
@@ -1227,8 +1367,8 @@ void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoi
//printf("glGetTexImage(0x%04X, %i, 0x%04X, 0x%04X, 0x%p), texture=%u, size=%i,%i\n", target, level, format, type, img, bound->glname, width, height);
GLvoid *dst = img;
if (state.buffers.pack)
dst += (uintptr_t)state.buffers.pack->data;
if (state.vao->pack)
dst += (uintptr_t)state.vao->pack->data;
#ifdef TEXSTREAM
if (texstream && bound->streamed) {
noerrorShim();
@@ -1315,8 +1455,8 @@ void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format
LOAD_GLES(glReadPixels);
errorGL();
GLvoid* dst = data;
if (state.buffers.pack)
dst += (uintptr_t)state.buffers.pack->data;
if (state.vao->pack)
dst += (uintptr_t)state.vao->pack->data;
readfboBegin();
if (format == GL_RGBA && format == GL_UNSIGNED_BYTE) {
@@ -1354,10 +1494,10 @@ void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffse
errorGL();
// "Unmap" if buffer mapped...
glbuffer_t *pack = state.buffers.pack;
glbuffer_t *unpack = state.buffers.unpack;
state.buffers.pack = NULL;
state.buffers.unpack = NULL;
glbuffer_t *pack = state.vao->pack;
glbuffer_t *unpack = state.vao->unpack;
state.vao->pack = NULL;
state.vao->unpack = NULL;
gltexture_t* bound = state.texture.bound[state.texture.active];
if (!bound) {
@@ -1393,8 +1533,8 @@ void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffse
}
}
// "Remap" if buffer mapped...
state.buffers.pack = pack;
state.buffers.unpack = unpack;
state.vao->pack = pack;
state.vao->unpack = unpack;
state.gl_batch = old_glbatch;
}
@@ -1412,10 +1552,10 @@ void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLin
errorGL();
// "Unmap" if buffer mapped...
glbuffer_t *pack = state.buffers.pack;
glbuffer_t *unpack = state.buffers.unpack;
state.buffers.pack = NULL;
state.buffers.unpack = NULL;
glbuffer_t *pack = state.vao->pack;
glbuffer_t *unpack = state.vao->unpack;
state.vao->pack = NULL;
state.vao->unpack = NULL;
if (copytex) {
LOAD_GLES(glCopyTexImage2D);
@@ -1428,8 +1568,8 @@ void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLin
}
// "Remap" if buffer mapped...
state.buffers.pack = pack;
state.buffers.unpack = unpack;
state.vao->pack = pack;
state.vao->unpack = unpack;
state.gl_batch = old_glbatch;
}
@@ -1524,7 +1664,7 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
errorShim(GL_INVALID_OPERATION);
return; // no texture bounded...
}
//printf("glCompressedTexImage2D on target=0x%04X with size(%i,%i), internalformat=%04x, imagesize=%i, upackbuffer=%p\n", target, width, height, internalformat, imageSize, state.buffers.unpack?state.buffers.unpack->data:0);
//printf("glCompressedTexImage2D on target=%s with size(%i,%i), internalformat=s, imagesize=%i, upackbuffer=%p\n", PrintEnum(target), width, height, PrintEnum(internalformat), imageSize, state.buffers.unpack?state.buffers.unpack->data:0);
// hack...
if (internalformat==GL_RGBA8)
internalformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
@@ -1542,8 +1682,8 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
LOAD_GLES(glCompressedTexImage2D);
errorGL();
glbuffer_t *unpack = state.buffers.unpack;
state.buffers.unpack = NULL;
glbuffer_t *unpack = state.vao->unpack;
state.vao->unpack = NULL;
GLvoid *datab = (GLvoid*)data;
if (unpack)
datab += (uintptr_t)unpack->data;
@@ -1599,7 +1739,7 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
state.texture.bound[state.texture.active]->compressed = true;
gles_glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, datab);
}
state.buffers.unpack = unpack;
state.vao->unpack = unpack;
state.gl_batch = old_glbatch;
}
@@ -1626,8 +1766,8 @@ void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return;
}
//printf("glCompressedTexSubImage2D with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, internalformat=%s, imagesize=%i\n", state.texture.unpack_row_length, width, height, xoffset, yoffset, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, PrintEnum(format), imageSize);
glbuffer_t *unpack = state.buffers.unpack;
state.buffers.unpack = NULL;
glbuffer_t *unpack = state.vao->unpack;
state.vao->unpack = NULL;
GLvoid *datab = (GLvoid*)data;
if (unpack)
datab += (uintptr_t)unpack->data;

View File

@@ -93,6 +93,8 @@ typedef struct {
GLsizei nheight;
GLenum format;
GLenum type;
GLenum orig_internal;
GLenum internalformat;
int shrink;
GLboolean mipmap_auto;
GLboolean mipmap_need;

View File

@@ -734,8 +734,8 @@ void glDrawRangeElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenu
//printf("glDrawRangeElements(0x%04X, %i, %i, %i, 0x%04X, @%p), inlist=%i\n", mode, start, end, count, type, indices, (state.list.active)?1:0);
GLushort *newinds = (GLushort*)malloc(sizeof(GLushort)*count);
int newcount=0;
glbuffer_t *elements = state.buffers.elements;
state.buffers.elements = NULL;
glbuffer_t *elements = state.vao->elements;
state.vao->elements = NULL;
uintptr_t ptr = (uintptr_t)indices;
if (elements)
@@ -750,7 +750,7 @@ void glDrawRangeElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenu
glDrawElements(mode, newcount, GL_UNSIGNED_SHORT, newinds);
free(newinds);
state.buffers.elements = elements;
state.vao->elements = elements;
}
void glDrawRangeElementsEXT(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const void *indices) {

View File

@@ -266,7 +266,7 @@ static void scan_env() {
return;
/* Check for some corruption inside state.... */
if ((state.texture.active < 0) || (state.texture.active > MAX_TEX) ||
(state.pointers.vertex.buffer!= 0) || (state.buffers.vertex != 0)) {
(state.vao->pointers.vertex.buffer!= 0) || (state.vao->vertex != 0)) {
printf("LIBGL: Warning, memory corruption detected at init, trying to compensate\n");
initialize_glshim();
}