0024778: Convertation of the generic classes to the non-generic. Part 9
[occt.git] / src / OpenGl / OpenGl_Window.cxx
CommitLineData
b311480e 1// Created on: 2011-09-20
2// Created by: Sergey ZERCHANINOV
973c2be1 3// Copyright (c) 2011-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
b5ac8292 16#include <OpenGl_GlCore12.hxx>
cfd5fa01 17
2166f0fa
SK
18#include <InterfaceGraphic.hxx>
19
20#include <OpenGl_Window.hxx>
21
22#include <OpenGl_Context.hxx>
23#include <OpenGl_Display.hxx>
2166f0fa
SK
24
25#include <Aspect_GraphicDeviceDefinitionError.hxx>
26#include <TCollection_AsciiString.hxx>
b5ac8292 27#include <TCollection_ExtendedString.hxx>
2166f0fa
SK
28
29IMPLEMENT_STANDARD_HANDLE(OpenGl_Window,MMgt_TShared)
30IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Window,MMgt_TShared)
31
4fe56619 32#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
33
2166f0fa
SK
34namespace
35{
36 static const TEL_COLOUR THE_DEFAULT_BG_COLOR = { { 0.F, 0.F, 0.F, 1.F } };
37
58655684 38#if defined(_WIN32)
39
abe46077 40 // WGL_ARB_pixel_format
41#ifndef WGL_NUMBER_PIXEL_FORMATS_ARB
42 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
43 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
44 #define WGL_DRAW_TO_BITMAP_ARB 0x2002
45 #define WGL_ACCELERATION_ARB 0x2003
46 #define WGL_NEED_PALETTE_ARB 0x2004
47 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
48 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
49 #define WGL_SWAP_METHOD_ARB 0x2007
50 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
51 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
52 #define WGL_TRANSPARENT_ARB 0x200A
53 #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
54 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
55 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
56 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
57 #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
58 #define WGL_SHARE_DEPTH_ARB 0x200C
59 #define WGL_SHARE_STENCIL_ARB 0x200D
60 #define WGL_SHARE_ACCUM_ARB 0x200E
61 #define WGL_SUPPORT_GDI_ARB 0x200F
62 #define WGL_SUPPORT_OPENGL_ARB 0x2010
63 #define WGL_DOUBLE_BUFFER_ARB 0x2011
64 #define WGL_STEREO_ARB 0x2012
65 #define WGL_PIXEL_TYPE_ARB 0x2013
66 #define WGL_COLOR_BITS_ARB 0x2014
67 #define WGL_RED_BITS_ARB 0x2015
68 #define WGL_RED_SHIFT_ARB 0x2016
69 #define WGL_GREEN_BITS_ARB 0x2017
70 #define WGL_GREEN_SHIFT_ARB 0x2018
71 #define WGL_BLUE_BITS_ARB 0x2019
72 #define WGL_BLUE_SHIFT_ARB 0x201A
73 #define WGL_ALPHA_BITS_ARB 0x201B
74 #define WGL_ALPHA_SHIFT_ARB 0x201C
75 #define WGL_ACCUM_BITS_ARB 0x201D
76 #define WGL_ACCUM_RED_BITS_ARB 0x201E
77 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
78 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
79 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
80 #define WGL_DEPTH_BITS_ARB 0x2022
81 #define WGL_STENCIL_BITS_ARB 0x2023
82 #define WGL_AUX_BUFFERS_ARB 0x2024
83
84 #define WGL_NO_ACCELERATION_ARB 0x2025
85 #define WGL_GENERIC_ACCELERATION_ARB 0x2026
86 #define WGL_FULL_ACCELERATION_ARB 0x2027
87
88 #define WGL_SWAP_EXCHANGE_ARB 0x2028
89 #define WGL_SWAP_COPY_ARB 0x2029
90 #define WGL_SWAP_UNDEFINED_ARB 0x202A
91
92 #define WGL_TYPE_RGBA_ARB 0x202B
93 #define WGL_TYPE_COLORINDEX_ARB 0x202C
94#endif // WGL_NUMBER_PIXEL_FORMATS_ARB
95
58655684 96 // WGL_ARB_create_context_profile
97#ifndef WGL_CONTEXT_MAJOR_VERSION_ARB
98 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
99 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
100 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
101 #define WGL_CONTEXT_FLAGS_ARB 0x2094
102 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
103
104 // WGL_CONTEXT_FLAGS bits
105 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
106 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
107
108 // WGL_CONTEXT_PROFILE_MASK_ARB bits
109 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
110 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
111#endif // WGL_CONTEXT_MAJOR_VERSION_ARB
112
113 static LRESULT CALLBACK wndProcDummy (HWND theWin, UINT theMsg, WPARAM theParamW, LPARAM theParamL)
114 {
115 return DefWindowProcW (theWin, theMsg, theParamW, theParamL);
116 }
2166f0fa
SK
117#else
118 static Bool WaitForNotify (Display* theDisp, XEvent* theEv, char* theArg)
119 {
120 return (theEv->type == MapNotify) && (theEv->xmap.window == (Window )theArg);
121 }
122#endif
123
5640d653 124}
2166f0fa
SK
125
126// =======================================================================
127// function : OpenGl_Window
128// purpose :
129// =======================================================================
130OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
131 const CALL_DEF_WINDOW& theCWindow,
5e27df78 132 Aspect_RenderingContext theGContext,
58655684 133 const Handle(OpenGl_Caps)& theCaps,
5e27df78 134 const Handle(OpenGl_Context)& theShareCtx)
2166f0fa 135: myDisplay (theDisplay),
58655684 136 myGlContext (new OpenGl_Context (theCaps)),
2166f0fa 137 myOwnGContext (theGContext == 0),
58655684 138#if defined(_WIN32)
2166f0fa
SK
139 mySysPalInUse (FALSE),
140#endif
141 myWidth ((Standard_Integer )theCWindow.dx),
142 myHeight ((Standard_Integer )theCWindow.dy),
143 myBgColor (THE_DEFAULT_BG_COLOR),
144 myDither (theDisplay->Dither()),
145 myBackDither (theDisplay->BackDither())
146{
147 myBgColor.rgb[0] = theCWindow.Background.r;
148 myBgColor.rgb[1] = theCWindow.Background.g;
149 myBgColor.rgb[2] = theCWindow.Background.b;
150
58655684 151#if defined(_WIN32)
5e27df78 152 HWND aWindow = (HWND )theCWindow.XWindow;
153 HDC aWindowDC = GetDC (aWindow);
154 HGLRC aGContext = (HGLRC )theGContext;
155
3d8969b1 156 PIXELFORMATDESCRIPTOR aPixelFrmt;
abe46077 157 memset (&aPixelFrmt, 0, sizeof(aPixelFrmt));
158 aPixelFrmt.nSize = sizeof(PIXELFORMATDESCRIPTOR);
159 aPixelFrmt.nVersion = 1;
160 aPixelFrmt.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
161 aPixelFrmt.iPixelType = PFD_TYPE_RGBA;
162 aPixelFrmt.cColorBits = 24;
163 aPixelFrmt.cDepthBits = 24;
164 aPixelFrmt.cStencilBits = 8;
165 aPixelFrmt.iLayerType = PFD_MAIN_PLANE;
166 if (theCaps->contextStereo)
167 {
168 aPixelFrmt.dwFlags |= PFD_STEREO;
169 }
170
171 int aPixelFrmtId = ChoosePixelFormat (aWindowDC, &aPixelFrmt);
b5ac8292 172
173 // in case of failure try without stereo if any
174 if (aPixelFrmtId == 0 && theCaps->contextStereo)
175 {
176 TCollection_ExtendedString aMsg ("OpenGl_Window::CreateWindow: "
177 "ChoosePixelFormat is unable to find stereo supported pixel format. "
178 "Choosing similar non stereo format.");
179 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
180 GL_DEBUG_TYPE_OTHER_ARB,
181 0, GL_DEBUG_SEVERITY_HIGH_ARB, aMsg);
182
183 aPixelFrmt.dwFlags &= ~PFD_STEREO;
184 aPixelFrmtId = ChoosePixelFormat (aWindowDC, &aPixelFrmt);
185 }
186
3d8969b1 187 if (aPixelFrmtId == 0)
5e27df78 188 {
189 ReleaseDC (aWindow, aWindowDC);
190
191 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: ChoosePixelFormat failed. Error code: ");
192 aMsg += (int )GetLastError();
193 Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
194 return;
195 }
196
abe46077 197 DescribePixelFormat (aWindowDC, aPixelFrmtId, sizeof(aPixelFrmt), &aPixelFrmt);
3d8969b1 198 if (aPixelFrmt.dwFlags & PFD_NEED_PALETTE)
5e27df78 199 {
3d8969b1 200 WINDOW_DATA* aWndData = (WINDOW_DATA* )GetWindowLongPtr (aWindow, GWLP_USERDATA);
5e27df78 201
3d8969b1 202 mySysPalInUse = (aPixelFrmt.dwFlags & PFD_NEED_SYSTEM_PALETTE) ? TRUE : FALSE;
203 InterfaceGraphic_RealizePalette (aWindowDC, aWndData->hPal, FALSE, mySysPalInUse);
5e27df78 204 }
205
206 if (myDither)
3d8969b1 207 {
208 myDither = (aPixelFrmt.cColorBits <= 8);
209 }
5e27df78 210
211 if (myBackDither)
3d8969b1 212 {
213 myBackDither = (aPixelFrmt.cColorBits <= 8);
214 }
5e27df78 215
58655684 216 HGLRC aSlaveCtx = !theShareCtx.IsNull() ? (HGLRC )theShareCtx->myGContext : NULL;
5e27df78 217 if (aGContext == NULL)
218 {
58655684 219 // create temporary context to retrieve advanced context creation procedures
220 HMODULE aModule = GetModuleHandleW(NULL);
221 WNDCLASSW aClass; memset (&aClass, 0, sizeof(aClass));
222 aClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
223 aClass.lpfnWndProc = wndProcDummy;
224 aClass.hInstance = aModule;
225 aClass.lpszClassName = L"OpenGl_WindowTmp";
226 HWND aWinTmp = NULL;
227 HDC aDevCtxTmp = NULL;
228 HGLRC aRendCtxTmp = NULL;
abe46077 229 if ((!theCaps->contextDebug && !theCaps->contextNoAccel)
58655684 230 || RegisterClassW (&aClass) == 0)
231 {
232 aClass.lpszClassName = NULL;
233 }
234 if (aClass.lpszClassName != NULL)
235 {
229c0b6a 236 DWORD anExStyle = WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE;
237 #if (_WIN32_WINNT >= 0x0500)
238 anExStyle |= WS_EX_NOACTIVATE;
239 #endif
240 aWinTmp = CreateWindowExW(anExStyle,
58655684 241 aClass.lpszClassName, L"OpenGl_WindowTmp",
242 WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED,
243 2, 2, 4, 4,
244 NULL, NULL, aModule, NULL);
245 }
246 if (aWinTmp != NULL)
247 {
248 aDevCtxTmp = GetDC (aWinTmp);
249 SetPixelFormat (aDevCtxTmp, aPixelFrmtId, &aPixelFrmt);
250 aRendCtxTmp = wglCreateContext (aDevCtxTmp);
251 }
abe46077 252
253 typedef BOOL (WINAPI *wglChoosePixelFormatARB_t)(HDC theDevCtx,
254 const int* theIntAttribs,
255 const float* theFloatAttribs,
256 unsigned int theMaxFormats,
257 int* theFormatsOut,
258 unsigned int* theNumFormatsOut);
259 typedef HGLRC (WINAPI *wglCreateContextAttribsARB_t)(HDC theDevCtx,
260 HGLRC theShareContext,
261 const int* theAttribs);
262 wglChoosePixelFormatARB_t aChoosePixProc = NULL;
263 wglCreateContextAttribsARB_t aCreateCtxProc = NULL;
58655684 264 if (aRendCtxTmp != NULL)
265 {
266 wglMakeCurrent (aDevCtxTmp, aRendCtxTmp);
267
268 typedef const char* (WINAPI *wglGetExtensionsStringARB_t)(HDC theDeviceContext);
abe46077 269 wglGetExtensionsStringARB_t aGetExtensions = (wglGetExtensionsStringARB_t )wglGetProcAddress ("wglGetExtensionsStringARB");
270 const char* aWglExts = (aGetExtensions != NULL) ? aGetExtensions (wglGetCurrentDC()) : NULL;
271 if (OpenGl_Context::CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
272 {
273 aChoosePixProc = (wglChoosePixelFormatARB_t )wglGetProcAddress ("wglChoosePixelFormatARB");
274 }
275 if (OpenGl_Context::CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
276 {
277 aCreateCtxProc = (wglCreateContextAttribsARB_t )wglGetProcAddress ("wglCreateContextAttribsARB");
278 }
279 }
280
281 // choose extended pixel format
282 if (aChoosePixProc != NULL)
283 {
284 const int aPixAttribs[] =
285 {
286 WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
287 WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
288 WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
289 WGL_STEREO_ARB, theCaps->contextStereo ? GL_TRUE : GL_FALSE,
290 WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
291 //WGL_SAMPLE_BUFFERS_ARB, 1,
292 //WGL_SAMPLES_ARB, 8,
293 WGL_COLOR_BITS_ARB, 24,
294 WGL_DEPTH_BITS_ARB, 24,
295 WGL_STENCIL_BITS_ARB, 8,
296 WGL_ACCELERATION_ARB, theCaps->contextNoAccel ? WGL_NO_ACCELERATION_ARB : WGL_FULL_ACCELERATION_ARB,
297 0, 0,
298 };
299 unsigned int aFrmtsNb = 0;
300 aChoosePixProc (aWindowDC, aPixAttribs, NULL, 1, &aPixelFrmtId, &aFrmtsNb);
301 }
302
303 // setup pixel format - may be set only once per window
304 if (!SetPixelFormat (aWindowDC, aPixelFrmtId, &aPixelFrmt))
305 {
306 ReleaseDC (aWindow, aWindowDC);
307
308 TCollection_AsciiString aMsg("OpenGl_Window::CreateWindow: SetPixelFormat failed. Error code: ");
309 aMsg += (int )GetLastError();
310 Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
311 return;
312 }
313
314 // create GL context with extra options
315 if (aCreateCtxProc != NULL)
316 {
317 // Beware! NVIDIA drivers reject context creation when WGL_CONTEXT_PROFILE_MASK_ARB are specified
318 // but not WGL_CONTEXT_MAJOR_VERSION_ARB/WGL_CONTEXT_MINOR_VERSION_ARB.
319 int aCtxAttribs[] =
320 {
321 //WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
322 //WGL_CONTEXT_MINOR_VERSION_ARB, 2,
323 //WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
324 WGL_CONTEXT_FLAGS_ARB, theCaps->contextDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
325 0, 0
326 };
327
328 aGContext = aCreateCtxProc (aWindowDC, aSlaveCtx, aCtxAttribs);
329 if (aGContext != NULL)
58655684 330 {
abe46077 331 aSlaveCtx = NULL;
58655684 332 }
333 }
334
335 if (aRendCtxTmp != NULL)
336 {
337 wglDeleteContext (aRendCtxTmp);
338 }
339 if (aDevCtxTmp != NULL)
340 {
341 ReleaseDC (aWinTmp, aDevCtxTmp);
342 }
343 if (aWinTmp != NULL)
344 {
345 DestroyWindow (aWinTmp);
346 }
347 if (aClass.lpszClassName != NULL)
348 {
349 UnregisterClassW (aClass.lpszClassName, aModule);
350 }
351
352 if (aGContext == NULL)
353 {
abe46077 354 // create context using obsolete functionality
58655684 355 aGContext = wglCreateContext (aWindowDC);
356 }
5e27df78 357 if (aGContext == NULL)
358 {
359 ReleaseDC (aWindow, aWindowDC);
360
361 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglCreateContext failed. Error code: ");
362 aMsg += (int )GetLastError();
363 Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
364 return;
365 }
366 }
367
368 // all GL context within one OpenGl_GraphicDriver should be shared!
58655684 369 if (aSlaveCtx != NULL && wglShareLists (aSlaveCtx, aGContext) != TRUE)
5e27df78 370 {
371 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglShareLists failed. Error code: ");
372 aMsg += (int )GetLastError();
373 Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
374 return;
375 }
376
377 myGlContext->Init ((Aspect_Handle )aWindow, (Aspect_Handle )aWindowDC, (Aspect_RenderingContext )aGContext);
378#else
2166f0fa 379 WINDOW aParent = (WINDOW )theCWindow.XWindow;
5e27df78 380 WINDOW aWindow = 0;
2166f0fa 381 DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay();
5e27df78 382 GLXContext aGContext = (GLXContext )theGContext;
2166f0fa 383
2166f0fa
SK
384 XWindowAttributes wattr;
385 XGetWindowAttributes (aDisp, aParent, &wattr);
386 const int scr = DefaultScreen (aDisp);
387
388 XVisualInfo* aVis = NULL;
389 {
390 unsigned long aVisInfoMask = VisualIDMask | VisualScreenMask;
391 XVisualInfo aVisInfo;
392 aVisInfo.visualid = wattr.visual->visualid;
393 aVisInfo.screen = scr;
394 int aNbItems;
395 aVis = XGetVisualInfo (aDisp, aVisInfoMask, &aVisInfo, &aNbItems);
396 }
397
2166f0fa
SK
398 if (!myOwnGContext)
399 {
400 if (aVis != NULL)
401 {
402 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: XGetVisualInfo failed.");
403 return;
404 }
405
5e27df78 406 aWindow = aParent;
2166f0fa
SK
407 }
408 else
409 {
cdc56cc8 410 #if defined(__linux) || defined(Linux) || defined(__APPLE__)
2166f0fa
SK
411 if (aVis != NULL)
412 {
413 // check Visual for OpenGl context's parameters compability
b5ac8292 414 int isGl = 0, isDoubleBuffer = 0, isRGBA = 0, isStereo = 0;
415 int aDepthSize = 0, aStencilSize = 0;
2166f0fa
SK
416
417 if (glXGetConfig (aDisp, aVis, GLX_USE_GL, &isGl) != 0)
418 isGl = 0;
419
420 if (glXGetConfig (aDisp, aVis, GLX_RGBA, &isRGBA) != 0)
421 isRGBA = 0;
422
423 if (glXGetConfig (aDisp, aVis, GLX_DOUBLEBUFFER, &isDoubleBuffer) != 0)
424 isDoubleBuffer = 0;
425
b5ac8292 426 if (glXGetConfig (aDisp, aVis, GLX_STEREO, &isStereo) != 0)
427 isStereo = 0;
428
2166f0fa
SK
429 if (glXGetConfig (aDisp, aVis, GLX_DEPTH_SIZE, &aDepthSize) != 0)
430 aDepthSize = 0;
431
3d8969b1 432 if (glXGetConfig (aDisp, aVis, GLX_STENCIL_SIZE, &aStencilSize) != 0)
433 aStencilSize = 0;
434
b5ac8292 435 if (!isGl || !aDepthSize || !isRGBA || !aStencilSize ||
436 (isDoubleBuffer ? 1 : 0) != (myDisplay->DBuffer() ? 1 : 0) ||
437 (isStereo ? 1 : 0) != (theCaps->contextStereo ? 1 : 0))
2166f0fa
SK
438 {
439 XFree (aVis);
440 aVis = NULL;
441 }
442 }
443 #endif
444
445 if (aVis == NULL)
446 {
447 int anIter = 0;
3d8969b1 448 int anAttribs[13];
2166f0fa
SK
449 anAttribs[anIter++] = GLX_RGBA;
450
451 anAttribs[anIter++] = GLX_DEPTH_SIZE;
452 anAttribs[anIter++] = 1;
453
3d8969b1 454 anAttribs[anIter++] = GLX_STENCIL_SIZE;
455 anAttribs[anIter++] = 1;
456
2166f0fa
SK
457 anAttribs[anIter++] = GLX_RED_SIZE;
458 anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1;
459
460 anAttribs[anIter++] = GLX_GREEN_SIZE;
461 anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1;
462
463 anAttribs[anIter++] = GLX_BLUE_SIZE;
464 anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1;
465
466 if (myDisplay->DBuffer())
467 anAttribs[anIter++] = GLX_DOUBLEBUFFER;
468
b5ac8292 469 // warning: this flag may be set to None, so it need to be last in anAttribs
470 Standard_Integer aStereoFlagPos = anIter;
471 if (theCaps->contextStereo)
472 anAttribs[anIter++] = GLX_STEREO;
473
2166f0fa
SK
474 anAttribs[anIter++] = None;
475
476 aVis = glXChooseVisual (aDisp, scr, anAttribs);
b5ac8292 477
478 // in case of failure try without stereo if any
479 if (aVis == NULL && theCaps->contextStereo)
480 {
481 TCollection_ExtendedString aMsg ("OpenGl_Window::CreateWindow: "
482 "glXChooseVisual is unable to find stereo supported pixel format. "
483 "Choosing similar non stereo format.");
484 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
485 GL_DEBUG_TYPE_OTHER_ARB,
486 0, GL_DEBUG_SEVERITY_HIGH_ARB, aMsg);
487
488 anAttribs[aStereoFlagPos] = None;
489 aVis = glXChooseVisual (aDisp, scr, anAttribs);
490 }
491
2166f0fa
SK
492 if (aVis == NULL)
493 {
494 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: glXChooseVisual failed.");
495 return;
496 }
497 }
498
5e27df78 499 if (!theShareCtx.IsNull())
2166f0fa 500 {
5e27df78 501 // ctx est une copie du previous
502 aGContext = glXCreateContext (aDisp, aVis, (GLXContext )theShareCtx->myGContext, GL_TRUE);
2166f0fa
SK
503 }
504 else
505 {
5e27df78 506 aGContext = glXCreateContext (aDisp, aVis, NULL, GL_TRUE);
2166f0fa
SK
507 }
508
5e27df78 509 if (!aGContext)
2166f0fa
SK
510 {
511 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: glXCreateContext failed.");
512 return;
513 }
514
2166f0fa
SK
515 Colormap cmap = XCreateColormap (aDisp, aParent, aVis->visual, AllocNone);
516
517 XColor color;
518 color.red = (unsigned short) (myBgColor.rgb[0] * 0xFFFF);
519 color.green = (unsigned short) (myBgColor.rgb[1] * 0xFFFF);
520 color.blue = (unsigned short) (myBgColor.rgb[2] * 0xFFFF);
521 color.flags = DoRed | DoGreen | DoBlue;
522 XAllocColor (aDisp, cmap, &color);
523
524 XSetWindowAttributes cwa;
525 cwa.colormap = cmap;
526 cwa.event_mask = StructureNotifyMask;
527 cwa.border_pixel = color.pixel;
528 cwa.background_pixel = color.pixel;
529
530 if (aVis->visualid == wattr.visual->visualid)
531 {
5e27df78 532 aWindow = aParent;
2166f0fa
SK
533 }
534 else
535 {
536 unsigned long mask = CWBackPixel | CWColormap | CWBorderPixel | CWEventMask;
5e27df78 537 aWindow = XCreateWindow (aDisp, aParent, 0, 0, myWidth, myHeight, 0/*bw*/, aVis->depth, InputOutput, aVis->visual, mask, &cwa);
2166f0fa
SK
538 }
539
5e27df78 540 XSetWindowBackground (aDisp, aWindow, cwa.background_pixel);
541 XClearWindow (aDisp, aWindow);
2166f0fa 542
5e27df78 543 if (aWindow != aParent)
2166f0fa
SK
544 {
545 XEvent anEvent;
5e27df78 546 XMapWindow (aDisp, aWindow);
547 XIfEvent (aDisp, &anEvent, WaitForNotify, (char* )aWindow);
2166f0fa 548 }
2166f0fa
SK
549 }
550
551 /*
552 * Le BackDitherProp est utilise pour le clear du background
553 * Pour eviter une difference de couleurs avec la couleur choisie
554 * par l'application (XWindow) il faut desactiver le dithering
555 * au dessus de 8 plans.
556 *
557 * Pour le DitherProp:
558 * On cherchera a activer le Dithering que si le Visual a au moins
559 * 8 plans pour le GLX_RED_SIZE. Le test est plus sur car on peut
560 * avoir une profondeur superieure a 12 mais avoir besoin du dithering.
561 * (Carte Impact avec GLX_RED_SIZE a 5 par exemple)
562 */
563
5e27df78 564 int aValue;
565 glXGetConfig (aDisp, aVis, GLX_RED_SIZE, &aValue);
2166f0fa
SK
566
567 if (myDither)
5e27df78 568 myDither = (aValue < 8);
2166f0fa
SK
569
570 if (myBackDither)
571 myBackDither = (aVis->depth <= 8);
572
573 XFree ((char* )aVis);
574
5e27df78 575 myGlContext->Init ((Aspect_Drawable )aWindow, (Aspect_Display )myDisplay->GetDisplay(), (Aspect_RenderingContext )aGContext);
2166f0fa 576#endif
5e27df78 577 myGlContext->Share (theShareCtx);
2166f0fa
SK
578
579 Init();
2166f0fa
SK
580}
581
582// =======================================================================
583// function : ~OpenGl_Window
584// purpose :
585// =======================================================================
586OpenGl_Window::~OpenGl_Window()
587{
fd4a6963 588 if (!myOwnGContext)
589 {
590 myGlContext.Nullify();
591 return;
592 }
593
594 // release "GL" context if it is owned by window
544da5a4 595 // Mesa implementation can fail to destroy GL context if it set for current thread.
596 // It should be safer to unset thread GL context before its destruction.
58655684 597#if defined(_WIN32)
fd4a6963 598 HWND aWindow = (HWND )myGlContext->myWindow;
599 HDC aWindowDC = (HDC )myGlContext->myWindowDC;
600 HGLRC aWindowGContext = (HGLRC )myGlContext->myGContext;
544da5a4 601 HGLRC aThreadGContext = wglGetCurrentContext();
5e27df78 602 myGlContext.Nullify();
2166f0fa 603
544da5a4 604 if (aThreadGContext != NULL)
2166f0fa 605 {
544da5a4 606 if (aThreadGContext == aWindowGContext)
2166f0fa 607 {
fd4a6963 608 wglMakeCurrent (NULL, NULL);
2166f0fa 609 }
fd4a6963 610
611 wglDeleteContext (aWindowGContext);
2166f0fa 612 }
fd4a6963 613 ReleaseDC (aWindow, aWindowDC);
5e27df78 614#else
544da5a4 615 Display* aDisplay = (Display* )myGlContext->myDisplay;
616 GLXContext aWindowGContext = (GLXContext )myGlContext->myGContext;
617 GLXContext aThreadGContext = glXGetCurrentContext();
5e27df78 618 myGlContext.Nullify();
619
fd4a6963 620 if (aDisplay != NULL)
2166f0fa 621 {
544da5a4 622 if (aThreadGContext == aWindowGContext)
623 {
624 glXMakeCurrent (aDisplay, None, NULL);
625 }
626
5e27df78 627 // FSXXX sync necessary if non-direct rendering
628 glXWaitGL();
544da5a4 629 glXDestroyContext (aDisplay, aWindowGContext);
2166f0fa
SK
630 }
631#endif
632}
633
4fe56619 634#endif // !__APPLE__
635
2166f0fa
SK
636// =======================================================================
637// function : Activate
638// purpose :
639// =======================================================================
640Standard_Boolean OpenGl_Window::Activate()
641{
86fa64d9 642 return myGlContext->MakeCurrent();
2166f0fa
SK
643}
644
4fe56619 645#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
646
2166f0fa
SK
647// =======================================================================
648// function : Resize
649// purpose : call_subr_resize
650// =======================================================================
651void OpenGl_Window::Resize (const CALL_DEF_WINDOW& theCWindow)
652{
653 DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay();
654 if (aDisp == NULL)
655 return;
656
657 // If the size is not changed - do nothing
658 if ((myWidth == theCWindow.dx) && (myHeight == theCWindow.dy))
659 return;
660
661 myWidth = (Standard_Integer )theCWindow.dx;
662 myHeight = (Standard_Integer )theCWindow.dy;
663
58655684 664#if !defined(_WIN32)
5e27df78 665 XResizeWindow (aDisp, myGlContext->myWindow, (unsigned int )myWidth, (unsigned int )myHeight);
2166f0fa
SK
666 XSync (aDisp, False);
667#endif
668
669 Init();
670}
671
4fe56619 672#endif // !__APPLE__
673
2166f0fa
SK
674// =======================================================================
675// function : ReadDepths
676// purpose : TelReadDepths
677// =======================================================================
678void OpenGl_Window::ReadDepths (const Standard_Integer theX, const Standard_Integer theY,
679 const Standard_Integer theWidth, const Standard_Integer theHeight,
680 float* theDepths)
681{
682 if (theDepths == NULL || !Activate())
683 return;
684
685 glMatrixMode (GL_PROJECTION);
686 glLoadIdentity();
687 gluOrtho2D (0.0, (GLdouble )myWidth, 0.0, (GLdouble )myHeight);
688 glMatrixMode (GL_MODELVIEW);
689 glLoadIdentity();
690
691 glRasterPos2i (theX, theY);
692 DisableFeatures();
693 glReadPixels (theX, theY, theWidth, theHeight, GL_DEPTH_COMPONENT, GL_FLOAT, theDepths);
694 EnableFeatures();
695}
696
697// =======================================================================
698// function : SetBackgroundColor
699// purpose : call_subr_set_background
700// =======================================================================
701void OpenGl_Window::SetBackgroundColor (const Standard_ShortReal theR,
702 const Standard_ShortReal theG,
703 const Standard_ShortReal theB)
704{
705 myBgColor.rgb[0] = theR;
706 myBgColor.rgb[1] = theG;
707 myBgColor.rgb[2] = theB;
708}
709
4fe56619 710#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
711
2166f0fa
SK
712// =======================================================================
713// function : Init
714// purpose :
715// =======================================================================
716void OpenGl_Window::Init()
717{
718 if (!Activate())
719 return;
720
58655684 721#if defined(_WIN32)
2166f0fa 722 RECT cr;
5e27df78 723 GetClientRect ((HWND )myGlContext->myWindow, &cr);
2166f0fa
SK
724 myWidth = cr.right - cr.left;
725 myHeight = cr.bottom - cr.top;
726#else
727 Window aRootWin;
728 int aDummy;
729 unsigned int aDummyU;
730 unsigned int aNewWidth = 0;
731 unsigned int aNewHeight = 0;
732 DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay();
5e27df78 733 XGetGeometry (aDisp, myGlContext->myWindow, &aRootWin, &aDummy, &aDummy, &aNewWidth, &aNewHeight, &aDummyU, &aDummyU);
2166f0fa
SK
734 myWidth = aNewWidth;
735 myHeight = aNewHeight;
736#endif
737
738 glMatrixMode (GL_MODELVIEW);
739 glViewport (0, 0, myWidth, myHeight);
740
741 glDisable (GL_SCISSOR_TEST);
742 glDrawBuffer (GL_BACK);
743}
744
4fe56619 745#endif // !__APPLE__
746
2166f0fa
SK
747// =======================================================================
748// function : EnablePolygonOffset
749// purpose : call_subr_enable_polygon_offset
750// =======================================================================
751void OpenGl_Window::EnablePolygonOffset() const
752{
753 Standard_ShortReal aFactor, aUnits;
754 myDisplay->PolygonOffset (aFactor, aUnits);
755 glPolygonOffset (aFactor, aUnits);
756 glEnable (GL_POLYGON_OFFSET_FILL);
757}
758
759// =======================================================================
760// function : DisablePolygonOffset
761// purpose : call_subr_disable_polygon_offset
762// =======================================================================
763void OpenGl_Window::DisablePolygonOffset() const
764{
765 glDisable (GL_POLYGON_OFFSET_FILL);
766}
767
768// =======================================================================
769// function : EnableFeatures
770// purpose :
771// =======================================================================
772void OpenGl_Window::EnableFeatures() const
773{
774 /*glPixelTransferi (GL_MAP_COLOR, GL_TRUE);*/
775
776 if (myDither)
777 glEnable (GL_DITHER);
778 else
779 glDisable (GL_DITHER);
780}
781
782// =======================================================================
783// function : DisableFeatures
784// purpose :
785// =======================================================================
786void OpenGl_Window::DisableFeatures() const
787{
788 glDisable (GL_DITHER);
789 glPixelTransferi (GL_MAP_COLOR, GL_FALSE);
790
791 /*
792 * Disable stuff that's likely to slow down glDrawPixels.
793 * (Omit as much of this as possible, when you know in advance
794 * that the OpenGL state will already be set correctly.)
795 */
796 glDisable(GL_ALPHA_TEST);
797 glDisable(GL_BLEND);
798 glDisable(GL_DEPTH_TEST);
799 glDisable(GL_FOG);
800 glDisable(GL_LIGHTING);
801
802 glDisable(GL_LOGIC_OP);
803 glDisable(GL_STENCIL_TEST);
804 glDisable(GL_TEXTURE_1D);
805 glDisable(GL_TEXTURE_2D);
806 glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
807 glPixelTransferi(GL_RED_SCALE, 1);
808 glPixelTransferi(GL_RED_BIAS, 0);
809 glPixelTransferi(GL_GREEN_SCALE, 1);
810 glPixelTransferi(GL_GREEN_BIAS, 0);
811 glPixelTransferi(GL_BLUE_SCALE, 1);
812 glPixelTransferi(GL_BLUE_BIAS, 0);
813 glPixelTransferi(GL_ALPHA_SCALE, 1);
814 glPixelTransferi(GL_ALPHA_BIAS, 0);
815
816 /*
817 * Disable extensions that could slow down glDrawPixels.
818 * (Actually, you should check for the presence of the proper
819 * extension before making these calls. I've omitted that
820 * code for simplicity.)
821 */
822
b5ac8292 823 if ((myGlContext->myGlVerMajor >= 1) && (myGlContext->myGlVerMinor >= 2))
824 {
2166f0fa 825#ifdef GL_EXT_convolution
b5ac8292 826 if (myGlContext->CheckExtension ("GL_CONVOLUTION_1D_EXT"))
827 glDisable(GL_CONVOLUTION_1D_EXT);
828
829 if (myGlContext->CheckExtension ("GL_CONVOLUTION_2D_EXT"))
830 glDisable(GL_CONVOLUTION_2D_EXT);
831
832 if (myGlContext->CheckExtension ("GL_SEPARABLE_2D_EXT"))
833 glDisable(GL_SEPARABLE_2D_EXT);
2166f0fa
SK
834#endif
835
836#ifdef GL_EXT_histogram
b5ac8292 837 if (myGlContext->CheckExtension ("GL_SEPARABLE_2D_EXT"))
838 glDisable(GL_HISTOGRAM_EXT);
839
840 if (myGlContext->CheckExtension ("GL_MINMAX_EXT"))
841 glDisable(GL_MINMAX_EXT);
2166f0fa
SK
842#endif
843
844#ifdef GL_EXT_texture3D
b5ac8292 845 if (myGlContext->CheckExtension ("GL_TEXTURE_3D_EXT"))
846 glDisable(GL_TEXTURE_3D_EXT);
2166f0fa 847#endif
b5ac8292 848 }
2166f0fa
SK
849}
850
851// =======================================================================
852// function : MakeFrontBufCurrent
853// purpose : TelMakeFrontBufCurrent
854// =======================================================================
855void OpenGl_Window::MakeFrontBufCurrent() const
856{
857 glDrawBuffer (GL_FRONT);
858}
859
860// =======================================================================
861// function : MakeBackBufCurrent
862// purpose : TelMakeBackBufCurrent
863// =======================================================================
864void OpenGl_Window::MakeBackBufCurrent() const
865{
866 glDrawBuffer (GL_BACK);
867}
868
5e27df78 869// =======================================================================
870// function : GetGContext
871// purpose :
872// =======================================================================
873GLCONTEXT OpenGl_Window::GetGContext() const
874{
875 return (GLCONTEXT )myGlContext->myGContext;
876}