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