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