Commit | Line | Data |
---|---|---|
7fd59977 | 1 | /*********************************************************************** |
2 | ||
3 | FONCTION : | |
4 | ---------- | |
5 | File OpenGl_txgl : | |
6 | ||
7 | ||
8 | REMARQUES: | |
9 | ---------- | |
10 | ||
11 | ||
12 | HISTORIQUE DES MODIFICATIONS : | |
13 | -------------------------------- | |
14 | xx-xx-xx : xxx ; Creation. | |
15 | 07-02-96 : FMN ; Suppression code inutile: | |
16 | - TxglLink() et TxglUnlink() | |
17 | 08-03-96 : FMN ; Suppression variables globales | |
18 | Ajout cmn_delete_from_htbl() dans TxglDestroyWindow() | |
19 | 21-03-96 : CAL ; test sur previous_ctx dans TxglDestroyWindow() | |
20 | et dans TxglSetDbuff() | |
21 | 01-04-96 : CAL ; Integration MINSK portage WNT | |
22 | 15-04-96 : CAL ; Integration travail PIXMAP de Jim ROTH | |
23 | 26-04-96 : FMN ; Correction warning de compilation | |
24 | 20-06-96 : CAL ; Retrait du XDestroyWindow dans TxglDestroyWindow | |
25 | 18-07-96 : FMN ; Suppression code inutile: TxglSetWindow(). | |
26 | 27-09-96 : CAL ; Portage WNT | |
27 | 16-10-96 : GG ; Coder le parametre de GLX_DEPTH_SIZE a 1 plutot | |
28 | que 0 si l'on souhaite accroitre les performances | |
29 | de 50% en utilisant le ZBuffer hardware !!! | |
30 | Si la fenetre fournie a deja le bon visual pas | |
31 | la peine de creer une sous-fenetre. | |
32 | 16-10-96 : GG ; Le dithering doit etre active aussi avec 12 plans | |
33 | de maniere a ameliorer la qualite | |
34 | 17-10-96 : FMN ; Ajout fonction printVisualInfo() | |
35 | 06-11-96 : CAL ; Remise a True du BackDitherProp pour < 12 plans | |
36 | 12-11-96 : CAL ; BackDitherProp = True pour <= 8 plans | |
37 | BackDitherProp = False pour > 8 plans | |
38 | 29-01-97 : FMN ; Amelioration du tests pour le dithering | |
39 | DitherProp = True pour <= 8 plans red | |
40 | DitherProp = False pour > 8 plans red | |
41 | Suppression de TxglSetDbuff() | |
42 | 06-06-97 : FMN ; Meilleure gestion glXMakeCurrent (pb avec LightWoks) | |
43 | Suppression de previous_win | |
44 | 02-07-97 : FMN ; Suppression variable ESSAI | |
45 | 07-10-97 : FMN ; Simplification WNT | |
46 | 13-10-97 : FMN ; Ajout wglShareLists | |
47 | 06-02-98 : FMN ; PRO11674: Suppression XSetErrorHandler(0) inutile | |
48 | 23-11-98 : CAL ; PRO16603: previous_ctx jamais remis a 0 pour eviter | |
49 | la perte des lists. | |
50 | 07-12-98 : CAL ; PRO 16311 et PRO 11821 | |
51 | 02.14.100 : JR : Warnings on WNT | |
52 | 14.07.06 : SAN : OCC12977: update previous_ctx properly in TxglDestroyWindow. | |
53 | Old code resulted in crashes on some ATI Radeon cards under Linux. | |
54 | ||
55 | ************************************************************************/ | |
56 | ||
57 | #define BUC60691 /*GG 06/06/00 Due to a severe bug in secondary | |
58 | // table hash-code computation not yet solve, | |
59 | // It's necessary to compute the primary hash-key key | |
60 | // correctly under WNT/W98. The actual method is wrong | |
61 | // because a size 4 is used for this table instead | |
62 | // a conventional prime number as under UNIX system (23). | |
63 | // Under W98 sometimes the function wglMakeContext() does | |
64 | // not work for an UNKNOWN reason, the number of DC | |
65 | // seems limited to 5 but nothing tell that the limit is | |
66 | // reached ! | |
67 | // We try right now to recover this error by creating a new DC. | |
68 | */ | |
69 | ||
70 | #define RIC120303 /*GG Add new function TxglSetWindow using | |
71 | // the GLXContext defined by the user | |
72 | // Add new function TxglGetContext. | |
73 | */ | |
74 | ||
75 | #define OCC954 /*SAV: 13/11/02 - check GLRC before deleting it*/ | |
76 | ||
77 | /*----------------------------------------------------------------------*/ | |
78 | /* | |
79 | * Includes | |
80 | */ | |
81 | #include <OpenGl_tgl_all.hxx> | |
82 | #include <OpenGl_telem_util.hxx> | |
83 | #include <stdio.h> | |
84 | ||
85 | #include <OpenGl_Memory.hxx> | |
d4c2114a | 86 | #include <OpenGl_ResourceCleaner.hxx> |
7fd59977 | 87 | |
88 | ||
89 | #ifdef WNT | |
90 | struct HTBL_ENTRY { | |
91 | HDC hDC; | |
92 | HGLRC hGLRC; | |
93 | int nUsed; | |
94 | IMPLEMENT_MEMORY_OPERATORS | |
95 | }; | |
96 | ||
97 | ||
98 | int call_util_osd_getenv ( char*, char*, int ); | |
99 | #endif /* WNT */ | |
100 | ||
101 | #include <OpenGl_txgl.hxx> | |
102 | int call_util_osd_getenv( char * , char * , int ) ; | |
103 | ||
104 | /*----------------------------------------------------------------------*/ | |
105 | /* | |
106 | * Variables statiques | |
107 | */ | |
108 | ||
109 | #ifndef WNT | |
110 | typedef NCollection_DataMap<Tint, GLCONTEXT> GLContextMap; | |
111 | #else | |
112 | typedef NCollection_DataMap<Tint, HTBL_ENTRY*> GLContextMap; | |
113 | #endif | |
114 | ||
115 | static GLContextMap _Txgl_Map; | |
116 | ||
117 | ||
118 | #ifndef WNT | |
119 | static int BackDitherProp = False; /* Dithering pour le background */ | |
120 | static int DitherProp = True; /* Dithering pour le trace */ | |
121 | static GLXContext previous_ctx = 0; /* Use for share display list */ | |
122 | static GLXContext dead_ctx; /* Context to be destroyed */ | |
123 | static Display *dead_dpy; /* Display associated with dead_ctx */ | |
124 | #else | |
125 | static int BackDitherProp = FALSE; /* Dithering pour le background */ | |
126 | static int DitherProp = TRUE; /* Dithering pour le trace */ | |
127 | static BOOL s_sysPalInUse; /* Flag to check system colors usage */ | |
128 | static HGLRC previous_ctx = 0; /* Use for share display list */ | |
129 | #endif /* WNT */ | |
130 | ||
131 | /*----------------------------------------------------------------------*/ | |
132 | /* | |
133 | * Constantes | |
134 | */ | |
135 | ||
136 | #define NO_TRACE | |
137 | ||
138 | #define CALL_DEF_STRING_LENGTH 132 | |
139 | ||
140 | #define WIN_HTBL_SIZE 23 | |
141 | ||
142 | /*----------------------------------------------------------------------*/ | |
143 | /* | |
144 | * Fonctions statiques | |
145 | */ | |
146 | ||
147 | #ifndef WNT | |
148 | #ifdef TRACE | |
149 | static GLvoid printVisualInfo( Display *, XVisualInfo *glxVisual ); | |
150 | #endif | |
151 | #else | |
152 | #ifdef BUC60691 | |
153 | static BOOL win95 = FALSE; | |
154 | #endif | |
155 | ||
156 | static int find_pixel_format(HTBL_ENTRY * hte, PIXELFORMATDESCRIPTOR * pfd); | |
157 | ||
158 | __declspec( dllexport ) int __fastcall __OpenGl_INIT__ ( | |
159 | unsigned hInstance, unsigned long reason_for_call | |
160 | ) { | |
161 | if ( reason_for_call == DLL_PROCESS_ATTACH ) { | |
162 | ||
163 | } | |
164 | return 1; | |
165 | ||
166 | } /* end __OpenGl_INIT__ */ | |
167 | #endif /* WNT */ | |
168 | ||
169 | /*----------------------------------------------------------------------*/ | |
170 | ||
171 | WINDOW | |
172 | TxglCreateWindow( DISPLAY *disp, WINDOW par, | |
173 | Tint x, Tint y, Tint w, Tint h, Tint bw, | |
174 | Tfloat bgcolr, Tfloat bgcolg, Tfloat bgcolb ) | |
175 | { | |
176 | ||
177 | #ifndef WNT | |
178 | ||
179 | GLCONTEXT ctx; | |
180 | static int sdesc[11]; | |
181 | Colormap cmap; | |
182 | XVisualInfo* vis=NULL; | |
183 | /* XVisualInfo tmplt;*/ | |
184 | XSetWindowAttributes cwa; | |
185 | XColor color; | |
186 | /* Tint i, n, nret;*/ | |
187 | Tint n; | |
188 | Tint scr; | |
189 | int value; | |
190 | char string[CALL_DEF_STRING_LENGTH]; | |
191 | int DBuffer = True; | |
192 | XWindowAttributes wattr; | |
193 | ||
194 | WINDOW win; | |
195 | ||
196 | unsigned long mask = 0; | |
197 | /* unsigned long background_pixel = 0;*/ | |
198 | ||
199 | if (call_util_osd_getenv("CALL_OPENGL_NO_DBF", string, CALL_DEF_STRING_LENGTH)) | |
200 | DBuffer = False; | |
201 | ||
202 | if (call_util_osd_getenv("JWR_PIXMAP_DB", string, CALL_DEF_STRING_LENGTH)) | |
203 | TelSetPixmapDB(1); | |
204 | ||
205 | XGetWindowAttributes( disp , par , &wattr ); | |
206 | ||
207 | n = 0; | |
208 | sdesc[n] = GLX_RGBA;n++; | |
209 | ||
210 | sdesc[n] = GLX_DEPTH_SIZE;n++; | |
211 | sdesc[n] = 1;n++; | |
212 | ||
213 | sdesc[n] = GLX_RED_SIZE;n++; | |
214 | sdesc[n] = (wattr.depth <= 8) ? 0 : 1;n++; | |
215 | ||
216 | sdesc[n] = GLX_GREEN_SIZE;n++; | |
217 | sdesc[n] = (wattr.depth <= 8) ? 0 : 1;n++; | |
218 | ||
219 | sdesc[n] = GLX_BLUE_SIZE;n++; | |
220 | sdesc[n] = (wattr.depth <= 8) ? 0 : 1;n++; | |
221 | ||
222 | if (DBuffer) { | |
223 | sdesc[n] = GLX_DOUBLEBUFFER;n++; | |
224 | } | |
225 | ||
226 | sdesc[n] = None;n++; | |
227 | ||
228 | scr = DefaultScreen( disp ); | |
229 | ||
230 | #if defined(__linux) || defined(Linux) | |
231 | { | |
232 | XVisualInfo vinfo; | |
233 | int ninfo; | |
234 | unsigned long vmask = VisualIDMask | VisualScreenMask; | |
235 | vinfo.visualid = wattr.visual->visualid; | |
236 | vinfo.screen = DefaultScreen( disp ); | |
237 | vis = XGetVisualInfo( disp, vmask, &vinfo, &ninfo); | |
238 | } | |
239 | #endif | |
240 | ||
241 | if( !vis ) | |
242 | vis = glXChooseVisual( disp, scr, sdesc ); | |
243 | if( !vis) return TFailure; | |
244 | ||
245 | #ifdef TRACE | |
246 | printf ("TxglCreateWindow \n"); | |
247 | printf ("Informations sur le visual\n"); | |
248 | printf ("par visualid %x%x %d\n", wattr.visual->visualid, wattr.visual->visualid); | |
249 | printf ("vis visualid 0x%x %d\n", vis->visualid, vis->visualid); | |
250 | printf ("vis depth %d\n", vis->depth); | |
251 | printf ("vis class %d\n", vis->class); | |
252 | printf ("vis red_mask %ld\n", vis->red_mask); | |
253 | printf ("vis green_mask %ld\n", vis->green_mask); | |
254 | printf ("vis blue_mask %ld\n", vis->blue_mask); | |
255 | printf ("vis colormap_size %d\n", vis->colormap_size); | |
256 | printf ("vis bits_per_rgb %d\n", vis->bits_per_rgb); | |
257 | printVisualInfo( disp, vis ); | |
258 | #endif | |
259 | ||
260 | /* | |
261 | * Le BackDitherProp est utilise pour le clear du background | |
262 | * Pour eviter une difference de couleurs avec la couleur choisie | |
263 | * par l'application (XWindow) il faut desactiver le dithering | |
264 | * au dessus de 8 plans. | |
265 | * | |
266 | * Pour le DitherProp: | |
267 | * On cherchera a activer le Dithering que si le Visual a au moins | |
268 | * 8 plans pour le GLX_RED_SIZE. Le test est plus sur car on peut | |
269 | * avoir une profondeur superieure a 12 mais avoir besoin du dithering. | |
270 | * (Carte Impact avec GLX_RED_SIZE a 5 par exemple) | |
271 | */ | |
272 | ||
273 | glXGetConfig( disp, vis, GLX_RED_SIZE, &value ); | |
274 | ||
275 | if ( value < 8 ) { | |
276 | DitherProp = True; | |
277 | } | |
278 | else | |
279 | { | |
280 | DitherProp = False; | |
281 | } | |
282 | ||
283 | if ( vis->depth <= 8 ) { | |
284 | BackDitherProp = True; | |
285 | } | |
286 | else | |
287 | { | |
288 | BackDitherProp = False; | |
289 | } | |
290 | ||
291 | #ifdef TRACE | |
292 | printf("Dithering %d BackDithering %d \n",DitherProp,BackDitherProp); | |
293 | #endif | |
294 | ||
295 | if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH)) | |
296 | DitherProp = False; | |
297 | ||
298 | if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH)) | |
299 | BackDitherProp = False; | |
300 | ||
301 | if (dead_ctx) { | |
302 | /* recover display lists from dead_ctx, then destroy it */ | |
303 | ctx = glXCreateContext( disp, vis, dead_ctx, GL_TRUE ); | |
304 | glXDestroyContext(dead_dpy, dead_ctx); | |
7fd59977 | 305 | } else if (previous_ctx == 0) { |
306 | ctx = glXCreateContext( disp, vis, NULL, GL_TRUE ); | |
307 | } else { | |
308 | /* ctx est une copie du previous */ | |
309 | ctx = glXCreateContext( disp, vis, previous_ctx, GL_TRUE ); | |
310 | } | |
311 | previous_ctx = ctx; | |
312 | ||
47d31ec6 A |
313 | if( ctx ) |
314 | OpenGl_ResourceCleaner::GetInstance()->AppendContext( ctx, true ); | |
7fd59977 | 315 | |
47d31ec6 A |
316 | // remove the dead_ctx for ResourceCleaner after appending shared ctx |
317 | if (dead_ctx) { | |
318 | OpenGl_ResourceCleaner::GetInstance()->RemoveContext(dead_ctx); | |
319 | dead_ctx = 0; | |
320 | } | |
321 | ||
322 | if( !ctx) return TFailure; | |
d4c2114a | 323 | |
7fd59977 | 324 | cmap = XCreateColormap( disp, par, vis->visual, AllocNone ); |
325 | ||
326 | color.red = (unsigned short) (bgcolr * 0xFFFF); | |
327 | color.green = (unsigned short) (bgcolg * 0xFFFF); | |
328 | color.blue = (unsigned short) (bgcolb * 0xFFFF); | |
329 | color.flags = DoRed | DoGreen | DoBlue; | |
330 | XAllocColor( disp, cmap, &color ); | |
331 | ||
332 | cwa.colormap = cmap; | |
333 | cwa.event_mask = StructureNotifyMask; | |
334 | cwa.border_pixel = color.pixel; | |
335 | cwa.background_pixel = color.pixel; | |
336 | ||
337 | mask = CWBackPixel | CWColormap | CWBorderPixel | CWEventMask; | |
338 | ||
339 | if( vis->visualid == wattr.visual->visualid ) { | |
340 | win = par; | |
341 | } | |
342 | else | |
343 | { | |
344 | win = XCreateWindow( disp, par, x, y, w, h, bw, | |
345 | vis->depth, InputOutput, vis->visual, | |
346 | mask, &cwa ); | |
347 | } | |
348 | ||
349 | #ifdef TRACE | |
350 | printf ("TxglCreateWindow win %x par %x \n", win, par); | |
351 | #endif | |
352 | ||
353 | XSetWindowBackground( disp, win, cwa.background_pixel ); | |
354 | XClearWindow( disp, win ); | |
355 | ||
356 | /* if in Pixmap double buffering mode, set up pixmap */ | |
357 | ||
358 | if (TelTestPixmapDB()) | |
359 | { | |
360 | GC gc; | |
361 | Pixmap pixmap; | |
362 | GLXPixmap glxpixmap; | |
363 | ||
364 | printf("setting up pixmap double buffering\n"); | |
365 | ||
366 | gc = XCreateGC(disp, win, 0, NULL); | |
367 | ||
368 | pixmap = XCreatePixmap(disp, win, w, h, vis->depth); | |
369 | ||
370 | glxpixmap = glXCreateGLXPixmap(disp, vis, pixmap); | |
371 | ||
372 | glXMakeCurrent(disp, glxpixmap, ctx); | |
373 | ||
374 | glDrawBuffer(GL_FRONT); | |
375 | ||
376 | TelSetPixmapDBParams(disp, win, w, h, vis->depth, gc, pixmap, glxpixmap, ctx); | |
377 | } | |
378 | ||
379 | XFree((char*)vis); | |
380 | ||
381 | _Txgl_Map.Bind( (Tint)win, ctx ); | |
382 | ||
383 | return win; | |
384 | ||
385 | #else /* WNT */ | |
386 | ||
387 | HTBL_ENTRY* hte; | |
388 | PIXELFORMATDESCRIPTOR pfd; | |
389 | BOOL DBuffer = TRUE; | |
390 | int iPixelFormat; | |
391 | char string[ CALL_DEF_STRING_LENGTH ]; | |
392 | ||
393 | #ifdef BUC60691 | |
394 | OSVERSIONINFO os; | |
395 | os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); | |
396 | GetVersionEx(&os); | |
397 | if( os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) win95 = TRUE; | |
398 | #endif | |
399 | ||
400 | if ( _Txgl_Map.IsBound( (Tint)par ) ) { | |
401 | hte = _Txgl_Map.ChangeFind( (Tint)par ); | |
402 | if ( hte ) | |
403 | { | |
404 | ++hte -> nUsed; | |
405 | printf("*TxglCreateWindow.window %d is alreday created\n",par); | |
406 | return par; | |
407 | } | |
408 | } | |
409 | ||
410 | hte = new HTBL_ENTRY(); | |
411 | ||
412 | if ( !hte ) return 0; | |
413 | hte -> hDC = GetDC ( par ); | |
414 | ||
415 | iPixelFormat = find_pixel_format(hte, &pfd); | |
416 | ||
417 | if ( !iPixelFormat ) | |
418 | { | |
419 | printf ("*OpenGL interface: ChoosePixelFormat failed. Error code: %d\n",GetLastError ()); | |
420 | ||
421 | ReleaseDC ( par, hte -> hDC ); | |
422 | delete hte; | |
423 | ||
424 | return 0; | |
425 | } | |
426 | ||
427 | if ( pfd.dwFlags & PFD_NEED_PALETTE ) | |
428 | { | |
8ab673bb | 429 | WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLongPtr ( par, GWLP_USERDATA ); |
7fd59977 | 430 | |
431 | InterfaceGraphic_RealizePalette (hte -> hDC, wd -> hPal, FALSE, | |
432 | s_sysPalInUse = pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE); | |
433 | } | |
434 | ||
435 | if ( pfd.cColorBits <= 8 ) | |
436 | { | |
437 | DitherProp = TRUE; | |
438 | BackDitherProp = TRUE; | |
439 | } | |
440 | ||
441 | if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH)) | |
442 | DitherProp = FALSE; | |
443 | ||
444 | if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH)) | |
445 | BackDitherProp = FALSE; | |
446 | ||
447 | if ( !SetPixelFormat ( hte -> hDC, iPixelFormat, &pfd ) ) | |
448 | { | |
449 | printf ("*OpenGL interface: SetPixelFormat failed. Error code %d\n",GetLastError ()); | |
450 | ReleaseDC ( par, hte -> hDC ); | |
451 | delete hte; | |
452 | return 0; | |
453 | } | |
454 | ||
455 | hte -> hGLRC = wglCreateContext ( hte -> hDC ); | |
456 | ||
457 | if ( !hte -> hGLRC ) | |
458 | { | |
459 | printf ("*OpenGL interface: wglCreateContext failed. Error code: %d\n",GetLastError ()); | |
460 | return 0; | |
461 | } | |
462 | ||
d4c2114a | 463 | Standard_Boolean isShared = Standard_True; |
464 | ||
465 | if (previous_ctx == 0 ) | |
8ab673bb | 466 | previous_ctx = hte -> hGLRC; |
d4c2114a | 467 | // if we already have some shared context |
468 | else | |
469 | { | |
470 | // try to share context with one from resource cleaner list | |
471 | GLCONTEXT shareCtx = OpenGl_ResourceCleaner::GetInstance()->GetSharedContext(); | |
472 | ||
473 | if (shareCtx != 0) | |
474 | isShared = (Standard_Boolean)wglShareLists(shareCtx, hte -> hGLRC); | |
475 | else | |
476 | { | |
477 | isShared = (Standard_Boolean)wglShareLists(previous_ctx, hte -> hGLRC); | |
478 | // add shared previous_ctx to a control list if it's not there | |
479 | if (isShared) | |
480 | OpenGl_ResourceCleaner::GetInstance()->AppendContext(previous_ctx, isShared); | |
481 | } | |
482 | } | |
7fd59977 | 483 | |
d4c2114a | 484 | // add the context to OpenGl_ResourceCleaner control list |
485 | OpenGl_ResourceCleaner::GetInstance()->AppendContext( hte -> hGLRC, isShared); | |
7fd59977 | 486 | _Txgl_Map.Bind( (Tint)par, hte ); |
487 | ||
488 | return par; | |
489 | ||
490 | #endif /* WNT */ | |
491 | ||
492 | } | |
493 | ||
494 | #ifdef RIC120302 | |
495 | WINDOW | |
496 | TxglSetWindow( DISPLAY *disp, WINDOW par, GLCONTEXT ctx) | |
497 | { | |
498 | #ifndef WNT | |
499 | XVisualInfo* vis; | |
500 | char string[CALL_DEF_STRING_LENGTH]; | |
501 | XWindowAttributes wattr; | |
502 | ||
503 | XGetWindowAttributes( disp , par , &wattr ); | |
504 | { | |
505 | unsigned long vmask = VisualIDMask | VisualScreenMask; | |
506 | XVisualInfo vinfo; | |
507 | int ninfo; | |
508 | vinfo.visualid = wattr.visual->visualid; | |
509 | vinfo.screen = DefaultScreen( disp ); | |
510 | vis = XGetVisualInfo( disp, vmask, &vinfo, &ninfo); | |
511 | } | |
512 | ||
513 | if( !vis) return TFailure; | |
514 | ||
515 | #ifdef TRACE | |
516 | printf ("TxglSetWindow \n"); | |
517 | printf ("Informations sur le visual\n"); | |
518 | printf ("par visualid %x%x %d\n", wattr.visual->visualid, wattr.visual->visualid); | |
519 | printf ("vis visualid 0x%x %d\n", vis->visualid, vis->visualid); | |
520 | printf ("vis depth %d\n", vis->depth); | |
521 | printf ("vis class %d\n", vis->class); | |
522 | printf ("vis red_mask %ld\n", vis->red_mask); | |
523 | printf ("vis green_mask %ld\n", vis->green_mask); | |
524 | printf ("vis blue_mask %ld\n", vis->blue_mask); | |
525 | printf ("vis colormap_size %d\n", vis->colormap_size); | |
526 | printf ("vis bits_per_rgb %d\n", vis->bits_per_rgb); | |
527 | printVisualInfo( disp, vis ); | |
528 | #endif | |
529 | ||
530 | /* | |
531 | * Le BackDitherProp est utilise pour le clear du background | |
532 | * Pour eviter une difference de couleurs avec la couleur choisie | |
533 | * par l'application (XWindow) il faut desactiver le dithering | |
534 | * au dessus de 8 plans. | |
535 | * | |
536 | * Pour le DitherProp: | |
537 | * On cherchera a activer le Dithering que si le Visual a au moins | |
538 | * 8 plans pour le GLX_RED_SIZE. Le test est plus sur car on peut | |
539 | * avoir une profondeur superieure a 12 mais avoir besoin du dithering. | |
540 | * (Carte Impact avec GLX_RED_SIZE a 5 par exemple) | |
541 | */ | |
542 | ||
543 | { | |
544 | int value; | |
545 | glXGetConfig( disp, vis, GLX_RED_SIZE, &value ); | |
546 | ||
547 | if ( value < 8 ) { | |
548 | DitherProp = True; | |
549 | } else { | |
550 | DitherProp = False; | |
551 | } | |
552 | ||
553 | if ( vis->depth <= 8 ) { | |
554 | BackDitherProp = True; | |
555 | } else { | |
556 | BackDitherProp = False; | |
557 | } | |
558 | } | |
559 | ||
560 | #ifdef TRACE | |
561 | printf("Dithering %d BackDithering %d \n",DitherProp,BackDitherProp); | |
562 | #endif | |
563 | ||
564 | if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH)) | |
565 | DitherProp = False; | |
566 | ||
567 | if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH)) | |
568 | BackDitherProp = False; | |
569 | ||
570 | previous_ctx = ctx; | |
571 | ||
572 | XFree((char*)vis); | |
573 | ||
574 | _Txgl_Map.Bind( ( Tint )par, ctx ); | |
575 | #else /* WNT */ | |
576 | ||
577 | /* abd | |
578 | cmn_htbl_elem rec;*/ | |
579 | HTBL_ENTRY* hte; | |
580 | PIXELFORMATDESCRIPTOR pfd; | |
581 | BOOL DBuffer = TRUE; | |
582 | int iPixelFormat; | |
583 | char string[ CALL_DEF_STRING_LENGTH ]; | |
584 | ||
585 | #ifdef BUC60691 | |
586 | OSVERSIONINFO os; | |
587 | os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); | |
588 | GetVersionEx(&os); | |
589 | if( os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) win95 = TRUE; | |
590 | #endif | |
591 | ||
592 | if ( _Txgl_Map.IsBound( ( Tint )par ) ) | |
593 | { | |
594 | hte = _Txgl_Map.ChangeFind( ( Tint )par ); | |
595 | ++hte -> nUsed; | |
596 | printf("*TxglSetWindow.window %d is alreday created\n",par); | |
597 | return par; | |
598 | } | |
599 | ||
600 | hte = new HTBL_ENTRY(); | |
601 | ||
602 | if ( !hte ) return 0; | |
603 | ||
604 | hte -> hDC = GetDC ( par ); | |
605 | iPixelFormat = find_pixel_format(hte, &pfd); | |
606 | ||
607 | if ( !iPixelFormat ) | |
608 | { | |
609 | printf ("*OpenGL interface: ChoosePixelFormat failed. Error code: %d\n",GetLastError ()); | |
610 | ||
611 | ReleaseDC ( par, hte -> hDC ); | |
612 | delete hte; | |
613 | ||
614 | return 0; | |
615 | } | |
616 | ||
617 | if ( pfd.dwFlags & PFD_NEED_PALETTE ) | |
618 | { | |
8ab673bb | 619 | WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLongPtr ( par, GWLP_USERDATA ); |
7fd59977 | 620 | |
621 | InterfaceGraphic_RealizePalette (hte -> hDC, wd -> hPal, FALSE, | |
622 | s_sysPalInUse = pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE); | |
623 | } | |
624 | ||
625 | if ( pfd.cColorBits <= 8 ) | |
626 | { | |
627 | DitherProp = TRUE; | |
628 | BackDitherProp = TRUE; | |
629 | } | |
630 | ||
631 | if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH)) | |
632 | DitherProp = FALSE; | |
633 | ||
634 | if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH)) | |
635 | BackDitherProp = FALSE; | |
636 | ||
637 | if ( !SetPixelFormat ( hte -> hDC, iPixelFormat, &pfd ) ) | |
638 | { | |
639 | printf ("*OpenGL interface: SetPixelFormat failed. Error code %d\n",GetLastError ()); | |
640 | ReleaseDC ( par, hte -> hDC ); | |
641 | delete hte; | |
642 | return 0; | |
643 | } | |
644 | ||
645 | hte -> hGLRC = previous_ctx = ctx; | |
646 | ||
647 | _Txgl_Map.Bind( ( Tint )par, hte ); | |
648 | #endif /* WNT */ | |
649 | ||
650 | return par; | |
651 | ||
652 | } | |
653 | #endif /*RIC120302*/ | |
654 | ||
655 | /*----------------------------------------------------------------------*/ | |
656 | ||
657 | TStatus | |
658 | TxglWinset( DISPLAY *disp, WINDOW win ) | |
659 | { | |
660 | ||
661 | #ifndef WNT | |
662 | ||
663 | Bool i; | |
664 | GLXContext ctx; | |
665 | GLenum errorcode; | |
666 | const GLubyte *errorstring; | |
667 | ||
668 | if ( !_Txgl_Map.IsBound( win ) ) | |
669 | return TFailure; | |
670 | ||
671 | ctx = _Txgl_Map.ChangeFind( win ); | |
672 | ||
673 | ||
674 | #ifdef TRACE | |
675 | printf ("TxglWinset::glXMakeCurrent %x \n", win); | |
676 | #endif | |
677 | if (TelTestPixmapDB()) | |
678 | { | |
679 | i = glXMakeCurrent(disp, TelGetGLXPixmap(), ctx); | |
680 | } | |
681 | else | |
682 | { | |
683 | i = glXMakeCurrent(disp, win, ctx); /* TRUE/FALSE */ | |
684 | } | |
685 | if (!i) | |
686 | { | |
687 | errorcode = glGetError(); | |
688 | errorstring = gluErrorString(errorcode); | |
689 | printf("glXMakeCurrent failed: %d %s\n", errorcode, errorstring); | |
690 | } | |
691 | ||
692 | return i == True ? TSuccess : TFailure; | |
693 | ||
694 | #else /* WNT */ | |
695 | ||
696 | HTBL_ENTRY* hte; | |
697 | HDC hdc = NULL; | |
698 | HGLRC hglrc = NULL; | |
699 | TStatus retVal = TFailure; | |
700 | ||
701 | __try { | |
702 | ||
703 | if ( !_Txgl_Map.IsBound( ( Tint )win ) ) { | |
704 | printf("OpenGL interface: TxglWinset failed.UNKNOWN win %x\n",win); | |
705 | __leave; | |
706 | } | |
707 | hte = _Txgl_Map.ChangeFind( ( Tint )win ); | |
708 | ||
709 | #ifdef BUC60691 | |
710 | if( win95 ) { | |
711 | retVal = (TStatus)ReleaseDC ( win, hte -> hDC ); | |
712 | hte -> hDC = GetDC ( win ); | |
713 | } | |
714 | #endif | |
715 | if ( !wglMakeCurrent ( hte -> hDC, hte -> hGLRC ) ) | |
716 | { | |
717 | #ifdef BUC60691 | |
718 | GLenum errorcode; | |
719 | const GLubyte *errorstring; | |
720 | ||
721 | errorcode = glGetError(); | |
722 | errorstring = gluErrorString(errorcode); | |
723 | printf("wglMakeCurrent failed: %d %s\n", errorcode, errorstring); | |
724 | #else | |
725 | printf ("OpenGL interface: wglMakeCurrent failed. Error code: %d\n",GetLastError ()); | |
726 | #endif | |
727 | retVal = TFailure; | |
728 | } else retVal = TSuccess; | |
729 | ||
730 | } /* end __try */ | |
731 | ||
732 | ||
733 | __finally | |
734 | { | |
735 | } | |
736 | ||
737 | return retVal; | |
738 | ||
739 | #endif /* WNT */ | |
740 | ||
741 | } | |
742 | ||
743 | /*----------------------------------------------------------------------*/ | |
744 | ||
745 | WINDOW | |
746 | TxglGetSubWindow( DISPLAY *disp, WINDOW win ) | |
747 | /* This function assumes that there is only | |
748 | one child for the parent */ | |
749 | { | |
750 | ||
751 | #ifndef WNT | |
752 | ||
753 | Window root, parent, *child, w; | |
754 | unsigned int num; | |
755 | ||
756 | if( XQueryTree( disp, win, &root, &parent, &child, &num ) ) | |
757 | { | |
758 | if (! num) return win; | |
759 | w = child[0]; | |
760 | XFree( (char *)child ); | |
761 | return w; | |
762 | } | |
763 | else | |
764 | return 0; | |
765 | ||
766 | #else /* WNT */ | |
767 | ||
768 | return win; | |
769 | ||
770 | #endif /* WNT */ | |
771 | ||
772 | } | |
773 | ||
774 | /*----------------------------------------------------------------------*/ | |
775 | ||
776 | void | |
777 | TxglDestroyWindow( DISPLAY *disp, WINDOW win ) | |
778 | { | |
779 | ||
780 | #ifndef WNT | |
781 | ||
782 | GLXContext ctx; | |
783 | Tint dummy; | |
784 | ||
785 | if ( !_Txgl_Map.IsBound(win) ) | |
786 | return; | |
787 | ctx = _Txgl_Map.ChangeFind(win); | |
788 | ||
789 | /* FSXXX sync necessary if non-direct rendering */ | |
790 | glXWaitGL(); | |
791 | ||
792 | _Txgl_Map.UnBind( win ); | |
793 | ||
794 | if (previous_ctx == ctx) { | |
795 | /* san -- OCC12977: it's important to put some valid GLXContext or null into | |
796 | previous_ctx here, otherwise next glxCreateContext() will crash on some ATI Radeon cards | |
797 | */ | |
798 | previous_ctx = NULL; | |
799 | if ( _Txgl_Map.Size() > 0 ) { | |
800 | GLContextMap::Iterator it(_Txgl_Map); | |
801 | previous_ctx = it.Value(); | |
802 | } | |
803 | /* | |
804 | * if this is the last remaining context, do not destroy it yet, to avoid | |
805 | * losing any shared display lists (fonts...) | |
806 | */ | |
807 | if (previous_ctx) { | |
47d31ec6 | 808 | OpenGl_ResourceCleaner::GetInstance()->RemoveContext(ctx); |
7fd59977 | 809 | glXDestroyContext(disp, ctx); |
810 | } else { | |
811 | dead_ctx = ctx; | |
812 | dead_dpy = disp; | |
813 | } | |
814 | } else { | |
47d31ec6 | 815 | OpenGl_ResourceCleaner::GetInstance()->RemoveContext(ctx); |
7fd59977 | 816 | glXDestroyContext(disp, ctx); |
817 | } | |
818 | ||
819 | #else /* WNT */ | |
820 | ||
821 | HTBL_ENTRY* hte; | |
822 | #ifdef _DEBUG | |
823 | WINDOW_DATA* wd; | |
824 | #endif /* _DEBUG */ | |
825 | if ( !_Txgl_Map.IsBound(( Tint )win) ) | |
826 | return; | |
827 | hte = _Txgl_Map.ChangeFind(( Tint )win); | |
828 | ||
829 | #ifdef _DEBUG | |
830 | /* In release version of application we need to process */ | |
831 | /* palette messages in the main application message loop. */ | |
832 | /* In debug version we don't have message loop for most */ | |
833 | /* cases. So, let's restore system colors here now. */ | |
8ab673bb | 834 | wd = ( WINDOW_DATA* )GetWindowLongPtr ( win, GWLP_USERDATA ); |
7fd59977 | 835 | |
836 | if ( wd != NULL ) InterfaceGraphic_RealizePalette ( | |
837 | hte -> hDC, wd -> hPal, TRUE, s_sysPalInUse); | |
838 | #endif /* _DEBUG */ | |
839 | ||
840 | if ( --hte -> nUsed == 0 ) | |
841 | { | |
d4c2114a | 842 | OpenGl_ResourceCleaner::GetInstance()->RemoveContext( hte -> hGLRC ); |
7fd59977 | 843 | #ifdef OCC954 |
844 | if ( wglGetCurrentContext() != NULL ) | |
845 | #endif | |
846 | wglDeleteContext ( hte -> hGLRC ); | |
847 | ReleaseDC ( win, hte -> hDC ); | |
848 | _Txgl_Map.UnBind( (Tint ) win ); | |
d4c2114a | 849 | if( _Txgl_Map.Size() == 0 ) { |
850 | previous_ctx = 0; | |
851 | } | |
7fd59977 | 852 | delete hte; |
853 | } | |
854 | ||
855 | #endif /* WNT */ | |
856 | ||
857 | } | |
858 | ||
859 | /*----------------------------------------------------------------------*/ | |
860 | ||
861 | int | |
862 | TxglGetDither(void) | |
863 | { | |
864 | return DitherProp; | |
865 | } | |
866 | ||
867 | /*----------------------------------------------------------------------*/ | |
868 | ||
869 | int | |
870 | TxglGetBackDither(void) | |
871 | { | |
872 | return BackDitherProp; | |
873 | } | |
874 | ||
875 | ||
876 | /*----------------------------------------------------------------------*/ | |
877 | /*RIC120302*/ | |
878 | GLCONTEXT | |
879 | TxglGetContext( WINDOW win ) | |
880 | { | |
881 | GLCONTEXT ctx = NULL; | |
882 | if ( _Txgl_Map.IsBound( (Tint) win ) ) | |
883 | ctx = | |
884 | #ifdef WNT | |
885 | _Txgl_Map.Find( (Tint) win )->hGLRC; | |
886 | #else | |
887 | _Txgl_Map.Find( win ); | |
888 | #endif | |
889 | ||
890 | return ctx; | |
891 | } | |
892 | /*RIC120302*/ | |
893 | ||
894 | /*----------------------------------------------------------------------*/ | |
895 | enum { ZERO = 0, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN }; | |
896 | ||
897 | /* Unused :*/ | |
898 | #ifdef TRACE | |
899 | static const char* | |
900 | className( int class ) | |
901 | { | |
902 | static char *classes[] = { | |
903 | "StaticGray", | |
904 | "GrayScale", | |
905 | "StaticColor", | |
906 | "PseudoColor", | |
907 | "TrueColor", | |
908 | "DirectColor", | |
909 | }; | |
910 | ||
911 | if ( class < ZERO || class > FIVE ) | |
912 | return "unknown"; | |
913 | else | |
914 | return classes[class]; | |
915 | } | |
916 | #endif | |
917 | /*----------------------------------------------------------------------*/ | |
918 | #ifndef WNT | |
919 | ||
920 | #ifdef TRACE | |
921 | static GLvoid printVisualInfo( DISPLAY *display, XVisualInfo *glxVisual ) | |
922 | { | |
923 | ||
924 | #define TrueFalse(x) ( x ? "True" : "False" ) | |
925 | ||
926 | int tmp; | |
927 | ||
928 | printf("\n" ); | |
929 | printf(" X Visual Information ...\n\n" ); | |
930 | printf("\tvisualid : 0x%x\n", glxVisual->visualid ); | |
931 | printf("\tclass : %s\n\n", className( glxVisual->class ) ); | |
932 | ||
933 | glXGetConfig(display, glxVisual, GLX_USE_GL, &tmp); | |
934 | printf( "\tSupport GL ( GLX_USE_GL ) : %s\n", TrueFalse(tmp) ); | |
935 | ||
936 | glXGetConfig(display, glxVisual, GLX_LEVEL, &tmp); | |
937 | printf( "\tFramebuffer ( GLX_LEVEL ) : %s\n\n", | |
938 | (tmp < ZERO) ? "Underlay" : (tmp == ZERO ? "Normal" : tmp > ONE ? "Overlay" : "Popup") ); | |
939 | ||
940 | glXGetConfig(display, glxVisual, GLX_BUFFER_SIZE, &tmp); | |
941 | printf( "\tFramebuffer depth ( GLX_BUFFER_SIZE ) : %d\n", tmp ); | |
942 | ||
943 | glXGetConfig(display, glxVisual, GLX_DOUBLEBUFFER, &tmp); | |
944 | printf( "\tDoublebuffer ( GLX_DOUBLEBUFFER ) : %s\n", | |
945 | TrueFalse(tmp) ); | |
946 | ||
947 | glXGetConfig(display, glxVisual, GLX_DEPTH_SIZE, &tmp); | |
948 | printf( "\tDepth buffer depth ( GLX_DEPTH_SIZE ) : %d\n", tmp ); | |
949 | ||
950 | glXGetConfig(display, glxVisual, GLX_STENCIL_SIZE, &tmp); | |
951 | printf( "\tStencil buffer depth ( GLX_STENCIL_SIZE ) : %d\n", tmp ); | |
952 | ||
953 | glXGetConfig(display, glxVisual, GLX_STEREO, &tmp); | |
954 | printf( "\tStereo Buffer ( GLX_STEREO ) : %s\n", | |
955 | TrueFalse(tmp) ); | |
956 | ||
957 | glXGetConfig(display, glxVisual, GLX_AUX_BUFFERS, &tmp); | |
958 | printf( "\tAuxillary Buffers ( GLX_AUX_BUFFERS) : %d\n\n", tmp ); | |
959 | ||
960 | glXGetConfig(display, glxVisual, GLX_RGBA, &tmp); | |
961 | printf( "\tColor mode ( GLX_RGBA ) : %s\n", tmp ? "RGBA" : | |
962 | "Color Index" ); | |
963 | ||
964 | glXGetConfig(display, glxVisual, GLX_RED_SIZE, &tmp); | |
965 | printf( "\tRed Bits ( GLX_RED_SIZE ) : %d\n", tmp ); | |
966 | ||
967 | glXGetConfig(display, glxVisual, GLX_GREEN_SIZE, &tmp); | |
968 | printf( "\tGreen Bits ( GLX_GREEN_SIZE ) : %d\n", tmp ); | |
969 | ||
970 | glXGetConfig(display, glxVisual, GLX_BLUE_SIZE, &tmp); | |
971 | printf( "\tBlue Bits ( GLX_BLUE_SIZE ) : %d\n", tmp ); | |
972 | ||
973 | glXGetConfig(display, glxVisual, GLX_ALPHA_SIZE, &tmp); | |
974 | printf( "\tAlpha Bits ( GLX_ALPHA_SIZE ) : %d\n\n", tmp ); | |
975 | ||
976 | glXGetConfig(display, glxVisual, GLX_ACCUM_RED_SIZE, &tmp); | |
977 | printf( "\tRed Accumulation Bits ( GLX_ACCUM_RED_SIZE ) : %d\n", tmp ); | |
978 | ||
979 | glXGetConfig(display, glxVisual, GLX_ACCUM_GREEN_SIZE, &tmp); | |
980 | printf( "\tGreen Accumulation Bits ( GLX_ACCUM_GREEN_SIZE ) : %d\n", tmp ); | |
981 | ||
982 | glXGetConfig(display, glxVisual, GLX_ACCUM_BLUE_SIZE, &tmp); | |
983 | printf( "\tBlue Accumulation Bits ( GLX_ACCUM_BLUE_SIZE ) : %d\n", tmp ); | |
984 | ||
985 | glXGetConfig(display, glxVisual, GLX_ACCUM_ALPHA_SIZE, &tmp); | |
986 | printf( "\tAlpha Accumulation Bits ( GLX_ACCUM_ALPHA_SIZE ) : %d\n\n", tmp ); | |
987 | } | |
988 | #endif //TRACE | |
989 | #else //WNT | |
990 | int find_pixel_format(HTBL_ENTRY * hte, PIXELFORMATDESCRIPTOR * pfd) | |
991 | { | |
992 | int iPixelFormat = 0; | |
993 | int iGood = 0; | |
994 | int i, j; | |
995 | PIXELFORMATDESCRIPTOR pfd0; | |
996 | char string[ CALL_DEF_STRING_LENGTH ]; | |
997 | BOOL DBuffer = TRUE; | |
998 | const int cBits[] = { 32, 24 }; | |
999 | const int dBits[] = { 32, 24, 16 }; | |
1000 | ||
1001 | if (call_util_osd_getenv ("CALL_OPENGL_NO_DBF", | |
1002 | string, CALL_DEF_STRING_LENGTH)) | |
1003 | DBuffer = FALSE; | |
1004 | ||
1005 | pfd0.nSize = sizeof ( PIXELFORMATDESCRIPTOR ); | |
1006 | pfd0.nVersion = 1; | |
1007 | pfd0.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; | |
1008 | pfd0.dwFlags |= ( DBuffer ) ? PFD_DOUBLEBUFFER : PFD_SUPPORT_GDI; | |
1009 | pfd0.iPixelType = PFD_TYPE_RGBA; | |
1010 | pfd0.cRedBits = 0; | |
1011 | pfd0.cRedShift = 0; | |
1012 | pfd0.cGreenBits = 0; | |
1013 | pfd0.cGreenShift = 0; | |
1014 | pfd0.cBlueBits = 0; | |
1015 | pfd0.cBlueShift = 0; | |
1016 | pfd0.cAlphaBits = 0; | |
1017 | pfd0.cAlphaShift = 0; | |
1018 | pfd0.cAccumBits = 0; | |
1019 | pfd0.cAccumRedBits = 0; | |
1020 | pfd0.cAccumGreenBits = 0; | |
1021 | pfd0.cAccumBlueBits = 0; | |
1022 | pfd0.cAccumAlphaBits = 0; | |
1023 | pfd0.cStencilBits = 0; | |
1024 | pfd0.cAuxBuffers = 0; | |
1025 | pfd0.iLayerType = PFD_MAIN_PLANE; | |
1026 | pfd0.bReserved = 0; | |
1027 | pfd0.dwLayerMask = 0; | |
1028 | pfd0.dwVisibleMask = 0; | |
1029 | pfd0.dwDamageMask = 0; | |
1030 | ||
1031 | hte -> nUsed = 1; | |
1032 | ||
1033 | for (i = 0; i < sizeof(dBits) / sizeof(int); i++) { | |
1034 | ||
1035 | pfd0.cDepthBits = dBits[i]; | |
1036 | iGood = 0; | |
1037 | for (j = 0; j < sizeof(cBits) / sizeof(int); j++) { | |
1038 | ||
1039 | pfd0.cColorBits = cBits[j]; | |
1040 | iPixelFormat = ChoosePixelFormat ( hte -> hDC, &pfd0 ); | |
1041 | ||
1042 | if (iPixelFormat) { | |
1043 | pfd->cDepthBits = 0; | |
1044 | pfd->cColorBits = 0; | |
1045 | DescribePixelFormat (hte -> hDC, iPixelFormat, | |
1046 | sizeof ( PIXELFORMATDESCRIPTOR ), pfd); | |
1047 | if (pfd->cColorBits >= cBits[j] && pfd->cDepthBits >= dBits[i]) | |
1048 | break; | |
1049 | if (iGood == 0) | |
1050 | iGood = iPixelFormat; | |
1051 | } | |
1052 | } | |
1053 | if (j < sizeof(cBits) / sizeof(int)) | |
1054 | break; | |
1055 | } | |
1056 | ||
1057 | if ( !iPixelFormat ) | |
1058 | iPixelFormat = iGood; | |
1059 | ||
1060 | return iPixelFormat; | |
1061 | } | |
1062 | ||
1063 | #endif /* WNT */ | |
1064 | /*----------------------------------------------------------------------*/ |