0024858: Convert class V3d_ListOfTransient to non-CDL
[occt.git] / src / OpenGl / OpenGl_Workspace.cxx
CommitLineData
b311480e 1// Created on: 2011-09-20
2// Created by: Sergey ZERCHANINOV
973c2be1 3// Copyright (c) 2011-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
e276548b 16#ifdef HAVE_CONFIG_H
17 #include <config.h>
18#endif
19
a577aaab 20#include <OpenGl_GlCore15.hxx>
5f8b738e 21
2166f0fa
SK
22#include <InterfaceGraphic.hxx>
23
2166f0fa
SK
24#include <OpenGl_AspectLine.hxx>
25#include <OpenGl_AspectFace.hxx>
26#include <OpenGl_AspectMarker.hxx>
27#include <OpenGl_AspectText.hxx>
bf75be98 28#include <OpenGl_Context.hxx>
679ecdee 29#include <OpenGl_Element.hxx>
a174a3c5 30#include <OpenGl_FrameBuffer.hxx>
679ecdee 31#include <OpenGl_Structure.hxx>
bf75be98 32#include <OpenGl_Texture.hxx>
e276548b 33#include <OpenGl_View.hxx>
a174a3c5 34#include <OpenGl_Workspace.hxx>
2166f0fa 35
bf75be98 36#include <Graphic3d_TextureParams.hxx>
2166f0fa 37
58655684 38#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
a174a3c5 39 #include <OpenGl_AVIWriter.hxx>
40#endif
41
2166f0fa
SK
42IMPLEMENT_STANDARD_HANDLE(OpenGl_Workspace,OpenGl_Window)
43IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,OpenGl_Window)
44
45namespace
46{
0adbd30f 47 static const TEL_COLOUR THE_WHITE_COLOR = { { 1.0f, 1.0f, 1.0f, 1.0f } };
48 static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f);
2166f0fa
SK
49
50 static const OpenGl_AspectLine myDefaultAspectLine;
51 static const OpenGl_AspectFace myDefaultAspectFace;
52 static const OpenGl_AspectMarker myDefaultAspectMarker;
53 static const OpenGl_AspectText myDefaultAspectText;
54
55 static const OpenGl_TextParam myDefaultTextParam =
56 {
57 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
58 };
59
60 static const OpenGl_Matrix myDefaultMatrix =
61 {
62 {{ 1.0F, 0.0F, 0.0F, 0.0F },
63 { 0.0F, 1.0F, 0.0F, 0.0F },
64 { 0.0F, 0.0F, 1.0F, 0.0F },
65 { 0.0F, 0.0F, 0.0F, 1.0F }}
66 };
bf75be98 67
2166f0fa
SK
68};
69
70// =======================================================================
0adbd30f 71// function : Init
72// purpose :
73// =======================================================================
74void OpenGl_Material::Init (const OPENGL_SURF_PROP& theProp)
75{
76 // ambient component
77 if (theProp.color_mask & OPENGL_AMBIENT_MASK)
78 {
79 const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb;
80 Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb,
81 aSrcAmb[1] * theProp.amb,
82 aSrcAmb[2] * theProp.amb,
83 1.0f);
84 }
85 else
86 {
87 Ambient = THE_BLACK_COLOR;
88 }
89
90 // diffusion component
91 if (theProp.color_mask & OPENGL_DIFFUSE_MASK)
92 {
93 const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb;
94 Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff,
95 aSrcDif[1] * theProp.diff,
96 aSrcDif[2] * theProp.diff,
97 1.0f);
98 }
99 else
100 {
101 Diffuse = THE_BLACK_COLOR;
102 }
103
104 // specular component
105 if (theProp.color_mask & OPENGL_SPECULAR_MASK)
106 {
107 const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb;
108 Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec,
109 aSrcSpe[1] * theProp.spec,
110 aSrcSpe[2] * theProp.spec,
111 1.0f);
112 }
113 else
114 {
115 Specular = THE_BLACK_COLOR;
116 }
117
118 // emission component
119 if (theProp.color_mask & OPENGL_EMISSIVE_MASK)
120 {
121 const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb;
122 Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv,
123 aSrcEms[1] * theProp.emsv,
124 aSrcEms[2] * theProp.emsv,
125 1.0f);
126 }
127 else
128 {
129 Emission = THE_BLACK_COLOR;
130 }
131
132 ChangeShine() = theProp.shine;
133 ChangeTransparency() = theProp.trans;
134}
135
136// =======================================================================
2166f0fa
SK
137// function : OpenGl_Workspace
138// purpose :
139// =======================================================================
140OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_Display)& theDisplay,
141 const CALL_DEF_WINDOW& theCWindow,
5e27df78 142 Aspect_RenderingContext theGContext,
58655684 143 const Handle(OpenGl_Caps)& theCaps,
5e27df78 144 const Handle(OpenGl_Context)& theShareCtx)
58655684 145: OpenGl_Window (theDisplay, theCWindow, theGContext, theCaps, theShareCtx),
a174a3c5 146 NamedStatus (0),
0adbd30f 147 HighlightColor (&THE_WHITE_COLOR),
a174a3c5 148 //
fc73a202 149 myComputeInitStatus (OpenGl_RT_NONE),
150 myIsRaytraceDataValid (Standard_False),
151 myTraversalStackSize (THE_DEFAULT_STACK_SIZE),
152 myViewModificationStatus (0),
153 myLayersModificationStatus (0),
154 //
a174a3c5 155 myTransientDrawToFront (Standard_True),
679ecdee 156 myBackBufferRestored (Standard_False),
157 myIsImmediateDrawn (Standard_False),
2166f0fa
SK
158 myUseTransparency (Standard_False),
159 myUseZBuffer (Standard_False),
160 myUseDepthTest (Standard_True),
161 myUseGLLight (Standard_True),
2166f0fa 162 //
2166f0fa
SK
163 AspectLine_set (&myDefaultAspectLine),
164 AspectLine_applied (NULL),
165 AspectFace_set (&myDefaultAspectFace),
166 AspectFace_applied (NULL),
167 AspectMarker_set (&myDefaultAspectMarker),
168 AspectMarker_applied (NULL),
169 AspectText_set (&myDefaultAspectText),
170 AspectText_applied (NULL),
171 TextParam_set (&myDefaultTextParam),
172 TextParam_applied (NULL),
173 ViewMatrix_applied (&myDefaultMatrix),
174 StructureMatrix_applied (&myDefaultMatrix),
3b1817a9 175 myCullingMode (TelCullUndefined),
0f8c0fb8 176 myModelViewMatrix (myDefaultMatrix),
2166f0fa
SK
177 PolygonOffset_applied (NULL)
178{
179 theDisplay->InitAttributes();
180
181 // General initialization of the context
182
183 // Eviter d'avoir les faces mal orientees en noir.
184 // Pourrait etre utiliser pour detecter les problemes d'orientation
bf75be98 185 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
2166f0fa
SK
186
187 // Optimisation pour le Fog et l'antialiasing
188 glHint (GL_FOG_HINT, GL_FASTEST);
189 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
190 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
191 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
192
193 // Polygon Offset
194 EnablePolygonOffset();
195}
196
197// =======================================================================
1981cb22 198// function : SetImmediateModeDrawToFront
199// purpose :
200// =======================================================================
201Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
202{
203 const Standard_Boolean aPrevMode = myTransientDrawToFront;
204 myTransientDrawToFront = theDrawToFrontBuffer;
205 return aPrevMode;
206}
207
208// =======================================================================
2166f0fa
SK
209// function : ~OpenGl_Workspace
210// purpose :
211// =======================================================================
212OpenGl_Workspace::~OpenGl_Workspace()
213{
fc73a202 214 ReleaseRaytraceResources();
2166f0fa
SK
215}
216
217// =======================================================================
218// function : Activate
219// purpose :
220// =======================================================================
221Standard_Boolean OpenGl_Workspace::Activate()
222{
223 if (!OpenGl_Window::Activate())
224 return Standard_False;
225
2166f0fa
SK
226 ViewMatrix_applied = &myDefaultMatrix;
227 StructureMatrix_applied = &myDefaultMatrix;
26395493 228
229 ResetAppliedAspect();
230
231 return Standard_True;
2166f0fa
SK
232}
233
234// =======================================================================
235// function : UseTransparency
236// purpose : call_togl_transparency
237// =======================================================================
238void OpenGl_Workspace::UseTransparency (const Standard_Boolean theFlag)
239{
de75ed09 240 myUseTransparency = theFlag;
2166f0fa 241}
26395493 242
243//=======================================================================
244//function : ResetAppliedAspect
245//purpose : Sets default values of GL parameters in accordance with default aspects
246//=======================================================================
247void OpenGl_Workspace::ResetAppliedAspect()
248{
bf75be98 249 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
0adbd30f 250 HighlightColor = &THE_WHITE_COLOR;
26395493 251 AspectLine_set = &myDefaultAspectLine;
252 AspectLine_applied = NULL;
253 AspectFace_set = &myDefaultAspectFace;
254 AspectFace_applied = NULL;
255 AspectMarker_set = &myDefaultAspectMarker;
256 AspectMarker_applied = NULL;
257 AspectText_set = &myDefaultAspectText;
258 AspectText_applied = NULL;
259 TextParam_set = &myDefaultTextParam;
260 TextParam_applied = NULL;
261 PolygonOffset_applied = NULL;
3b1817a9 262 myCullingMode = TelCullUndefined;
26395493 263
264 AspectLine(Standard_True);
265 AspectFace(Standard_True);
266 AspectMarker(Standard_True);
267 AspectText(Standard_True);
268}
bf75be98 269
270// =======================================================================
271// function : DisableTexture
272// purpose :
273// =======================================================================
274Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
275{
276 if (myTextureBound.IsNull())
277 {
278 return myTextureBound;
279 }
280
281 // reset texture matrix because some code may expect it is identity
282 GLint aMatrixMode = GL_TEXTURE;
283 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
284 glMatrixMode (GL_TEXTURE);
285 glLoadIdentity();
286 glMatrixMode (aMatrixMode);
287
288 myTextureBound->Unbind (myGlContext);
289 switch (myTextureBound->GetTarget())
290 {
291 case GL_TEXTURE_1D:
292 {
293 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
294 {
295 glDisable (GL_TEXTURE_GEN_S);
296 }
297 glDisable (GL_TEXTURE_1D);
298 break;
299 }
300 case GL_TEXTURE_2D:
301 {
302 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
303 {
304 glDisable (GL_TEXTURE_GEN_S);
305 glDisable (GL_TEXTURE_GEN_T);
a577aaab 306 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
307 {
308 glDisable (GL_POINT_SPRITE);
309 }
bf75be98 310 }
311 glDisable (GL_TEXTURE_2D);
312 break;
313 }
314 default: break;
315 }
316
317 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
318 myTextureBound.Nullify();
319 return aPrevTexture;
320}
321
322// =======================================================================
323// function : setTextureParams
324// purpose :
325// =======================================================================
326void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
327 const Handle(Graphic3d_TextureParams)& theParams)
328{
329 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
330 if (aParams.IsNull())
331 {
332 return;
333 }
334
335 GLint aMatrixMode = GL_TEXTURE;
336 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
337
338 // setup texture matrix
339 glMatrixMode (GL_TEXTURE);
340 glLoadIdentity();
341 const Graphic3d_Vec2& aScale = aParams->Scale();
342 const Graphic3d_Vec2& aTrans = aParams->Translation();
343 glScalef ( aScale.x(), aScale.y(), 1.0f);
344 glTranslatef (-aTrans.x(), -aTrans.y(), 0.0f);
345 glRotatef (-aParams->Rotation(), 0.0f, 0.0f, 1.0f);
346
347 // setup generation of texture coordinates
348 switch (aParams->GenMode())
349 {
350 case Graphic3d_TOTM_OBJECT:
351 {
352 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
353 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
354 if (theTexture->GetTarget() != GL_TEXTURE_1D)
355 {
356 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
357 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
358 }
359 break;
360 }
361 case Graphic3d_TOTM_SPHERE:
362 {
363 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
364 if (theTexture->GetTarget() != GL_TEXTURE_1D)
365 {
366 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
367 }
368 break;
369 }
370 case Graphic3d_TOTM_EYE:
371 {
372 glMatrixMode (GL_MODELVIEW);
373 glPushMatrix();
374 glLoadIdentity();
375
376 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
377 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
378
379 if (theTexture->GetTarget() != GL_TEXTURE_1D)
380 {
381 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
382 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
383 }
384 glPopMatrix();
385 break;
386 }
a577aaab 387 case Graphic3d_TOTM_SPRITE:
388 {
389 if (GetGlContext()->core20 != NULL)
390 {
391 glEnable (GL_POINT_SPRITE);
392 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
393 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
394 GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
395 }
396 break;
397 }
bf75be98 398 case Graphic3d_TOTM_MANUAL:
399 default: break;
400 }
401
402 // setup lighting
a577aaab 403 if (aParams->GenMode() != Graphic3d_TOTM_SPRITE)
404 {
405 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aParams->IsModulate() ? GL_MODULATE : GL_DECAL);
406 }
bf75be98 407
408 // setup texture filtering and wrapping
409 //if (theTexture->GetParams() != theParams)
410 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
411 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : GL_CLAMP;
412 switch (theTexture->GetTarget())
413 {
414 case GL_TEXTURE_1D:
415 {
416 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
417 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
418 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
419 break;
420 }
421 case GL_TEXTURE_2D:
422 {
423 GLenum aFilterMin = aFilter;
424 if (theTexture->HasMipmaps())
425 {
426 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
427 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
428 {
429 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
430 }
431 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
432 {
433 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
434 }
435
436 if (myGlContext->extAnis)
437 {
438 // setup degree of anisotropy filter
439 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
440 switch (aParams->AnisoFilter())
441 {
442 case Graphic3d_LOTA_QUALITY:
443 {
444 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aMaxDegree);
445 break;
446 }
447 case Graphic3d_LOTA_MIDDLE:
448 {
449
450 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2));
451 break;
452 }
453 case Graphic3d_LOTA_FAST:
454 {
455 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2);
456 break;
457 }
458 case Graphic3d_LOTA_OFF:
459 default:
460 {
461 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
462 break;
463 }
464 }
465 }
466 }
467 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
468 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
469 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
470 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
471 break;
472 }
473 default: break;
474 }
475
476 switch (theTexture->GetTarget())
477 {
478 case GL_TEXTURE_1D:
479 {
480 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
481 {
482 glEnable (GL_TEXTURE_GEN_S);
483 }
484 glEnable (GL_TEXTURE_1D);
485 break;
486 }
487 case GL_TEXTURE_2D:
488 {
489 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
490 {
491 glEnable (GL_TEXTURE_GEN_S);
492 glEnable (GL_TEXTURE_GEN_T);
493 }
494 glEnable (GL_TEXTURE_2D);
495 break;
496 }
497 default: break;
498 }
499
500 glMatrixMode (aMatrixMode); // turn back active matrix
501 theTexture->SetParams (aParams);
502}
503
504// =======================================================================
505// function : EnableTexture
506// purpose :
507// =======================================================================
508Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
509 const Handle(Graphic3d_TextureParams)& theParams)
510{
511 if (theTexture.IsNull() || !theTexture->IsValid())
512 {
513 return DisableTexture();
514 }
515
bca1d6e2 516 if (myTextureBound == theTexture
517 && (theParams.IsNull() || theParams == theTexture->GetParams()))
bf75be98 518 {
bca1d6e2 519 // already bound
520 return myTextureBound;
bf75be98 521 }
522
523 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
524 myTextureBound = theTexture;
525 myTextureBound->Bind (myGlContext);
526 setTextureParams (myTextureBound, theParams);
527
528 return aPrevTexture;
529}
a174a3c5 530
531// =======================================================================
532// function : Redraw
533// purpose :
534// =======================================================================
535void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
536 const Aspect_CLayer2d& theCUnderLayer,
537 const Aspect_CLayer2d& theCOverLayer)
538{
539 if (!Activate())
540 {
541 return;
542 }
543
544 // release pending GL resources
545 Handle(OpenGl_Context) aGlCtx = GetGlContext();
546 aGlCtx->ReleaseDelayed();
547
b5ac8292 548 // fetch OpenGl context state
549 aGlCtx->FetchState();
a174a3c5 550
b5ac8292 551 Tint toSwap = (aGlCtx->IsRender()); // swap buffers
a174a3c5 552 GLint aViewPortBack[4];
553 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
554 if (aFrameBuffer != NULL)
555 {
556 glGetIntegerv (GL_VIEWPORT, aViewPortBack);
fd4a6963 557 aFrameBuffer->SetupViewport (aGlCtx);
558 aFrameBuffer->BindBuffer (aGlCtx);
a174a3c5 559 toSwap = 0; // no need to swap buffers
560 }
561
fc73a202 562 if (!theCView.IsRaytracing || myComputeInitStatus == OpenGl_RT_FAIL)
e276548b 563 {
679ecdee 564 const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
565 redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap);
566 if (isImmediate)
e276548b 567 {
679ecdee 568 RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
e276548b 569 }
570
571 theCView.WasRedrawnGL = Standard_True;
e276548b 572 }
573 else
a174a3c5 574 {
e276548b 575 int aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
576 int aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
577
fc73a202 578 Raytrace (theCView, aSizeX, aSizeY, toSwap, aFrameBuffer);
e276548b 579
580 theCView.WasRedrawnGL = Standard_False;
a174a3c5 581 }
582
583 if (aFrameBuffer != NULL)
584 {
585 aFrameBuffer->UnbindBuffer (aGlCtx);
586 // move back original viewport
587 glViewport (aViewPortBack[0], aViewPortBack[1], aViewPortBack[2], aViewPortBack[3]);
588 }
589
679ecdee 590#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
a174a3c5 591 if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow))
592 {
593 GLint params[4];
594 glGetIntegerv (GL_VIEWPORT, params);
595 int nWidth = params[2] & ~0x7;
596 int nHeight = params[3] & ~0x7;
597
598 const int nBitsPerPixel = 24;
599 GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
600
601 glPixelStorei (GL_PACK_ALIGNMENT, 1);
602 glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
603 OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
604 delete[] aDumpData;
605 }
606#endif
607
608 // reset render mode state
b5ac8292 609 aGlCtx->FetchState();
a174a3c5 610}
679ecdee 611
612// =======================================================================
613// function : redraw1
614// purpose :
615// =======================================================================
616void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
617 const Aspect_CLayer2d& theCUnderLayer,
618 const Aspect_CLayer2d& theCOverLayer,
619 const int theToSwap)
620{
621 if (myDisplay.IsNull() || myView.IsNull())
622 {
623 return;
624 }
625
626 // request reset of material
627 NamedStatus |= OPENGL_NS_RESMAT;
628
629 // GL_DITHER on/off pour le background
630 if (myBackDither)
631 {
632 glEnable (GL_DITHER);
633 }
634 else
635 {
636 glDisable (GL_DITHER);
637 }
638
639 GLbitfield toClear = GL_COLOR_BUFFER_BIT;
640 if (myUseZBuffer)
641 {
642 glDepthFunc (GL_LEQUAL);
643 glDepthMask (GL_TRUE);
644 if (myUseDepthTest)
645 {
646 glEnable (GL_DEPTH_TEST);
647 }
648 else
649 {
650 glDisable (GL_DEPTH_TEST);
651 }
652
653 glClearDepth (1.0);
654 toClear |= GL_DEPTH_BUFFER_BIT;
655 }
656 else
657 {
658 glDisable (GL_DEPTH_TEST);
659 }
660
661 if (NamedStatus & OPENGL_NS_WHITEBACK)
662 {
663 // set background to white
664 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
665 toClear |= GL_DEPTH_BUFFER_BIT;
666 }
667 else
668 {
669 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
670 }
671 glClear (toClear);
672
673 Handle(OpenGl_Workspace) aWS (this);
674 myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer);
675
676 // swap the buffers
677 if (theToSwap)
678 {
679 GetGlContext()->SwapBuffers();
680 myBackBufferRestored = Standard_False;
681 myIsImmediateDrawn = Standard_False;
682 }
683 else
684 {
685 glFlush();
686 myBackBufferRestored = Standard_True;
687 myIsImmediateDrawn = Standard_False;
688 }
689}
690
691// =======================================================================
692// function : copyBackToFront
693// purpose :
694// =======================================================================
695void OpenGl_Workspace::copyBackToFront()
696{
697 glMatrixMode (GL_PROJECTION);
698 glPushMatrix();
699 glLoadIdentity();
700 gluOrtho2D (0.0, (GLdouble )myWidth, 0.0, (GLdouble )myHeight);
701 glMatrixMode (GL_MODELVIEW);
702 glPushMatrix();
703 glLoadIdentity();
704
705 DisableFeatures();
706
707 glDrawBuffer (GL_FRONT);
708 glReadBuffer (GL_BACK);
709
710 glRasterPos2i (0, 0);
711 glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR);
712
713 EnableFeatures();
714
715 glMatrixMode (GL_PROJECTION);
716 glPopMatrix();
717 glMatrixMode (GL_MODELVIEW);
718 glPopMatrix();
719
720 glDrawBuffer (GL_BACK);
721
722 myIsImmediateDrawn = Standard_False;
723}
724
725// =======================================================================
726// function : DisplayCallback
727// purpose :
728// =======================================================================
729void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
730 Standard_Integer theReason)
731{
732 if (theCView.GDisplayCB == NULL)
733 {
734 return;
735 }
736
737 Aspect_GraphicCallbackStruct aCallData;
738 aCallData.reason = theReason;
739 aCallData.glContext = GetGlContext();
740 aCallData.wsID = theCView.WsId;
741 aCallData.viewID = theCView.ViewId;
742 theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
743}
744
745// =======================================================================
746// function : RedrawImmediate
747// purpose :
748// =======================================================================
749void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
750 const Aspect_CLayer2d& theCUnderLayer,
751 const Aspect_CLayer2d& theCOverLayer,
752 const Standard_Boolean theToForce)
753{
754 if (!Activate())
755 {
756 return;
757 }
758
759 GLboolean isDoubleBuffer = GL_FALSE;
760 glGetBooleanv (GL_DOUBLEBUFFER, &isDoubleBuffer);
761 if (myView->ImmediateStructures().IsEmpty())
762 {
763 if (theToForce
764 || !myIsImmediateDrawn)
765 {
766 myIsImmediateDrawn = Standard_False;
767 return;
768 }
769
770 if (myBackBufferRestored
771 && isDoubleBuffer)
772 {
773 copyBackToFront();
65812bd0 774 glFlush();
679ecdee 775 }
776 else
777 {
778 Redraw (theCView, theCUnderLayer, theCOverLayer);
779 }
780 return;
781 }
782
783 if (isDoubleBuffer && myTransientDrawToFront)
784 {
785 if (!myBackBufferRestored)
786 {
787 Redraw (theCView, theCUnderLayer, theCOverLayer);
788 return;
789 }
790 copyBackToFront();
791 MakeFrontBufCurrent();
792 }
793 else
794 {
795 myBackBufferRestored = Standard_False;
796 }
797 myIsImmediateDrawn = Standard_True;
798
799 NamedStatus |= OPENGL_NS_IMMEDIATE;
800 ///glDisable (GL_LIGHTING);
801 glDisable (GL_DEPTH_TEST);
802
803 Handle(OpenGl_Workspace) aWS (this);
804 for (OpenGl_SequenceOfStructure::Iterator anIter (myView->ImmediateStructures());
805 anIter.More(); anIter.Next())
806 {
807 const OpenGl_Structure* aStructure = anIter.Value();
808 aStructure->Render (aWS);
809 }
810
811 NamedStatus &= ~OPENGL_NS_IMMEDIATE;
812
813 if (isDoubleBuffer && myTransientDrawToFront)
814 {
815 glFlush();
816 MakeBackBufCurrent();
817 }
818}