0024552: Convertation of the generic classes to the non-generic (BndLib).
[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//
973c2be1 7// This library is free software; you can redistribute it and / or modify it
8// under the terms of the GNU Lesser General Public version 2.1 as published
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>
a174a3c5 29#include <OpenGl_FrameBuffer.hxx>
bf75be98 30#include <OpenGl_Texture.hxx>
e276548b 31#include <OpenGl_View.hxx>
a174a3c5 32#include <OpenGl_Workspace.hxx>
4269bd1b 33#include <OpenGl_Element.hxx>
2166f0fa 34
bf75be98 35#include <Graphic3d_TextureParams.hxx>
2166f0fa 36
58655684 37#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
a174a3c5 38 #include <OpenGl_AVIWriter.hxx>
39#endif
40
2166f0fa
SK
41IMPLEMENT_STANDARD_HANDLE(OpenGl_Workspace,OpenGl_Window)
42IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,OpenGl_Window)
43
44namespace
45{
0adbd30f 46 static const TEL_COLOUR THE_WHITE_COLOR = { { 1.0f, 1.0f, 1.0f, 1.0f } };
47 static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f);
2166f0fa
SK
48
49 static const OpenGl_AspectLine myDefaultAspectLine;
50 static const OpenGl_AspectFace myDefaultAspectFace;
51 static const OpenGl_AspectMarker myDefaultAspectMarker;
52 static const OpenGl_AspectText myDefaultAspectText;
53
54 static const OpenGl_TextParam myDefaultTextParam =
55 {
56 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
57 };
58
59 static const OpenGl_Matrix myDefaultMatrix =
60 {
61 {{ 1.0F, 0.0F, 0.0F, 0.0F },
62 { 0.0F, 1.0F, 0.0F, 0.0F },
63 { 0.0F, 0.0F, 1.0F, 0.0F },
64 { 0.0F, 0.0F, 0.0F, 1.0F }}
65 };
bf75be98 66
2166f0fa
SK
67};
68
69// =======================================================================
0adbd30f 70// function : Init
71// purpose :
72// =======================================================================
73void OpenGl_Material::Init (const OPENGL_SURF_PROP& theProp)
74{
75 // ambient component
76 if (theProp.color_mask & OPENGL_AMBIENT_MASK)
77 {
78 const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb;
79 Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb,
80 aSrcAmb[1] * theProp.amb,
81 aSrcAmb[2] * theProp.amb,
82 1.0f);
83 }
84 else
85 {
86 Ambient = THE_BLACK_COLOR;
87 }
88
89 // diffusion component
90 if (theProp.color_mask & OPENGL_DIFFUSE_MASK)
91 {
92 const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb;
93 Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff,
94 aSrcDif[1] * theProp.diff,
95 aSrcDif[2] * theProp.diff,
96 1.0f);
97 }
98 else
99 {
100 Diffuse = THE_BLACK_COLOR;
101 }
102
103 // specular component
104 if (theProp.color_mask & OPENGL_SPECULAR_MASK)
105 {
106 const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb;
107 Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec,
108 aSrcSpe[1] * theProp.spec,
109 aSrcSpe[2] * theProp.spec,
110 1.0f);
111 }
112 else
113 {
114 Specular = THE_BLACK_COLOR;
115 }
116
117 // emission component
118 if (theProp.color_mask & OPENGL_EMISSIVE_MASK)
119 {
120 const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb;
121 Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv,
122 aSrcEms[1] * theProp.emsv,
123 aSrcEms[2] * theProp.emsv,
124 1.0f);
125 }
126 else
127 {
128 Emission = THE_BLACK_COLOR;
129 }
130
131 ChangeShine() = theProp.shine;
132 ChangeTransparency() = theProp.trans;
133}
134
135// =======================================================================
2166f0fa
SK
136// function : OpenGl_Workspace
137// purpose :
138// =======================================================================
139OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_Display)& theDisplay,
140 const CALL_DEF_WINDOW& theCWindow,
5e27df78 141 Aspect_RenderingContext theGContext,
58655684 142 const Handle(OpenGl_Caps)& theCaps,
5e27df78 143 const Handle(OpenGl_Context)& theShareCtx)
58655684 144: OpenGl_Window (theDisplay, theCWindow, theGContext, theCaps, theShareCtx),
a174a3c5 145 NamedStatus (0),
0adbd30f 146 HighlightColor (&THE_WHITE_COLOR),
a174a3c5 147 //
2166f0fa
SK
148 myIsTransientOpen (Standard_False),
149 myRetainMode (Standard_False),
a174a3c5 150 myTransientDrawToFront (Standard_True),
2166f0fa
SK
151 myUseTransparency (Standard_False),
152 myUseZBuffer (Standard_False),
153 myUseDepthTest (Standard_True),
154 myUseGLLight (Standard_True),
155 myBackBufferRestored (Standard_False),
156 //
2166f0fa
SK
157 AspectLine_set (&myDefaultAspectLine),
158 AspectLine_applied (NULL),
159 AspectFace_set (&myDefaultAspectFace),
160 AspectFace_applied (NULL),
161 AspectMarker_set (&myDefaultAspectMarker),
162 AspectMarker_applied (NULL),
163 AspectText_set (&myDefaultAspectText),
164 AspectText_applied (NULL),
165 TextParam_set (&myDefaultTextParam),
166 TextParam_applied (NULL),
167 ViewMatrix_applied (&myDefaultMatrix),
168 StructureMatrix_applied (&myDefaultMatrix),
3b1817a9 169 myCullingMode (TelCullUndefined),
0f8c0fb8 170 myModelViewMatrix (myDefaultMatrix),
2166f0fa
SK
171 PolygonOffset_applied (NULL)
172{
173 theDisplay->InitAttributes();
174
175 // General initialization of the context
176
177 // Eviter d'avoir les faces mal orientees en noir.
178 // Pourrait etre utiliser pour detecter les problemes d'orientation
bf75be98 179 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
2166f0fa
SK
180
181 // Optimisation pour le Fog et l'antialiasing
182 glHint (GL_FOG_HINT, GL_FASTEST);
183 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
184 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
185 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
186
187 // Polygon Offset
188 EnablePolygonOffset();
e276548b 189
190#ifdef HAVE_OPENCL
191
192 myComputeInitStatus = OpenGl_CLIS_NONE;
193
194 myViewModificationStatus = 0;
195 myLayersModificationStatus = 0;
196
e276548b 197 myIsRaytraceDataValid = Standard_False;
198 myToUpdateRaytraceData = Standard_False;
199
200#endif
2166f0fa
SK
201}
202
203// =======================================================================
1981cb22 204// function : SetImmediateModeDrawToFront
205// purpose :
206// =======================================================================
207Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
208{
209 const Standard_Boolean aPrevMode = myTransientDrawToFront;
210 myTransientDrawToFront = theDrawToFrontBuffer;
211 return aPrevMode;
212}
213
214// =======================================================================
2166f0fa
SK
215// function : ~OpenGl_Workspace
216// purpose :
217// =======================================================================
218OpenGl_Workspace::~OpenGl_Workspace()
219{
e276548b 220#ifdef HAVE_OPENCL
221 ReleaseOpenCL();
222#endif
2166f0fa
SK
223}
224
225// =======================================================================
226// function : Activate
227// purpose :
228// =======================================================================
229Standard_Boolean OpenGl_Workspace::Activate()
230{
231 if (!OpenGl_Window::Activate())
232 return Standard_False;
233
2166f0fa
SK
234 ViewMatrix_applied = &myDefaultMatrix;
235 StructureMatrix_applied = &myDefaultMatrix;
26395493 236
237 ResetAppliedAspect();
238
239 return Standard_True;
2166f0fa
SK
240}
241
242// =======================================================================
243// function : UseTransparency
244// purpose : call_togl_transparency
245// =======================================================================
246void OpenGl_Workspace::UseTransparency (const Standard_Boolean theFlag)
247{
de75ed09 248 myUseTransparency = theFlag;
2166f0fa 249}
26395493 250
251//=======================================================================
252//function : ResetAppliedAspect
253//purpose : Sets default values of GL parameters in accordance with default aspects
254//=======================================================================
255void OpenGl_Workspace::ResetAppliedAspect()
256{
bf75be98 257 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
0adbd30f 258 HighlightColor = &THE_WHITE_COLOR;
26395493 259 AspectLine_set = &myDefaultAspectLine;
260 AspectLine_applied = NULL;
261 AspectFace_set = &myDefaultAspectFace;
262 AspectFace_applied = NULL;
263 AspectMarker_set = &myDefaultAspectMarker;
264 AspectMarker_applied = NULL;
265 AspectText_set = &myDefaultAspectText;
266 AspectText_applied = NULL;
267 TextParam_set = &myDefaultTextParam;
268 TextParam_applied = NULL;
269 PolygonOffset_applied = NULL;
3b1817a9 270 myCullingMode = TelCullUndefined;
26395493 271
272 AspectLine(Standard_True);
273 AspectFace(Standard_True);
274 AspectMarker(Standard_True);
275 AspectText(Standard_True);
276}
bf75be98 277
278// =======================================================================
279// function : DisableTexture
280// purpose :
281// =======================================================================
282Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
283{
284 if (myTextureBound.IsNull())
285 {
286 return myTextureBound;
287 }
288
289 // reset texture matrix because some code may expect it is identity
290 GLint aMatrixMode = GL_TEXTURE;
291 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
292 glMatrixMode (GL_TEXTURE);
293 glLoadIdentity();
294 glMatrixMode (aMatrixMode);
295
296 myTextureBound->Unbind (myGlContext);
297 switch (myTextureBound->GetTarget())
298 {
299 case GL_TEXTURE_1D:
300 {
301 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
302 {
303 glDisable (GL_TEXTURE_GEN_S);
304 }
305 glDisable (GL_TEXTURE_1D);
306 break;
307 }
308 case GL_TEXTURE_2D:
309 {
310 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
311 {
312 glDisable (GL_TEXTURE_GEN_S);
313 glDisable (GL_TEXTURE_GEN_T);
a577aaab 314 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
315 {
316 glDisable (GL_POINT_SPRITE);
317 }
bf75be98 318 }
319 glDisable (GL_TEXTURE_2D);
320 break;
321 }
322 default: break;
323 }
324
325 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
326 myTextureBound.Nullify();
327 return aPrevTexture;
328}
329
330// =======================================================================
331// function : setTextureParams
332// purpose :
333// =======================================================================
334void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
335 const Handle(Graphic3d_TextureParams)& theParams)
336{
337 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
338 if (aParams.IsNull())
339 {
340 return;
341 }
342
343 GLint aMatrixMode = GL_TEXTURE;
344 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
345
346 // setup texture matrix
347 glMatrixMode (GL_TEXTURE);
348 glLoadIdentity();
349 const Graphic3d_Vec2& aScale = aParams->Scale();
350 const Graphic3d_Vec2& aTrans = aParams->Translation();
351 glScalef ( aScale.x(), aScale.y(), 1.0f);
352 glTranslatef (-aTrans.x(), -aTrans.y(), 0.0f);
353 glRotatef (-aParams->Rotation(), 0.0f, 0.0f, 1.0f);
354
355 // setup generation of texture coordinates
356 switch (aParams->GenMode())
357 {
358 case Graphic3d_TOTM_OBJECT:
359 {
360 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
361 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
362 if (theTexture->GetTarget() != GL_TEXTURE_1D)
363 {
364 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
365 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
366 }
367 break;
368 }
369 case Graphic3d_TOTM_SPHERE:
370 {
371 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
372 if (theTexture->GetTarget() != GL_TEXTURE_1D)
373 {
374 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
375 }
376 break;
377 }
378 case Graphic3d_TOTM_EYE:
379 {
380 glMatrixMode (GL_MODELVIEW);
381 glPushMatrix();
382 glLoadIdentity();
383
384 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
385 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
386
387 if (theTexture->GetTarget() != GL_TEXTURE_1D)
388 {
389 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
390 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
391 }
392 glPopMatrix();
393 break;
394 }
a577aaab 395 case Graphic3d_TOTM_SPRITE:
396 {
397 if (GetGlContext()->core20 != NULL)
398 {
399 glEnable (GL_POINT_SPRITE);
400 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
401 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
402 GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
403 }
404 break;
405 }
bf75be98 406 case Graphic3d_TOTM_MANUAL:
407 default: break;
408 }
409
410 // setup lighting
a577aaab 411 if (aParams->GenMode() != Graphic3d_TOTM_SPRITE)
412 {
413 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aParams->IsModulate() ? GL_MODULATE : GL_DECAL);
414 }
bf75be98 415
416 // setup texture filtering and wrapping
417 //if (theTexture->GetParams() != theParams)
418 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
419 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : GL_CLAMP;
420 switch (theTexture->GetTarget())
421 {
422 case GL_TEXTURE_1D:
423 {
424 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
425 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
426 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
427 break;
428 }
429 case GL_TEXTURE_2D:
430 {
431 GLenum aFilterMin = aFilter;
432 if (theTexture->HasMipmaps())
433 {
434 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
435 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
436 {
437 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
438 }
439 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
440 {
441 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
442 }
443
444 if (myGlContext->extAnis)
445 {
446 // setup degree of anisotropy filter
447 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
448 switch (aParams->AnisoFilter())
449 {
450 case Graphic3d_LOTA_QUALITY:
451 {
452 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aMaxDegree);
453 break;
454 }
455 case Graphic3d_LOTA_MIDDLE:
456 {
457
458 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2));
459 break;
460 }
461 case Graphic3d_LOTA_FAST:
462 {
463 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2);
464 break;
465 }
466 case Graphic3d_LOTA_OFF:
467 default:
468 {
469 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
470 break;
471 }
472 }
473 }
474 }
475 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
476 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
477 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
478 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
479 break;
480 }
481 default: break;
482 }
483
484 switch (theTexture->GetTarget())
485 {
486 case GL_TEXTURE_1D:
487 {
488 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
489 {
490 glEnable (GL_TEXTURE_GEN_S);
491 }
492 glEnable (GL_TEXTURE_1D);
493 break;
494 }
495 case GL_TEXTURE_2D:
496 {
497 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
498 {
499 glEnable (GL_TEXTURE_GEN_S);
500 glEnable (GL_TEXTURE_GEN_T);
501 }
502 glEnable (GL_TEXTURE_2D);
503 break;
504 }
505 default: break;
506 }
507
508 glMatrixMode (aMatrixMode); // turn back active matrix
509 theTexture->SetParams (aParams);
510}
511
512// =======================================================================
513// function : EnableTexture
514// purpose :
515// =======================================================================
516Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
517 const Handle(Graphic3d_TextureParams)& theParams)
518{
519 if (theTexture.IsNull() || !theTexture->IsValid())
520 {
521 return DisableTexture();
522 }
523
bca1d6e2 524 if (myTextureBound == theTexture
525 && (theParams.IsNull() || theParams == theTexture->GetParams()))
bf75be98 526 {
bca1d6e2 527 // already bound
528 return myTextureBound;
bf75be98 529 }
530
531 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
532 myTextureBound = theTexture;
533 myTextureBound->Bind (myGlContext);
534 setTextureParams (myTextureBound, theParams);
535
536 return aPrevTexture;
537}
a174a3c5 538
539// =======================================================================
540// function : Redraw
541// purpose :
542// =======================================================================
543void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
544 const Aspect_CLayer2d& theCUnderLayer,
545 const Aspect_CLayer2d& theCOverLayer)
546{
547 if (!Activate())
548 {
549 return;
550 }
551
552 // release pending GL resources
553 Handle(OpenGl_Context) aGlCtx = GetGlContext();
554 aGlCtx->ReleaseDelayed();
555
556 // cache render mode state
557 GLint aRendMode = GL_RENDER;
558 glGetIntegerv (GL_RENDER_MODE, &aRendMode);
559 aGlCtx->SetFeedback (aRendMode == GL_FEEDBACK);
560
561 Tint toSwap = (aRendMode == GL_RENDER); // swap buffers
562 GLint aViewPortBack[4];
563 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
564 if (aFrameBuffer != NULL)
565 {
566 glGetIntegerv (GL_VIEWPORT, aViewPortBack);
fd4a6963 567 aFrameBuffer->SetupViewport (aGlCtx);
568 aFrameBuffer->BindBuffer (aGlCtx);
a174a3c5 569 toSwap = 0; // no need to swap buffers
570 }
571
e276548b 572#ifdef HAVE_OPENCL
573 if (!theCView.IsRaytracing || myComputeInitStatus == OpenGl_CLIS_FAIL)
574 {
575#endif
576 Redraw1 (theCView, theCUnderLayer, theCOverLayer, toSwap);
577 if (aFrameBuffer == NULL || !myTransientDrawToFront)
578 {
579 RedrawImmediatMode();
580 }
581
582 theCView.WasRedrawnGL = Standard_True;
583#ifdef HAVE_OPENCL
584 }
585 else
a174a3c5 586 {
e276548b 587 int aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
588 int aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
589
590 Raytrace (theCView, aSizeX, aSizeY, toSwap);
591
592 theCView.WasRedrawnGL = Standard_False;
a174a3c5 593 }
e276548b 594#endif
a174a3c5 595
596 if (aFrameBuffer != NULL)
597 {
598 aFrameBuffer->UnbindBuffer (aGlCtx);
599 // move back original viewport
600 glViewport (aViewPortBack[0], aViewPortBack[1], aViewPortBack[2], aViewPortBack[3]);
601 }
602
603#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE)
604 if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow))
605 {
606 GLint params[4];
607 glGetIntegerv (GL_VIEWPORT, params);
608 int nWidth = params[2] & ~0x7;
609 int nHeight = params[3] & ~0x7;
610
611 const int nBitsPerPixel = 24;
612 GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
613
614 glPixelStorei (GL_PACK_ALIGNMENT, 1);
615 glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
616 OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
617 delete[] aDumpData;
618 }
619#endif
620
621 // reset render mode state
622 aGlCtx->SetFeedback (Standard_False);
623}