version 2.8
texture.c
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  gl_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  (void)c;
190 
191  if (target != GL_TEXTURE_ENV) {
192  error:
193  gl_fatal_error("glTexParameter: unsupported option");
194  }
195 
196  if (pname != GL_TEXTURE_ENV_MODE) goto error;
197 
198  if (param != GL_DECAL) goto error;
199 }
200 
201 /* TODO: not all tests are done */
202 void glopTexParameter(GLContext *c,GLParam *p)
203 {
204  int target=p[1].i;
205  int pname=p[2].i;
206  int param=p[3].i;
207  (void)c;
208 
209  if (target != GL_TEXTURE_2D) {
210  error:
211  gl_fatal_error("glTexParameter: unsupported option");
212  }
213 
214  switch(pname) {
215  case GL_TEXTURE_WRAP_S:
216  case GL_TEXTURE_WRAP_T:
217  if (param != GL_REPEAT) goto error;
218  break;
219  }
220 }
221 
222 void glopPixelStore(GLContext *c,GLParam *p)
223 {
224  int pname=p[1].i;
225  int param=p[2].i;
226  (void)c;
227 
228  if (pname != GL_UNPACK_ALIGNMENT ||
229  param != 1) {
230  gl_fatal_error("glPixelStore: unsupported option");
231  }
232 }