diff --git a/GL/texture.c b/GL/texture.c index 18c1db8..e1f2d3a 100644 --- a/GL/texture.c +++ b/GL/texture.c @@ -170,24 +170,28 @@ GLboolean APIENTRY glIsTexture(GLuint texture) { return (named_array_used(&TEXTURE_OBJECTS, texture)) ? GL_TRUE : GL_FALSE; } +static void _glInitializeTextureObject(TextureObject* txr, unsigned int id) { + txr->index = id; + txr->width = txr->height = 0; + txr->mipmap = 0; + txr->uv_clamp = 0; + txr->env = PVR_TXRENV_MODULATEALPHA; + txr->data = NULL; + txr->mipmapCount = 0; + txr->minFilter = GL_NEAREST; + txr->magFilter = GL_NEAREST; + txr->palette = NULL; + txr->isCompressed = GL_FALSE; + txr->isPaletted = GL_FALSE; +} + void APIENTRY glGenTextures(GLsizei n, GLuint *textures) { TRACE(); while(n--) { GLuint id = 0; TextureObject* txr = (TextureObject*) named_array_alloc(&TEXTURE_OBJECTS, &id); - txr->index = id; - txr->width = txr->height = 0; - txr->mipmap = 0; - txr->uv_clamp = 0; - txr->env = PVR_TXRENV_MODULATEALPHA; - txr->data = NULL; - txr->mipmapCount = 0; - txr->minFilter = GL_NEAREST; - txr->magFilter = GL_NEAREST; - txr->palette = NULL; - txr->isCompressed = GL_FALSE; - txr->isPaletted = GL_FALSE; + _glInitializeTextureObject(txr, id); *textures = id; @@ -236,6 +240,13 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) { return; } + /* If this didn't come from glGenTextures, then we should initialize the + * texture the first time it's bound */ + if(!named_array_used(&TEXTURE_OBJECTS, texture)) { + TextureObject* txr = named_array_reserve(&TEXTURE_OBJECTS, texture); + _glInitializeTextureObject(txr, texture); + } + if(texture) { TEXTURE_UNITS[ACTIVE_TEXTURE] = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, texture); } else { diff --git a/containers/named_array.c b/containers/named_array.c index 7ddfc7e..4ae07bd 100644 --- a/containers/named_array.c +++ b/containers/named_array.c @@ -1,6 +1,7 @@ #include #include #include +#include #ifndef __APPLE__ #include @@ -57,6 +58,23 @@ void* named_array_alloc(NamedArray* array, unsigned int* new_id) { return NULL; } +void* named_array_reserve(NamedArray* array, unsigned int id) { + if(!named_array_used(array, id)) { + unsigned int j = id % 8; + unsigned int i = (id - j) / 8; + + assert(!named_array_used(array, id)); + array->used_markers[i] |= (unsigned char) 1 << j; + assert(named_array_used(array, id)); + + unsigned char* ptr = &array->elements[(id - 1) * array->element_size]; + memset(ptr, 0, array->element_size); + return ptr; + } + + return named_array_get(array, id); +} + void named_array_release(NamedArray* array, unsigned int new_id) { new_id--; diff --git a/containers/named_array.h b/containers/named_array.h index ecf4d7f..a0f6c97 100644 --- a/containers/named_array.h +++ b/containers/named_array.h @@ -15,7 +15,10 @@ typedef struct { void named_array_init(NamedArray* array, unsigned int element_size, unsigned int max_elements); char named_array_used(NamedArray* array, unsigned int id); + void* named_array_alloc(NamedArray* array, unsigned int* new_id); +void* named_array_reserve(NamedArray* array, unsigned int id); + void named_array_release(NamedArray* array, unsigned int new_id); void* named_array_get(NamedArray* array, unsigned int id); void named_array_cleanup(NamedArray* array);