| [1] | 1 | /* | 
|---|
|  | 2 | * Texture Manager | 
|---|
|  | 3 | */ | 
|---|
|  | 4 |  | 
|---|
|  | 5 | #include "zgl.h" | 
|---|
|  | 6 |  | 
|---|
|  | 7 | static GLTexture *find_texture(GLContext *c,int h) | 
|---|
|  | 8 | { | 
|---|
|  | 9 | GLTexture *t; | 
|---|
|  | 10 |  | 
|---|
|  | 11 | t=c->shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE]; | 
|---|
|  | 12 | while (t!=NULL) { | 
|---|
|  | 13 | if (t->handle == h) return t; | 
|---|
|  | 14 | t=t->next; | 
|---|
|  | 15 | } | 
|---|
|  | 16 | return NULL; | 
|---|
|  | 17 | } | 
|---|
|  | 18 |  | 
|---|
|  | 19 | static void free_texture(GLContext *c,int h) | 
|---|
|  | 20 | { | 
|---|
|  | 21 | GLTexture *t,**ht; | 
|---|
|  | 22 | GLImage *im; | 
|---|
|  | 23 | int i; | 
|---|
|  | 24 |  | 
|---|
|  | 25 | t=find_texture(c,h); | 
|---|
|  | 26 | if (t->prev==NULL) { | 
|---|
|  | 27 | ht=&c->shared_state.texture_hash_table | 
|---|
|  | 28 | [t->handle % TEXTURE_HASH_TABLE_SIZE]; | 
|---|
|  | 29 | *ht=t->next; | 
|---|
|  | 30 | } else { | 
|---|
|  | 31 | t->prev->next=t->next; | 
|---|
|  | 32 | } | 
|---|
|  | 33 | if (t->next!=NULL) t->next->prev=t->prev; | 
|---|
|  | 34 |  | 
|---|
|  | 35 | for(i=0;i<MAX_TEXTURE_LEVELS;i++) { | 
|---|
|  | 36 | im=&t->images[i]; | 
|---|
|  | 37 | if (im->pixmap != NULL) gl_free(im->pixmap); | 
|---|
|  | 38 | } | 
|---|
|  | 39 |  | 
|---|
|  | 40 | gl_free(t); | 
|---|
|  | 41 | } | 
|---|
|  | 42 |  | 
|---|
|  | 43 | GLTexture *alloc_texture(GLContext *c,int h) | 
|---|
|  | 44 | { | 
|---|
|  | 45 | GLTexture *t,**ht; | 
|---|
|  | 46 |  | 
|---|
|  | 47 | t=gl_zalloc(sizeof(GLTexture)); | 
|---|
|  | 48 |  | 
|---|
|  | 49 | ht=&c->shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE]; | 
|---|
|  | 50 |  | 
|---|
|  | 51 | t->next=*ht; | 
|---|
|  | 52 | t->prev=NULL; | 
|---|
|  | 53 | if (t->next != NULL) t->next->prev=t; | 
|---|
|  | 54 | *ht=t; | 
|---|
|  | 55 |  | 
|---|
|  | 56 | t->handle=h; | 
|---|
|  | 57 |  | 
|---|
|  | 58 | return t; | 
|---|
|  | 59 | } | 
|---|
|  | 60 |  | 
|---|
|  | 61 |  | 
|---|
|  | 62 | void glInitTextures(GLContext *c) | 
|---|
|  | 63 | { | 
|---|
|  | 64 | /* textures */ | 
|---|
|  | 65 |  | 
|---|
|  | 66 | c->texture_2d_enabled=0; | 
|---|
|  | 67 | c->current_texture=find_texture(c,0); | 
|---|
|  | 68 | } | 
|---|
|  | 69 |  | 
|---|
|  | 70 | void glGenTextures(int n, unsigned int *textures) | 
|---|
|  | 71 | { | 
|---|
|  | 72 | GLContext *c=gl_get_context(); | 
|---|
|  | 73 | int max,i; | 
|---|
|  | 74 | GLTexture *t; | 
|---|
|  | 75 |  | 
|---|
|  | 76 | max=0; | 
|---|
|  | 77 | for(i=0;i<TEXTURE_HASH_TABLE_SIZE;i++) { | 
|---|
|  | 78 | t=c->shared_state.texture_hash_table[i]; | 
|---|
|  | 79 | while (t!=NULL) { | 
|---|
|  | 80 | if (t->handle>max) max=t->handle; | 
|---|
|  | 81 | t=t->next; | 
|---|
|  | 82 | } | 
|---|
|  | 83 |  | 
|---|
|  | 84 | } | 
|---|
|  | 85 | for(i=0;i<n;i++) { | 
|---|
|  | 86 | textures[i]=max+i+1; | 
|---|
|  | 87 | } | 
|---|
|  | 88 | } | 
|---|
|  | 89 |  | 
|---|
|  | 90 |  | 
|---|
|  | 91 | void glDeleteTextures(int n, const unsigned int *textures) | 
|---|
|  | 92 | { | 
|---|
|  | 93 | GLContext *c=gl_get_context(); | 
|---|
|  | 94 | int i; | 
|---|
|  | 95 | GLTexture *t; | 
|---|
|  | 96 |  | 
|---|
|  | 97 | for(i=0;i<n;i++) { | 
|---|
|  | 98 | t=find_texture(c,textures[i]); | 
|---|
|  | 99 | if (t!=NULL && t!=0) { | 
|---|
|  | 100 | if (t==c->current_texture) { | 
|---|
|  | 101 | glBindTexture(GL_TEXTURE_2D,0); | 
|---|
|  | 102 | } | 
|---|
|  | 103 | free_texture(c,textures[i]); | 
|---|
|  | 104 | } | 
|---|
|  | 105 | } | 
|---|
|  | 106 | } | 
|---|
|  | 107 |  | 
|---|
|  | 108 |  | 
|---|
|  | 109 | void glopBindTexture(GLContext *c,GLParam *p) | 
|---|
|  | 110 | { | 
|---|
|  | 111 | int target=p[1].i; | 
|---|
|  | 112 | int texture=p[2].i; | 
|---|
|  | 113 | GLTexture *t; | 
|---|
|  | 114 |  | 
|---|
|  | 115 | assert(target == GL_TEXTURE_2D && texture >= 0); | 
|---|
|  | 116 |  | 
|---|
|  | 117 | t=find_texture(c,texture); | 
|---|
|  | 118 | if (t==NULL) { | 
|---|
|  | 119 | t=alloc_texture(c,texture); | 
|---|
|  | 120 | } | 
|---|
|  | 121 | c->current_texture=t; | 
|---|
|  | 122 | } | 
|---|
|  | 123 |  | 
|---|
|  | 124 | void glopTexImage2D(GLContext *c,GLParam *p) | 
|---|
|  | 125 | { | 
|---|
|  | 126 | int target=p[1].i; | 
|---|
|  | 127 | int level=p[2].i; | 
|---|
|  | 128 | int components=p[3].i; | 
|---|
|  | 129 | int width=p[4].i; | 
|---|
|  | 130 | int height=p[5].i; | 
|---|
|  | 131 | int border=p[6].i; | 
|---|
|  | 132 | int format=p[7].i; | 
|---|
|  | 133 | int type=p[8].i; | 
|---|
|  | 134 | void *pixels=p[9].p; | 
|---|
|  | 135 | GLImage *im; | 
|---|
|  | 136 | unsigned char *pixels1; | 
|---|
|  | 137 | int do_free; | 
|---|
|  | 138 |  | 
|---|
|  | 139 | if (!(target == GL_TEXTURE_2D && level == 0 && components == 3 && | 
|---|
|  | 140 | border == 0 && format == GL_RGB && | 
|---|
|  | 141 | type == GL_UNSIGNED_BYTE)) { | 
|---|
|  | 142 | gl_fatal_error("glTexImage2D: combinaison of parameters not handled"); | 
|---|
|  | 143 | } | 
|---|
|  | 144 |  | 
|---|
|  | 145 | do_free=0; | 
|---|
|  | 146 | if (width != 256 || height != 256) { | 
|---|
|  | 147 | pixels1 = gl_malloc(256 * 256 * 3); | 
|---|
|  | 148 | /* no interpolation is done here to respect the original image aliasing ! */ | 
|---|
|  | 149 | gl_resizeImageNoInterpolate(pixels1,256,256,pixels,width,height); | 
|---|
|  | 150 | do_free=1; | 
|---|
|  | 151 | width=256; | 
|---|
|  | 152 | height=256; | 
|---|
|  | 153 | } else { | 
|---|
|  | 154 | pixels1=pixels; | 
|---|
|  | 155 | } | 
|---|
|  | 156 |  | 
|---|
|  | 157 | im=&c->current_texture->images[level]; | 
|---|
|  | 158 | im->xsize=width; | 
|---|
|  | 159 | im->ysize=height; | 
|---|
|  | 160 | if (im->pixmap!=NULL) gl_free(im->pixmap); | 
|---|
|  | 161 | #if TGL_FEATURE_RENDER_BITS == 24 | 
|---|
|  | 162 | im->pixmap=gl_malloc(width*height*3); | 
|---|
|  | 163 | if(im->pixmap) { | 
|---|
|  | 164 | memcpy(im->pixmap,pixels1,width*height*3); | 
|---|
|  | 165 | } | 
|---|
|  | 166 | #elif TGL_FEATURE_RENDER_BITS == 32 | 
|---|
|  | 167 | im->pixmap=gl_malloc(width*height*4); | 
|---|
|  | 168 | if(im->pixmap) { | 
|---|
|  | 169 | gl_convertRGB_to_8A8R8G8B(im->pixmap,pixels1,width,height); | 
|---|
|  | 170 | } | 
|---|
|  | 171 | #elif TGL_FEATURE_RENDER_BITS == 16 | 
|---|
|  | 172 | im->pixmap=gl_malloc(width*height*2); | 
|---|
|  | 173 | if(im->pixmap) { | 
|---|
|  | 174 | gl_convertRGB_to_5R6G5B(im->pixmap,pixels1,width,height); | 
|---|
|  | 175 | } | 
|---|
|  | 176 | #else | 
|---|
|  | 177 | #error TODO | 
|---|
|  | 178 | #endif | 
|---|
|  | 179 | if (do_free) gl_free(pixels1); | 
|---|
|  | 180 | } | 
|---|
|  | 181 |  | 
|---|
|  | 182 |  | 
|---|
|  | 183 | /* TODO: not all tests are done */ | 
|---|
|  | 184 | void glopTexEnv(GLContext *c,GLParam *p) | 
|---|
|  | 185 | { | 
|---|
|  | 186 | int target=p[1].i; | 
|---|
|  | 187 | int pname=p[2].i; | 
|---|
|  | 188 | int param=p[3].i; | 
|---|
|  | 189 |  | 
|---|
|  | 190 | if (target != GL_TEXTURE_ENV) { | 
|---|
|  | 191 | error: | 
|---|
|  | 192 | gl_fatal_error("glTexParameter: unsupported option"); | 
|---|
|  | 193 | } | 
|---|
|  | 194 |  | 
|---|
|  | 195 | if (pname != GL_TEXTURE_ENV_MODE) goto error; | 
|---|
|  | 196 |  | 
|---|
|  | 197 | if (param != GL_DECAL) goto error; | 
|---|
|  | 198 | } | 
|---|
|  | 199 |  | 
|---|
|  | 200 | /* TODO: not all tests are done */ | 
|---|
|  | 201 | void glopTexParameter(GLContext *c,GLParam *p) | 
|---|
|  | 202 | { | 
|---|
|  | 203 | int target=p[1].i; | 
|---|
|  | 204 | int pname=p[2].i; | 
|---|
|  | 205 | int param=p[3].i; | 
|---|
|  | 206 |  | 
|---|
|  | 207 | if (target != GL_TEXTURE_2D) { | 
|---|
|  | 208 | error: | 
|---|
|  | 209 | gl_fatal_error("glTexParameter: unsupported option"); | 
|---|
|  | 210 | } | 
|---|
|  | 211 |  | 
|---|
|  | 212 | switch(pname) { | 
|---|
|  | 213 | case GL_TEXTURE_WRAP_S: | 
|---|
|  | 214 | case GL_TEXTURE_WRAP_T: | 
|---|
|  | 215 | if (param != GL_REPEAT) goto error; | 
|---|
|  | 216 | break; | 
|---|
|  | 217 | } | 
|---|
|  | 218 | } | 
|---|
|  | 219 |  | 
|---|
|  | 220 | void glopPixelStore(GLContext *c,GLParam *p) | 
|---|
|  | 221 | { | 
|---|
|  | 222 | int pname=p[1].i; | 
|---|
|  | 223 | int param=p[2].i; | 
|---|
|  | 224 |  | 
|---|
|  | 225 | if (pname != GL_UNPACK_ALIGNMENT || | 
|---|
|  | 226 | param != 1) { | 
|---|
|  | 227 | gl_fatal_error("glPixelStore: unsupported option"); | 
|---|
|  | 228 | } | 
|---|
|  | 229 | } | 
|---|