#include "array.h" #include "debug.h" #include "enum_info.h" #include "glcase.h" #include "light.h" #include "state.h" GLvoid *copy_gl_array(const GLvoid *src, GLenum from, GLsizei width, GLsizei stride, GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, void* dst) { if (! src || !count) return NULL; if (! stride) stride = width * gl_sizeof(from); const char *unknown_str = "LIBGL: copy_gl_array -> unknown type: %x\n"; if(!dst) { dst = malloc((count-skip) * to_width * gl_sizeof(to)); } GLsizei from_size = gl_sizeof(from) * width; if (to_width < width) { /* printf("Warning: copy_gl_array: %i < %i\n", to_width, width); return NULL;*/ width = to_width; } // quick path if just copying same to same and no specific stride involved if(stride == (to_width*gl_sizeof(to)) && width==to_width && from==to) { memcpy(dst, (char*)src + stride*skip, (count-skip) * to_width * gl_sizeof(to)); return dst; } // if stride is weird, we need to be able to arbitrarily shift src // so we leave it in a uintptr_t and cast after incrementing uintptr_t in = (uintptr_t)src; in += stride*skip; if (from == to && to_width >= width) { GL_TYPE_SWITCH(out, dst, to, for (int i = skip; i < count; i++) { memcpy(out, (GLvoid *)in, from_size); for (int j = width; j < to_width; j++) { out[j] = 0; } out += to_width; in += stride; }, default: printf(unknown_str, from); return NULL; ) } else { GL_TYPE_SWITCH(out, dst, to, for (int i = skip; i < count; i++) { GL_TYPE_SWITCH(input, in, from, for (int j = 0; j < width; j++) { out[j] = input[j]; } for (int j = width; j < to_width; j++) { out[j] = 0; } out += to_width; in += stride; , default: printf(unknown_str, from); return NULL; ) }, default: printf(unknown_str, to); return NULL; ) } return dst; } GLvoid *copy_gl_array_texcoord(const GLvoid *src, GLenum from, GLsizei width, GLsizei stride, GLsizei to_width, GLsizei skip, GLsizei count, void* dst) { if (! src || !count) return NULL; if (! stride) stride = width * gl_sizeof(from); static const char *unknown_str = "LIBGL: copy_gl_array -> unknown type: %x\n"; if(!dst) dst = malloc((count-skip) * to_width * gl_sizeof(GL_FLOAT)); GLsizei from_size = gl_sizeof(from) * width; GLsizei to_elem = gl_sizeof(GL_FLOAT); uintptr_t in = (uintptr_t)src; in += stride*skip; GLfloat* out = (GLfloat*)dst; if (from == GL_FLOAT && to_width >= width) { for (int i = skip; i < count; i++) { GLfloat* input = (GLfloat*)in; //memcpy(out, (GLvoid *)in, from_size); // which one is faster ? for (int j = 0; j < width; j++) { out[j] = input[j]; } for (int j = width; j < to_width; j++) { if(j==3) out[j] = 1.0f; else out[j] = 0.0f; } out += to_width; in += stride; } } else { for (int i = skip; i < count; i++) { GL_TYPE_SWITCH(input, in, from, for (int j = 0; j < width; j++) { out[j] = input[j]; } for (int j = width; j < to_width; j++) { if(j==3) out[j] = 1.0f; else out[j] = 0.0f; } out += to_width; in += stride; , default: printf(unknown_str, from); return NULL; ) } } return dst; } GLvoid *copy_gl_array_quickconvert(const GLvoid *src, GLenum from, GLsizei stride, GLsizei skip, GLsizei count, void* dest) { if (! stride) stride = 4 * gl_sizeof(from); const char *unknown_str = "LIBGL: copy_gl_array_quickconvert -> unknown type: %x\n"; GLvoid *dst = (dest)?dest:malloc((count-skip) * 4 * gl_sizeof(GL_FLOAT)); uintptr_t in = (uintptr_t)src; in += stride*skip; int j; GLfloat *out = (GLfloat*)dst; GL_TYPE_SWITCH2(input, in, from, const GLfloat maxf = 1.0f/gl_max_value(from); for (int i = skip; i < count; i++) , for (j = 0; j < 4; j++) { out[j] = ((GLfloat)input[j])*maxf; } out += 4; in += stride; , default: printf(unknown_str, from); return NULL; ) return dst; } GLvoid *copy_gl_array_convert(const GLvoid *src, GLenum from, GLsizei width, GLsizei stride, GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, GLvoid* filler, void* dst) { if (! src || !count) return NULL; if (! stride) stride = width * gl_sizeof(from); GLsizei from_size = gl_sizeof(from) * width; if(to==from && width==to_width && stride==(to_width * gl_sizeof(to))) { if(!dst) dst = malloc((count-skip) * stride); memcpy(dst, (char*)src+stride*skip, (count-skip)*stride); return dst; } if(to==GL_FLOAT && width==to_width && width==4) return copy_gl_array_quickconvert(src, from, stride, skip, count, dst); if(to==GL_FLOAT && from==GL_FLOAT) if(width<4 || *(GLfloat*)filler==1.0f) // no need to convert return copy_gl_array_texcoord(src, from, width, stride, to_width, skip, count, dst); else return copy_gl_array(src, from, width, stride, to, to_width, skip, count, dst); const char *unknown_str = "LIBGL: copy_gl_array_convert -> unknown type: %x\n"; if(!dst) dst = malloc((count-skip) * to_width * gl_sizeof(to)); if (to_width < width) { /*printf("Warning: copy_gl_array: %i < %i\n", to_width, width); return NULL;*/ width = to_width; } // if stride is weird, we need to be able to arbitrarily shift src // so we leave it in a uintptr_t and cast after incrementing uintptr_t in = (uintptr_t)src; in += stride*skip; int j; if (from == to && to_width >= width) { GL_TYPE_SWITCH(out, dst, to, for (int i = skip; i < count; i++) { memcpy(out, (GLvoid *)in, from_size); for (j = width; j < to_width-1; j++) { out[j]=0; } for (; j < to_width; j++) { memcpy(&out[j], filler, gl_sizeof(to)); } out += to_width; in += stride; }, default: printf(unknown_str, from); return NULL; ) } else { GL_TYPE_SWITCH_MAX(out, dst, to, GL_TYPE_SWITCH2(input, in, from, const GLuint maxf = gl_max_value(from); for (int i = skip; i < count; i++) , for (j = 0; j < width; j++) { out[j] = input[j]*maxv/maxf; } for (; j < to_width-1; j++) { out[j]=0; } for (; j < to_width; j++) { memcpy(&out[j], filler, gl_sizeof(to)); } out += to_width; in += stride; , default: printf(unknown_str, from); return NULL; ), default: printf(unknown_str, to); return NULL; ) } return dst; } GLvoid *copy_gl_pointer(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { float filler = 0.0f; return copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride, GL_FLOAT, width, skip, count, &filler, NULL); } GLvoid *copy_gl_pointer_color(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { float filler = 1.0f; return copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride, GL_FLOAT, width, skip, count, &filler, NULL); } GLvoid *copy_gl_pointer_bytecolor(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { GLubyte filler = 255; return copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride, GL_UNSIGNED_BYTE, width, skip, count, &filler, NULL); } GLvoid *copy_gl_pointer_raw(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { return copy_gl_array((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride, GL_FLOAT, width, skip, count, NULL); } GLvoid *copy_gl_pointer_tex(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { //float filler = 1.0f; return copy_gl_array_texcoord((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride, /*GL_FLOAT,*/ width, skip, count, /*&filler,*/ NULL); } void copy_gl_pointer_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { float filler = 0.0f; copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride, GL_FLOAT, width, skip, count, &filler, dest); } void copy_gl_pointer_color_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { float filler = 1.0f; copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride, GL_FLOAT, width, skip, count, &filler, dest); } void copy_gl_pointer_bytecolor_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { GLubyte filler = 255; copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride, GL_UNSIGNED_BYTE, width, skip, count, &filler, dest); } void copy_gl_pointer_raw_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { copy_gl_array((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride, GL_FLOAT, width, skip, count, dest); } void copy_gl_pointer_tex_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { //float filler = 1.0f; copy_gl_array_texcoord((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride, /*GL_FLOAT,*/ width, skip, count, /*&filler,*/ dest); } GLfloat *gl_pointer_index(vertexattrib_t *p, GLint index) { static GLfloat buf[4]; GLsizei size = gl_sizeof(p->type); GLsizei stride = p->stride ? p->stride : (size * p->size); uintptr_t ptr = (uintptr_t)p->pointer+(uintptr_t)p->real_pointer + (stride * index); GL_TYPE_SWITCH(src, ptr, p->type, for (int i = 0; i < p->size; i++) { buf[i] = src[i]; } // zero anything not set by the pointer for (int i = p->size; i < 4; i++) { buf[i] = 0; }, default: printf("LIBGL: unknown pointer type: 0x%x\n", p->type); ) return buf; } GLfloat *copy_eval_double1(GLenum target, GLint ustride, GLint uorder, const GLdouble *src) { GLsizei width = get_map_width(target); GLfloat* out; if(!src || !width) return NULL; out = malloc(uorder*width*sizeof(GLfloat)); GLfloat *p = out; for (int i=0; i vorder ? uorder : vorder)*width; if(hsize>dsize) out = malloc((uorder*vorder*width+hsize)*sizeof(GLfloat)); else out = malloc((uorder*vorder*width+dsize)*sizeof(GLfloat)); int uinc = ustride - vorder*vstride; GLfloat* p = out; for (int i=0; i vorder ? uorder : vorder)*width; if(hsize>dsize) out = malloc((uorder*vorder*width+hsize)*sizeof(GLfloat)); else out = malloc((uorder*vorder*width+dsize)*sizeof(GLfloat)); int uinc = ustride - vorder*vstride; GLfloat* p = out; for (int i=0; i *max) *max = n; } } void normalize_indices_us(GLushort *indices, GLsizei *max, GLsizei *min, GLsizei count) { getminmax_indices_us(indices, max, min, count); for (int i = 0; i < count; i++) { indices[i] -= *min; } } void getminmax_indices_ui(const GLuint *indices, GLsizei *max, GLsizei *min, GLsizei count) { if (!count) return; *max = indices[0]; *min = indices[0]; for (int i = 1; i < count; i++) { GLsizei n = indices[i]; if( n < *min) *min = n; if (n > *max) *max = n; } } void normalize_indices_ui(GLuint *indices, GLsizei *max, GLsizei *min, GLsizei count) { getminmax_indices_ui(indices, max, min, count); for (int i = 0; i < count; i++) { indices[i] -= *min; } } void *copy_gl_array_bgra(void* dest, const void *ptr, GLint stride, GLsizei width, GLsizei skip, GLsizei count) { // this one only convert from BGRA (unsigned byte) to RGBA FLOAT GLubyte* src = (GLubyte*)ptr; if (! src || !(count-skip)) return NULL; if (! stride) stride = 4; if(!dest) dest = malloc(4*sizeof(GLfloat)*(count-skip)); GLfloat* dst = dest; src += skip*(stride); static const float d = 1.0f/255.0f; for (int i=skip; i>16) | ((lsrc&0x000000ff)<<16); asm volatile ( "vmov s12, %1 \n\t" // because you cannot vmovl.u8 d6, s11 "vmovl.u8 q3, d6 \n\t" // Expand to 16-bit (so unsetuped s13 is expanded in d7) "vmovl.u16 q3, d6 \n\t" // Expand to 32-bit, ignoring expanded d7 "vcvt.f32.u32 q3, q3 \n\t" // Convert to float "vmul.f32 q3, q3, %y2 \n\t" // Normalize "vst1.f32 {q3}, [%0]! \n\t" // Store, next :"+r"(dst) :"r"(lsrc), "w"(d) : "q3", "memory" ); #else const GLubyte b = src[0], g = src[1], r = src[2], a = src[3]; *dst++ = r*d; *dst++ = g*d; *dst++ = b*d; *dst++ = a*d; #endif src+=stride; } return dest; } GLvoid *copy_gl_pointer_color_bgra(const void *ptr, GLint stride, GLsizei width, GLsizei skip, GLsizei count) { return copy_gl_array_bgra(NULL, ptr, stride, width, skip, count); } void copy_gl_pointer_color_bgra_noalloc(void* dest, const void *ptr, GLint stride, GLsizei width, GLsizei skip, GLsizei count) { copy_gl_array_bgra(dest, ptr, stride, width, skip, count); }