Merge branch 'master' of ssh://repo.or.cz/srv/git/tgl
[tgl.git] / src / texture.c
blob6b55cffbd9ec54e0359b62c04c409cd5fa274926
1 /*
2 * Texture Manager
3 */
5 #include "zgl.h"
7 static GLTexture *find_texture(GLContext *c,int h)
9 GLTexture *t;
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;
16 return NULL;
19 static void free_texture(GLContext *c,int h)
21 GLTexture *t,**ht;
22 GLImage *im;
23 int i;
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;
33 if (t->next!=NULL) t->next->prev=t->prev;
35 for(i=0;i<MAX_TEXTURE_LEVELS;i++) {
36 im=&t->images[i];
37 if (im->pixmap != NULL) gl_free(im->pixmap);
40 gl_free(t);
43 GLTexture *alloc_texture(GLContext *c,int h)
45 GLTexture *t,**ht;
47 t=gl_zalloc(sizeof(GLTexture));
49 ht=&c->shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE];
51 t->next=*ht;
52 t->prev=NULL;
53 if (t->next != NULL) t->next->prev=t;
54 *ht=t;
56 t->handle=h;
58 return t;
62 void glInitTextures(GLContext *c)
64 /* textures */
66 c->texture_2d_enabled=0;
67 c->current_texture=find_texture(c,0);
70 void glGenTextures(int n, unsigned int *textures)
72 GLContext *c=gl_get_context();
73 int max,i;
74 GLTexture *t;
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;
85 for(i=0;i<n;i++) {
86 textures[i]=max+i+1;
91 void glDeleteTextures(int n, const unsigned int *textures)
93 GLContext *c=gl_get_context();
94 int i;
95 GLTexture *t;
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);
103 free_texture(c,textures[i]);
109 void glopBindTexture(GLContext *c,GLParam *p)
111 int target=p[1].i;
112 int texture=p[2].i;
113 GLTexture *t;
115 assert(target == GL_TEXTURE_2D && texture >= 0);
117 t=find_texture(c,texture);
118 if (t==NULL) {
119 t=alloc_texture(c,texture);
121 c->current_texture=t;
124 void glopTexImage2D(GLContext *c,GLParam *p)
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;
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");
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;
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);
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);
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);
176 #else
177 #error TODO
178 #endif
179 if (do_free) gl_free(pixels1);
183 /* TODO: not all tests are done */
184 void glopTexEnv(GLContext *c,GLParam *p)
186 int target=p[1].i;
187 int pname=p[2].i;
188 int param=p[3].i;
190 if (target != GL_TEXTURE_ENV) {
191 error:
192 gl_fatal_error("glTexParameter: unsupported option");
195 if (pname != GL_TEXTURE_ENV_MODE) goto error;
197 if (param != GL_DECAL) goto error;
200 /* TODO: not all tests are done */
201 void glopTexParameter(GLContext *c,GLParam *p)
203 int target=p[1].i;
204 int pname=p[2].i;
205 int param=p[3].i;
207 if (target != GL_TEXTURE_2D) {
208 error:
209 gl_fatal_error("glTexParameter: unsupported option");
212 switch(pname) {
213 case GL_TEXTURE_WRAP_S:
214 case GL_TEXTURE_WRAP_T:
215 if (param != GL_REPEAT) goto error;
216 break;
220 void glopPixelStore(GLContext *c,GLParam *p)
222 int pname=p[1].i;
223 int param=p[2].i;
225 if (pname != GL_UNPACK_ALIGNMENT ||
226 param != 1) {
227 gl_fatal_error("glPixelStore: unsupported option");