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