Commit | Line | Data |
---|---|---|
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 | |
4d476dd2 | 16 | #if defined(_WIN32) |
17 | #include <windows.h> | |
18 | #endif | |
19 | ||
b5ac8292 | 20 | #include <OpenGl_GlCore12.hxx> |
2166f0fa | 21 | |
b9280b8b | 22 | #include <OpenGl_FrameBuffer.hxx> |
25b97fac | 23 | #include <OpenGl_GraphicDriver.hxx> |
c827ea3a | 24 | #include <OpenGl_Window.hxx> |
2166f0fa SK |
25 | |
26 | #include <Aspect_GraphicDeviceDefinitionError.hxx> | |
b9280b8b | 27 | #include <Aspect_Handle.hxx> |
2166f0fa | 28 | #include <TCollection_AsciiString.hxx> |
b5ac8292 | 29 | #include <TCollection_ExtendedString.hxx> |
2166f0fa | 30 | |
2f690078 | 31 | #include <memory> |
32 | ||
f4a7308f | 33 | #include <Standard_WarningDisableFunctionCast.hxx> |
34 | ||
25e59720 | 35 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Window,Standard_Transient) |
92efcf78 | 36 | |
1ce0716b | 37 | #if defined(HAVE_EGL) |
25b97fac | 38 | #include <EGL/egl.h> |
b69e576a | 39 | #elif defined(HAVE_XLIB) |
40 | #include <GL/glx.h> | |
25b97fac | 41 | #endif |
42 | ||
b69e576a | 43 | #if !defined(__APPLE__) || defined(HAVE_XLIB) |
4fe56619 | 44 | |
2166f0fa SK |
45 | namespace |
46 | { | |
2166f0fa | 47 | |
1ce0716b | 48 | #if defined(HAVE_EGL) |
25b97fac | 49 | // |
50 | #elif defined(_WIN32) | |
58655684 | 51 | |
abe46077 | 52 | // WGL_ARB_pixel_format |
53 | #ifndef WGL_NUMBER_PIXEL_FORMATS_ARB | |
54 | #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 | |
55 | #define WGL_DRAW_TO_WINDOW_ARB 0x2001 | |
56 | #define WGL_DRAW_TO_BITMAP_ARB 0x2002 | |
57 | #define WGL_ACCELERATION_ARB 0x2003 | |
58 | #define WGL_NEED_PALETTE_ARB 0x2004 | |
59 | #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 | |
60 | #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 | |
61 | #define WGL_SWAP_METHOD_ARB 0x2007 | |
62 | #define WGL_NUMBER_OVERLAYS_ARB 0x2008 | |
63 | #define WGL_NUMBER_UNDERLAYS_ARB 0x2009 | |
64 | #define WGL_TRANSPARENT_ARB 0x200A | |
65 | #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 | |
66 | #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 | |
67 | #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 | |
68 | #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A | |
69 | #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B | |
70 | #define WGL_SHARE_DEPTH_ARB 0x200C | |
71 | #define WGL_SHARE_STENCIL_ARB 0x200D | |
72 | #define WGL_SHARE_ACCUM_ARB 0x200E | |
73 | #define WGL_SUPPORT_GDI_ARB 0x200F | |
74 | #define WGL_SUPPORT_OPENGL_ARB 0x2010 | |
75 | #define WGL_DOUBLE_BUFFER_ARB 0x2011 | |
76 | #define WGL_STEREO_ARB 0x2012 | |
77 | #define WGL_PIXEL_TYPE_ARB 0x2013 | |
78 | #define WGL_COLOR_BITS_ARB 0x2014 | |
79 | #define WGL_RED_BITS_ARB 0x2015 | |
80 | #define WGL_RED_SHIFT_ARB 0x2016 | |
81 | #define WGL_GREEN_BITS_ARB 0x2017 | |
82 | #define WGL_GREEN_SHIFT_ARB 0x2018 | |
83 | #define WGL_BLUE_BITS_ARB 0x2019 | |
84 | #define WGL_BLUE_SHIFT_ARB 0x201A | |
85 | #define WGL_ALPHA_BITS_ARB 0x201B | |
86 | #define WGL_ALPHA_SHIFT_ARB 0x201C | |
87 | #define WGL_ACCUM_BITS_ARB 0x201D | |
88 | #define WGL_ACCUM_RED_BITS_ARB 0x201E | |
89 | #define WGL_ACCUM_GREEN_BITS_ARB 0x201F | |
90 | #define WGL_ACCUM_BLUE_BITS_ARB 0x2020 | |
91 | #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 | |
92 | #define WGL_DEPTH_BITS_ARB 0x2022 | |
93 | #define WGL_STENCIL_BITS_ARB 0x2023 | |
94 | #define WGL_AUX_BUFFERS_ARB 0x2024 | |
95 | ||
96 | #define WGL_NO_ACCELERATION_ARB 0x2025 | |
97 | #define WGL_GENERIC_ACCELERATION_ARB 0x2026 | |
98 | #define WGL_FULL_ACCELERATION_ARB 0x2027 | |
99 | ||
100 | #define WGL_SWAP_EXCHANGE_ARB 0x2028 | |
101 | #define WGL_SWAP_COPY_ARB 0x2029 | |
102 | #define WGL_SWAP_UNDEFINED_ARB 0x202A | |
103 | ||
104 | #define WGL_TYPE_RGBA_ARB 0x202B | |
105 | #define WGL_TYPE_COLORINDEX_ARB 0x202C | |
106 | #endif // WGL_NUMBER_PIXEL_FORMATS_ARB | |
107 | ||
58655684 | 108 | // WGL_ARB_create_context_profile |
109 | #ifndef WGL_CONTEXT_MAJOR_VERSION_ARB | |
110 | #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 | |
111 | #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 | |
112 | #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 | |
113 | #define WGL_CONTEXT_FLAGS_ARB 0x2094 | |
114 | #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 | |
115 | ||
116 | // WGL_CONTEXT_FLAGS bits | |
117 | #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 | |
118 | #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 | |
119 | ||
120 | // WGL_CONTEXT_PROFILE_MASK_ARB bits | |
121 | #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 | |
122 | #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 | |
123 | #endif // WGL_CONTEXT_MAJOR_VERSION_ARB | |
124 | ||
125 | static LRESULT CALLBACK wndProcDummy (HWND theWin, UINT theMsg, WPARAM theParamW, LPARAM theParamL) | |
126 | { | |
127 | return DefWindowProcW (theWin, theMsg, theParamW, theParamL); | |
128 | } | |
b69e576a | 129 | #elif defined(HAVE_XLIB) |
b6bf4ec1 | 130 | |
131 | // GLX_ARB_create_context | |
132 | #ifndef GLX_CONTEXT_MAJOR_VERSION_ARB | |
133 | #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 | |
134 | #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 | |
135 | #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 | |
136 | #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 | |
137 | #define GLX_CONTEXT_FLAGS_ARB 0x2094 | |
138 | ||
139 | // GLX_ARB_create_context_profile | |
140 | #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 | |
141 | #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 | |
142 | #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 | |
143 | #endif | |
144 | ||
145 | //! Dummy XError handler which just skips errors | |
146 | static int xErrorDummyHandler (Display* /*theDisplay*/, | |
147 | XErrorEvent* /*theErrorEvent*/) | |
148 | { | |
149 | return 0; | |
150 | } | |
151 | ||
152 | //! Auxiliary method to format list. | |
153 | static void addMsgToList (TCollection_ExtendedString& theList, | |
154 | const TCollection_ExtendedString& theMsg) | |
2166f0fa | 155 | { |
b6bf4ec1 | 156 | if (!theList.IsEmpty()) |
157 | { | |
158 | theList += ", "; | |
159 | } | |
160 | theList += theMsg; | |
2166f0fa SK |
161 | } |
162 | #endif | |
163 | ||
5640d653 | 164 | } |
2166f0fa SK |
165 | |
166 | // ======================================================================= | |
167 | // function : OpenGl_Window | |
168 | // purpose : | |
169 | // ======================================================================= | |
879768fb | 170 | OpenGl_Window::OpenGl_Window() |
171 | : myOwnGContext (false), | |
172 | mySwapInterval (0) | |
2166f0fa | 173 | { |
879768fb | 174 | // |
175 | } | |
176 | ||
177 | // ======================================================================= | |
178 | // function : Init | |
179 | // purpose : | |
180 | // ======================================================================= | |
181 | void OpenGl_Window::Init (const Handle(OpenGl_GraphicDriver)& theDriver, | |
182 | const Handle(Aspect_Window)& thePlatformWindow, | |
183 | const Handle(Aspect_Window)& theSizeWindow, | |
184 | Aspect_RenderingContext theGContext, | |
185 | const Handle(OpenGl_Caps)& theCaps, | |
186 | const Handle(OpenGl_Context)& theShareCtx) | |
187 | { | |
188 | myGlContext = new OpenGl_Context (theCaps); | |
189 | myOwnGContext = (theGContext == 0); | |
190 | myPlatformWindow = thePlatformWindow; | |
191 | mySizeWindow = theSizeWindow; | |
192 | mySwapInterval = theCaps->swapInterval; | |
193 | ||
194 | mySizeWindow->Size (mySize.x(), mySize.y()); | |
2166f0fa | 195 | |
4e1523ef | 196 | Standard_Boolean isCoreProfile = Standard_False; |
197 | ||
1ce0716b | 198 | #if defined(HAVE_EGL) |
25b97fac | 199 | EGLDisplay anEglDisplay = (EGLDisplay )theDriver->getRawGlDisplay(); |
200 | EGLContext anEglContext = (EGLContext )theDriver->getRawGlContext(); | |
201 | EGLConfig anEglConfig = (EGLConfig )theDriver->getRawGlConfig(); | |
202 | if (anEglDisplay == EGL_NO_DISPLAY | |
203 | || anEglContext == EGL_NO_CONTEXT | |
39235bed | 204 | || (anEglConfig == NULL |
205 | && (EGLContext )theGContext == EGL_NO_CONTEXT)) | |
25b97fac | 206 | { |
9775fa61 | 207 | throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL does not provide compatible configurations!"); |
25b97fac | 208 | } |
209 | ||
210 | EGLSurface anEglSurf = EGL_NO_SURFACE; | |
39235bed | 211 | if ((EGLContext )theGContext == EGL_NO_CONTEXT) |
25b97fac | 212 | { |
ba00aab7 | 213 | // EGL_KHR_gl_colorspace extension specifies if OpenGL should write into window buffer as into sRGB or RGB framebuffer |
214 | //const int aSurfAttribs[] = | |
215 | //{ | |
216 | // EGL_GL_COLORSPACE_KHR, !theCaps->sRGBDisable ? EGL_GL_COLORSPACE_SRGB_KHR : EGL_GL_COLORSPACE_LINEAR_KHR, | |
217 | // EGL_NONE, | |
218 | //}; | |
219 | ||
25b97fac | 220 | // create new surface |
c357e426 | 221 | anEglSurf = eglCreateWindowSurface (anEglDisplay, |
222 | anEglConfig, | |
223 | (EGLNativeWindowType )myPlatformWindow->NativeHandle(), | |
224 | NULL); | |
b69e576a | 225 | if (anEglSurf == EGL_NO_SURFACE |
226 | && myPlatformWindow->NativeHandle() != 0) | |
25b97fac | 227 | { |
9775fa61 | 228 | throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to create surface for window!"); |
b69e576a | 229 | } |
230 | else if (anEglSurf == EGL_NO_SURFACE) | |
231 | { | |
232 | // window-less EGL context (off-screen) | |
233 | //throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to retrieve current surface!"); | |
234 | if (anEglConfig != NULL) | |
235 | { | |
236 | #if !defined(__EMSCRIPTEN__) // eglCreatePbufferSurface() is not implemented by Emscripten EGL | |
237 | const int aSurfAttribs[] = | |
238 | { | |
879768fb | 239 | EGL_WIDTH, mySize.x(), |
240 | EGL_HEIGHT, mySize.y(), | |
b69e576a | 241 | // EGL_KHR_gl_colorspace extension specifies if OpenGL should write into window buffer as into sRGB or RGB framebuffer |
242 | //EGL_GL_COLORSPACE_KHR, !theCaps->sRGBDisable ? EGL_GL_COLORSPACE_SRGB_KHR : EGL_GL_COLORSPACE_LINEAR_KHR, | |
243 | EGL_NONE | |
244 | }; | |
245 | anEglSurf = eglCreatePbufferSurface (anEglDisplay, anEglConfig, aSurfAttribs); | |
246 | if (anEglSurf == EGL_NO_SURFACE) | |
247 | { | |
248 | throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to create off-screen surface!"); | |
249 | } | |
250 | #endif | |
251 | } | |
252 | myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW, | |
253 | "OpenGl_Window::CreateWindow: WARNING, a Window is created without a EGL Surface!"); | |
25b97fac | 254 | } |
255 | } | |
256 | else if (theGContext != anEglContext) | |
257 | { | |
9775fa61 | 258 | throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is used in unsupported combination!"); |
25b97fac | 259 | } |
260 | else | |
261 | { | |
262 | anEglSurf = eglGetCurrentSurface(EGL_DRAW); | |
263 | if (anEglSurf == EGL_NO_SURFACE) | |
264 | { | |
39235bed | 265 | // window-less EGL context (off-screen) |
266 | //throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to retrieve current surface!"); | |
267 | if (anEglConfig != NULL) | |
268 | { | |
565baee6 | 269 | #if !defined(__EMSCRIPTEN__) // eglCreatePbufferSurface() is not implemented by Emscripten EGL |
39235bed | 270 | const int aSurfAttribs[] = |
271 | { | |
879768fb | 272 | EGL_WIDTH, mySize.x(), |
273 | EGL_HEIGHT, mySize.y(), | |
ba00aab7 | 274 | // EGL_KHR_gl_colorspace extension specifies if OpenGL should write into window buffer as into sRGB or RGB framebuffer |
275 | //EGL_GL_COLORSPACE_KHR, !theCaps->sRGBDisable ? EGL_GL_COLORSPACE_SRGB_KHR : EGL_GL_COLORSPACE_LINEAR_KHR, | |
39235bed | 276 | EGL_NONE |
277 | }; | |
278 | anEglSurf = eglCreatePbufferSurface (anEglDisplay, anEglConfig, aSurfAttribs); | |
279 | if (anEglSurf == EGL_NO_SURFACE) | |
280 | { | |
281 | throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to create off-screen surface!"); | |
282 | } | |
565baee6 | 283 | #endif |
39235bed | 284 | } |
285 | myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW, | |
286 | "OpenGl_Window::CreateWindow: WARNING, a Window is created without a EGL Surface!"); | |
25b97fac | 287 | } |
288 | } | |
289 | ||
4e1523ef | 290 | myGlContext->Init ((Aspect_Drawable )anEglSurf, (Aspect_Display )anEglDisplay, (Aspect_RenderingContext )anEglContext, isCoreProfile); |
25b97fac | 291 | #elif defined(_WIN32) |
292 | (void )theDriver; | |
c357e426 | 293 | HWND aWindow = (HWND )myPlatformWindow->NativeHandle(); |
5e27df78 | 294 | HDC aWindowDC = GetDC (aWindow); |
295 | HGLRC aGContext = (HGLRC )theGContext; | |
296 | ||
3d8969b1 | 297 | PIXELFORMATDESCRIPTOR aPixelFrmt; |
abe46077 | 298 | memset (&aPixelFrmt, 0, sizeof(aPixelFrmt)); |
299 | aPixelFrmt.nSize = sizeof(PIXELFORMATDESCRIPTOR); | |
300 | aPixelFrmt.nVersion = 1; | |
301 | aPixelFrmt.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; | |
302 | aPixelFrmt.iPixelType = PFD_TYPE_RGBA; | |
303 | aPixelFrmt.cColorBits = 24; | |
304 | aPixelFrmt.cDepthBits = 24; | |
305 | aPixelFrmt.cStencilBits = 8; | |
306 | aPixelFrmt.iLayerType = PFD_MAIN_PLANE; | |
307 | if (theCaps->contextStereo) | |
308 | { | |
309 | aPixelFrmt.dwFlags |= PFD_STEREO; | |
310 | } | |
311 | ||
312 | int aPixelFrmtId = ChoosePixelFormat (aWindowDC, &aPixelFrmt); | |
b5ac8292 | 313 | |
314 | // in case of failure try without stereo if any | |
4e1523ef | 315 | const Standard_Boolean hasStereo = aPixelFrmtId != 0 && theCaps->contextStereo; |
b5ac8292 | 316 | if (aPixelFrmtId == 0 && theCaps->contextStereo) |
317 | { | |
318 | TCollection_ExtendedString aMsg ("OpenGl_Window::CreateWindow: " | |
319 | "ChoosePixelFormat is unable to find stereo supported pixel format. " | |
320 | "Choosing similar non stereo format."); | |
3b523c4c | 321 | myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, |
322 | GL_DEBUG_TYPE_OTHER, | |
323 | 0, GL_DEBUG_SEVERITY_HIGH, aMsg); | |
b5ac8292 | 324 | |
325 | aPixelFrmt.dwFlags &= ~PFD_STEREO; | |
326 | aPixelFrmtId = ChoosePixelFormat (aWindowDC, &aPixelFrmt); | |
327 | } | |
328 | ||
3d8969b1 | 329 | if (aPixelFrmtId == 0) |
5e27df78 | 330 | { |
331 | ReleaseDC (aWindow, aWindowDC); | |
332 | ||
333 | TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: ChoosePixelFormat failed. Error code: "); | |
334 | aMsg += (int )GetLastError(); | |
9775fa61 | 335 | throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString()); |
5e27df78 | 336 | } |
337 | ||
abe46077 | 338 | DescribePixelFormat (aWindowDC, aPixelFrmtId, sizeof(aPixelFrmt), &aPixelFrmt); |
5e27df78 | 339 | |
58655684 | 340 | HGLRC aSlaveCtx = !theShareCtx.IsNull() ? (HGLRC )theShareCtx->myGContext : NULL; |
5e27df78 | 341 | if (aGContext == NULL) |
342 | { | |
58655684 | 343 | // create temporary context to retrieve advanced context creation procedures |
344 | HMODULE aModule = GetModuleHandleW(NULL); | |
345 | WNDCLASSW aClass; memset (&aClass, 0, sizeof(aClass)); | |
346 | aClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; | |
347 | aClass.lpfnWndProc = wndProcDummy; | |
348 | aClass.hInstance = aModule; | |
349 | aClass.lpszClassName = L"OpenGl_WindowTmp"; | |
350 | HWND aWinTmp = NULL; | |
351 | HDC aDevCtxTmp = NULL; | |
352 | HGLRC aRendCtxTmp = NULL; | |
ddb9ed48 | 353 | if ((!theCaps->contextDebug && !theCaps->contextNoAccel && theCaps->contextCompatible && !theCaps->buffersDeepColor) |
58655684 | 354 | || RegisterClassW (&aClass) == 0) |
355 | { | |
356 | aClass.lpszClassName = NULL; | |
357 | } | |
358 | if (aClass.lpszClassName != NULL) | |
359 | { | |
229c0b6a | 360 | DWORD anExStyle = WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE; |
361 | #if (_WIN32_WINNT >= 0x0500) | |
362 | anExStyle |= WS_EX_NOACTIVATE; | |
363 | #endif | |
364 | aWinTmp = CreateWindowExW(anExStyle, | |
58655684 | 365 | aClass.lpszClassName, L"OpenGl_WindowTmp", |
366 | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED, | |
367 | 2, 2, 4, 4, | |
368 | NULL, NULL, aModule, NULL); | |
369 | } | |
370 | if (aWinTmp != NULL) | |
371 | { | |
372 | aDevCtxTmp = GetDC (aWinTmp); | |
373 | SetPixelFormat (aDevCtxTmp, aPixelFrmtId, &aPixelFrmt); | |
374 | aRendCtxTmp = wglCreateContext (aDevCtxTmp); | |
375 | } | |
abe46077 | 376 | |
377 | typedef BOOL (WINAPI *wglChoosePixelFormatARB_t)(HDC theDevCtx, | |
378 | const int* theIntAttribs, | |
379 | const float* theFloatAttribs, | |
380 | unsigned int theMaxFormats, | |
381 | int* theFormatsOut, | |
382 | unsigned int* theNumFormatsOut); | |
383 | typedef HGLRC (WINAPI *wglCreateContextAttribsARB_t)(HDC theDevCtx, | |
384 | HGLRC theShareContext, | |
385 | const int* theAttribs); | |
386 | wglChoosePixelFormatARB_t aChoosePixProc = NULL; | |
387 | wglCreateContextAttribsARB_t aCreateCtxProc = NULL; | |
58655684 | 388 | if (aRendCtxTmp != NULL) |
389 | { | |
390 | wglMakeCurrent (aDevCtxTmp, aRendCtxTmp); | |
391 | ||
392 | typedef const char* (WINAPI *wglGetExtensionsStringARB_t)(HDC theDeviceContext); | |
abe46077 | 393 | wglGetExtensionsStringARB_t aGetExtensions = (wglGetExtensionsStringARB_t )wglGetProcAddress ("wglGetExtensionsStringARB"); |
394 | const char* aWglExts = (aGetExtensions != NULL) ? aGetExtensions (wglGetCurrentDC()) : NULL; | |
395 | if (OpenGl_Context::CheckExtension (aWglExts, "WGL_ARB_pixel_format")) | |
396 | { | |
397 | aChoosePixProc = (wglChoosePixelFormatARB_t )wglGetProcAddress ("wglChoosePixelFormatARB"); | |
398 | } | |
399 | if (OpenGl_Context::CheckExtension (aWglExts, "WGL_ARB_create_context_profile")) | |
400 | { | |
401 | aCreateCtxProc = (wglCreateContextAttribsARB_t )wglGetProcAddress ("wglCreateContextAttribsARB"); | |
402 | } | |
403 | } | |
404 | ||
405 | // choose extended pixel format | |
406 | if (aChoosePixProc != NULL) | |
407 | { | |
408 | const int aPixAttribs[] = | |
409 | { | |
410 | WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, | |
411 | WGL_SUPPORT_OPENGL_ARB, GL_TRUE, | |
412 | WGL_DOUBLE_BUFFER_ARB, GL_TRUE, | |
4e1523ef | 413 | WGL_STEREO_ARB, hasStereo ? GL_TRUE : GL_FALSE, |
abe46077 | 414 | WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, |
415 | //WGL_SAMPLE_BUFFERS_ARB, 1, | |
416 | //WGL_SAMPLES_ARB, 8, | |
ddb9ed48 | 417 | //WGL_COLOR_BITS_ARB, 24, |
418 | WGL_RED_BITS_ARB, theCaps->buffersDeepColor ? 10 : 8, | |
419 | WGL_GREEN_BITS_ARB, theCaps->buffersDeepColor ? 10 : 8, | |
420 | WGL_BLUE_BITS_ARB, theCaps->buffersDeepColor ? 10 : 8, | |
421 | WGL_ALPHA_BITS_ARB, theCaps->buffersDeepColor ? 2 : 8, | |
abe46077 | 422 | WGL_DEPTH_BITS_ARB, 24, |
423 | WGL_STENCIL_BITS_ARB, 8, | |
ba00aab7 | 424 | // WGL_EXT_colorspace extension specifies if OpenGL should write into window buffer as into sRGB or RGB framebuffer |
425 | //WGL_COLORSPACE_EXT, !theCaps->sRGBDisable ? WGL_COLORSPACE_SRGB_EXT : WGL_COLORSPACE_LINEAR_EXT, | |
426 | // requires WGL_ARB_framebuffer_sRGB or WGL_EXT_framebuffer_sRGB extensions | |
427 | //WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, !theCaps->sRGBDisable ? GL_TRUE : GL_FALSE, | |
abe46077 | 428 | WGL_ACCELERATION_ARB, theCaps->contextNoAccel ? WGL_NO_ACCELERATION_ARB : WGL_FULL_ACCELERATION_ARB, |
429 | 0, 0, | |
430 | }; | |
431 | unsigned int aFrmtsNb = 0; | |
ddb9ed48 | 432 | if (!aChoosePixProc (aWindowDC, aPixAttribs, NULL, 1, &aPixelFrmtId, &aFrmtsNb) |
433 | && theCaps->buffersDeepColor) | |
434 | { | |
435 | /// TODO | |
436 | Message::SendFail() << "Error: unable to find RGB10_A2 window buffer format!"; | |
437 | } | |
abe46077 | 438 | } |
439 | ||
440 | // setup pixel format - may be set only once per window | |
441 | if (!SetPixelFormat (aWindowDC, aPixelFrmtId, &aPixelFrmt)) | |
442 | { | |
443 | ReleaseDC (aWindow, aWindowDC); | |
444 | ||
445 | TCollection_AsciiString aMsg("OpenGl_Window::CreateWindow: SetPixelFormat failed. Error code: "); | |
446 | aMsg += (int )GetLastError(); | |
9775fa61 | 447 | throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString()); |
abe46077 | 448 | } |
449 | ||
450 | // create GL context with extra options | |
451 | if (aCreateCtxProc != NULL) | |
452 | { | |
4e1523ef | 453 | if (!theCaps->contextCompatible) |
abe46077 | 454 | { |
4e1523ef | 455 | int aCoreCtxAttribs[] = |
456 | { | |
457 | WGL_CONTEXT_MAJOR_VERSION_ARB, 3, | |
458 | WGL_CONTEXT_MINOR_VERSION_ARB, 2, | |
459 | WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, | |
460 | WGL_CONTEXT_FLAGS_ARB, theCaps->contextDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, | |
461 | 0, 0 | |
462 | }; | |
463 | ||
464 | // Try to create the core profile of highest OpenGL version supported by OCCT | |
465 | // (this will be done automatically by some drivers when requesting 3.2, | |
466 | // but some will not (e.g. AMD Catalyst) since WGL_ARB_create_context_profile specification allows both implementations). | |
72ed0644 | 467 | for (int aLowVer4 = 6; aLowVer4 >= 0 && aGContext == NULL; --aLowVer4) |
4e1523ef | 468 | { |
469 | aCoreCtxAttribs[1] = 4; | |
470 | aCoreCtxAttribs[3] = aLowVer4; | |
471 | aGContext = aCreateCtxProc (aWindowDC, aSlaveCtx, aCoreCtxAttribs); | |
472 | } | |
473 | for (int aLowVer3 = 3; aLowVer3 >= 2 && aGContext == NULL; --aLowVer3) | |
474 | { | |
475 | aCoreCtxAttribs[1] = 3; | |
476 | aCoreCtxAttribs[3] = aLowVer3; | |
477 | aGContext = aCreateCtxProc (aWindowDC, aSlaveCtx, aCoreCtxAttribs); | |
478 | } | |
479 | isCoreProfile = aGContext != NULL; | |
480 | } | |
481 | ||
482 | if (aGContext == NULL) | |
483 | { | |
484 | int aCtxAttribs[] = | |
485 | { | |
486 | // Beware! NVIDIA drivers reject context creation when WGL_CONTEXT_PROFILE_MASK_ARB are specified | |
487 | // but not WGL_CONTEXT_MAJOR_VERSION_ARB/WGL_CONTEXT_MINOR_VERSION_ARB. | |
488 | //WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, | |
489 | WGL_CONTEXT_FLAGS_ARB, theCaps->contextDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, | |
490 | 0, 0 | |
491 | }; | |
492 | isCoreProfile = Standard_False; | |
493 | aGContext = aCreateCtxProc (aWindowDC, aSlaveCtx, aCtxAttribs); | |
494 | ||
495 | if (aGContext != NULL | |
496 | && !theCaps->contextCompatible) | |
497 | { | |
498 | TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: core profile creation failed."); | |
3b523c4c | 499 | myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW, aMsg); |
4e1523ef | 500 | } |
501 | } | |
abe46077 | 502 | |
abe46077 | 503 | if (aGContext != NULL) |
58655684 | 504 | { |
abe46077 | 505 | aSlaveCtx = NULL; |
58655684 | 506 | } |
507 | } | |
508 | ||
509 | if (aRendCtxTmp != NULL) | |
510 | { | |
511 | wglDeleteContext (aRendCtxTmp); | |
512 | } | |
513 | if (aDevCtxTmp != NULL) | |
514 | { | |
515 | ReleaseDC (aWinTmp, aDevCtxTmp); | |
516 | } | |
517 | if (aWinTmp != NULL) | |
518 | { | |
519 | DestroyWindow (aWinTmp); | |
520 | } | |
521 | if (aClass.lpszClassName != NULL) | |
522 | { | |
523 | UnregisterClassW (aClass.lpszClassName, aModule); | |
524 | } | |
525 | ||
526 | if (aGContext == NULL) | |
527 | { | |
abe46077 | 528 | // create context using obsolete functionality |
58655684 | 529 | aGContext = wglCreateContext (aWindowDC); |
530 | } | |
5e27df78 | 531 | if (aGContext == NULL) |
532 | { | |
533 | ReleaseDC (aWindow, aWindowDC); | |
534 | ||
535 | TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglCreateContext failed. Error code: "); | |
536 | aMsg += (int )GetLastError(); | |
9775fa61 | 537 | throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString()); |
5e27df78 | 538 | } |
539 | } | |
540 | ||
541 | // all GL context within one OpenGl_GraphicDriver should be shared! | |
58655684 | 542 | if (aSlaveCtx != NULL && wglShareLists (aSlaveCtx, aGContext) != TRUE) |
5e27df78 | 543 | { |
544 | TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglShareLists failed. Error code: "); | |
545 | aMsg += (int )GetLastError(); | |
9775fa61 | 546 | throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString()); |
5e27df78 | 547 | } |
548 | ||
4e1523ef | 549 | myGlContext->Init ((Aspect_Handle )aWindow, (Aspect_Handle )aWindowDC, (Aspect_RenderingContext )aGContext, isCoreProfile); |
b69e576a | 550 | #elif defined(HAVE_XLIB) |
b6bf4ec1 | 551 | Window aWindow = (Window )myPlatformWindow->NativeHandle(); |
b69e576a | 552 | Display* aDisp = (Display* )theDriver->GetDisplayConnection()->GetDisplayAspect(); |
5e27df78 | 553 | GLXContext aGContext = (GLXContext )theGContext; |
b6bf4ec1 | 554 | GLXContext aSlaveCtx = !theShareCtx.IsNull() ? (GLXContext )theShareCtx->myGContext : NULL; |
555 | ||
556 | XWindowAttributes aWinAttribs; | |
557 | XGetWindowAttributes (aDisp, aWindow, &aWinAttribs); | |
558 | XVisualInfo aVisInfo; | |
559 | aVisInfo.visualid = aWinAttribs.visual->visualid; | |
560 | aVisInfo.screen = DefaultScreen (aDisp); | |
561 | int aNbItems; | |
2f690078 | 562 | std::unique_ptr<XVisualInfo, int(*)(void*)> aVis (XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfo, &aNbItems), &XFree); |
b6bf4ec1 | 563 | int isGl = 0; |
2f690078 | 564 | if (aVis.get() == NULL) |
2166f0fa | 565 | { |
9775fa61 | 566 | throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window::CreateWindow: XGetVisualInfo is unable to choose needed configuration in existing OpenGL context. "); |
2166f0fa | 567 | } |
2f690078 | 568 | else if (glXGetConfig (aDisp, aVis.get(), GLX_USE_GL, &isGl) != 0 || !isGl) |
2166f0fa | 569 | { |
9775fa61 | 570 | throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window::CreateWindow: window Visual does not support GL rendering!"); |
b6bf4ec1 | 571 | } |
3d8969b1 | 572 | |
b6bf4ec1 | 573 | // create new context |
574 | GLXFBConfig anFBConfig = myPlatformWindow->NativeFBConfig(); | |
575 | const char* aGlxExts = glXQueryExtensionsString (aDisp, aVisInfo.screen); | |
576 | if (myOwnGContext | |
577 | && anFBConfig != NULL | |
578 | && OpenGl_Context::CheckExtension (aGlxExts, "GLX_ARB_create_context_profile")) | |
579 | { | |
580 | // Replace default XError handler to ignore errors. | |
581 | // Warning - this is global for all threads! | |
582 | typedef int (*xerrorhandler_t)(Display* , XErrorEvent* ); | |
583 | xerrorhandler_t anOldHandler = XSetErrorHandler(xErrorDummyHandler); | |
584 | ||
585 | typedef GLXContext (*glXCreateContextAttribsARB_t)(Display* dpy, GLXFBConfig config, | |
586 | GLXContext share_context, Bool direct, | |
587 | const int* attrib_list); | |
588 | glXCreateContextAttribsARB_t aCreateCtxProc = (glXCreateContextAttribsARB_t )glXGetProcAddress((const GLubyte* )"glXCreateContextAttribsARB"); | |
589 | if (!theCaps->contextCompatible) | |
95db72f1 | 590 | { |
b6bf4ec1 | 591 | int aCoreCtxAttribs[] = |
95db72f1 | 592 | { |
b6bf4ec1 | 593 | GLX_CONTEXT_MAJOR_VERSION_ARB, 3, |
594 | GLX_CONTEXT_MINOR_VERSION_ARB, 2, | |
595 | GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, | |
596 | GLX_CONTEXT_FLAGS_ARB, theCaps->contextDebug ? GLX_CONTEXT_DEBUG_BIT_ARB : 0, | |
597 | 0, 0 | |
598 | }; | |
599 | ||
600 | // try to create the core profile of highest OpenGL version supported by OCCT | |
72ed0644 | 601 | for (int aLowVer4 = 6; aLowVer4 >= 0 && aGContext == NULL; --aLowVer4) |
2166f0fa | 602 | { |
b6bf4ec1 | 603 | aCoreCtxAttribs[1] = 4; |
604 | aCoreCtxAttribs[3] = aLowVer4; | |
605 | aGContext = aCreateCtxProc (aDisp, anFBConfig, aSlaveCtx, True, aCoreCtxAttribs); | |
2166f0fa | 606 | } |
b6bf4ec1 | 607 | for (int aLowVer3 = 3; aLowVer3 >= 2 && aGContext == NULL; --aLowVer3) |
95db72f1 | 608 | { |
b6bf4ec1 | 609 | aCoreCtxAttribs[1] = 3; |
610 | aCoreCtxAttribs[3] = aLowVer3; | |
611 | aGContext = aCreateCtxProc (aDisp, anFBConfig, aSlaveCtx, True, aCoreCtxAttribs); | |
95db72f1 | 612 | } |
b6bf4ec1 | 613 | isCoreProfile = aGContext != NULL; |
2166f0fa | 614 | } |
2166f0fa | 615 | |
b6bf4ec1 | 616 | if (aGContext == NULL) |
2166f0fa | 617 | { |
b6bf4ec1 | 618 | int aCtxAttribs[] = |
b5ac8292 | 619 | { |
b6bf4ec1 | 620 | GLX_CONTEXT_FLAGS_ARB, theCaps->contextDebug ? GLX_CONTEXT_DEBUG_BIT_ARB : 0, |
621 | 0, 0 | |
622 | }; | |
623 | isCoreProfile = Standard_False; | |
624 | aGContext = aCreateCtxProc (aDisp, anFBConfig, aSlaveCtx, True, aCtxAttribs); | |
b5ac8292 | 625 | |
b6bf4ec1 | 626 | if (aGContext != NULL |
627 | && !theCaps->contextCompatible) | |
95db72f1 | 628 | { |
b6bf4ec1 | 629 | TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: core profile creation failed."); |
3b523c4c | 630 | myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW, aMsg); |
95db72f1 | 631 | } |
2166f0fa | 632 | } |
b6bf4ec1 | 633 | XSetErrorHandler(anOldHandler); |
634 | } | |
2166f0fa | 635 | |
b6bf4ec1 | 636 | if (myOwnGContext |
637 | && aGContext == NULL) | |
638 | { | |
2f690078 | 639 | aGContext = glXCreateContext (aDisp, aVis.get(), aSlaveCtx, GL_TRUE); |
b6bf4ec1 | 640 | if (aGContext == NULL) |
2166f0fa | 641 | { |
9775fa61 | 642 | throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window::CreateWindow: glXCreateContext failed."); |
2166f0fa | 643 | } |
b6bf4ec1 | 644 | } |
2166f0fa | 645 | |
b6bf4ec1 | 646 | // check Visual for OpenGl context's parameters compatibility |
647 | TCollection_ExtendedString aList; | |
648 | int isDoubleBuffer = 0, isRGBA = 0, isStereo = 0; | |
649 | int aDepthSize = 0, aStencilSize = 0; | |
2f690078 | 650 | glXGetConfig (aDisp, aVis.get(), GLX_RGBA, &isRGBA); |
651 | glXGetConfig (aDisp, aVis.get(), GLX_DOUBLEBUFFER, &isDoubleBuffer); | |
652 | glXGetConfig (aDisp, aVis.get(), GLX_STEREO, &isStereo); | |
653 | glXGetConfig (aDisp, aVis.get(), GLX_DEPTH_SIZE, &aDepthSize); | |
654 | glXGetConfig (aDisp, aVis.get(), GLX_STENCIL_SIZE, &aStencilSize); | |
b6bf4ec1 | 655 | if (aDepthSize < 1) addMsgToList (aList, "no depth buffer"); |
656 | if (aStencilSize < 1) addMsgToList (aList, "no stencil buffer"); | |
657 | if (isRGBA == 0) addMsgToList (aList, "no RGBA color buffer"); | |
658 | if (isDoubleBuffer == 0) addMsgToList (aList, "no Double Buffer"); | |
659 | if (theCaps->contextStereo && isStereo == 0) | |
660 | { | |
661 | addMsgToList (aList, "no Quad Buffer"); | |
662 | } | |
663 | else if (!theCaps->contextStereo && isStereo == 1) | |
664 | { | |
665 | addMsgToList (aList, "extra Quad Buffer"); | |
666 | } | |
667 | if (!aList.IsEmpty()) | |
668 | { | |
669 | TCollection_ExtendedString aMsg = TCollection_ExtendedString ("OpenGl_Window::CreateWindow: window Visual is incomplete: ") + aList; | |
3b523c4c | 670 | myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, |
671 | GL_DEBUG_TYPE_OTHER, | |
672 | 0, GL_DEBUG_SEVERITY_MEDIUM, aMsg); | |
2166f0fa SK |
673 | } |
674 | ||
4e1523ef | 675 | myGlContext->Init ((Aspect_Drawable )aWindow, (Aspect_Display )aDisp, (Aspect_RenderingContext )aGContext, isCoreProfile); |
b69e576a | 676 | #else |
677 | // not implemented | |
678 | (void )isCoreProfile; | |
2166f0fa | 679 | #endif |
5e27df78 | 680 | myGlContext->Share (theShareCtx); |
f978241f | 681 | myGlContext->SetSwapInterval (mySwapInterval); |
879768fb | 682 | init(); |
2166f0fa SK |
683 | } |
684 | ||
685 | // ======================================================================= | |
686 | // function : ~OpenGl_Window | |
687 | // purpose : | |
688 | // ======================================================================= | |
689 | OpenGl_Window::~OpenGl_Window() | |
690 | { | |
25b97fac | 691 | if (!myOwnGContext |
692 | || myGlContext.IsNull()) | |
fd4a6963 | 693 | { |
694 | myGlContext.Nullify(); | |
695 | return; | |
696 | } | |
697 | ||
698 | // release "GL" context if it is owned by window | |
544da5a4 | 699 | // Mesa implementation can fail to destroy GL context if it set for current thread. |
700 | // It should be safer to unset thread GL context before its destruction. | |
1ce0716b | 701 | #if defined(HAVE_EGL) |
25b97fac | 702 | if ((EGLSurface )myGlContext->myWindow != EGL_NO_SURFACE) |
703 | { | |
704 | eglDestroySurface ((EGLDisplay )myGlContext->myDisplay, | |
705 | (EGLSurface )myGlContext->myWindow); | |
706 | } | |
707 | #elif defined(_WIN32) | |
fd4a6963 | 708 | HWND aWindow = (HWND )myGlContext->myWindow; |
b69e576a | 709 | HDC aWindowDC = (HDC )myGlContext->myDisplay; |
fd4a6963 | 710 | HGLRC aWindowGContext = (HGLRC )myGlContext->myGContext; |
544da5a4 | 711 | HGLRC aThreadGContext = wglGetCurrentContext(); |
5e27df78 | 712 | myGlContext.Nullify(); |
2166f0fa | 713 | |
544da5a4 | 714 | if (aThreadGContext != NULL) |
2166f0fa | 715 | { |
544da5a4 | 716 | if (aThreadGContext == aWindowGContext) |
2166f0fa | 717 | { |
fd4a6963 | 718 | wglMakeCurrent (NULL, NULL); |
2166f0fa | 719 | } |
fd4a6963 | 720 | |
721 | wglDeleteContext (aWindowGContext); | |
2166f0fa | 722 | } |
fd4a6963 | 723 | ReleaseDC (aWindow, aWindowDC); |
b69e576a | 724 | #elif defined(HAVE_XLIB) |
544da5a4 | 725 | Display* aDisplay = (Display* )myGlContext->myDisplay; |
726 | GLXContext aWindowGContext = (GLXContext )myGlContext->myGContext; | |
727 | GLXContext aThreadGContext = glXGetCurrentContext(); | |
5e27df78 | 728 | myGlContext.Nullify(); |
729 | ||
fd4a6963 | 730 | if (aDisplay != NULL) |
2166f0fa | 731 | { |
544da5a4 | 732 | if (aThreadGContext == aWindowGContext) |
733 | { | |
734 | glXMakeCurrent (aDisplay, None, NULL); | |
735 | } | |
736 | ||
5e27df78 | 737 | // FSXXX sync necessary if non-direct rendering |
738 | glXWaitGL(); | |
544da5a4 | 739 | glXDestroyContext (aDisplay, aWindowGContext); |
2166f0fa | 740 | } |
b69e576a | 741 | #else |
742 | // not implemented | |
2166f0fa SK |
743 | #endif |
744 | } | |
745 | ||
4fe56619 | 746 | #endif // !__APPLE__ |
747 | ||
2166f0fa SK |
748 | // ======================================================================= |
749 | // function : Activate | |
750 | // purpose : | |
751 | // ======================================================================= | |
752 | Standard_Boolean OpenGl_Window::Activate() | |
753 | { | |
86fa64d9 | 754 | return myGlContext->MakeCurrent(); |
2166f0fa SK |
755 | } |
756 | ||
b69e576a | 757 | #if !defined(__APPLE__) || defined(HAVE_XLIB) |
4fe56619 | 758 | |
2166f0fa SK |
759 | // ======================================================================= |
760 | // function : Resize | |
761 | // purpose : call_subr_resize | |
762 | // ======================================================================= | |
c357e426 | 763 | void OpenGl_Window::Resize() |
2166f0fa | 764 | { |
879768fb | 765 | Graphic3d_Vec2i aWinSize; |
766 | mySizeWindow->Size (aWinSize.x(), aWinSize.y()); | |
767 | if (mySize == aWinSize) | |
e89202ea | 768 | { |
769 | // if the size is not changed - do nothing | |
2166f0fa | 770 | return; |
e89202ea | 771 | } |
2166f0fa | 772 | |
879768fb | 773 | mySize = aWinSize; |
2166f0fa | 774 | |
879768fb | 775 | init(); |
2166f0fa SK |
776 | } |
777 | ||
2166f0fa | 778 | // ======================================================================= |
879768fb | 779 | // function : init |
2166f0fa SK |
780 | // purpose : |
781 | // ======================================================================= | |
879768fb | 782 | void OpenGl_Window::init() |
2166f0fa SK |
783 | { |
784 | if (!Activate()) | |
879768fb | 785 | { |
2166f0fa | 786 | return; |
879768fb | 787 | } |
2166f0fa | 788 | |
1ce0716b | 789 | #if defined(HAVE_EGL) |
39235bed | 790 | if ((EGLSurface )myGlContext->myWindow == EGL_NO_SURFACE) |
791 | { | |
792 | // define an offscreen default FBO to avoid rendering into EGL_NO_SURFACE; | |
793 | // note that this code is currently never called, since eglCreatePbufferSurface() is used instead as more robust solution | |
794 | // for offscreen rendering on bugged OpenGL ES drivers | |
795 | Handle(OpenGl_FrameBuffer) aDefFbo = myGlContext->SetDefaultFrameBuffer (Handle(OpenGl_FrameBuffer)()); | |
796 | if (!aDefFbo.IsNull()) | |
797 | { | |
798 | aDefFbo->Release (myGlContext.operator->()); | |
799 | } | |
800 | else | |
801 | { | |
802 | aDefFbo = new OpenGl_FrameBuffer(); | |
803 | } | |
804 | ||
c8365a1c | 805 | OpenGl_ColorFormats aColorFormats; |
806 | aColorFormats.Append (GL_RGBA8); | |
879768fb | 807 | if (!aDefFbo->InitRenderBuffer (myGlContext, mySize, aColorFormats, GL_DEPTH24_STENCIL8)) |
39235bed | 808 | { |
809 | TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO creation failed"); | |
810 | throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString()); | |
811 | } | |
812 | myGlContext->SetDefaultFrameBuffer (aDefFbo); | |
813 | aDefFbo->BindBuffer (myGlContext); | |
814 | } | |
7090725e | 815 | else if (!myPlatformWindow->IsVirtual() |
816 | && mySizeWindow == myPlatformWindow) | |
6cde53c4 | 817 | { |
879768fb | 818 | eglQuerySurface ((EGLDisplay )myGlContext->myDisplay, (EGLSurface )myGlContext->myWindow, EGL_WIDTH, &mySize.x()); |
819 | eglQuerySurface ((EGLDisplay )myGlContext->myDisplay, (EGLSurface )myGlContext->myWindow, EGL_HEIGHT, &mySize.y()); | |
6cde53c4 | 820 | } |
2166f0fa | 821 | #else |
e89202ea | 822 | // |
2166f0fa SK |
823 | #endif |
824 | ||
8f7159cb | 825 | myGlContext->core11fwd->glDisable (GL_DITHER); |
826 | myGlContext->core11fwd->glDisable (GL_SCISSOR_TEST); | |
879768fb | 827 | const Standard_Integer aViewport[4] = { 0, 0, mySize.x(), mySize.y() }; |
3bffef55 | 828 | myGlContext->ResizeViewport (aViewport); |
3bffef55 | 829 | myGlContext->SetDrawBuffer (GL_BACK); |
43eddb47 | 830 | if (myGlContext->core11ffp != NULL) |
4e1523ef | 831 | { |
8f7159cb | 832 | myGlContext->core11ffp->glMatrixMode (GL_MODELVIEW); |
4e1523ef | 833 | } |
2166f0fa SK |
834 | } |
835 | ||
2166f0fa | 836 | // ======================================================================= |
c357e426 | 837 | // function : SetSwapInterval |
2166f0fa SK |
838 | // purpose : |
839 | // ======================================================================= | |
b40cdc2b | 840 | void OpenGl_Window::SetSwapInterval (Standard_Boolean theToForceNoSync) |
2166f0fa | 841 | { |
b40cdc2b | 842 | const Standard_Integer aSwapInterval = theToForceNoSync ? 0 : myGlContext->caps->swapInterval; |
843 | if (mySwapInterval != aSwapInterval) | |
b5ac8292 | 844 | { |
b40cdc2b | 845 | mySwapInterval = aSwapInterval; |
c357e426 | 846 | myGlContext->SetSwapInterval (mySwapInterval); |
b5ac8292 | 847 | } |
2166f0fa | 848 | } |
c357e426 | 849 | |
850 | #endif // !__APPLE__ |