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