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