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