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