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