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