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