source: trunk/sys/TinyGL/src/texture.c @ 278

Last change on this file since 278 was 1, checked in by alain, 7 years ago

First import

File size: 4.4 KB
Line 
1/*
2 * Texture Manager
3 */
4
5#include "zgl.h"
6
7static 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
19static 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
43GLTexture *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
62void glInitTextures(GLContext *c)
63{
64  /* textures */
65
66  c->texture_2d_enabled=0;
67  c->current_texture=find_texture(c,0);
68}
69
70void 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
91void 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
109void 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
124void 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 */
184void 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 */
201void 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
220void 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}
Note: See TracBrowser for help on using the repository browser.