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