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); |
305 | dead_ctx = 0; |
306 | } else if (previous_ctx == 0) { |
307 | ctx = glXCreateContext( disp, vis, NULL, GL_TRUE ); |
308 | } else { |
309 | /* ctx est une copie du previous */ |
310 | ctx = glXCreateContext( disp, vis, previous_ctx, GL_TRUE ); |
311 | } |
312 | previous_ctx = ctx; |
313 | |
314 | if( !ctx) return TFailure; |
315 | |
d4c2114a |
316 | OpenGl_ResourceCleaner::GetInstance()->AppendContext( ctx, true ); |
317 | |
7fd59977 |
318 | cmap = XCreateColormap( disp, par, vis->visual, AllocNone ); |
319 | |
320 | color.red = (unsigned short) (bgcolr * 0xFFFF); |
321 | color.green = (unsigned short) (bgcolg * 0xFFFF); |
322 | color.blue = (unsigned short) (bgcolb * 0xFFFF); |
323 | color.flags = DoRed | DoGreen | DoBlue; |
324 | XAllocColor( disp, cmap, &color ); |
325 | |
326 | cwa.colormap = cmap; |
327 | cwa.event_mask = StructureNotifyMask; |
328 | cwa.border_pixel = color.pixel; |
329 | cwa.background_pixel = color.pixel; |
330 | |
331 | mask = CWBackPixel | CWColormap | CWBorderPixel | CWEventMask; |
332 | |
333 | if( vis->visualid == wattr.visual->visualid ) { |
334 | win = par; |
335 | } |
336 | else |
337 | { |
338 | win = XCreateWindow( disp, par, x, y, w, h, bw, |
339 | vis->depth, InputOutput, vis->visual, |
340 | mask, &cwa ); |
341 | } |
342 | |
343 | #ifdef TRACE |
344 | printf ("TxglCreateWindow win %x par %x \n", win, par); |
345 | #endif |
346 | |
347 | XSetWindowBackground( disp, win, cwa.background_pixel ); |
348 | XClearWindow( disp, win ); |
349 | |
350 | /* if in Pixmap double buffering mode, set up pixmap */ |
351 | |
352 | if (TelTestPixmapDB()) |
353 | { |
354 | GC gc; |
355 | Pixmap pixmap; |
356 | GLXPixmap glxpixmap; |
357 | |
358 | printf("setting up pixmap double buffering\n"); |
359 | |
360 | gc = XCreateGC(disp, win, 0, NULL); |
361 | |
362 | pixmap = XCreatePixmap(disp, win, w, h, vis->depth); |
363 | |
364 | glxpixmap = glXCreateGLXPixmap(disp, vis, pixmap); |
365 | |
366 | glXMakeCurrent(disp, glxpixmap, ctx); |
367 | |
368 | glDrawBuffer(GL_FRONT); |
369 | |
370 | TelSetPixmapDBParams(disp, win, w, h, vis->depth, gc, pixmap, glxpixmap, ctx); |
371 | } |
372 | |
373 | XFree((char*)vis); |
374 | |
375 | _Txgl_Map.Bind( (Tint)win, ctx ); |
376 | |
377 | return win; |
378 | |
379 | #else /* WNT */ |
380 | |
381 | HTBL_ENTRY* hte; |
382 | PIXELFORMATDESCRIPTOR pfd; |
383 | BOOL DBuffer = TRUE; |
384 | int iPixelFormat; |
385 | char string[ CALL_DEF_STRING_LENGTH ]; |
386 | |
387 | #ifdef BUC60691 |
388 | OSVERSIONINFO os; |
389 | os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); |
390 | GetVersionEx(&os); |
391 | if( os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) win95 = TRUE; |
392 | #endif |
393 | |
394 | if ( _Txgl_Map.IsBound( (Tint)par ) ) { |
395 | hte = _Txgl_Map.ChangeFind( (Tint)par ); |
396 | if ( hte ) |
397 | { |
398 | ++hte -> nUsed; |
399 | printf("*TxglCreateWindow.window %d is alreday created\n",par); |
400 | return par; |
401 | } |
402 | } |
403 | |
404 | hte = new HTBL_ENTRY(); |
405 | |
406 | if ( !hte ) return 0; |
407 | hte -> hDC = GetDC ( par ); |
408 | |
409 | iPixelFormat = find_pixel_format(hte, &pfd); |
410 | |
411 | if ( !iPixelFormat ) |
412 | { |
413 | printf ("*OpenGL interface: ChoosePixelFormat failed. Error code: %d\n",GetLastError ()); |
414 | |
415 | ReleaseDC ( par, hte -> hDC ); |
416 | delete hte; |
417 | |
418 | return 0; |
419 | } |
420 | |
421 | if ( pfd.dwFlags & PFD_NEED_PALETTE ) |
422 | { |
8ab673bb |
423 | WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLongPtr ( par, GWLP_USERDATA ); |
7fd59977 |
424 | |
425 | InterfaceGraphic_RealizePalette (hte -> hDC, wd -> hPal, FALSE, |
426 | s_sysPalInUse = pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE); |
427 | } |
428 | |
429 | if ( pfd.cColorBits <= 8 ) |
430 | { |
431 | DitherProp = TRUE; |
432 | BackDitherProp = TRUE; |
433 | } |
434 | |
435 | if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH)) |
436 | DitherProp = FALSE; |
437 | |
438 | if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH)) |
439 | BackDitherProp = FALSE; |
440 | |
441 | if ( !SetPixelFormat ( hte -> hDC, iPixelFormat, &pfd ) ) |
442 | { |
443 | printf ("*OpenGL interface: SetPixelFormat failed. Error code %d\n",GetLastError ()); |
444 | ReleaseDC ( par, hte -> hDC ); |
445 | delete hte; |
446 | return 0; |
447 | } |
448 | |
449 | hte -> hGLRC = wglCreateContext ( hte -> hDC ); |
450 | |
451 | if ( !hte -> hGLRC ) |
452 | { |
453 | printf ("*OpenGL interface: wglCreateContext failed. Error code: %d\n",GetLastError ()); |
454 | return 0; |
455 | } |
456 | |
d4c2114a |
457 | Standard_Boolean isShared = Standard_True; |
458 | |
459 | if (previous_ctx == 0 ) |
8ab673bb |
460 | previous_ctx = hte -> hGLRC; |
d4c2114a |
461 | // if we already have some shared context |
462 | else |
463 | { |
464 | // try to share context with one from resource cleaner list |
465 | GLCONTEXT shareCtx = OpenGl_ResourceCleaner::GetInstance()->GetSharedContext(); |
466 | |
467 | if (shareCtx != 0) |
468 | isShared = (Standard_Boolean)wglShareLists(shareCtx, hte -> hGLRC); |
469 | else |
470 | { |
471 | isShared = (Standard_Boolean)wglShareLists(previous_ctx, hte -> hGLRC); |
472 | // add shared previous_ctx to a control list if it's not there |
473 | if (isShared) |
474 | OpenGl_ResourceCleaner::GetInstance()->AppendContext(previous_ctx, isShared); |
475 | } |
476 | } |
7fd59977 |
477 | |
d4c2114a |
478 | // add the context to OpenGl_ResourceCleaner control list |
479 | OpenGl_ResourceCleaner::GetInstance()->AppendContext( hte -> hGLRC, isShared); |
7fd59977 |
480 | _Txgl_Map.Bind( (Tint)par, hte ); |
481 | |
482 | return par; |
483 | |
484 | #endif /* WNT */ |
485 | |
486 | } |
487 | |
488 | #ifdef RIC120302 |
489 | WINDOW |
490 | TxglSetWindow( DISPLAY *disp, WINDOW par, GLCONTEXT ctx) |
491 | { |
492 | #ifndef WNT |
493 | XVisualInfo* vis; |
494 | char string[CALL_DEF_STRING_LENGTH]; |
495 | XWindowAttributes wattr; |
496 | |
497 | XGetWindowAttributes( disp , par , &wattr ); |
498 | { |
499 | unsigned long vmask = VisualIDMask | VisualScreenMask; |
500 | XVisualInfo vinfo; |
501 | int ninfo; |
502 | vinfo.visualid = wattr.visual->visualid; |
503 | vinfo.screen = DefaultScreen( disp ); |
504 | vis = XGetVisualInfo( disp, vmask, &vinfo, &ninfo); |
505 | } |
506 | |
507 | if( !vis) return TFailure; |
508 | |
509 | #ifdef TRACE |
510 | printf ("TxglSetWindow \n"); |
511 | printf ("Informations sur le visual\n"); |
512 | printf ("par visualid %x%x %d\n", wattr.visual->visualid, wattr.visual->visualid); |
513 | printf ("vis visualid 0x%x %d\n", vis->visualid, vis->visualid); |
514 | printf ("vis depth %d\n", vis->depth); |
515 | printf ("vis class %d\n", vis->class); |
516 | printf ("vis red_mask %ld\n", vis->red_mask); |
517 | printf ("vis green_mask %ld\n", vis->green_mask); |
518 | printf ("vis blue_mask %ld\n", vis->blue_mask); |
519 | printf ("vis colormap_size %d\n", vis->colormap_size); |
520 | printf ("vis bits_per_rgb %d\n", vis->bits_per_rgb); |
521 | printVisualInfo( disp, vis ); |
522 | #endif |
523 | |
524 | /* |
525 | * Le BackDitherProp est utilise pour le clear du background |
526 | * Pour eviter une difference de couleurs avec la couleur choisie |
527 | * par l'application (XWindow) il faut desactiver le dithering |
528 | * au dessus de 8 plans. |
529 | * |
530 | * Pour le DitherProp: |
531 | * On cherchera a activer le Dithering que si le Visual a au moins |
532 | * 8 plans pour le GLX_RED_SIZE. Le test est plus sur car on peut |
533 | * avoir une profondeur superieure a 12 mais avoir besoin du dithering. |
534 | * (Carte Impact avec GLX_RED_SIZE a 5 par exemple) |
535 | */ |
536 | |
537 | { |
538 | int value; |
539 | glXGetConfig( disp, vis, GLX_RED_SIZE, &value ); |
540 | |
541 | if ( value < 8 ) { |
542 | DitherProp = True; |
543 | } else { |
544 | DitherProp = False; |
545 | } |
546 | |
547 | if ( vis->depth <= 8 ) { |
548 | BackDitherProp = True; |
549 | } else { |
550 | BackDitherProp = False; |
551 | } |
552 | } |
553 | |
554 | #ifdef TRACE |
555 | printf("Dithering %d BackDithering %d \n",DitherProp,BackDitherProp); |
556 | #endif |
557 | |
558 | if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH)) |
559 | DitherProp = False; |
560 | |
561 | if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH)) |
562 | BackDitherProp = False; |
563 | |
564 | previous_ctx = ctx; |
565 | |
566 | XFree((char*)vis); |
567 | |
568 | _Txgl_Map.Bind( ( Tint )par, ctx ); |
569 | #else /* WNT */ |
570 | |
571 | /* abd |
572 | cmn_htbl_elem rec;*/ |
573 | HTBL_ENTRY* hte; |
574 | PIXELFORMATDESCRIPTOR pfd; |
575 | BOOL DBuffer = TRUE; |
576 | int iPixelFormat; |
577 | char string[ CALL_DEF_STRING_LENGTH ]; |
578 | |
579 | #ifdef BUC60691 |
580 | OSVERSIONINFO os; |
581 | os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); |
582 | GetVersionEx(&os); |
583 | if( os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) win95 = TRUE; |
584 | #endif |
585 | |
586 | if ( _Txgl_Map.IsBound( ( Tint )par ) ) |
587 | { |
588 | hte = _Txgl_Map.ChangeFind( ( Tint )par ); |
589 | ++hte -> nUsed; |
590 | printf("*TxglSetWindow.window %d is alreday created\n",par); |
591 | return par; |
592 | } |
593 | |
594 | hte = new HTBL_ENTRY(); |
595 | |
596 | if ( !hte ) return 0; |
597 | |
598 | hte -> hDC = GetDC ( par ); |
599 | iPixelFormat = find_pixel_format(hte, &pfd); |
600 | |
601 | if ( !iPixelFormat ) |
602 | { |
603 | printf ("*OpenGL interface: ChoosePixelFormat failed. Error code: %d\n",GetLastError ()); |
604 | |
605 | ReleaseDC ( par, hte -> hDC ); |
606 | delete hte; |
607 | |
608 | return 0; |
609 | } |
610 | |
611 | if ( pfd.dwFlags & PFD_NEED_PALETTE ) |
612 | { |
8ab673bb |
613 | WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLongPtr ( par, GWLP_USERDATA ); |
7fd59977 |
614 | |
615 | InterfaceGraphic_RealizePalette (hte -> hDC, wd -> hPal, FALSE, |
616 | s_sysPalInUse = pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE); |
617 | } |
618 | |
619 | if ( pfd.cColorBits <= 8 ) |
620 | { |
621 | DitherProp = TRUE; |
622 | BackDitherProp = TRUE; |
623 | } |
624 | |
625 | if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH)) |
626 | DitherProp = FALSE; |
627 | |
628 | if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH)) |
629 | BackDitherProp = FALSE; |
630 | |
631 | if ( !SetPixelFormat ( hte -> hDC, iPixelFormat, &pfd ) ) |
632 | { |
633 | printf ("*OpenGL interface: SetPixelFormat failed. Error code %d\n",GetLastError ()); |
634 | ReleaseDC ( par, hte -> hDC ); |
635 | delete hte; |
636 | return 0; |
637 | } |
638 | |
639 | hte -> hGLRC = previous_ctx = ctx; |
640 | |
641 | _Txgl_Map.Bind( ( Tint )par, hte ); |
642 | #endif /* WNT */ |
643 | |
644 | return par; |
645 | |
646 | } |
647 | #endif /*RIC120302*/ |
648 | |
649 | /*----------------------------------------------------------------------*/ |
650 | |
651 | TStatus |
652 | TxglWinset( DISPLAY *disp, WINDOW win ) |
653 | { |
654 | |
655 | #ifndef WNT |
656 | |
657 | Bool i; |
658 | GLXContext ctx; |
659 | GLenum errorcode; |
660 | const GLubyte *errorstring; |
661 | |
662 | if ( !_Txgl_Map.IsBound( win ) ) |
663 | return TFailure; |
664 | |
665 | ctx = _Txgl_Map.ChangeFind( win ); |
666 | |
667 | |
668 | #ifdef TRACE |
669 | printf ("TxglWinset::glXMakeCurrent %x \n", win); |
670 | #endif |
671 | if (TelTestPixmapDB()) |
672 | { |
673 | i = glXMakeCurrent(disp, TelGetGLXPixmap(), ctx); |
674 | } |
675 | else |
676 | { |
677 | i = glXMakeCurrent(disp, win, ctx); /* TRUE/FALSE */ |
678 | } |
679 | if (!i) |
680 | { |
681 | errorcode = glGetError(); |
682 | errorstring = gluErrorString(errorcode); |
683 | printf("glXMakeCurrent failed: %d %s\n", errorcode, errorstring); |
684 | } |
685 | |
686 | return i == True ? TSuccess : TFailure; |
687 | |
688 | #else /* WNT */ |
689 | |
690 | HTBL_ENTRY* hte; |
691 | HDC hdc = NULL; |
692 | HGLRC hglrc = NULL; |
693 | TStatus retVal = TFailure; |
694 | |
695 | __try { |
696 | |
697 | if ( !_Txgl_Map.IsBound( ( Tint )win ) ) { |
698 | printf("OpenGL interface: TxglWinset failed.UNKNOWN win %x\n",win); |
699 | __leave; |
700 | } |
701 | hte = _Txgl_Map.ChangeFind( ( Tint )win ); |
702 | |
703 | #ifdef BUC60691 |
704 | if( win95 ) { |
705 | retVal = (TStatus)ReleaseDC ( win, hte -> hDC ); |
706 | hte -> hDC = GetDC ( win ); |
707 | } |
708 | #endif |
709 | if ( !wglMakeCurrent ( hte -> hDC, hte -> hGLRC ) ) |
710 | { |
711 | #ifdef BUC60691 |
712 | GLenum errorcode; |
713 | const GLubyte *errorstring; |
714 | |
715 | errorcode = glGetError(); |
716 | errorstring = gluErrorString(errorcode); |
717 | printf("wglMakeCurrent failed: %d %s\n", errorcode, errorstring); |
718 | #else |
719 | printf ("OpenGL interface: wglMakeCurrent failed. Error code: %d\n",GetLastError ()); |
720 | #endif |
721 | retVal = TFailure; |
722 | } else retVal = TSuccess; |
723 | |
724 | } /* end __try */ |
725 | |
726 | |
727 | __finally |
728 | { |
729 | } |
730 | |
731 | return retVal; |
732 | |
733 | #endif /* WNT */ |
734 | |
735 | } |
736 | |
737 | /*----------------------------------------------------------------------*/ |
738 | |
739 | WINDOW |
740 | TxglGetSubWindow( DISPLAY *disp, WINDOW win ) |
741 | /* This function assumes that there is only |
742 | one child for the parent */ |
743 | { |
744 | |
745 | #ifndef WNT |
746 | |
747 | Window root, parent, *child, w; |
748 | unsigned int num; |
749 | |
750 | if( XQueryTree( disp, win, &root, &parent, &child, &num ) ) |
751 | { |
752 | if (! num) return win; |
753 | w = child[0]; |
754 | XFree( (char *)child ); |
755 | return w; |
756 | } |
757 | else |
758 | return 0; |
759 | |
760 | #else /* WNT */ |
761 | |
762 | return win; |
763 | |
764 | #endif /* WNT */ |
765 | |
766 | } |
767 | |
768 | /*----------------------------------------------------------------------*/ |
769 | |
770 | void |
771 | TxglDestroyWindow( DISPLAY *disp, WINDOW win ) |
772 | { |
773 | |
774 | #ifndef WNT |
775 | |
776 | GLXContext ctx; |
777 | Tint dummy; |
778 | |
779 | if ( !_Txgl_Map.IsBound(win) ) |
780 | return; |
781 | ctx = _Txgl_Map.ChangeFind(win); |
782 | |
783 | /* FSXXX sync necessary if non-direct rendering */ |
784 | glXWaitGL(); |
785 | |
d4c2114a |
786 | OpenGl_ResourceCleaner::GetInstance()->RemoveContext( ctx ); |
7fd59977 |
787 | _Txgl_Map.UnBind( win ); |
788 | |
789 | if (previous_ctx == ctx) { |
790 | /* san -- OCC12977: it's important to put some valid GLXContext or null into |
791 | previous_ctx here, otherwise next glxCreateContext() will crash on some ATI Radeon cards |
792 | */ |
793 | previous_ctx = NULL; |
794 | if ( _Txgl_Map.Size() > 0 ) { |
795 | GLContextMap::Iterator it(_Txgl_Map); |
796 | previous_ctx = it.Value(); |
797 | } |
798 | /* |
799 | * if this is the last remaining context, do not destroy it yet, to avoid |
800 | * losing any shared display lists (fonts...) |
801 | */ |
802 | if (previous_ctx) { |
803 | glXDestroyContext(disp, ctx); |
804 | } else { |
805 | dead_ctx = ctx; |
806 | dead_dpy = disp; |
807 | } |
808 | } else { |
809 | glXDestroyContext(disp, ctx); |
810 | } |
811 | |
812 | #else /* WNT */ |
813 | |
814 | HTBL_ENTRY* hte; |
815 | #ifdef _DEBUG |
816 | WINDOW_DATA* wd; |
817 | #endif /* _DEBUG */ |
818 | if ( !_Txgl_Map.IsBound(( Tint )win) ) |
819 | return; |
820 | hte = _Txgl_Map.ChangeFind(( Tint )win); |
821 | |
822 | #ifdef _DEBUG |
823 | /* In release version of application we need to process */ |
824 | /* palette messages in the main application message loop. */ |
825 | /* In debug version we don't have message loop for most */ |
826 | /* cases. So, let's restore system colors here now. */ |
8ab673bb |
827 | wd = ( WINDOW_DATA* )GetWindowLongPtr ( win, GWLP_USERDATA ); |
7fd59977 |
828 | |
829 | if ( wd != NULL ) InterfaceGraphic_RealizePalette ( |
830 | hte -> hDC, wd -> hPal, TRUE, s_sysPalInUse); |
831 | #endif /* _DEBUG */ |
832 | |
833 | if ( --hte -> nUsed == 0 ) |
834 | { |
d4c2114a |
835 | OpenGl_ResourceCleaner::GetInstance()->RemoveContext( hte -> hGLRC ); |
7fd59977 |
836 | #ifdef OCC954 |
837 | if ( wglGetCurrentContext() != NULL ) |
838 | #endif |
839 | wglDeleteContext ( hte -> hGLRC ); |
840 | ReleaseDC ( win, hte -> hDC ); |
841 | _Txgl_Map.UnBind( (Tint ) win ); |
d4c2114a |
842 | if( _Txgl_Map.Size() == 0 ) { |
843 | previous_ctx = 0; |
844 | } |
7fd59977 |
845 | delete hte; |
846 | } |
847 | |
848 | #endif /* WNT */ |
849 | |
850 | } |
851 | |
852 | /*----------------------------------------------------------------------*/ |
853 | |
854 | int |
855 | TxglGetDither(void) |
856 | { |
857 | return DitherProp; |
858 | } |
859 | |
860 | /*----------------------------------------------------------------------*/ |
861 | |
862 | int |
863 | TxglGetBackDither(void) |
864 | { |
865 | return BackDitherProp; |
866 | } |
867 | |
868 | |
869 | /*----------------------------------------------------------------------*/ |
870 | /*RIC120302*/ |
871 | GLCONTEXT |
872 | TxglGetContext( WINDOW win ) |
873 | { |
874 | GLCONTEXT ctx = NULL; |
875 | if ( _Txgl_Map.IsBound( (Tint) win ) ) |
876 | ctx = |
877 | #ifdef WNT |
878 | _Txgl_Map.Find( (Tint) win )->hGLRC; |
879 | #else |
880 | _Txgl_Map.Find( win ); |
881 | #endif |
882 | |
883 | return ctx; |
884 | } |
885 | /*RIC120302*/ |
886 | |
887 | /*----------------------------------------------------------------------*/ |
888 | enum { ZERO = 0, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN }; |
889 | |
890 | /* Unused :*/ |
891 | #ifdef TRACE |
892 | static const char* |
893 | className( int class ) |
894 | { |
895 | static char *classes[] = { |
896 | "StaticGray", |
897 | "GrayScale", |
898 | "StaticColor", |
899 | "PseudoColor", |
900 | "TrueColor", |
901 | "DirectColor", |
902 | }; |
903 | |
904 | if ( class < ZERO || class > FIVE ) |
905 | return "unknown"; |
906 | else |
907 | return classes[class]; |
908 | } |
909 | #endif |
910 | /*----------------------------------------------------------------------*/ |
911 | #ifndef WNT |
912 | |
913 | #ifdef TRACE |
914 | static GLvoid printVisualInfo( DISPLAY *display, XVisualInfo *glxVisual ) |
915 | { |
916 | |
917 | #define TrueFalse(x) ( x ? "True" : "False" ) |
918 | |
919 | int tmp; |
920 | |
921 | printf("\n" ); |
922 | printf(" X Visual Information ...\n\n" ); |
923 | printf("\tvisualid : 0x%x\n", glxVisual->visualid ); |
924 | printf("\tclass : %s\n\n", className( glxVisual->class ) ); |
925 | |
926 | glXGetConfig(display, glxVisual, GLX_USE_GL, &tmp); |
927 | printf( "\tSupport GL ( GLX_USE_GL ) : %s\n", TrueFalse(tmp) ); |
928 | |
929 | glXGetConfig(display, glxVisual, GLX_LEVEL, &tmp); |
930 | printf( "\tFramebuffer ( GLX_LEVEL ) : %s\n\n", |
931 | (tmp < ZERO) ? "Underlay" : (tmp == ZERO ? "Normal" : tmp > ONE ? "Overlay" : "Popup") ); |
932 | |
933 | glXGetConfig(display, glxVisual, GLX_BUFFER_SIZE, &tmp); |
934 | printf( "\tFramebuffer depth ( GLX_BUFFER_SIZE ) : %d\n", tmp ); |
935 | |
936 | glXGetConfig(display, glxVisual, GLX_DOUBLEBUFFER, &tmp); |
937 | printf( "\tDoublebuffer ( GLX_DOUBLEBUFFER ) : %s\n", |
938 | TrueFalse(tmp) ); |
939 | |
940 | glXGetConfig(display, glxVisual, GLX_DEPTH_SIZE, &tmp); |
941 | printf( "\tDepth buffer depth ( GLX_DEPTH_SIZE ) : %d\n", tmp ); |
942 | |
943 | glXGetConfig(display, glxVisual, GLX_STENCIL_SIZE, &tmp); |
944 | printf( "\tStencil buffer depth ( GLX_STENCIL_SIZE ) : %d\n", tmp ); |
945 | |
946 | glXGetConfig(display, glxVisual, GLX_STEREO, &tmp); |
947 | printf( "\tStereo Buffer ( GLX_STEREO ) : %s\n", |
948 | TrueFalse(tmp) ); |
949 | |
950 | glXGetConfig(display, glxVisual, GLX_AUX_BUFFERS, &tmp); |
951 | printf( "\tAuxillary Buffers ( GLX_AUX_BUFFERS) : %d\n\n", tmp ); |
952 | |
953 | glXGetConfig(display, glxVisual, GLX_RGBA, &tmp); |
954 | printf( "\tColor mode ( GLX_RGBA ) : %s\n", tmp ? "RGBA" : |
955 | "Color Index" ); |
956 | |
957 | glXGetConfig(display, glxVisual, GLX_RED_SIZE, &tmp); |
958 | printf( "\tRed Bits ( GLX_RED_SIZE ) : %d\n", tmp ); |
959 | |
960 | glXGetConfig(display, glxVisual, GLX_GREEN_SIZE, &tmp); |
961 | printf( "\tGreen Bits ( GLX_GREEN_SIZE ) : %d\n", tmp ); |
962 | |
963 | glXGetConfig(display, glxVisual, GLX_BLUE_SIZE, &tmp); |
964 | printf( "\tBlue Bits ( GLX_BLUE_SIZE ) : %d\n", tmp ); |
965 | |
966 | glXGetConfig(display, glxVisual, GLX_ALPHA_SIZE, &tmp); |
967 | printf( "\tAlpha Bits ( GLX_ALPHA_SIZE ) : %d\n\n", tmp ); |
968 | |
969 | glXGetConfig(display, glxVisual, GLX_ACCUM_RED_SIZE, &tmp); |
970 | printf( "\tRed Accumulation Bits ( GLX_ACCUM_RED_SIZE ) : %d\n", tmp ); |
971 | |
972 | glXGetConfig(display, glxVisual, GLX_ACCUM_GREEN_SIZE, &tmp); |
973 | printf( "\tGreen Accumulation Bits ( GLX_ACCUM_GREEN_SIZE ) : %d\n", tmp ); |
974 | |
975 | glXGetConfig(display, glxVisual, GLX_ACCUM_BLUE_SIZE, &tmp); |
976 | printf( "\tBlue Accumulation Bits ( GLX_ACCUM_BLUE_SIZE ) : %d\n", tmp ); |
977 | |
978 | glXGetConfig(display, glxVisual, GLX_ACCUM_ALPHA_SIZE, &tmp); |
979 | printf( "\tAlpha Accumulation Bits ( GLX_ACCUM_ALPHA_SIZE ) : %d\n\n", tmp ); |
980 | } |
981 | #endif //TRACE |
982 | #else //WNT |
983 | int find_pixel_format(HTBL_ENTRY * hte, PIXELFORMATDESCRIPTOR * pfd) |
984 | { |
985 | int iPixelFormat = 0; |
986 | int iGood = 0; |
987 | int i, j; |
988 | PIXELFORMATDESCRIPTOR pfd0; |
989 | char string[ CALL_DEF_STRING_LENGTH ]; |
990 | BOOL DBuffer = TRUE; |
991 | const int cBits[] = { 32, 24 }; |
992 | const int dBits[] = { 32, 24, 16 }; |
993 | |
994 | if (call_util_osd_getenv ("CALL_OPENGL_NO_DBF", |
995 | string, CALL_DEF_STRING_LENGTH)) |
996 | DBuffer = FALSE; |
997 | |
998 | pfd0.nSize = sizeof ( PIXELFORMATDESCRIPTOR ); |
999 | pfd0.nVersion = 1; |
1000 | pfd0.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; |
1001 | pfd0.dwFlags |= ( DBuffer ) ? PFD_DOUBLEBUFFER : PFD_SUPPORT_GDI; |
1002 | pfd0.iPixelType = PFD_TYPE_RGBA; |
1003 | pfd0.cRedBits = 0; |
1004 | pfd0.cRedShift = 0; |
1005 | pfd0.cGreenBits = 0; |
1006 | pfd0.cGreenShift = 0; |
1007 | pfd0.cBlueBits = 0; |
1008 | pfd0.cBlueShift = 0; |
1009 | pfd0.cAlphaBits = 0; |
1010 | pfd0.cAlphaShift = 0; |
1011 | pfd0.cAccumBits = 0; |
1012 | pfd0.cAccumRedBits = 0; |
1013 | pfd0.cAccumGreenBits = 0; |
1014 | pfd0.cAccumBlueBits = 0; |
1015 | pfd0.cAccumAlphaBits = 0; |
1016 | pfd0.cStencilBits = 0; |
1017 | pfd0.cAuxBuffers = 0; |
1018 | pfd0.iLayerType = PFD_MAIN_PLANE; |
1019 | pfd0.bReserved = 0; |
1020 | pfd0.dwLayerMask = 0; |
1021 | pfd0.dwVisibleMask = 0; |
1022 | pfd0.dwDamageMask = 0; |
1023 | |
1024 | hte -> nUsed = 1; |
1025 | |
1026 | for (i = 0; i < sizeof(dBits) / sizeof(int); i++) { |
1027 | |
1028 | pfd0.cDepthBits = dBits[i]; |
1029 | iGood = 0; |
1030 | for (j = 0; j < sizeof(cBits) / sizeof(int); j++) { |
1031 | |
1032 | pfd0.cColorBits = cBits[j]; |
1033 | iPixelFormat = ChoosePixelFormat ( hte -> hDC, &pfd0 ); |
1034 | |
1035 | if (iPixelFormat) { |
1036 | pfd->cDepthBits = 0; |
1037 | pfd->cColorBits = 0; |
1038 | DescribePixelFormat (hte -> hDC, iPixelFormat, |
1039 | sizeof ( PIXELFORMATDESCRIPTOR ), pfd); |
1040 | if (pfd->cColorBits >= cBits[j] && pfd->cDepthBits >= dBits[i]) |
1041 | break; |
1042 | if (iGood == 0) |
1043 | iGood = iPixelFormat; |
1044 | } |
1045 | } |
1046 | if (j < sizeof(cBits) / sizeof(int)) |
1047 | break; |
1048 | } |
1049 | |
1050 | if ( !iPixelFormat ) |
1051 | iPixelFormat = iGood; |
1052 | |
1053 | return iPixelFormat; |
1054 | } |
1055 | |
1056 | #endif /* WNT */ |
1057 | /*----------------------------------------------------------------------*/ |