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