0023363: [Regression] Lost gradient background when switching to the hollow interior...
[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_ResourceTexture.hxx>
78 #include <OpenGl_Context.hxx>
79
80 #include <GL/glu.h> // gluBuild2DMipmaps()
81
82 #include <NCollection_Vector.hxx>
83
84 typedef enum {TEXDATA_NONE, TEXDATA_1D, TEXDATA_2D, TEXDATA_2DMM} texDataStatus;
85 typedef enum {TEX_NONE, TEX_ALLOCATED} texStatus;
86
87 typedef GLfloat SizeType[4]; 
88
89 typedef int TextureDataID;
90 #define TEXTUREDATA_ERROR -1
91
92 struct texData
93 {
94   char imageFileName[128];
95   int imageWidth, imageHeight;
96   GLubyte *image;
97   texDataStatus status;
98   GLint type;
99   int share_count;
100   DEFINE_STANDARD_ALLOC
101 };  
102
103 struct contextData
104 {
105   GLuint number;
106   GLDRAWABLE drawable;
107   GLCONTEXT context;
108 };
109
110 struct texDraw
111 {
112   TextureDataID data;
113   NCollection_Vector<contextData> contextdata;
114   texStatus status;
115
116   GLint Gen;
117   GLint Light;
118   GLint Wrap;
119   GLfloat Plane1[4];
120   GLfloat Plane2[4];
121   GLint Render;
122   GLfloat scalex, scaley;
123   GLfloat transx, transy;
124   GLfloat angle;
125
126   DEFINE_STANDARD_ALLOC
127 };
128
129
130 /*----------------------------------------------------------------------*/
131 /*
132 * Variables statiques
133 */
134
135 static NCollection_Vector<texDraw> textab;
136
137 static NCollection_Vector<texData> texdata;
138
139 static TextureDataID current_texture_data = TEXTUREDATA_ERROR;
140 static TextureID current_texture = TEXTUREBOX_ERROR;
141
142 static GLfloat sgenparams[] = { 1.0 ,0.0 ,0.0 ,0.0};
143 static GLfloat tgenparams[] = { 0.0 ,1.0 ,0.0 ,0.0};
144
145 static GLenum status2type[] = { GL_NONE, GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_2D };
146
147 /*----------------------------------------------------------------------*/
148 /*
149 * Fonctions privees
150 */
151
152 /*----------------------------------------------------------------------*/
153 /*
154 * recherche l'existence de datas de texture par son nom
155 */
156 static TextureDataID FindTextureData(char *FileName)
157 {
158   for (int i = 0; i < texdata.Length(); i++)
159   {
160     if ( texdata(i).status != TEXDATA_NONE && strcmp(FileName, texdata(i).imageFileName) == 0 )
161     {
162       return i;
163     }
164   }
165
166   return TEXTUREDATA_ERROR;
167 }
168
169 /*----------------------------------------------------------------------*/
170 /*
171 * recherche un emplacement de data texture libre
172 */
173 static TextureDataID FindFreeTextureData(void)
174 {
175   for (int i = 0; i < texdata.Length(); i++)
176   {
177     if (texdata(i).status == TEXDATA_NONE)
178     {
179       return i;
180     }
181   }
182
183   texData aTexData;
184   texdata.Append(aTexData);
185   return texdata.Length() - 1;
186 }
187
188 /*----------------------------------------------------------------------*/
189 /*
190 * recherche un emplacement de texture libre
191 */
192 static TextureID FindFreeTexture(void)
193 {
194   for (int i = 0; i < textab.Length(); i++)
195   {
196     if (textab(i).status == TEX_NONE)
197     {
198       return i;
199     }
200   }
201
202   texDraw aTexDraw;
203   textab.Append(aTexDraw);
204   return textab.Length() - 1;
205 }
206
207 /*----------------------------------------------------------------------*/
208 /*
209 * regarde si la texture a ete definie pour le contexte courant
210 */
211 static int FindTextureContext(TextureID ID)
212 {
213   int i;
214
215   GLCONTEXT cur = GET_GL_CONTEXT();
216   for (i=0; i<textab(ID).contextdata.Length(); i++)
217     if (textab(ID).contextdata(i).context == cur)
218       return i;
219
220   return TEXTUREBOX_ERROR;
221 }
222
223 /*----------------------------------------------------------------------*/
224 /*
225 * chargement d'une texture suivant son type
226 */
227 static void LoadTexture(TextureID ID)
228 {
229   TextureDataID data;
230
231   data = textab(ID).data;
232   switch (texdata(data).status)
233   {
234   case TEXDATA_1D:
235     glTexImage1D(GL_TEXTURE_1D, 0, 4, 
236       texdata(data).imageWidth, 0,
237       GL_RGBA, GL_UNSIGNED_BYTE, texdata(data).image);
238     break;
239
240   case TEXDATA_2D:
241     glTexImage2D(GL_TEXTURE_2D, 0, 4,
242       texdata(data).imageWidth, texdata(data).imageHeight, 0,
243       GL_RGBA, GL_UNSIGNED_BYTE, texdata(data).image);
244     break;
245
246   case TEXDATA_2DMM:
247     gluBuild2DMipmaps(GL_TEXTURE_2D, 4,
248       texdata(data).imageWidth, 
249       texdata(data).imageHeight,
250       GL_RGBA, GL_UNSIGNED_BYTE, texdata(data).image);
251     break;
252   default:
253     break;
254   }
255 }
256
257 /*----------------------------------------------------------------------*/
258 /*
259 * les parametres d'initialisation d'une texture
260 * NE PAS METTRE DANS UNE DISPLAY LIST POUR L'INSTANT ( pb avec les matrices )
261 */
262 static void SetTextureParam(TextureID ID)
263 {
264   GLint cur_matrix;
265   TextureDataID data;
266
267
268   data = textab(ID).data;
269   glGetIntegerv(GL_MATRIX_MODE, &cur_matrix);
270
271   /*
272   * MISE EN PLACE DE LA MATRICE DE TEXTURE
273   */
274   glMatrixMode(GL_TEXTURE);
275   glLoadIdentity();
276   /* if (textab(ID).Gen != GL_SPHERE_MAP)
277   {*/
278   glScalef(textab(ID).scalex, textab(ID).scaley, 1.0);
279   glTranslatef(-textab(ID).transx, -textab(ID).transy, 0.0);
280   glRotatef(-textab(ID).angle, 0.0, 0.0, 1.0);
281   /*}*/
282
283
284   /*
285   * GENERATION AUTOMATIQUE DE TEXTURE
286   */
287   switch (textab(ID).Gen)
288   {
289   case GL_OBJECT_LINEAR:
290     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
291     glTexGenfv(GL_S, GL_OBJECT_PLANE, textab(ID).Plane1);
292     if (texdata(data).status != TEXDATA_1D)
293     {
294       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
295       glTexGenfv(GL_T, GL_OBJECT_PLANE, textab(ID).Plane2);
296     }
297     break;
298
299   case GL_SPHERE_MAP:
300     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
301     if (texdata(data).status != TEXDATA_1D)
302       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
303     break;
304
305   case GL_EYE_LINEAR:
306     glMatrixMode(GL_MODELVIEW);
307     glPushMatrix();
308     glLoadIdentity();
309
310     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
311     glTexGenfv(GL_S, GL_EYE_PLANE, textab(ID).Plane1);
312
313     if (texdata(data).status != TEXDATA_1D)
314     {
315       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
316       glTexGenfv(GL_T, GL_EYE_PLANE, textab(ID).Plane2);
317     }
318
319     glPopMatrix();
320     break;
321   }
322
323
324   /*
325   * RENDU DE LA TEXTURE AVEC LES LUMIERES
326   */
327   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, textab(ID).Light);
328
329
330   /*
331   * LISSAGE DE LA TEXTURE
332   */
333   switch (texdata(data).status)
334   {
335   case TEXDATA_1D:
336   case TEXDATA_2D:
337     glTexParameteri(texdata(data).type, GL_TEXTURE_MAG_FILTER, textab(ID).Render);
338     glTexParameteri(texdata(data).type, GL_TEXTURE_MIN_FILTER, textab(ID).Render);
339     break;
340
341   case TEXDATA_2DMM:
342     if (textab(ID).Render == GL_NEAREST)
343     {
344       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
345       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
346     }
347     else
348     {
349       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
350       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
351     }
352     break;  
353   default:
354     break;
355   }
356
357
358   /*
359   * WRAP DE LA TEXTURE
360   */
361   switch (texdata(data).status)
362   {
363   case TEXDATA_1D:
364     glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, textab(ID).Wrap);
365     break;
366
367   case TEXDATA_2D:
368   case TEXDATA_2DMM:
369     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, textab(ID).Wrap);
370     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, textab(ID).Wrap);
371     break;
372   default:
373     break;
374   }
375
376   glMatrixMode(cur_matrix);
377 }
378
379 /*----------------------------------------------------------------------*/
380 /*
381 * simulation du glGenTexturesEXT pour un context
382 */
383 static void MyGenTextureEXT (TextureID ID)
384 {
385   TextureDataID data = textab(ID).data;
386   contextData aContextData;
387
388   aContextData.context = GET_GL_CONTEXT();
389   aContextData.drawable = GET_GLDEV_CONTEXT();
390   glGenTextures (1, &aContextData.number);
391   textab(ID).contextdata.Append(aContextData);
392   glBindTexture (texdata(data).type, aContextData.number);
393   LoadTexture (ID);
394 }
395
396 /*----------------------------------------------------------------------*/
397 /*
398 * simulation du glBindTextureEXT
399 */
400 static void MyBindTextureEXT (TextureID ID, int Context)
401 {
402   TextureDataID data = textab(ID).data;
403   if (texdata(data).status == TEXDATA_NONE)
404     return;
405
406   GLenum aParamName = texdata(data).status == TEXDATA_1D ? 
407   GL_TEXTURE_BINDING_1D : GL_TEXTURE_BINDING_2D;
408
409   GLint aCurrTex = -1;
410   glGetIntegerv (aParamName, &aCurrTex);
411   if (textab(ID).contextdata(Context).number != aCurrTex)
412   {
413     glBindTexture (texdata(data).type, textab(ID).contextdata(Context).number);
414   }
415 }
416
417 /*----------------------------------------------------------------------*/
418 /*
419 * installation de la texture pour le dernier contexte
420 */
421 static int InstallTextureInContext(TextureID ID)
422 {
423 #ifdef PRINT
424   printf("InstallTextureInContext::installation de la texture dans le context\n");
425 #endif
426   MyGenTextureEXT(ID);
427   SetTextureParam(ID);
428 #ifdef PRINT
429   printf("InstallTextureInContext::context ok\n");
430 #endif
431   return 0;
432 }  
433
434 /*----------------------------------------------------------------------*/
435 static TextureID GetTexture(char *FileName, texDataStatus status)
436 {
437   TextureDataID i;
438   TextureID j;
439   int dummy;
440
441   /* essait de trouver la texture */
442   i = FindTextureData(FileName);
443   if (i == TEXTUREDATA_ERROR)
444   {
445 #ifdef PRINT
446     printf("GetTexture::la texture %s n'existe pas => chargement\n", FileName);
447 #endif
448     /* creation d'une texture */
449     i = FindFreeTextureData();
450     if (i == TEXTUREDATA_ERROR) return TEXTUREBOX_ERROR;
451
452     texdata(i).share_count = 0;
453     strcpy(texdata(i).imageFileName, FileName);
454     texdata(i).image = (GLubyte *)read_texture(FileName, 
455       &texdata(i).imageWidth,
456       &texdata(i).imageHeight,
457       &dummy);
458     if (texdata(i).image == NULL) return TEXTUREBOX_ERROR;
459
460     texdata(i).status = status;            
461     texdata(i).type = status2type[status];
462   }
463
464   j = FindFreeTexture();
465   if (j != TEXTUREBOX_ERROR)
466   {
467 #ifdef PRINT
468     printf("GetTexture::installation texture pour obj %d\n", j);
469 #endif
470     textab(j).contextdata.Clear();
471     textab(j).data = i;
472     textab(j).status = TEX_ALLOCATED;
473     texdata(i).share_count++;
474
475     SetTextureDefaultParams(j);
476
477 #ifdef PRINT
478     printf("GetTexture::texture %s(%d)    texture %d   count=%d\n", texdata(i).imageFileName, i, j, texdata(i).share_count);
479 #endif
480   }
481   else
482     if (texdata(i).share_count != 0)
483       delete [] texdata(i).image;  
484
485   return j;
486 }
487
488
489 /*----------------------------------------------------------------------*/
490 static TextureID GetTextureData(char *FileName, texDataStatus status, const GLint width, const GLint height, const void *data)
491 {
492   TextureDataID i;
493   TextureID j;
494
495   /* essait de trouver la texture */
496   i = FindTextureData(FileName);
497   if (i == TEXTUREDATA_ERROR)
498   {
499 #ifdef PRINT
500     printf("GetTextureData::la texture %s n'existe pas => chargement\n", FileName);
501 #endif
502     /* creation d'une texture */
503     i = FindFreeTextureData();
504     if (i == TEXTUREDATA_ERROR) return TEXTUREBOX_ERROR;
505
506     texdata(i).share_count = 0;
507     strcpy(texdata(i).imageFileName, FileName);
508     texdata(i).image = new GLubyte[width*height*4];
509     memcpy(texdata(i).image, data, (width*height*4));
510     texdata(i).imageWidth = width;
511     texdata(i).imageHeight = height;
512
513     if (texdata(i).image == NULL) return TEXTUREBOX_ERROR;
514
515     texdata(i).status = status;            
516     texdata(i).type = status2type[status];
517   }
518
519   j = FindFreeTexture();
520   if (j != TEXTUREBOX_ERROR)
521   {
522 #ifdef PRINT
523     printf("GetTextureData::installation texture pour obj %d\n", j);
524 #endif
525     textab(j).contextdata.Clear();
526     textab(j).data = i;
527     textab(j).status = TEX_ALLOCATED;
528     texdata(i).share_count++;
529
530     SetTextureDefaultParams(j);
531
532 #ifdef PRINT
533     printf("GetTextureData::texture %s(%d)    texture %d   count=%d\n", texdata(i).imageFileName, i, j, texdata(i).share_count);
534 #endif
535   }
536   else
537     if (texdata(i).share_count != 0)
538       delete [] texdata(i).image;  
539
540   return j;
541 }
542
543 /*----------------------------------------------------------------------*/
544 /*
545 * Fonctions publiques 
546 */
547
548
549 /*----------------------------------------------------------------------*/
550
551 GLboolean IsTextureValid(TextureID ID)
552 {
553   if ( (ID < 0) || (ID >= textab.Length()) )
554     return GL_FALSE;
555
556   if (textab.Length() > 0) 
557   {
558     return textab(ID).status == TEX_ALLOCATED;
559   }
560   else
561   {
562     return GL_FALSE;
563   }
564 }
565
566 /*----------------------------------------------------------------------*/
567
568 TextureID GetTexture1D(char *FileName)
569 {
570 #ifdef PRINT
571   printf("GetTexture1D::loading 1d %s   \n", FileName);
572 #endif
573   return GetTexture(FileName, TEXDATA_1D);
574 }
575
576 /*----------------------------------------------------------------------*/
577
578 TextureID GetTexture2D(char *FileName)
579 {
580 #ifdef PRINT
581   printf("GetTexture2D::loading 2d %s   \n", FileName);
582 #endif
583   return GetTexture(FileName, TEXDATA_2D);
584 }
585
586 /*----------------------------------------------------------------------*/
587
588 TextureID GetTexture2DMipMap(char *FileName)
589 {
590 #ifdef PRINT
591   printf("GetTexture2DMipMap::loading 2dmm %s   \n", FileName);
592 #endif
593   return GetTexture(FileName, TEXDATA_2DMM);
594 }
595
596 /*----------------------------------------------------------------------*/
597
598 TextureID GetTextureData1D(char *FileName, const GLint width, const GLint height, const void *data)
599 {
600 #ifdef PRINT
601   printf("GetTextureData1D::loading 1d %s  \n", FileName);
602 #endif
603   return GetTextureData(FileName, TEXDATA_1D, width, height, data);
604 }
605
606 /*----------------------------------------------------------------------*/
607
608 TextureID GetTextureData2D(char *FileName, const GLint width, const GLint height, const void *data)
609 {
610 #ifdef PRINT
611   printf("GetTextureData2D::loading 2d %s   \n", FileName);
612 #endif
613   return GetTextureData(FileName, TEXDATA_2D, width, height, data);
614 }
615
616 /*----------------------------------------------------------------------*/
617
618 TextureID GetTextureData2DMipMap(char *FileName, const GLint width, const GLint height, const void *data)
619 {
620 #ifdef PRINT
621   printf("GetTextureData2DMipMap::loading 2dmm %s   \n", FileName);
622 #endif
623   return GetTextureData(FileName, TEXDATA_2DMM, width, height, data);
624 }
625
626
627 /*----------------------------------------------------------------------*/
628
629 void SetCurrentTexture(TextureID ID)
630 {
631   int context;
632
633   if (!IsTextureValid(ID)) return;
634
635   context = FindTextureContext(ID);
636
637   /* la texture n'existe pas dans ce contexte */
638   if (context == TEXTUREBOX_ERROR)
639   {
640 #ifdef PRINT
641     printf("SetCurrentTexture::installation texture %d dans context\n", ID);
642 #endif
643     /* si on a une erreur pendant l'installation dans le context
644     * alors on installe la texture sans bind */
645     if (InstallTextureInContext(ID) == TEXTUREBOX_ERROR)
646     {
647       LoadTexture(ID);
648       SetTextureParam(ID);
649     }
650   }
651
652   /*oui, alors on bind directement */
653   else
654   {
655 #ifdef PRINT
656     printf("SetCurrentTexture: utilisation du bind %d\n", ID);
657 #endif
658     MyBindTextureEXT(ID, context); 
659     SetTextureParam(ID);
660   }
661
662   current_texture = ID;
663   current_texture_data = textab(ID).data;
664 }
665
666 /*----------------------------------------------------------------------*/
667
668 void FreeTexture (const Handle(OpenGl_Context)& theContext,
669                   TextureID                     ID)
670 {
671   if (!IsTextureValid (ID))
672   {
673     return;
674   }
675
676   TextureDataID data = textab(ID).data;
677   texdata(data).share_count--;
678   if (texdata(data).share_count == 0)
679   {
680     // release texture data
681     delete [] texdata(data).image;
682
683     // liberation de la texture dans tous les contextes
684     for (int i = 0; i < textab(ID).contextdata.Length(); ++i)
685     {
686       Handle(OpenGl_ResourceTexture) aResource = new OpenGl_ResourceTexture (textab(ID).contextdata(i).number);
687       theContext->DelayedRelease (aResource);
688     }
689
690     texdata(data).status = TEXDATA_NONE;
691
692     textab(ID).contextdata.Clear();
693   }
694
695   textab(ID).status = TEX_NONE;
696
697   current_texture_data = TEXTUREDATA_ERROR;
698 }
699
700 /*----------------------------------------------------------------------*/
701
702 void EnableTexture(void)
703 {
704   if (!IsTextureValid(current_texture)) return;
705
706   switch (texdata(current_texture_data).status)
707   {
708   case TEXDATA_1D:
709     if (textab(current_texture).Gen != GL_NONE) 
710       glEnable(GL_TEXTURE_GEN_S);
711     glEnable(GL_TEXTURE_1D);
712     break;
713
714   case TEXDATA_2D:
715   case TEXDATA_2DMM:
716     if (textab(current_texture).Gen != GL_NONE)
717     {
718       glEnable(GL_TEXTURE_GEN_S);
719       glEnable(GL_TEXTURE_GEN_T);
720     }
721     glEnable(GL_TEXTURE_2D);
722     break;
723   default:
724     break;
725   }
726 }
727
728 /*----------------------------------------------------------------------*/
729
730 void DisableTexture(void)
731 {
732   if ( !IsTextureEnabled() ) 
733     return;
734   if ( !IsTextureValid( current_texture ) ) 
735     return;
736
737   switch (texdata(current_texture_data).status)
738   {
739   case TEXDATA_1D:
740     if (textab(current_texture).Gen != GL_NONE) 
741       glDisable(GL_TEXTURE_GEN_S);
742     glDisable(GL_TEXTURE_1D);
743     break;
744
745   case TEXDATA_2D:
746   case TEXDATA_2DMM:
747     if (textab(current_texture).Gen != GL_NONE)
748     {
749       glDisable(GL_TEXTURE_GEN_S);
750       glDisable(GL_TEXTURE_GEN_T);
751     }
752     glDisable(GL_TEXTURE_2D);
753     break;
754   default:
755     break;
756   }
757 }
758
759 /*----------------------------------------------------------------------*/
760
761 GLboolean IsTextureEnabled(void)
762 {
763   GLboolean isEnabled1D= GL_FALSE, isEnabled2D= GL_FALSE;
764   glGetBooleanv( GL_TEXTURE_1D, &isEnabled1D );
765   glGetBooleanv( GL_TEXTURE_2D, &isEnabled2D );
766   return isEnabled1D || isEnabled2D;
767 }
768
769 /*----------------------------------------------------------------------*/
770
771 void SetTextureModulate(TextureID ID)
772 {
773   if (!IsTextureValid(ID)) return;
774
775   textab(ID).Light = GL_MODULATE;
776 }
777
778 /*----------------------------------------------------------------------*/
779
780 void SetTextureDecal(TextureID ID)
781 {
782   if (!IsTextureValid(ID)) return;
783
784   textab(ID).Light = GL_DECAL;
785 }
786
787 /*----------------------------------------------------------------------*/
788
789 void SetTextureClamp(TextureID ID)
790 {
791   if (!IsTextureValid(ID)) return;
792
793   textab(ID).Wrap = GL_CLAMP;
794 }
795
796 /*----------------------------------------------------------------------*/
797
798 void SetTextureRepeat(TextureID ID)
799 {
800   if (!IsTextureValid(ID)) return;
801
802   textab(ID).Wrap = GL_REPEAT;
803 }
804
805 /*----------------------------------------------------------------------*/
806
807 /* gestion de la facon d'appliquer la texture */
808 void SetModeObject(TextureID ID, const GLfloat sparams[4], const GLfloat tparams[4])
809 {
810   if (!IsTextureValid(ID)) return;
811
812   textab(ID).Gen = GL_OBJECT_LINEAR;
813   if (sparams != NULL) memcpy(textab(ID).Plane1, sparams, sizeof(sgenparams));
814   else                 memcpy(textab(ID).Plane1, sgenparams, sizeof(sgenparams));
815
816   if (texdata(textab(ID).data).status != TEXDATA_1D) {
817     if (tparams != NULL) memcpy(textab(ID).Plane2, tparams, sizeof(tgenparams));
818     else                 memcpy(textab(ID).Plane2, tgenparams, sizeof(tgenparams));
819   }
820 }
821
822 /*----------------------------------------------------------------------*/
823
824 void SetModeSphere(TextureID ID)
825 {
826   if (!IsTextureValid(ID)) return;
827
828   textab(ID).Gen = GL_SPHERE_MAP;
829 }
830
831 /*----------------------------------------------------------------------*/
832
833 void SetModeEye(TextureID ID, const GLfloat sparams[4], const GLfloat tparams[4])
834 {  
835   if (!IsTextureValid(ID)) return;
836
837   textab(ID).Gen = GL_EYE_LINEAR;
838   if (sparams != NULL) memcpy(textab(ID).Plane1, sparams, sizeof(sgenparams));
839   else                 memcpy(textab(ID).Plane1, sgenparams, sizeof(sgenparams));
840
841   if (texdata(textab(ID).data).status != TEXDATA_1D) {
842     if (tparams != NULL) memcpy(textab(ID).Plane2, tparams, sizeof(tgenparams));
843     else                 memcpy(textab(ID).Plane2, tgenparams, sizeof(tgenparams));
844   }
845 }
846
847 /*----------------------------------------------------------------------*/
848
849 void SetModeManual(TextureID ID)
850 {
851   if (!IsTextureValid(ID)) return;
852
853   textab(ID).Gen = GL_NONE;
854 }
855
856 /*----------------------------------------------------------------------*/
857
858 void SetRenderNearest(TextureID ID)
859 {
860   if (!IsTextureValid(ID)) return;
861
862   textab(ID).Render = GL_NEAREST;
863 }
864
865 /*----------------------------------------------------------------------*/
866
867 void SetRenderLinear(TextureID ID)
868 {
869   if (!IsTextureValid(ID)) return;
870
871   textab(ID).Render = GL_LINEAR;
872 }
873
874 /*----------------------------------------------------------------------*/
875
876 void SetTexturePosition(TextureID ID,
877                         GLfloat scalex, GLfloat scaley,
878                         GLfloat transx, GLfloat transy,
879                         GLfloat angle)
880 {
881   textab(ID).scalex = scalex;
882   textab(ID).scaley = scaley;
883   textab(ID).transx = transx;
884   textab(ID).transy = transy;
885   textab(ID).angle = angle;
886 }
887
888 /*----------------------------------------------------------------------*/
889
890 void SetTextureDefaultParams(TextureID ID)
891 {
892   if (!IsTextureValid(ID)) return;
893
894 #ifdef PRINT
895   printf("SetTextureDefaultParams::set parm par defaut textures\n");
896 #endif
897
898
899   textab(ID).scalex = 1.0;
900   textab(ID).scaley = 1.0;
901   textab(ID).transx = 0.0;
902   textab(ID).transy = 0.0;
903   textab(ID).angle = 0.0;
904
905   textab(ID).Gen = GL_OBJECT_LINEAR;
906   textab(ID).Light = texdata(textab(ID).data).status == TEXDATA_1D ? GL_DECAL : GL_MODULATE;
907   textab(ID).Wrap = texdata(textab(ID).data).status == TEXDATA_1D ? GL_CLAMP : GL_REPEAT;
908   memcpy(textab(ID).Plane1, sgenparams, sizeof(sgenparams));
909   memcpy(textab(ID).Plane2, tgenparams, sizeof(tgenparams));
910   textab(ID).Render = texdata(textab(ID).data).status == TEXDATA_1D ? GL_NEAREST : GL_LINEAR;
911 }
912
913 /*----------------------------------------------------------------------*/
914 /* Transfere de donnee des donnees internes a la structure TransferData */
915 void TransferTexture_To_Data(TextureID ID, TextureData *TransfDt)
916 {
917   /* affectations */    
918   strcpy(TransfDt->path, texdata(textab(ID).data).imageFileName);    
919   TransfDt->gen = textab(ID).Gen;
920   TransfDt->wrap  = textab(ID).Wrap;
921   TransfDt->render  = textab(ID).Light;
922   TransfDt->scalex  = textab(ID).scalex;
923   TransfDt->scaley  = textab(ID).scaley;
924   TransfDt->transx  = textab(ID).transx;
925   TransfDt->transy  = textab(ID).transy;
926   TransfDt->angle = textab(ID).angle;            
927   memcpy(TransfDt->plane1,  textab(ID).Plane1, sizeof(SizeType));
928   memcpy(TransfDt->plane2,  textab(ID).Plane2, sizeof(SizeType));                
929 }