0022819: Redesign of OpenGl driver
[occt.git] / src / OpenGl / OpenGl_TextureBox.cxx
1 /*
2 * Fonction
3 * ~~~~~~~~
4 *   Gestion des textures sous OpenGL
5 *
6 *
7 * Notes
8 * ~~~~~
9 *   Les textures sont toujours initialisee avec des parametres par defaut
10 *     texture 1D:        WRAP_S = CLAMP
11 *                        MAG_FILTER = NEAREST
12 *                        generation de texture automatique en OBJECT_LINEAR
13 *                        rendu avec DECAL
14 *
15 *     texture 2D:        WRAP_S/T = REPEAT
16 *                        MAG/MIN_FILTER = LINEAR
17 *                        generation de texture automatique en OBJECT_LINEAR
18 *                        rendu avec MODULATE
19 *
20 *     texture 2D MipMap: WRAP_S/T = REPEAT
21 *                        MAG_FILTER = LINEAR
22 *                        MIN_FILTER = LINEAR_MIPMAP_NEAREST
23 *                        generation de texture automatique en OBJECT_LINEAR
24 *                        rendu avec MODULATE
25 *
26 * Historique des modifications
27 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28 *   22-05-97: PCT ; Creation
29 *   18-06-97: FMN ; Ajout entete
30 *   20-06-97: PCT ; Correction bug parametres par defaut texture 1D
31 *   30-06-97: PCT ; Correction bug rechargement de la texture courante
32 *   04-07-97: PCT ; suppression de l'utilisation de libimage.a de SGI
33 *   01-08-97: PCT ; suppression InitializeTextureBox()
34 *   04-08-97: FMN,PCT ; Portage WNT
35 *   05-08-97: FMN ; ajout GetTextureData...
36 *   10-09-97: PCT ; ajout commentaires. GetTexture() ne doit pas
37 *                   etre utilisee dans Cas.Cade ( le chargement est
38 *                   fait par Graphic3d )
39 *   06-10-97: FMN ; Portage HP
40 *   14-10-97: FMN ; Ajout OpenGl_Extension
41 *   22-10-97: FMN ; Meilleure gestion de l'extension glXGetCurrentDisplayEXT
42 *   04-11-97: FMN ; Gestion des differentes versions GLX
43 *   19-11-97: FMN ; Ajout GetCurrentDisplay plus simple que glXGetCurrentDisplayEXT
44 *   04-12-97: FMN ; On suppose que l'on travaille en OpenGL1.1 (cf OpenGl_Extension)
45 *   17-12-97: FMN ; Probleme compilation SGI
46 *   17-12-97: FMN ; Probleme sur Optimisation sur MyBindTextureEXT()
47 *        Le test sur la texture courante doit tenir compte du contexte.
48 *   22-07-98: FGU ; Ajout fonctions TransferTexture_To_Data() et TransferData_To_Texture()
49 *        
50 */
51
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55
56 #include <OpenGl_tgl_all.hxx>
57 #include <OpenGl_Display.hxx>
58 #include <OpenGl_TextureBox.hxx>
59 #include <OpenGl_ImageBox.hxx>
60 #include <OpenGl_Memory.hxx>
61 #include <OpenGl_ResourceCleaner.hxx>
62 #include <OpenGl_ResourceTexture.hxx>
63
64 #define GROW_TEXTURES 8
65 #define GROW_TEXTURES_DATA 8
66 #define GROW_CONTEXT 8
67
68 #ifndef max
69   #define max(a,b) ((a) > (b)) ? (a) : (b);
70 #endif
71
72 typedef enum {TEXDATA_NONE, TEXDATA_1D, TEXDATA_2D, TEXDATA_2DMM} texDataStatus;
73 typedef enum {TEX_NONE, TEX_ALLOCATED} texStatus;
74
75 typedef GLfloat SizeType[4]; 
76
77 typedef int TextureDataID;
78 #define TEXTUREDATA_ERROR -1
79
80 struct texData
81 {
82   char imageFileName[128];
83   int imageWidth, imageHeight;
84   GLubyte *image;
85   texDataStatus status;
86   GLint type;
87   int share_count;
88   IMPLEMENT_MEMORY_OPERATORS
89 };  
90
91
92 struct texDraw
93 {
94   TextureDataID data;
95   GLuint *number;
96   GLDRAWABLE *drawable;
97   GLCONTEXT *context;
98   char *use_bind_texture;
99   int context_count;
100   int context_size;  
101   texStatus status;
102
103   GLint Gen;
104   GLint Light;
105   GLint Wrap;
106   GLfloat Plane1[4];
107   GLfloat Plane2[4];
108   GLint Render;
109   GLfloat scalex, scaley;
110   GLfloat transx, transy;
111   GLfloat angle;
112
113   IMPLEMENT_MEMORY_OPERATORS
114 };
115
116
117 /*----------------------------------------------------------------------*/
118 /*
119 * Variables statiques
120 */
121
122 static texDraw *textab = NULL;
123 static int textures_count = 0;
124 static int textures_size = 0;
125
126 static texData *texdata = NULL;
127 static int textures_data_count = 0;
128 static int textures_data_size = 0;
129
130 static TextureDataID current_texture_data = TEXTUREDATA_ERROR;
131 static TextureID current_texture = TEXTUREBOX_ERROR;
132
133 static GLfloat sgenparams[] = { 1.0 ,0.0 ,0.0 ,0.0};
134 static GLfloat tgenparams[] = { 0.0 ,1.0 ,0.0 ,0.0};
135
136 static GLenum status2type[] = { GL_NONE, GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_2D };
137
138 /*----------------------------------------------------------------------*/
139 /*
140 * Fonctions privees
141 */
142
143 /*----------------------------------------------------------------------*/
144 /*
145 * recherche l'existence de datas de texture par son nom
146 */
147 static TextureDataID FindTextureData(char *FileName)
148 {
149   int i;
150
151   for (i=0; i<textures_data_size; i++)
152     if ( texdata[i].status!=TEXDATA_NONE && strcmp(FileName, texdata[i].imageFileName)==0 )
153       return i;
154
155   return TEXTUREDATA_ERROR;
156 }
157
158 /*----------------------------------------------------------------------*/
159 /*
160 * recherche un emplacement de data texture libre
161 */
162 static TextureDataID FindFreeTextureData(void)
163 {
164   int i;
165
166   /* ya encore de la place ? */
167   if (textures_data_count == textures_data_size)
168   {
169     textures_data_size += GROW_TEXTURES_DATA;
170 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
171     texdata = (texData*)realloc(texdata, textures_data_size*sizeof(texData));
172 #else
173     texdata = cmn_resizemem<texData>(texdata, textures_data_size);
174 #endif
175     if (texdata == NULL) return TEXTUREDATA_ERROR;
176
177     for (i=textures_data_count; i<textures_data_size; i++)
178       texdata[i].status = TEXDATA_NONE;
179
180     /* on a deja assez perdu de temps comme ca => retourne un ID rapidement... */
181     return textures_data_count++;
182   }
183
184   /* recherche d'un ID libre */
185   for (i=0; i<textures_data_size; i++)
186     if (texdata[i].status == TEXDATA_NONE)
187     {
188       textures_data_count = max (textures_data_count, i + 1);
189       return i;
190     }
191
192     return TEXTUREDATA_ERROR;
193 }
194
195 /*----------------------------------------------------------------------*/
196 /*
197 * recherche un emplacement de texture libre
198 */
199 static TextureID FindFreeTexture(void)
200 {
201   int i;
202
203   /* ya encore de la place ? */
204   if (textures_count == textures_size)
205   {
206     textures_size += GROW_TEXTURES;
207 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
208     textab = (texDraw*)realloc(textab, textures_size*sizeof(texDraw));
209 #else
210     textab = cmn_resizemem<texDraw>(textab, textures_size);
211 #endif
212     if (textab == NULL) return TEXTUREBOX_ERROR;
213
214     for (i=textures_count; i<textures_size; i++)
215       textab[i].status = TEX_NONE;
216
217     /* on a deja assez perdu de temps comme ca => retourne un ID rapidement... */
218     return textures_count++;
219   }
220
221   for (i=0; i<textures_size; i++)
222     if (textab[i].status == TEX_NONE)
223     {
224       textures_count = max (textures_count, i + 1);
225       return i;
226     }
227
228     return TEXTUREBOX_ERROR;
229 }
230
231 /*----------------------------------------------------------------------*/
232 /*
233 * regarde si la texture a ete definie pour le contexte courant
234 */
235 static int FindTextureContext(TextureID ID)
236 {
237   int i;
238
239   GLCONTEXT cur = GET_GL_CONTEXT();
240   for (i=0; i<textab[ID].context_count; i++)
241     if (textab[ID].context[i] == cur)
242       return i;
243
244   return TEXTUREBOX_ERROR;
245 }
246
247 /*----------------------------------------------------------------------*/
248 /*
249 * chargement d'une texture suivant son type
250 */
251 static void LoadTexture(TextureID ID)
252 {
253   TextureDataID data;
254
255   data = textab[ID].data;
256   switch (texdata[data].status)
257   {
258   case TEXDATA_1D:
259     glTexImage1D(GL_TEXTURE_1D, 0, 4, 
260       texdata[data].imageWidth, 0,
261       GL_RGBA, GL_UNSIGNED_BYTE, texdata[data].image);
262     break;
263
264   case TEXDATA_2D:
265     glTexImage2D(GL_TEXTURE_2D, 0, 4,
266       texdata[data].imageWidth, texdata[data].imageHeight, 0,
267       GL_RGBA, GL_UNSIGNED_BYTE, texdata[data].image);
268     break;
269
270   case TEXDATA_2DMM:
271     gluBuild2DMipmaps(GL_TEXTURE_2D, 4,
272       texdata[data].imageWidth, 
273       texdata[data].imageHeight,
274       GL_RGBA, GL_UNSIGNED_BYTE, texdata[data].image);
275     break;
276   default:
277     break;
278   }
279 }
280
281 /*----------------------------------------------------------------------*/
282 /*
283 * les parametres d'initialisation d'une texture
284 * NE PAS METTRE DANS UNE DISPLAY LIST POUR L'INSTANT ( pb avec les matrices )
285 */
286 static void SetTextureParam(TextureID ID)
287 {
288   GLint cur_matrix;
289   TextureDataID data;
290
291
292   data = textab[ID].data;
293   glGetIntegerv(GL_MATRIX_MODE, &cur_matrix);
294
295   /*
296   * MISE EN PLACE DE LA MATRICE DE TEXTURE
297   */
298   glMatrixMode(GL_TEXTURE);
299   glLoadIdentity();
300   /* if (textab[ID].Gen != GL_SPHERE_MAP)
301   {*/
302   glScalef(textab[ID].scalex, textab[ID].scaley, 1.0);
303   glTranslatef(-textab[ID].transx, -textab[ID].transy, 0.0);
304   glRotatef(-textab[ID].angle, 0.0, 0.0, 1.0);
305   /*}*/
306
307
308   /*
309   * GENERATION AUTOMATIQUE DE TEXTURE
310   */
311   switch (textab[ID].Gen)
312   {
313   case GL_OBJECT_LINEAR:
314     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
315     glTexGenfv(GL_S, GL_OBJECT_PLANE, textab[ID].Plane1);
316     if (texdata[data].status != TEXDATA_1D)
317     {
318       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
319       glTexGenfv(GL_T, GL_OBJECT_PLANE, textab[ID].Plane2);
320     }
321     break;
322
323   case GL_SPHERE_MAP:
324     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
325     if (texdata[data].status != TEXDATA_1D)
326       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
327     break;
328
329   case GL_EYE_LINEAR:
330     glMatrixMode(GL_MODELVIEW);
331     glPushMatrix();
332     glLoadIdentity();
333
334     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
335     glTexGenfv(GL_S, GL_EYE_PLANE, textab[ID].Plane1);
336
337     if (texdata[data].status != TEXDATA_1D)
338     {
339       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
340       glTexGenfv(GL_T, GL_EYE_PLANE, textab[ID].Plane2);
341     }
342
343     glPopMatrix();
344     break;
345   }
346
347
348   /*
349   * RENDU DE LA TEXTURE AVEC LES LUMIERES
350   */
351   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, textab[ID].Light);
352
353
354   /*
355   * LISSAGE DE LA TEXTURE
356   */
357   switch (texdata[data].status)
358   {
359   case TEXDATA_1D:
360   case TEXDATA_2D:
361     glTexParameteri(texdata[data].type, GL_TEXTURE_MAG_FILTER, textab[ID].Render);
362     glTexParameteri(texdata[data].type, GL_TEXTURE_MIN_FILTER, textab[ID].Render);
363     break;
364
365   case TEXDATA_2DMM:
366     if (textab[ID].Render == GL_NEAREST)
367     {
368       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
369       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
370     }
371     else
372     {
373       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
374       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
375     }
376     break;  
377   default:
378     break;
379   }
380
381
382   /*
383   * WRAP DE LA TEXTURE
384   */
385   switch (texdata[data].status)
386   {
387   case TEXDATA_1D:
388     glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, textab[ID].Wrap);
389     break;
390
391   case TEXDATA_2D:
392   case TEXDATA_2DMM:
393     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, textab[ID].Wrap);
394     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, textab[ID].Wrap);
395     break;
396   default:
397     break;
398   }
399
400   glMatrixMode(cur_matrix);
401 }
402
403 /*----------------------------------------------------------------------*/
404 /*
405 * simulation du glGenTexturesEXT pour un context
406 */
407 static void MyGenTextureEXT (TextureID ID)
408 {
409   int Context = textab[ID].context_count;
410   TextureDataID data = textab[ID].data;
411
412   textab[ID].context[Context]  = GET_GL_CONTEXT();
413   textab[ID].drawable[Context] = GET_GLDEV_CONTEXT();
414   textab[ID].use_bind_texture[Context] = (char )GL_TRUE;
415   glGenTextures (1, &textab[ID].number[Context]);
416   glBindTexture (texdata[data].type, textab[ID].number[Context]);
417   LoadTexture (ID);
418   textab[ID].context_count++;
419 }
420
421 /*----------------------------------------------------------------------*/
422 /*
423 * simulation du glBindTextureEXT
424 */
425 static void MyBindTextureEXT (TextureID ID, int Context)
426 {
427   // si l'extension est presente, c'est facile
428   TextureDataID data = textab[ID].data;
429   if (textab[ID].status == TEXDATA_NONE)
430     return;
431
432   // OCC11904 - make sure that the correct texture is bound before drawing
433   GLenum aParamName = textab[ID].status == TEXDATA_1D ? GL_TEXTURE_BINDING_1D : GL_TEXTURE_BINDING_2D;
434   GLint aCurrTex = -1;
435   glGetIntegerv (aParamName, &aCurrTex);
436   if (textab[ID].number[Context] != aCurrTex)
437   {
438     glBindTexture (texdata[data].type, textab[ID].number[Context]);
439   }
440 }
441
442 /*----------------------------------------------------------------------*/
443 /*
444 * installation de la texture pour le dernier contexte
445 */
446 static int InstallTextureInContext(TextureID ID)
447 {
448 #ifdef PRINT
449   printf("InstallTextureInContext::installation de la texture dans le context\n");
450 #endif
451
452
453   /* ya encore de la place dans le tableau de context ? */
454   if (textab[ID].context_count == textab[ID].context_size)
455   {
456 #ifdef PRINT
457     printf("InstallTextureInContext::allocation dans le context\n");
458 #endif
459     textab[ID].context_size += GROW_CONTEXT;
460 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
461     textab[ID].number =
462       (GLuint*)realloc(textab[ID].number, textab[ID].context_size*sizeof(GLuint));
463     textab[ID].context =
464       (GLCONTEXT*)realloc(textab[ID].context, textab[ID].context_size*sizeof(GLCONTEXT));
465     textab[ID].drawable =
466       (GLDRAWABLE*)realloc(textab[ID].drawable, textab[ID].context_size*sizeof(GLDRAWABLE));
467     textab[ID].use_bind_texture =
468       (char*)realloc(textab[ID].use_bind_texture, textab[ID].context_size);
469 #else
470     textab[ID].number =
471       cmn_resizemem<GLuint>(textab[ID].number, textab[ID].context_size);
472     textab[ID].context =
473       cmn_resizemem<GLCONTEXT>(textab[ID].context, textab[ID].context_size);
474     textab[ID].drawable =
475       cmn_resizemem<GLDRAWABLE>(textab[ID].drawable, textab[ID].context_size);
476     textab[ID].use_bind_texture =
477       cmn_resizemem<char>(textab[ID].use_bind_texture, textab[ID].context_size);
478 #endif
479     if ( (textab[ID].number == NULL) ||
480       (textab[ID].context == NULL) ||
481       (textab[ID].drawable == NULL) ||
482       (textab[ID].use_bind_texture == NULL) )
483     {
484       /* erreur => libere tout */
485       free(textab[ID].number);
486       free(textab[ID].context);
487       free(textab[ID].drawable);
488       free(textab[ID].use_bind_texture);
489       textab[ID].context_size = 0;
490
491       return TEXTUREBOX_ERROR;
492     }
493   }
494
495   MyGenTextureEXT(ID);
496   SetTextureParam(ID);
497 #ifdef PRINT
498   printf("InstallTextureInContext::context ok\n");
499 #endif
500   return 0;
501 }  
502
503 /*----------------------------------------------------------------------*/
504 static TextureID GetTexture(char *FileName, texDataStatus status)
505 {
506   TextureDataID i;
507   TextureID j;
508   int dummy;
509
510   /* essait de trouver la texture */
511   i = FindTextureData(FileName);
512   if (i == TEXTUREDATA_ERROR)
513   {
514 #ifdef PRINT
515     printf("GetTexture::la texture %s n'existe pas => chargement\n", FileName);
516 #endif
517     /* creation d'une texture */
518     i = FindFreeTextureData();
519     if (i == TEXTUREDATA_ERROR) return TEXTUREBOX_ERROR;
520
521     texdata[i].share_count = 0;
522     strcpy(texdata[i].imageFileName, FileName);
523     texdata[i].image = (GLubyte *)read_texture(FileName, 
524       &texdata[i].imageWidth,
525       &texdata[i].imageHeight,
526       &dummy);
527     if (texdata[i].image == NULL) return TEXTUREBOX_ERROR;
528
529     texdata[i].status = status;            
530     texdata[i].type = status2type[status];
531   }
532
533   j = FindFreeTexture();
534   if (j != TEXTUREBOX_ERROR)
535   {
536 #ifdef PRINT
537     printf("GetTexture::installation texture pour obj %d\n", j);
538 #endif
539     textab[j].context_count = 0;
540     textab[j].context_size = 0;
541     textab[j].number = NULL;
542     textab[j].drawable = NULL;
543     textab[j].context = NULL;
544     textab[j].use_bind_texture = NULL;
545     textab[j].data = i;
546     textab[j].status = TEX_ALLOCATED;
547     texdata[i].share_count++;
548
549     SetTextureDefaultParams(j);
550
551 #ifdef PRINT
552     printf("GetTexture::texture %s(%d)    texture %d   count=%d\n", texdata[i].imageFileName, i, j, texdata[i].share_count);
553 #endif
554   }
555   else
556     if (texdata[i].share_count != 0)
557       free(texdata[i].image);  
558
559   return j;
560 }
561
562
563 /*----------------------------------------------------------------------*/
564 static TextureID GetTextureData(char *FileName, texDataStatus status, const GLint width, const GLint height, const void *data)
565 {
566   TextureDataID i;
567   TextureID j;
568
569   /* essait de trouver la texture */
570   i = FindTextureData(FileName);
571   if (i == TEXTUREDATA_ERROR)
572   {
573 #ifdef PRINT
574     printf("GetTextureData::la texture %s n'existe pas => chargement\n", FileName);
575 #endif
576     /* creation d'une texture */
577     i = FindFreeTextureData();
578     if (i == TEXTUREDATA_ERROR) return TEXTUREBOX_ERROR;
579
580     texdata[i].share_count = 0;
581     strcpy(texdata[i].imageFileName, FileName);
582     texdata[i].image = (GLubyte *)malloc(width*height*4*sizeof(GLubyte));
583     memcpy(texdata[i].image, data, (width*height*4));
584     texdata[i].imageWidth = width;
585     texdata[i].imageHeight = height;
586
587     if (texdata[i].image == NULL) return TEXTUREBOX_ERROR;
588
589     texdata[i].status = status;            
590     texdata[i].type = status2type[status];
591   }
592
593   j = FindFreeTexture();
594   if (j != TEXTUREBOX_ERROR)
595   {
596 #ifdef PRINT
597     printf("GetTextureData::installation texture pour obj %d\n", j);
598 #endif
599     textab[j].context_count = 0;
600     textab[j].context_size = 0;
601     textab[j].number = NULL;
602     textab[j].drawable = NULL;
603     textab[j].context = NULL;
604     textab[j].use_bind_texture = NULL;
605     textab[j].data = i;
606     textab[j].status = TEX_ALLOCATED;
607     texdata[i].share_count++;
608
609     SetTextureDefaultParams(j);
610
611 #ifdef PRINT
612     printf("GetTextureData::texture %s(%d)    texture %d   count=%d\n", texdata[i].imageFileName, i, j, texdata[i].share_count);
613 #endif
614   }
615   else
616     if (texdata[i].share_count != 0)
617       free(texdata[i].image);  
618
619   return j;
620 }
621
622 /*----------------------------------------------------------------------*/
623 /*
624 * Fonctions publiques 
625 */
626
627
628 /*----------------------------------------------------------------------*/
629
630 GLboolean IsTextureValid(TextureID ID)
631 {
632   if ((ID<0) | (ID>=textures_count))
633     return GL_FALSE;
634
635   if (textab)
636     return textab[ID].status == TEX_ALLOCATED;
637   else
638     return GL_TRUE;
639 }
640
641 /*----------------------------------------------------------------------*/
642
643 TextureID GetTexture1D(char *FileName)
644 {
645 #ifdef PRINT
646   printf("GetTexture1D::loading 1d %s   \n", FileName);
647 #endif
648   return GetTexture(FileName, TEXDATA_1D);
649 }
650
651 /*----------------------------------------------------------------------*/
652
653 TextureID GetTexture2D(char *FileName)
654 {
655 #ifdef PRINT
656   printf("GetTexture2D::loading 2d %s   \n", FileName);
657 #endif
658   return GetTexture(FileName, TEXDATA_2D);
659 }
660
661 /*----------------------------------------------------------------------*/
662
663 TextureID GetTexture2DMipMap(char *FileName)
664 {
665 #ifdef PRINT
666   printf("GetTexture2DMipMap::loading 2dmm %s   \n", FileName);
667 #endif
668   return GetTexture(FileName, TEXDATA_2DMM);
669 }
670
671 /*----------------------------------------------------------------------*/
672
673 TextureID GetTextureData1D(char *FileName, const GLint width, const GLint height, const void *data)
674 {
675 #ifdef PRINT
676   printf("GetTextureData1D::loading 1d %s  \n", FileName);
677 #endif
678   return GetTextureData(FileName, TEXDATA_1D, width, height, data);
679 }
680
681 /*----------------------------------------------------------------------*/
682
683 TextureID GetTextureData2D(char *FileName, const GLint width, const GLint height, const void *data)
684 {
685 #ifdef PRINT
686   printf("GetTextureData2D::loading 2d %s   \n", FileName);
687 #endif
688   return GetTextureData(FileName, TEXDATA_2D, width, height, data);
689 }
690
691 /*----------------------------------------------------------------------*/
692
693 TextureID GetTextureData2DMipMap(char *FileName, const GLint width, const GLint height, const void *data)
694 {
695 #ifdef PRINT
696   printf("GetTextureData2DMipMap::loading 2dmm %s   \n", FileName);
697 #endif
698   return GetTextureData(FileName, TEXDATA_2DMM, width, height, data);
699 }
700
701
702 /*----------------------------------------------------------------------*/
703
704 void SetCurrentTexture(TextureID ID)
705 {
706   int context;
707
708   if (!IsTextureValid(ID)) return;
709
710   context = FindTextureContext(ID);
711
712   /* la texture n'existe pas dans ce contexte */
713   if (context == TEXTUREBOX_ERROR)
714   {
715 #ifdef PRINT
716     printf("SetCurrentTexture::installation texture %d dans context\n", ID);
717 #endif
718     /* si on a une erreur pendant l'installation dans le context
719     * alors on installe la texture sans bind */
720     if (InstallTextureInContext(ID) == TEXTUREBOX_ERROR)
721     {
722       LoadTexture(ID);
723       SetTextureParam(ID);
724     }
725   }
726
727   /*oui, alors on bind directement */
728   else
729   {
730 #ifdef PRINT
731     printf("SetCurrentTexture: utilisation du bind %d\n", ID);
732 #endif
733     MyBindTextureEXT(ID, context); 
734     SetTextureParam(ID);
735   }
736
737   current_texture = ID;
738   current_texture_data = textab[ID].data;
739 }
740
741 /*----------------------------------------------------------------------*/
742
743 void FreeTexture(TextureID ID)
744 {
745   TextureDataID data;
746   bool notResource = false; // if there old-style texture deletion
747
748   GLCONTEXT cur_context;
749   GLDRAWABLE cur_drawable;
750   int i;
751
752   if (!IsTextureValid(ID)) return;
753
754   data = textab[ID].data;
755   texdata[data].share_count--;
756   if (texdata[data].share_count == 0)
757   {      
758     // liberation des datas de la textures
759     free(texdata[data].image);
760
761     // liberation de la texture dans tous les contextes
762     cur_drawable = GET_GLDEV_CONTEXT();
763     for (i = 0; i < textab[ID].context_count; ++i)
764     {
765       cur_context = 0;
766       bool isResource = false; 
767
768       if (textab[ID].use_bind_texture[i])
769       {
770         if( !OpenGl_ResourceCleaner::GetInstance()->AddResource(textab[ID].context[i], 
771                       new OpenGl_ResourceTexture(textab[ID].number[i])) )
772         {
773           GL_MAKE_CURRENT((openglDisplay.IsNull() ? (Display* )NULL : (Display* )openglDisplay->GetDisplay()),
774             textab[ID].drawable[i],
775             textab[ID].context[i]);
776
777           // This check has been added to avoid exception, 
778           // which is raised when trying to delete textures when no rendering context is available
779           cur_context = GET_GL_CONTEXT();
780           if (cur_context)
781             glDeleteTextures (1, &textab[ID].number[i]);
782           notResource = true;
783         }
784         else
785         {
786           isResource = true;
787         }
788       }
789
790       if( !isResource && cur_context )
791         glFinish();
792     }
793
794     if( notResource )
795       GL_MAKE_CURRENT((openglDisplay.IsNull() ? (Display* )NULL : (Display* )openglDisplay->GetDisplay()),
796                       cur_drawable, cur_context);
797
798     texdata[data].status = TEXDATA_NONE;
799     if (data + 1 == textures_data_count)
800     {
801       --textures_data_count;
802     }
803
804     free(textab[ID].context);
805     free(textab[ID].drawable);
806     free(textab[ID].use_bind_texture);
807     free(textab[ID].number);
808   }
809
810   textab[ID].status = TEX_NONE;
811   if (ID + 1 == textures_count)
812   {
813     --textures_count;
814   }
815
816   current_texture_data = TEXTUREDATA_ERROR;
817 }
818
819 /*----------------------------------------------------------------------*/
820
821 void EnableTexture(void)
822 {
823   if (!IsTextureValid(current_texture)) return;
824
825   switch (texdata[current_texture_data].status)
826   {
827   case TEXDATA_1D:
828     if (textab[current_texture].Gen != GL_NONE) 
829       glEnable(GL_TEXTURE_GEN_S);
830     glEnable(GL_TEXTURE_1D);
831     break;
832
833   case TEXDATA_2D:
834   case TEXDATA_2DMM:
835     if (textab[current_texture].Gen != GL_NONE)
836     {
837       glEnable(GL_TEXTURE_GEN_S);
838       glEnable(GL_TEXTURE_GEN_T);
839     }
840     glEnable(GL_TEXTURE_2D);
841     break;
842   default:
843     break;
844   }
845 }
846
847 /*----------------------------------------------------------------------*/
848
849 void DisableTexture(void)
850 {
851   if ( !IsTextureEnabled() ) 
852     return;
853   if ( !IsTextureValid( current_texture ) ) 
854     return;
855
856   switch (texdata[current_texture_data].status)
857   {
858   case TEXDATA_1D:
859     if (textab[current_texture].Gen != GL_NONE) 
860       glDisable(GL_TEXTURE_GEN_S);
861     glDisable(GL_TEXTURE_1D);
862     break;
863
864   case TEXDATA_2D:
865   case TEXDATA_2DMM:
866     if (textab[current_texture].Gen != GL_NONE)
867     {
868       glDisable(GL_TEXTURE_GEN_S);
869       glDisable(GL_TEXTURE_GEN_T);
870     }
871     glDisable(GL_TEXTURE_2D);
872     break;
873   default:
874     break;
875   }
876 }
877
878 /*----------------------------------------------------------------------*/
879
880 GLboolean IsTextureEnabled(void)
881 {
882   GLboolean isEnabled1D= GL_FALSE, isEnabled2D= GL_FALSE;
883   glGetBooleanv( GL_TEXTURE_1D, &isEnabled1D );
884   glGetBooleanv( GL_TEXTURE_2D, &isEnabled2D );
885   return isEnabled1D || isEnabled2D;
886 }
887
888 /*----------------------------------------------------------------------*/
889
890 void SetTextureModulate(TextureID ID)
891 {
892   if (!IsTextureValid(ID)) return;
893
894   textab[ID].Light = GL_MODULATE;
895 }
896
897 /*----------------------------------------------------------------------*/
898
899 void SetTextureDecal(TextureID ID)
900 {
901   if (!IsTextureValid(ID)) return;
902
903   textab[ID].Light = GL_DECAL;
904 }
905
906 /*----------------------------------------------------------------------*/
907
908 void SetTextureClamp(TextureID ID)
909 {
910   if (!IsTextureValid(ID)) return;
911
912   textab[ID].Wrap = GL_CLAMP;
913 }
914
915 /*----------------------------------------------------------------------*/
916
917 void SetTextureRepeat(TextureID ID)
918 {
919   if (!IsTextureValid(ID)) return;
920
921   textab[ID].Wrap = GL_REPEAT;
922 }
923
924 /*----------------------------------------------------------------------*/
925
926 /* gestion de la facon d'appliquer la texture */
927 void SetModeObject(TextureID ID, GLfloat sparams[4], GLfloat tparams[4])
928 {
929   if (!IsTextureValid(ID)) return;
930
931   textab[ID].Gen = GL_OBJECT_LINEAR;
932   if (sparams != NULL) memcpy(textab[ID].Plane1, sparams, sizeof(sgenparams));
933   else                 memcpy(textab[ID].Plane1, sgenparams, sizeof(sgenparams));
934
935   if (texdata[textab[ID].data].status != TEXDATA_1D) {
936     if (tparams != NULL) memcpy(textab[ID].Plane2, tparams, sizeof(tgenparams));
937     else                 memcpy(textab[ID].Plane2, tgenparams, sizeof(tgenparams));
938   }
939 }
940
941 /*----------------------------------------------------------------------*/
942
943 void SetModeSphere(TextureID ID)
944 {
945   if (!IsTextureValid(ID)) return;
946
947   textab[ID].Gen = GL_SPHERE_MAP;
948 }
949
950 /*----------------------------------------------------------------------*/
951
952 void SetModeEye(TextureID ID, GLfloat sparams[4], GLfloat tparams[4])
953 {  
954   if (!IsTextureValid(ID)) return;
955
956   textab[ID].Gen = GL_EYE_LINEAR;
957   if (sparams != NULL) memcpy(textab[ID].Plane1, sparams, sizeof(sgenparams));
958   else                 memcpy(textab[ID].Plane1, sgenparams, sizeof(sgenparams));
959
960   if (texdata[textab[ID].data].status != TEXDATA_1D) {
961     if (tparams != NULL) memcpy(textab[ID].Plane2, tparams, sizeof(tgenparams));
962     else                 memcpy(textab[ID].Plane2, tgenparams, sizeof(tgenparams));
963   }
964 }
965
966 /*----------------------------------------------------------------------*/
967
968 void SetModeManual(TextureID ID)
969 {
970   if (!IsTextureValid(ID)) return;
971
972   textab[ID].Gen = GL_NONE;
973 }
974
975 /*----------------------------------------------------------------------*/
976
977 void SetRenderNearest(TextureID ID)
978 {
979   if (!IsTextureValid(ID)) return;
980
981   textab[ID].Render = GL_NEAREST;
982 }
983
984 /*----------------------------------------------------------------------*/
985
986 void SetRenderLinear(TextureID ID)
987 {
988   if (!IsTextureValid(ID)) return;
989
990   textab[ID].Render = GL_LINEAR;
991 }
992
993 /*----------------------------------------------------------------------*/
994
995 void SetTexturePosition(TextureID ID,
996                         GLfloat scalex, GLfloat scaley,
997                         GLfloat transx, GLfloat transy,
998                         GLfloat angle)
999 {
1000   textab[ID].scalex = scalex;
1001   textab[ID].scaley = scaley;
1002   textab[ID].transx = transx;
1003   textab[ID].transy = transy;
1004   textab[ID].angle = angle;
1005 }
1006
1007 /*----------------------------------------------------------------------*/
1008
1009 void SetTextureDefaultParams(TextureID ID)
1010 {
1011   if (!IsTextureValid(ID)) return;
1012
1013 #ifdef PRINT
1014   printf("SetTextureDefaultParams::set parm par defaut textures\n");
1015 #endif
1016
1017
1018   textab[ID].scalex = 1.0;
1019   textab[ID].scaley = 1.0;
1020   textab[ID].transx = 0.0;
1021   textab[ID].transy = 0.0;
1022   textab[ID].angle = 0.0;
1023
1024   textab[ID].Gen = GL_OBJECT_LINEAR;
1025   textab[ID].Light = texdata[textab[ID].data].status == TEXDATA_1D ? GL_DECAL : GL_MODULATE;
1026   textab[ID].Wrap = texdata[textab[ID].data].status == TEXDATA_1D ? GL_CLAMP : GL_REPEAT;
1027   memcpy(textab[ID].Plane1, sgenparams, sizeof(sgenparams));
1028   memcpy(textab[ID].Plane2, tgenparams, sizeof(tgenparams));
1029   textab[ID].Render = texdata[textab[ID].data].status == TEXDATA_1D ? GL_NEAREST : GL_LINEAR;
1030 }
1031
1032 /*----------------------------------------------------------------------*/
1033 /* Transfere de donnee des donnees internes a la structure TransferData */
1034 void TransferTexture_To_Data(TextureID ID, TextureData *TransfDt)
1035 {
1036   /* affectations */    
1037   strcpy(TransfDt->path, texdata[textab[ID].data].imageFileName);    
1038   TransfDt->gen = textab[ID].Gen;
1039   TransfDt->wrap  = textab[ID].Wrap;
1040   TransfDt->render  = textab[ID].Light;
1041   TransfDt->scalex  = textab[ID].scalex;
1042   TransfDt->scaley  = textab[ID].scaley;
1043   TransfDt->transx  = textab[ID].transx;
1044   TransfDt->transy  = textab[ID].transy;
1045   TransfDt->angle = textab[ID].angle;            
1046   memcpy(TransfDt->plane1,  textab[ID].Plane1, sizeof(SizeType));
1047   memcpy(TransfDt->plane2,  textab[ID].Plane2, sizeof(SizeType));                
1048 }
1049
1050 /*----------------------------------------------------------------------*/
1051 /* Transfere de donnee de la structure TransferData aux donnees internes */
1052 void TransferData_To_Texture(TextureData *TransfDt, TextureID *newID)
1053 {                            
1054   TextureID ID;
1055
1056   /* Affectations */
1057   FreeTexture(*newID);     
1058   ID = GetTexture2DMipMap(TransfDt->path);  
1059
1060   if(IsTextureValid(ID))
1061   {
1062     /* Affectation de l id courant */
1063     *newID = ID;
1064
1065     /* Donnees concernant les caracteristiques de la texture */ 
1066     strcpy(texdata[textab[ID].data].imageFileName, TransfDt->path);       
1067     textab[ID].Gen    = TransfDt->gen;
1068     textab[ID].Wrap   = TransfDt->wrap;
1069     textab[ID].Light  = TransfDt->render;
1070     textab[ID].scalex = TransfDt->scalex;
1071     textab[ID].scaley = TransfDt->scaley; 
1072     textab[ID].transx = TransfDt->transx;
1073     textab[ID].transy = TransfDt->transy;
1074     textab[ID].angle  = TransfDt->angle;
1075     memcpy(textab[ID].Plane1,  TransfDt->plane1, sizeof(SizeType));
1076     memcpy(textab[ID].Plane2,  TransfDt->plane2, sizeof(SizeType)); 
1077   }               
1078 }