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