/* * Texture Manager */ #include "zgl.h" static GLTexture *find_texture(GLContext *c,int h) { GLTexture *t; t=c->shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE]; while (t!=NULL) { if (t->handle == h) return t; t=t->next; } return NULL; } static void free_texture(GLContext *c,int h) { GLTexture *t,**ht; GLImage *im; int i; t=find_texture(c,h); if (t->prev==NULL) { ht=&c->shared_state.texture_hash_table [t->handle % TEXTURE_HASH_TABLE_SIZE]; *ht=t->next; } else { t->prev->next=t->next; } if (t->next!=NULL) t->next->prev=t->prev; for(i=0;iimages[i]; if (im->pixmap != NULL) gl_free(im->pixmap); } gl_free(t); } GLTexture *alloc_texture(GLContext *c,int h) { GLTexture *t,**ht; t=gl_zalloc(sizeof(GLTexture)); ht=&c->shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE]; t->next=*ht; t->prev=NULL; if (t->next != NULL) t->next->prev=t; *ht=t; t->handle=h; return t; } void glInitTextures(GLContext *c) { /* textures */ c->texture_2d_enabled=0; c->current_texture=find_texture(c,0); } void glGenTextures(int n, unsigned int *textures) { GLContext *c=gl_get_context(); int max,i; GLTexture *t; max=0; for(i=0;ishared_state.texture_hash_table[i]; while (t!=NULL) { if (t->handle>max) max=t->handle; t=t->next; } } for(i=0;icurrent_texture) { glBindTexture(GL_TEXTURE_2D,0); } free_texture(c,textures[i]); } } } void glopBindTexture(GLContext *c,GLParam *p) { int target=p[1].i; int texture=p[2].i; GLTexture *t; assert(target == GL_TEXTURE_2D && texture >= 0); t=find_texture(c,texture); if (t==NULL) { t=alloc_texture(c,texture); } c->current_texture=t; } void glopTexImage2D(GLContext *c,GLParam *p) { int target=p[1].i; int level=p[2].i; int components=p[3].i; int width=p[4].i; int height=p[5].i; int border=p[6].i; int format=p[7].i; int type=p[8].i; void *pixels=p[9].p; GLImage *im; unsigned char *pixels1; int do_free; if (!(target == GL_TEXTURE_2D && level == 0 && components == 3 && border == 0 && format == GL_RGB && type == GL_UNSIGNED_BYTE)) { gl_fatal_error("glTexImage2D: combinaison of parameters not handled"); } do_free=0; if (width != 256 || height != 256) { pixels1 = gl_malloc(256 * 256 * 3); /* no interpolation is done here to respect the original image aliasing ! */ gl_resizeImageNoInterpolate(pixels1,256,256,pixels,width,height); do_free=1; width=256; height=256; } else { pixels1=pixels; } im=&c->current_texture->images[level]; im->xsize=width; im->ysize=height; if (im->pixmap!=NULL) gl_free(im->pixmap); #if TGL_FEATURE_RENDER_BITS == 24 im->pixmap=gl_malloc(width*height*3); if(im->pixmap) { memcpy(im->pixmap,pixels1,width*height*3); } #elif TGL_FEATURE_RENDER_BITS == 32 im->pixmap=gl_malloc(width*height*4); if(im->pixmap) { gl_convertRGB_to_8A8R8G8B(im->pixmap,pixels1,width,height); } #elif TGL_FEATURE_RENDER_BITS == 16 im->pixmap=gl_malloc(width*height*2); if(im->pixmap) { gl_convertRGB_to_5R6G5B(im->pixmap,pixels1,width,height); } #else #error TODO #endif if (do_free) gl_free(pixels1); } /* TODO: not all tests are done */ void glopTexEnv(GLContext *c,GLParam *p) { int target=p[1].i; int pname=p[2].i; int param=p[3].i; if (target != GL_TEXTURE_ENV) { error: gl_fatal_error("glTexParameter: unsupported option"); } if (pname != GL_TEXTURE_ENV_MODE) goto error; if (param != GL_DECAL) goto error; } /* TODO: not all tests are done */ void glopTexParameter(GLContext *c,GLParam *p) { int target=p[1].i; int pname=p[2].i; int param=p[3].i; if (target != GL_TEXTURE_2D) { error: gl_fatal_error("glTexParameter: unsupported option"); } switch(pname) { case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: if (param != GL_REPEAT) goto error; break; } } void glopPixelStore(GLContext *c,GLParam *p) { int pname=p[1].i; int param=p[2].i; if (pname != GL_UNPACK_ALIGNMENT || param != 1) { gl_fatal_error("glPixelStore: unsupported option"); } }