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