Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-09-20 |
2 | // Created by: Sergey ZERCHANINOV | |
3 | // Copyright (c) 2011-2012 OPEN CASCADE SAS | |
4 | // | |
5 | // The content of this file is subject to the Open CASCADE Technology Public | |
6 | // License Version 6.5 (the "License"). You may not use the content of this file | |
7 | // except in compliance with the License. Please obtain a copy of the License | |
8 | // at http://www.opencascade.org and read it completely before using this file. | |
9 | // | |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
12 | // | |
13 | // The Original Code and all software distributed under the License is | |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
15 | // Initial Developer hereby disclaims all such warranties, including without | |
16 | // limitation, any warranties of merchantability, fitness for a particular | |
17 | // purpose or non-infringement. Please see the License for the specific terms | |
18 | // and conditions governing the rights and limitations under the License. | |
19 | ||
2166f0fa SK |
20 | |
21 | #include <InterfaceGraphic.hxx> | |
22 | ||
23 | #include <OpenGl_Window.hxx> | |
24 | ||
25 | #include <OpenGl_Context.hxx> | |
26 | #include <OpenGl_Display.hxx> | |
27 | #include <OpenGl_ResourceCleaner.hxx> | |
28 | #include <OpenGl_ResourceTexture.hxx> | |
29 | ||
30 | #include <Aspect_GraphicDeviceDefinitionError.hxx> | |
31 | #include <TCollection_AsciiString.hxx> | |
32 | ||
5f8b738e | 33 | #include <GL/glu.h> // gluOrtho2D() |
34 | ||
2166f0fa SK |
35 | IMPLEMENT_STANDARD_HANDLE(OpenGl_Window,MMgt_TShared) |
36 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Window,MMgt_TShared) | |
37 | ||
38 | namespace | |
39 | { | |
40 | static const TEL_COLOUR THE_DEFAULT_BG_COLOR = { { 0.F, 0.F, 0.F, 1.F } }; | |
41 | ||
42 | static GLCONTEXT ThePreviousCtx = 0; // to share GL resources | |
43 | #if (!defined(_WIN32) && !defined(__WIN32__)) | |
44 | static GLXContext TheDeadGlxCtx; // Context to be destroyed | |
45 | static Display* TheDeadGlxDpy; // Display associated with TheDeadGlxCtx | |
46 | #endif | |
47 | ||
48 | #if (defined(_WIN32) || defined(__WIN32__)) | |
49 | static int find_pixel_format (HDC hDC, PIXELFORMATDESCRIPTOR* pfd, const Standard_Boolean dbuff) | |
50 | { | |
51 | PIXELFORMATDESCRIPTOR pfd0; | |
52 | memset (&pfd0, 0, sizeof (PIXELFORMATDESCRIPTOR)); | |
53 | pfd0.nSize = sizeof (PIXELFORMATDESCRIPTOR); | |
54 | pfd0.nVersion = 1; | |
55 | pfd0.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | (dbuff ? PFD_DOUBLEBUFFER : PFD_SUPPORT_GDI); | |
56 | pfd0.iPixelType = PFD_TYPE_RGBA; | |
57 | pfd0.iLayerType = PFD_MAIN_PLANE; | |
58 | ||
59 | int iPixelFormat = 0; | |
60 | int iGood = 0; | |
61 | const int cBits[] = { 32, 24 }; | |
62 | const int dBits[] = { 32, 24, 16 }; | |
63 | ||
64 | int i, j; | |
65 | for (i = 0; i < sizeof(dBits) / sizeof(int); i++) | |
66 | { | |
67 | pfd0.cDepthBits = dBits[i]; | |
68 | iGood = 0; | |
69 | for (j = 0; j < sizeof(cBits) / sizeof(int); j++) | |
70 | { | |
71 | pfd0.cColorBits = cBits[j]; | |
72 | iPixelFormat = ChoosePixelFormat (hDC, &pfd0); | |
73 | if (iPixelFormat) | |
74 | { | |
75 | pfd->cDepthBits = 0; | |
76 | pfd->cColorBits = 0; | |
77 | DescribePixelFormat (hDC, iPixelFormat, sizeof (PIXELFORMATDESCRIPTOR), pfd); | |
78 | if (pfd->cColorBits >= cBits[j] && pfd->cDepthBits >= dBits[i]) | |
79 | break; | |
80 | if (iGood == 0) | |
81 | iGood = iPixelFormat; | |
82 | } | |
83 | } | |
84 | if (j < sizeof(cBits) / sizeof(int)) | |
85 | break; | |
86 | } | |
87 | ||
88 | if (iPixelFormat == 0) | |
89 | iPixelFormat = iGood; | |
90 | ||
91 | return iPixelFormat; | |
92 | } | |
93 | #else | |
94 | static Bool WaitForNotify (Display* theDisp, XEvent* theEv, char* theArg) | |
95 | { | |
96 | return (theEv->type == MapNotify) && (theEv->xmap.window == (Window )theArg); | |
97 | } | |
98 | #endif | |
99 | ||
100 | }; | |
101 | ||
102 | // ======================================================================= | |
103 | // function : OpenGl_Window | |
104 | // purpose : | |
105 | // ======================================================================= | |
106 | OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay, | |
107 | const CALL_DEF_WINDOW& theCWindow, | |
108 | Aspect_RenderingContext theGContext) | |
109 | : myDisplay (theDisplay), | |
110 | myWindow (0), | |
111 | myGContext ((GLCONTEXT )theGContext), | |
112 | myGlContext (new OpenGl_Context()), | |
113 | myOwnGContext (theGContext == 0), | |
114 | #if (defined(_WIN32) || defined(__WIN32__)) | |
115 | myWindowDC (0), | |
116 | mySysPalInUse (FALSE), | |
117 | #endif | |
118 | myWidth ((Standard_Integer )theCWindow.dx), | |
119 | myHeight ((Standard_Integer )theCWindow.dy), | |
120 | myBgColor (THE_DEFAULT_BG_COLOR), | |
121 | myDither (theDisplay->Dither()), | |
122 | myBackDither (theDisplay->BackDither()) | |
123 | { | |
124 | myBgColor.rgb[0] = theCWindow.Background.r; | |
125 | myBgColor.rgb[1] = theCWindow.Background.g; | |
126 | myBgColor.rgb[2] = theCWindow.Background.b; | |
127 | ||
128 | WINDOW aParent = (WINDOW )theCWindow.XWindow; | |
129 | DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay(); | |
130 | ||
131 | #if (!defined(_WIN32) && !defined(__WIN32__)) | |
132 | XWindowAttributes wattr; | |
133 | XGetWindowAttributes (aDisp, aParent, &wattr); | |
134 | const int scr = DefaultScreen (aDisp); | |
135 | ||
136 | XVisualInfo* aVis = NULL; | |
137 | { | |
138 | unsigned long aVisInfoMask = VisualIDMask | VisualScreenMask; | |
139 | XVisualInfo aVisInfo; | |
140 | aVisInfo.visualid = wattr.visual->visualid; | |
141 | aVisInfo.screen = scr; | |
142 | int aNbItems; | |
143 | aVis = XGetVisualInfo (aDisp, aVisInfoMask, &aVisInfo, &aNbItems); | |
144 | } | |
145 | ||
146 | WINDOW win; | |
147 | ||
148 | if (!myOwnGContext) | |
149 | { | |
150 | if (aVis != NULL) | |
151 | { | |
152 | Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: XGetVisualInfo failed."); | |
153 | return; | |
154 | } | |
155 | ||
156 | win = aParent; | |
157 | } | |
158 | else | |
159 | { | |
160 | GLCONTEXT ctx; | |
161 | ||
162 | #if defined(__linux) || defined(Linux) | |
163 | if (aVis != NULL) | |
164 | { | |
165 | // check Visual for OpenGl context's parameters compability | |
166 | int isGl = 0, isDoubleBuffer = 0, isRGBA = 0, aDepthSize = 0; | |
167 | ||
168 | if (glXGetConfig (aDisp, aVis, GLX_USE_GL, &isGl) != 0) | |
169 | isGl = 0; | |
170 | ||
171 | if (glXGetConfig (aDisp, aVis, GLX_RGBA, &isRGBA) != 0) | |
172 | isRGBA = 0; | |
173 | ||
174 | if (glXGetConfig (aDisp, aVis, GLX_DOUBLEBUFFER, &isDoubleBuffer) != 0) | |
175 | isDoubleBuffer = 0; | |
176 | ||
177 | if (glXGetConfig (aDisp, aVis, GLX_DEPTH_SIZE, &aDepthSize) != 0) | |
178 | aDepthSize = 0; | |
179 | ||
180 | if (!isGl || !aDepthSize || !isRGBA || (isDoubleBuffer ? 1 : 0) != (myDisplay->DBuffer()? 1 : 0)) | |
181 | { | |
182 | XFree (aVis); | |
183 | aVis = NULL; | |
184 | } | |
185 | } | |
186 | #endif | |
187 | ||
188 | if (aVis == NULL) | |
189 | { | |
190 | int anIter = 0; | |
191 | int anAttribs[11]; | |
192 | anAttribs[anIter++] = GLX_RGBA; | |
193 | ||
194 | anAttribs[anIter++] = GLX_DEPTH_SIZE; | |
195 | anAttribs[anIter++] = 1; | |
196 | ||
197 | anAttribs[anIter++] = GLX_RED_SIZE; | |
198 | anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1; | |
199 | ||
200 | anAttribs[anIter++] = GLX_GREEN_SIZE; | |
201 | anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1; | |
202 | ||
203 | anAttribs[anIter++] = GLX_BLUE_SIZE; | |
204 | anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1; | |
205 | ||
206 | if (myDisplay->DBuffer()) | |
207 | anAttribs[anIter++] = GLX_DOUBLEBUFFER; | |
208 | ||
209 | anAttribs[anIter++] = None; | |
210 | ||
211 | aVis = glXChooseVisual (aDisp, scr, anAttribs); | |
212 | if (aVis == NULL) | |
213 | { | |
214 | Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: glXChooseVisual failed."); | |
215 | return; | |
216 | } | |
217 | } | |
218 | ||
219 | if (TheDeadGlxCtx) | |
220 | { | |
221 | // recover display lists from TheDeadGlxCtx, then destroy it | |
222 | ctx = glXCreateContext (aDisp, aVis, TheDeadGlxCtx, GL_TRUE); | |
223 | ||
224 | OpenGl_ResourceCleaner::GetInstance()->RemoveContext (TheDeadGlxCtx); | |
225 | glXDestroyContext (TheDeadGlxDpy, TheDeadGlxCtx); | |
226 | ||
227 | TheDeadGlxCtx = 0; | |
228 | } | |
229 | else if (ThePreviousCtx == 0) | |
230 | { | |
231 | ctx = glXCreateContext (aDisp, aVis, NULL, GL_TRUE); | |
232 | } | |
233 | else | |
234 | { | |
235 | // ctx est une copie du previous | |
236 | ctx = glXCreateContext (aDisp, aVis, ThePreviousCtx, GL_TRUE); | |
237 | } | |
238 | ||
239 | if (!ctx) | |
240 | { | |
241 | Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: glXCreateContext failed."); | |
242 | return; | |
243 | } | |
244 | ||
245 | OpenGl_ResourceCleaner::GetInstance()->AppendContext (ctx, true); | |
246 | ||
247 | ThePreviousCtx = ctx; | |
248 | ||
249 | Colormap cmap = XCreateColormap (aDisp, aParent, aVis->visual, AllocNone); | |
250 | ||
251 | XColor color; | |
252 | color.red = (unsigned short) (myBgColor.rgb[0] * 0xFFFF); | |
253 | color.green = (unsigned short) (myBgColor.rgb[1] * 0xFFFF); | |
254 | color.blue = (unsigned short) (myBgColor.rgb[2] * 0xFFFF); | |
255 | color.flags = DoRed | DoGreen | DoBlue; | |
256 | XAllocColor (aDisp, cmap, &color); | |
257 | ||
258 | XSetWindowAttributes cwa; | |
259 | cwa.colormap = cmap; | |
260 | cwa.event_mask = StructureNotifyMask; | |
261 | cwa.border_pixel = color.pixel; | |
262 | cwa.background_pixel = color.pixel; | |
263 | ||
264 | if (aVis->visualid == wattr.visual->visualid) | |
265 | { | |
266 | win = aParent; | |
267 | } | |
268 | else | |
269 | { | |
270 | unsigned long mask = CWBackPixel | CWColormap | CWBorderPixel | CWEventMask; | |
271 | win = XCreateWindow (aDisp, aParent, 0, 0, myWidth, myHeight, 0/*bw*/, aVis->depth, InputOutput, aVis->visual, mask, &cwa); | |
272 | } | |
273 | ||
274 | XSetWindowBackground (aDisp, win, cwa.background_pixel); | |
275 | XClearWindow (aDisp, win); | |
276 | ||
277 | if (win != aParent) | |
278 | { | |
279 | XEvent anEvent; | |
280 | XMapWindow (aDisp, win); | |
281 | XIfEvent (aDisp, &anEvent, WaitForNotify, (char* )win); | |
282 | } | |
283 | ||
284 | myGContext = ctx; | |
285 | } | |
286 | ||
287 | /* | |
288 | * Le BackDitherProp est utilise pour le clear du background | |
289 | * Pour eviter une difference de couleurs avec la couleur choisie | |
290 | * par l'application (XWindow) il faut desactiver le dithering | |
291 | * au dessus de 8 plans. | |
292 | * | |
293 | * Pour le DitherProp: | |
294 | * On cherchera a activer le Dithering que si le Visual a au moins | |
295 | * 8 plans pour le GLX_RED_SIZE. Le test est plus sur car on peut | |
296 | * avoir une profondeur superieure a 12 mais avoir besoin du dithering. | |
297 | * (Carte Impact avec GLX_RED_SIZE a 5 par exemple) | |
298 | */ | |
299 | ||
300 | int value; | |
301 | glXGetConfig (aDisp, aVis, GLX_RED_SIZE, &value); | |
302 | ||
303 | if (myDither) | |
304 | myDither = (value < 8); | |
305 | ||
306 | if (myBackDither) | |
307 | myBackDither = (aVis->depth <= 8); | |
308 | ||
309 | XFree ((char* )aVis); | |
310 | ||
311 | myWindow = win; | |
312 | ||
313 | #else | |
314 | ||
315 | myWindowDC = GetDC (aParent); | |
316 | ||
317 | PIXELFORMATDESCRIPTOR pfd; | |
318 | int iPixelFormat = find_pixel_format (myWindowDC, &pfd, myDisplay->DBuffer()); | |
319 | if (iPixelFormat == 0) | |
320 | { | |
321 | ReleaseDC (aParent, myWindowDC); | |
322 | myWindowDC = 0; | |
323 | ||
324 | TCollection_AsciiString msg ("OpenGl_Window::CreateWindow: ChoosePixelFormat failed. Error code: "); | |
325 | msg += (int )GetLastError(); | |
326 | Aspect_GraphicDeviceDefinitionError::Raise (msg.ToCString()); | |
327 | return; | |
328 | } | |
329 | ||
330 | if (pfd.dwFlags & PFD_NEED_PALETTE) | |
331 | { | |
332 | WINDOW_DATA* wd = (WINDOW_DATA* )GetWindowLongPtr (aParent, GWLP_USERDATA); | |
333 | ||
334 | mySysPalInUse = (pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE) ? TRUE : FALSE; | |
335 | InterfaceGraphic_RealizePalette (myWindowDC, wd->hPal, FALSE, mySysPalInUse); | |
336 | } | |
337 | ||
338 | if (myDither) | |
339 | myDither = (pfd.cColorBits <= 8); | |
340 | ||
341 | if (myBackDither) | |
342 | myBackDither = (pfd.cColorBits <= 8); | |
343 | ||
344 | if (!SetPixelFormat (myWindowDC, iPixelFormat, &pfd)) | |
345 | { | |
346 | ReleaseDC (aParent, myWindowDC); | |
347 | myWindowDC = NULL; | |
348 | ||
349 | TCollection_AsciiString msg("OpenGl_Window::CreateWindow: SetPixelFormat failed. Error code: "); | |
350 | msg += (int)GetLastError(); | |
351 | Aspect_GraphicDeviceDefinitionError::Raise (msg.ToCString()); | |
352 | return; | |
353 | } | |
354 | ||
355 | if (!myOwnGContext) | |
356 | { | |
357 | ThePreviousCtx = myGContext; | |
358 | } | |
359 | else | |
360 | { | |
361 | myGContext = wglCreateContext (myWindowDC); | |
362 | if (myGContext == NULL) | |
363 | { | |
364 | ReleaseDC (aParent, myWindowDC); | |
365 | myWindowDC = NULL; | |
366 | ||
367 | TCollection_AsciiString msg ("OpenGl_Window::CreateWindow: wglCreateContext failed. Error code: "); | |
368 | msg += (int )GetLastError(); | |
369 | Aspect_GraphicDeviceDefinitionError::Raise (msg.ToCString()); | |
370 | return; | |
371 | } | |
372 | ||
373 | Standard_Boolean isShared = Standard_True; | |
374 | if (ThePreviousCtx == NULL) | |
375 | { | |
376 | ThePreviousCtx = myGContext; | |
377 | } | |
378 | else | |
379 | { | |
380 | // if we already have some shared context | |
381 | GLCONTEXT shareCtx = OpenGl_ResourceCleaner::GetInstance()->GetSharedContext(); | |
382 | if (shareCtx != NULL) | |
383 | { | |
384 | // try to share context with one from resource cleaner list | |
385 | isShared = (Standard_Boolean )wglShareLists (shareCtx, myGContext); | |
386 | } | |
387 | else | |
388 | { | |
389 | isShared = (Standard_Boolean )wglShareLists (ThePreviousCtx, myGContext); | |
390 | // add shared ThePreviousCtx to a control list if it's not there | |
391 | if (isShared) | |
392 | OpenGl_ResourceCleaner::GetInstance()->AppendContext (ThePreviousCtx, isShared); | |
393 | } | |
394 | } | |
395 | ||
396 | // add the context to OpenGl_ResourceCleaner control list | |
397 | OpenGl_ResourceCleaner::GetInstance()->AppendContext (myGContext, isShared); | |
398 | } | |
399 | ||
400 | myWindow = aParent; | |
401 | #endif | |
402 | ||
86fa64d9 | 403 | #if (defined(_WIN32) || defined(__WIN32__)) |
404 | myGlContext->Init (myWindow, myWindowDC, myGContext); | |
405 | #else | |
406 | myGlContext->Init (myWindow, myDisplay->GetDisplay(), myGContext); | |
407 | #endif | |
2166f0fa | 408 | Init(); |
2166f0fa SK |
409 | } |
410 | ||
411 | // ======================================================================= | |
412 | // function : ~OpenGl_Window | |
413 | // purpose : | |
414 | // ======================================================================= | |
415 | OpenGl_Window::~OpenGl_Window() | |
416 | { | |
417 | DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay(); | |
418 | if (aDisp == NULL || !myOwnGContext) | |
419 | return; | |
420 | ||
421 | #if (defined(_WIN32) || defined(__WIN32__)) | |
422 | OpenGl_ResourceCleaner::GetInstance()->RemoveContext (myGContext); | |
423 | ||
424 | if (wglGetCurrentContext() != NULL) | |
425 | wglDeleteContext (myGContext); | |
426 | ReleaseDC (myWindow, myWindowDC); | |
427 | ||
428 | if (myDisplay->myMapOfWindows.Size() == 0) | |
429 | ThePreviousCtx = 0; | |
430 | #else | |
431 | // FSXXX sync necessary if non-direct rendering | |
432 | glXWaitGL(); | |
433 | ||
434 | if (ThePreviousCtx == myGContext) | |
435 | { | |
436 | ThePreviousCtx = NULL; | |
437 | if (myDisplay->myMapOfWindows.Size() > 0) | |
438 | { | |
439 | NCollection_DataMap<Standard_Integer, Handle(OpenGl_Window)>::Iterator it (myDisplay->myMapOfWindows); | |
440 | ThePreviousCtx = it.Value()->myGContext; | |
441 | } | |
442 | ||
443 | // if this is the last remaining context, do not destroy it yet, to avoid | |
444 | // losing any shared display lists (fonts...) | |
445 | if (ThePreviousCtx) | |
446 | { | |
447 | OpenGl_ResourceCleaner::GetInstance()->RemoveContext(myGContext); | |
448 | glXDestroyContext(aDisp, myGContext); | |
449 | } | |
450 | else | |
451 | { | |
452 | TheDeadGlxCtx = myGContext; | |
453 | TheDeadGlxDpy = aDisp; | |
454 | } | |
455 | } | |
456 | else | |
457 | { | |
458 | OpenGl_ResourceCleaner::GetInstance()->RemoveContext (myGContext); | |
459 | glXDestroyContext (aDisp, myGContext); | |
460 | } | |
461 | #endif | |
462 | } | |
463 | ||
464 | // ======================================================================= | |
465 | // function : Activate | |
466 | // purpose : | |
467 | // ======================================================================= | |
468 | Standard_Boolean OpenGl_Window::Activate() | |
469 | { | |
86fa64d9 | 470 | return myGlContext->MakeCurrent(); |
2166f0fa SK |
471 | } |
472 | ||
473 | // ======================================================================= | |
474 | // function : Resize | |
475 | // purpose : call_subr_resize | |
476 | // ======================================================================= | |
477 | void OpenGl_Window::Resize (const CALL_DEF_WINDOW& theCWindow) | |
478 | { | |
479 | DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay(); | |
480 | if (aDisp == NULL) | |
481 | return; | |
482 | ||
483 | // If the size is not changed - do nothing | |
484 | if ((myWidth == theCWindow.dx) && (myHeight == theCWindow.dy)) | |
485 | return; | |
486 | ||
487 | myWidth = (Standard_Integer )theCWindow.dx; | |
488 | myHeight = (Standard_Integer )theCWindow.dy; | |
489 | ||
490 | #if (!defined(_WIN32) && !defined(__WIN32__)) | |
491 | XResizeWindow (aDisp, myWindow, (unsigned int )myWidth, (unsigned int )myHeight); | |
492 | XSync (aDisp, False); | |
493 | #endif | |
494 | ||
495 | Init(); | |
496 | } | |
497 | ||
498 | // ======================================================================= | |
499 | // function : ReadDepths | |
500 | // purpose : TelReadDepths | |
501 | // ======================================================================= | |
502 | void OpenGl_Window::ReadDepths (const Standard_Integer theX, const Standard_Integer theY, | |
503 | const Standard_Integer theWidth, const Standard_Integer theHeight, | |
504 | float* theDepths) | |
505 | { | |
506 | if (theDepths == NULL || !Activate()) | |
507 | return; | |
508 | ||
509 | glMatrixMode (GL_PROJECTION); | |
510 | glLoadIdentity(); | |
511 | gluOrtho2D (0.0, (GLdouble )myWidth, 0.0, (GLdouble )myHeight); | |
512 | glMatrixMode (GL_MODELVIEW); | |
513 | glLoadIdentity(); | |
514 | ||
515 | glRasterPos2i (theX, theY); | |
516 | DisableFeatures(); | |
517 | glReadPixels (theX, theY, theWidth, theHeight, GL_DEPTH_COMPONENT, GL_FLOAT, theDepths); | |
518 | EnableFeatures(); | |
519 | } | |
520 | ||
521 | // ======================================================================= | |
522 | // function : SetBackgroundColor | |
523 | // purpose : call_subr_set_background | |
524 | // ======================================================================= | |
525 | void OpenGl_Window::SetBackgroundColor (const Standard_ShortReal theR, | |
526 | const Standard_ShortReal theG, | |
527 | const Standard_ShortReal theB) | |
528 | { | |
529 | myBgColor.rgb[0] = theR; | |
530 | myBgColor.rgb[1] = theG; | |
531 | myBgColor.rgb[2] = theB; | |
532 | } | |
533 | ||
534 | // ======================================================================= | |
535 | // function : Init | |
536 | // purpose : | |
537 | // ======================================================================= | |
538 | void OpenGl_Window::Init() | |
539 | { | |
540 | if (!Activate()) | |
541 | return; | |
542 | ||
543 | #if (defined(_WIN32) || defined(__WIN32__)) | |
544 | RECT cr; | |
545 | GetClientRect (myWindow, &cr); | |
546 | myWidth = cr.right - cr.left; | |
547 | myHeight = cr.bottom - cr.top; | |
548 | #else | |
549 | Window aRootWin; | |
550 | int aDummy; | |
551 | unsigned int aDummyU; | |
552 | unsigned int aNewWidth = 0; | |
553 | unsigned int aNewHeight = 0; | |
554 | DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay(); | |
555 | XGetGeometry (aDisp, myWindow, &aRootWin, &aDummy, &aDummy, &aNewWidth, &aNewHeight, &aDummyU, &aDummyU); | |
556 | myWidth = aNewWidth; | |
557 | myHeight = aNewHeight; | |
558 | #endif | |
559 | ||
560 | glMatrixMode (GL_MODELVIEW); | |
561 | glViewport (0, 0, myWidth, myHeight); | |
562 | ||
563 | glDisable (GL_SCISSOR_TEST); | |
564 | glDrawBuffer (GL_BACK); | |
565 | } | |
566 | ||
567 | // ======================================================================= | |
568 | // function : EnablePolygonOffset | |
569 | // purpose : call_subr_enable_polygon_offset | |
570 | // ======================================================================= | |
571 | void OpenGl_Window::EnablePolygonOffset() const | |
572 | { | |
573 | Standard_ShortReal aFactor, aUnits; | |
574 | myDisplay->PolygonOffset (aFactor, aUnits); | |
575 | glPolygonOffset (aFactor, aUnits); | |
576 | glEnable (GL_POLYGON_OFFSET_FILL); | |
577 | } | |
578 | ||
579 | // ======================================================================= | |
580 | // function : DisablePolygonOffset | |
581 | // purpose : call_subr_disable_polygon_offset | |
582 | // ======================================================================= | |
583 | void OpenGl_Window::DisablePolygonOffset() const | |
584 | { | |
585 | glDisable (GL_POLYGON_OFFSET_FILL); | |
586 | } | |
587 | ||
588 | // ======================================================================= | |
589 | // function : EnableFeatures | |
590 | // purpose : | |
591 | // ======================================================================= | |
592 | void OpenGl_Window::EnableFeatures() const | |
593 | { | |
594 | /*glPixelTransferi (GL_MAP_COLOR, GL_TRUE);*/ | |
595 | ||
596 | if (myDither) | |
597 | glEnable (GL_DITHER); | |
598 | else | |
599 | glDisable (GL_DITHER); | |
600 | } | |
601 | ||
602 | // ======================================================================= | |
603 | // function : DisableFeatures | |
604 | // purpose : | |
605 | // ======================================================================= | |
606 | void OpenGl_Window::DisableFeatures() const | |
607 | { | |
608 | glDisable (GL_DITHER); | |
609 | glPixelTransferi (GL_MAP_COLOR, GL_FALSE); | |
610 | ||
611 | /* | |
612 | * Disable stuff that's likely to slow down glDrawPixels. | |
613 | * (Omit as much of this as possible, when you know in advance | |
614 | * that the OpenGL state will already be set correctly.) | |
615 | */ | |
616 | glDisable(GL_ALPHA_TEST); | |
617 | glDisable(GL_BLEND); | |
618 | glDisable(GL_DEPTH_TEST); | |
619 | glDisable(GL_FOG); | |
620 | glDisable(GL_LIGHTING); | |
621 | ||
622 | glDisable(GL_LOGIC_OP); | |
623 | glDisable(GL_STENCIL_TEST); | |
624 | glDisable(GL_TEXTURE_1D); | |
625 | glDisable(GL_TEXTURE_2D); | |
626 | glPixelTransferi(GL_MAP_COLOR, GL_FALSE); | |
627 | glPixelTransferi(GL_RED_SCALE, 1); | |
628 | glPixelTransferi(GL_RED_BIAS, 0); | |
629 | glPixelTransferi(GL_GREEN_SCALE, 1); | |
630 | glPixelTransferi(GL_GREEN_BIAS, 0); | |
631 | glPixelTransferi(GL_BLUE_SCALE, 1); | |
632 | glPixelTransferi(GL_BLUE_BIAS, 0); | |
633 | glPixelTransferi(GL_ALPHA_SCALE, 1); | |
634 | glPixelTransferi(GL_ALPHA_BIAS, 0); | |
635 | ||
636 | /* | |
637 | * Disable extensions that could slow down glDrawPixels. | |
638 | * (Actually, you should check for the presence of the proper | |
639 | * extension before making these calls. I've omitted that | |
640 | * code for simplicity.) | |
641 | */ | |
642 | ||
643 | #ifdef GL_EXT_convolution | |
644 | glDisable(GL_CONVOLUTION_1D_EXT); | |
645 | glDisable(GL_CONVOLUTION_2D_EXT); | |
646 | glDisable(GL_SEPARABLE_2D_EXT); | |
647 | #endif | |
648 | ||
649 | #ifdef GL_EXT_histogram | |
650 | glDisable(GL_HISTOGRAM_EXT); | |
651 | glDisable(GL_MINMAX_EXT); | |
652 | #endif | |
653 | ||
654 | #ifdef GL_EXT_texture3D | |
655 | glDisable(GL_TEXTURE_3D_EXT); | |
656 | #endif | |
657 | } | |
658 | ||
659 | // ======================================================================= | |
660 | // function : MakeFrontBufCurrent | |
661 | // purpose : TelMakeFrontBufCurrent | |
662 | // ======================================================================= | |
663 | void OpenGl_Window::MakeFrontBufCurrent() const | |
664 | { | |
665 | glDrawBuffer (GL_FRONT); | |
666 | } | |
667 | ||
668 | // ======================================================================= | |
669 | // function : MakeBackBufCurrent | |
670 | // purpose : TelMakeBackBufCurrent | |
671 | // ======================================================================= | |
672 | void OpenGl_Window::MakeBackBufCurrent() const | |
673 | { | |
674 | glDrawBuffer (GL_BACK); | |
675 | } | |
676 | ||
677 | // ======================================================================= | |
678 | // function : MakeFrontAndBackBufCurrent | |
679 | // purpose : TelMakeFrontAndBackBufCurrent | |
680 | // ======================================================================= | |
681 | void OpenGl_Window::MakeFrontAndBackBufCurrent() const | |
682 | { | |
683 | glDrawBuffer (GL_FRONT_AND_BACK); | |
684 | } |