0024819: TKOpenGl - extend the ray-tracing core by visualization of lines, text and...
[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// =======================================================================
73192b37 140OpenGl_Workspace::OpenGl_Workspace (const Handle(Aspect_DisplayConnection)& theDisplayConnection,
2166f0fa 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)
73192b37 145: OpenGl_Window (theDisplayConnection, 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),
fc73a202 151 myViewModificationStatus (0),
152 myLayersModificationStatus (0),
153 //
a89742cf 154 myRaytraceFilter (new OpenGl_RaytraceFilter()),
155 myToRedrawGL (Standard_True),
73192b37 156 myAntiAliasingMode (3),
a174a3c5 157 myTransientDrawToFront (Standard_True),
679ecdee 158 myBackBufferRestored (Standard_False),
159 myIsImmediateDrawn (Standard_False),
2166f0fa
SK
160 myUseTransparency (Standard_False),
161 myUseZBuffer (Standard_False),
162 myUseDepthTest (Standard_True),
163 myUseGLLight (Standard_True),
b7cd4ba7 164 myIsCullingEnabled (Standard_False),
a89742cf 165 myFrameCounter (0),
2166f0fa 166 //
2166f0fa
SK
167 AspectLine_set (&myDefaultAspectLine),
168 AspectLine_applied (NULL),
169 AspectFace_set (&myDefaultAspectFace),
170 AspectFace_applied (NULL),
171 AspectMarker_set (&myDefaultAspectMarker),
172 AspectMarker_applied (NULL),
173 AspectText_set (&myDefaultAspectText),
174 AspectText_applied (NULL),
175 TextParam_set (&myDefaultTextParam),
176 TextParam_applied (NULL),
177 ViewMatrix_applied (&myDefaultMatrix),
178 StructureMatrix_applied (&myDefaultMatrix),
3b1817a9 179 myCullingMode (TelCullUndefined),
0f8c0fb8 180 myModelViewMatrix (myDefaultMatrix),
550f3b8b 181 PolygonOffset_applied (THE_DEFAULT_POFFSET)
2166f0fa 182{
73192b37 183 myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
184
185 if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
186 {
187 // share and register for release once the resource is no longer used
188 myLineAttribs = new OpenGl_LineAttributes();
189 myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs);
190 myLineAttribs->Init (myGlContext);
191 }
2166f0fa
SK
192
193 // General initialization of the context
194
195 // Eviter d'avoir les faces mal orientees en noir.
196 // Pourrait etre utiliser pour detecter les problemes d'orientation
bf75be98 197 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
2166f0fa
SK
198
199 // Optimisation pour le Fog et l'antialiasing
200 glHint (GL_FOG_HINT, GL_FASTEST);
201 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
202 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
203 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
204
73192b37 205 // AA mode
206 const char* anAaEnv = ::getenv ("CALL_OPENGL_ANTIALIASING_MODE");
207 if (anAaEnv != NULL)
208 {
209 int v;
210 if (sscanf (anAaEnv, "%d", &v) > 0) myAntiAliasingMode = v;
211 }
2166f0fa
SK
212}
213
214// =======================================================================
1981cb22 215// function : SetImmediateModeDrawToFront
216// purpose :
217// =======================================================================
218Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
219{
220 const Standard_Boolean aPrevMode = myTransientDrawToFront;
221 myTransientDrawToFront = theDrawToFrontBuffer;
222 return aPrevMode;
223}
224
225// =======================================================================
2166f0fa
SK
226// function : ~OpenGl_Workspace
227// purpose :
228// =======================================================================
229OpenGl_Workspace::~OpenGl_Workspace()
230{
73192b37 231 if (!myLineAttribs.IsNull())
232 {
233 myLineAttribs.Nullify();
234 myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
235 }
236
fc73a202 237 ReleaseRaytraceResources();
2166f0fa
SK
238}
239
240// =======================================================================
241// function : Activate
242// purpose :
243// =======================================================================
244Standard_Boolean OpenGl_Workspace::Activate()
245{
246 if (!OpenGl_Window::Activate())
247 return Standard_False;
248
2166f0fa
SK
249 ViewMatrix_applied = &myDefaultMatrix;
250 StructureMatrix_applied = &myDefaultMatrix;
26395493 251
252 ResetAppliedAspect();
253
254 return Standard_True;
2166f0fa
SK
255}
256
257// =======================================================================
258// function : UseTransparency
259// purpose : call_togl_transparency
260// =======================================================================
261void OpenGl_Workspace::UseTransparency (const Standard_Boolean theFlag)
262{
de75ed09 263 myUseTransparency = theFlag;
2166f0fa 264}
26395493 265
266//=======================================================================
267//function : ResetAppliedAspect
268//purpose : Sets default values of GL parameters in accordance with default aspects
269//=======================================================================
270void OpenGl_Workspace::ResetAppliedAspect()
271{
bf75be98 272 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
0adbd30f 273 HighlightColor = &THE_WHITE_COLOR;
26395493 274 AspectLine_set = &myDefaultAspectLine;
275 AspectLine_applied = NULL;
276 AspectFace_set = &myDefaultAspectFace;
277 AspectFace_applied = NULL;
278 AspectMarker_set = &myDefaultAspectMarker;
279 AspectMarker_applied = NULL;
280 AspectText_set = &myDefaultAspectText;
281 AspectText_applied = NULL;
282 TextParam_set = &myDefaultTextParam;
283 TextParam_applied = NULL;
550f3b8b 284 PolygonOffset_applied = THE_DEFAULT_POFFSET;
3b1817a9 285 myCullingMode = TelCullUndefined;
26395493 286
287 AspectLine(Standard_True);
288 AspectFace(Standard_True);
289 AspectMarker(Standard_True);
290 AspectText(Standard_True);
291}
bf75be98 292
293// =======================================================================
294// function : DisableTexture
295// purpose :
296// =======================================================================
297Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
298{
299 if (myTextureBound.IsNull())
300 {
301 return myTextureBound;
302 }
303
304 // reset texture matrix because some code may expect it is identity
305 GLint aMatrixMode = GL_TEXTURE;
306 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
307 glMatrixMode (GL_TEXTURE);
308 glLoadIdentity();
309 glMatrixMode (aMatrixMode);
310
311 myTextureBound->Unbind (myGlContext);
312 switch (myTextureBound->GetTarget())
313 {
314 case GL_TEXTURE_1D:
315 {
316 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
317 {
318 glDisable (GL_TEXTURE_GEN_S);
319 }
320 glDisable (GL_TEXTURE_1D);
321 break;
322 }
323 case GL_TEXTURE_2D:
324 {
325 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
326 {
327 glDisable (GL_TEXTURE_GEN_S);
328 glDisable (GL_TEXTURE_GEN_T);
a577aaab 329 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
330 {
331 glDisable (GL_POINT_SPRITE);
332 }
bf75be98 333 }
334 glDisable (GL_TEXTURE_2D);
335 break;
336 }
337 default: break;
338 }
339
340 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
341 myTextureBound.Nullify();
342 return aPrevTexture;
343}
344
345// =======================================================================
346// function : setTextureParams
347// purpose :
348// =======================================================================
349void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
350 const Handle(Graphic3d_TextureParams)& theParams)
351{
352 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
353 if (aParams.IsNull())
354 {
355 return;
356 }
357
358 GLint aMatrixMode = GL_TEXTURE;
359 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
360
361 // setup texture matrix
362 glMatrixMode (GL_TEXTURE);
363 glLoadIdentity();
364 const Graphic3d_Vec2& aScale = aParams->Scale();
365 const Graphic3d_Vec2& aTrans = aParams->Translation();
366 glScalef ( aScale.x(), aScale.y(), 1.0f);
367 glTranslatef (-aTrans.x(), -aTrans.y(), 0.0f);
368 glRotatef (-aParams->Rotation(), 0.0f, 0.0f, 1.0f);
369
370 // setup generation of texture coordinates
371 switch (aParams->GenMode())
372 {
373 case Graphic3d_TOTM_OBJECT:
374 {
375 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
376 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
377 if (theTexture->GetTarget() != GL_TEXTURE_1D)
378 {
379 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
380 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
381 }
382 break;
383 }
384 case Graphic3d_TOTM_SPHERE:
385 {
386 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
387 if (theTexture->GetTarget() != GL_TEXTURE_1D)
388 {
389 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
390 }
391 break;
392 }
393 case Graphic3d_TOTM_EYE:
394 {
395 glMatrixMode (GL_MODELVIEW);
396 glPushMatrix();
397 glLoadIdentity();
398
399 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
400 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
401
402 if (theTexture->GetTarget() != GL_TEXTURE_1D)
403 {
404 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
405 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
406 }
407 glPopMatrix();
408 break;
409 }
a577aaab 410 case Graphic3d_TOTM_SPRITE:
411 {
412 if (GetGlContext()->core20 != NULL)
413 {
414 glEnable (GL_POINT_SPRITE);
415 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
416 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
417 GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
418 }
419 break;
420 }
bf75be98 421 case Graphic3d_TOTM_MANUAL:
422 default: break;
423 }
424
425 // setup lighting
a577aaab 426 if (aParams->GenMode() != Graphic3d_TOTM_SPRITE)
427 {
428 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aParams->IsModulate() ? GL_MODULATE : GL_DECAL);
429 }
bf75be98 430
431 // setup texture filtering and wrapping
432 //if (theTexture->GetParams() != theParams)
433 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
434 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : GL_CLAMP;
435 switch (theTexture->GetTarget())
436 {
437 case GL_TEXTURE_1D:
438 {
439 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
440 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
441 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
442 break;
443 }
444 case GL_TEXTURE_2D:
445 {
446 GLenum aFilterMin = aFilter;
447 if (theTexture->HasMipmaps())
448 {
449 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
450 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
451 {
452 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
453 }
454 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
455 {
456 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
457 }
458
459 if (myGlContext->extAnis)
460 {
461 // setup degree of anisotropy filter
462 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
463 switch (aParams->AnisoFilter())
464 {
465 case Graphic3d_LOTA_QUALITY:
466 {
467 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aMaxDegree);
468 break;
469 }
470 case Graphic3d_LOTA_MIDDLE:
471 {
472
473 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2));
474 break;
475 }
476 case Graphic3d_LOTA_FAST:
477 {
478 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2);
479 break;
480 }
481 case Graphic3d_LOTA_OFF:
482 default:
483 {
484 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
485 break;
486 }
487 }
488 }
489 }
490 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
491 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
492 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
493 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
494 break;
495 }
496 default: break;
497 }
498
499 switch (theTexture->GetTarget())
500 {
501 case GL_TEXTURE_1D:
502 {
503 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
504 {
505 glEnable (GL_TEXTURE_GEN_S);
506 }
507 glEnable (GL_TEXTURE_1D);
508 break;
509 }
510 case GL_TEXTURE_2D:
511 {
512 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
513 {
514 glEnable (GL_TEXTURE_GEN_S);
515 glEnable (GL_TEXTURE_GEN_T);
516 }
517 glEnable (GL_TEXTURE_2D);
518 break;
519 }
520 default: break;
521 }
522
523 glMatrixMode (aMatrixMode); // turn back active matrix
524 theTexture->SetParams (aParams);
525}
526
527// =======================================================================
528// function : EnableTexture
529// purpose :
530// =======================================================================
531Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
532 const Handle(Graphic3d_TextureParams)& theParams)
533{
534 if (theTexture.IsNull() || !theTexture->IsValid())
535 {
536 return DisableTexture();
537 }
538
bca1d6e2 539 if (myTextureBound == theTexture
540 && (theParams.IsNull() || theParams == theTexture->GetParams()))
bf75be98 541 {
bca1d6e2 542 // already bound
543 return myTextureBound;
bf75be98 544 }
545
546 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
547 myTextureBound = theTexture;
548 myTextureBound->Bind (myGlContext);
549 setTextureParams (myTextureBound, theParams);
550
551 return aPrevTexture;
552}
a174a3c5 553
554// =======================================================================
555// function : Redraw
556// purpose :
557// =======================================================================
558void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
559 const Aspect_CLayer2d& theCUnderLayer,
560 const Aspect_CLayer2d& theCOverLayer)
561{
562 if (!Activate())
563 {
564 return;
565 }
566
a89742cf 567 ++myFrameCounter;
b7cd4ba7 568 myIsCullingEnabled = theCView.IsCullingEnabled;
569
a174a3c5 570 // release pending GL resources
571 Handle(OpenGl_Context) aGlCtx = GetGlContext();
572 aGlCtx->ReleaseDelayed();
573
b5ac8292 574 // fetch OpenGl context state
575 aGlCtx->FetchState();
a174a3c5 576
b5ac8292 577 Tint toSwap = (aGlCtx->IsRender()); // swap buffers
a174a3c5 578 GLint aViewPortBack[4];
579 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
580 if (aFrameBuffer != NULL)
581 {
582 glGetIntegerv (GL_VIEWPORT, aViewPortBack);
fd4a6963 583 aFrameBuffer->SetupViewport (aGlCtx);
a174a3c5 584 toSwap = 0; // no need to swap buffers
585 }
586
a89742cf 587 myToRedrawGL = Standard_True;
588 if (theCView.RenderParams.Method == Graphic3d_RM_RAYTRACING
589 && myComputeInitStatus != OpenGl_RT_FAIL)
e276548b 590 {
a89742cf 591 if (UpdateRaytraceGeometry (OpenGl_GUM_CHECK) && myIsRaytraceDataValid)
592 {
593 myToRedrawGL = Standard_False;
594
595 // Only non-raytracable structures should be rendered in OpenGL mode.
596 Handle(OpenGl_RenderFilter) aRenderFilter = GetRenderFilter();
597 myRaytraceFilter->SetPrevRenderFilter (aRenderFilter);
598 SetRenderFilter (myRaytraceFilter);
599
600 Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
601 Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
602
603 if (myOpenGlFBO.IsNull())
604 {
605 myOpenGlFBO = new OpenGl_FrameBuffer();
606 }
607 if (myOpenGlFBO->GetVPSizeX() != aSizeX
608 || myOpenGlFBO->GetVPSizeY() != aSizeY)
609 {
610 myOpenGlFBO->Init (aGlCtx, aSizeX, aSizeY);
611 }
612
613 // OverLayer and UnderLayer shouldn't be drawn by OpenGL.
614 // They will be drawn during ray-tracing.
615 Aspect_CLayer2d anEmptyCLayer;
616 anEmptyCLayer.ptrLayer = NULL;
617
618 myOpenGlFBO->BindBuffer (aGlCtx);
619 redraw1 (theCView, anEmptyCLayer, anEmptyCLayer, 0);
620 myOpenGlFBO->UnbindBuffer (aGlCtx);
621
622 const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
623 Raytrace (theCView, aSizeX, aSizeY, isImmediate ? 0 : toSwap,
624 theCOverLayer, theCUnderLayer, aFrameBuffer);
625
626 if (isImmediate)
627 {
628 RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
629 }
630
631 SetRenderFilter (aRenderFilter);
632
633 theCView.WasRedrawnGL = Standard_False;
634 }
635 }
636
637 if (myToRedrawGL)
638 {
639 // draw entire frame using normal OpenGL pipeline
640 if (aFrameBuffer != NULL)
641 {
642 aFrameBuffer->BindBuffer (aGlCtx);
643 }
644
679ecdee 645 const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
646 redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap);
647 if (isImmediate)
e276548b 648 {
679ecdee 649 RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
e276548b 650 }
651
652 theCView.WasRedrawnGL = Standard_True;
e276548b 653 }
a174a3c5 654
655 if (aFrameBuffer != NULL)
656 {
657 aFrameBuffer->UnbindBuffer (aGlCtx);
658 // move back original viewport
659 glViewport (aViewPortBack[0], aViewPortBack[1], aViewPortBack[2], aViewPortBack[3]);
660 }
661
679ecdee 662#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
a174a3c5 663 if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow))
664 {
665 GLint params[4];
666 glGetIntegerv (GL_VIEWPORT, params);
667 int nWidth = params[2] & ~0x7;
668 int nHeight = params[3] & ~0x7;
669
670 const int nBitsPerPixel = 24;
671 GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
672
673 glPixelStorei (GL_PACK_ALIGNMENT, 1);
674 glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
675 OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
676 delete[] aDumpData;
677 }
678#endif
679
680 // reset render mode state
b5ac8292 681 aGlCtx->FetchState();
a174a3c5 682}
679ecdee 683
684// =======================================================================
685// function : redraw1
686// purpose :
687// =======================================================================
688void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
689 const Aspect_CLayer2d& theCUnderLayer,
690 const Aspect_CLayer2d& theCOverLayer,
691 const int theToSwap)
692{
73192b37 693 if (myView.IsNull())
679ecdee 694 {
695 return;
696 }
697
698 // request reset of material
699 NamedStatus |= OPENGL_NS_RESMAT;
700
679ecdee 701 GLbitfield toClear = GL_COLOR_BUFFER_BIT;
702 if (myUseZBuffer)
703 {
704 glDepthFunc (GL_LEQUAL);
705 glDepthMask (GL_TRUE);
706 if (myUseDepthTest)
707 {
708 glEnable (GL_DEPTH_TEST);
709 }
710 else
711 {
712 glDisable (GL_DEPTH_TEST);
713 }
714
715 glClearDepth (1.0);
716 toClear |= GL_DEPTH_BUFFER_BIT;
717 }
718 else
719 {
720 glDisable (GL_DEPTH_TEST);
721 }
722
a89742cf 723 if (!ToRedrawGL())
679ecdee 724 {
a89742cf 725 // set background to black
726 glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
727 toClear |= GL_DEPTH_BUFFER_BIT; //
679ecdee 728 }
729 else
730 {
a89742cf 731 if (NamedStatus & OPENGL_NS_WHITEBACK)
732 {
733 // set background to white
734 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
735 toClear |= GL_DEPTH_BUFFER_BIT;
736 }
737 else
738 {
739 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
740 }
679ecdee 741 }
742 glClear (toClear);
743
744 Handle(OpenGl_Workspace) aWS (this);
745 myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer);
746
747 // swap the buffers
748 if (theToSwap)
749 {
750 GetGlContext()->SwapBuffers();
751 myBackBufferRestored = Standard_False;
752 myIsImmediateDrawn = Standard_False;
753 }
754 else
755 {
a89742cf 756 glFlush(); //
757 myBackBufferRestored = Standard_True;//
758 myIsImmediateDrawn = Standard_False;//
679ecdee 759 }
760}
761
762// =======================================================================
763// function : copyBackToFront
764// purpose :
765// =======================================================================
766void OpenGl_Workspace::copyBackToFront()
767{
768 glMatrixMode (GL_PROJECTION);
769 glPushMatrix();
770 glLoadIdentity();
771 gluOrtho2D (0.0, (GLdouble )myWidth, 0.0, (GLdouble )myHeight);
772 glMatrixMode (GL_MODELVIEW);
773 glPushMatrix();
774 glLoadIdentity();
775
776 DisableFeatures();
777
778 glDrawBuffer (GL_FRONT);
779 glReadBuffer (GL_BACK);
780
781 glRasterPos2i (0, 0);
782 glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR);
783
784 EnableFeatures();
785
786 glMatrixMode (GL_PROJECTION);
787 glPopMatrix();
788 glMatrixMode (GL_MODELVIEW);
789 glPopMatrix();
790
791 glDrawBuffer (GL_BACK);
792
793 myIsImmediateDrawn = Standard_False;
794}
795
796// =======================================================================
797// function : DisplayCallback
798// purpose :
799// =======================================================================
800void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
801 Standard_Integer theReason)
802{
803 if (theCView.GDisplayCB == NULL)
804 {
805 return;
806 }
807
808 Aspect_GraphicCallbackStruct aCallData;
809 aCallData.reason = theReason;
810 aCallData.glContext = GetGlContext();
811 aCallData.wsID = theCView.WsId;
812 aCallData.viewID = theCView.ViewId;
813 theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
814}
815
816// =======================================================================
817// function : RedrawImmediate
818// purpose :
819// =======================================================================
820void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
821 const Aspect_CLayer2d& theCUnderLayer,
822 const Aspect_CLayer2d& theCOverLayer,
823 const Standard_Boolean theToForce)
824{
825 if (!Activate())
826 {
827 return;
828 }
829
830 GLboolean isDoubleBuffer = GL_FALSE;
831 glGetBooleanv (GL_DOUBLEBUFFER, &isDoubleBuffer);
832 if (myView->ImmediateStructures().IsEmpty())
833 {
834 if (theToForce
835 || !myIsImmediateDrawn)
836 {
837 myIsImmediateDrawn = Standard_False;
838 return;
839 }
840
841 if (myBackBufferRestored
842 && isDoubleBuffer)
843 {
844 copyBackToFront();
65812bd0 845 glFlush();
679ecdee 846 }
847 else
848 {
849 Redraw (theCView, theCUnderLayer, theCOverLayer);
850 }
851 return;
852 }
853
854 if (isDoubleBuffer && myTransientDrawToFront)
855 {
856 if (!myBackBufferRestored)
857 {
858 Redraw (theCView, theCUnderLayer, theCOverLayer);
859 return;
860 }
861 copyBackToFront();
862 MakeFrontBufCurrent();
863 }
864 else
865 {
866 myBackBufferRestored = Standard_False;
867 }
868 myIsImmediateDrawn = Standard_True;
869
870 NamedStatus |= OPENGL_NS_IMMEDIATE;
871 ///glDisable (GL_LIGHTING);
872 glDisable (GL_DEPTH_TEST);
873
874 Handle(OpenGl_Workspace) aWS (this);
875 for (OpenGl_SequenceOfStructure::Iterator anIter (myView->ImmediateStructures());
876 anIter.More(); anIter.Next())
877 {
878 const OpenGl_Structure* aStructure = anIter.Value();
879 aStructure->Render (aWS);
880 }
881
882 NamedStatus &= ~OPENGL_NS_IMMEDIATE;
883
884 if (isDoubleBuffer && myTransientDrawToFront)
885 {
886 glFlush();
887 MakeBackBufCurrent();
888 }
889}