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