0026273: Comments to methods are misplaced in gp_Vec.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
a577aaab 16#include <OpenGl_GlCore15.hxx>
b86bb3df 17#include <OpenGl_ArbFBO.hxx>
5f8b738e 18
2166f0fa
SK
19#include <InterfaceGraphic.hxx>
20
2166f0fa
SK
21#include <OpenGl_AspectLine.hxx>
22#include <OpenGl_AspectFace.hxx>
23#include <OpenGl_AspectMarker.hxx>
24#include <OpenGl_AspectText.hxx>
bf75be98 25#include <OpenGl_Context.hxx>
679ecdee 26#include <OpenGl_Element.hxx>
a174a3c5 27#include <OpenGl_FrameBuffer.hxx>
679ecdee 28#include <OpenGl_Structure.hxx>
25ef750e 29#include <OpenGl_Sampler.hxx>
b86bb3df 30#include <OpenGl_ShaderManager.hxx>
bf75be98 31#include <OpenGl_Texture.hxx>
c827ea3a 32#include <OpenGl_Utils.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
0adbd30f 70// =======================================================================
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
2166f0fa
SK
136// =======================================================================
137// function : OpenGl_Workspace
138// purpose :
139// =======================================================================
25b97fac 140OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_GraphicDriver)& theDriver,
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)
25b97fac 145: OpenGl_Window (theDriver, theCWindow, theGContext, theCaps, theShareCtx),
a174a3c5 146 NamedStatus (0),
0adbd30f 147 HighlightColor (&THE_WHITE_COLOR),
a174a3c5 148 //
ee51a9fe 149 myHasFboBlit (Standard_True),
fc73a202 150 //
a272ed94 151 myViewId (-1),
73192b37 152 myAntiAliasingMode (3),
a174a3c5 153 myTransientDrawToFront (Standard_True),
679ecdee 154 myBackBufferRestored (Standard_False),
155 myIsImmediateDrawn (Standard_False),
eae454e3 156 myUseZBuffer (Standard_True),
157 myUseDepthWrite (Standard_True),
2166f0fa 158 myUseGLLight (Standard_True),
b7cd4ba7 159 myIsCullingEnabled (Standard_False),
a89742cf 160 myFrameCounter (0),
2166f0fa 161 //
2166f0fa
SK
162 AspectLine_set (&myDefaultAspectLine),
163 AspectLine_applied (NULL),
164 AspectFace_set (&myDefaultAspectFace),
165 AspectFace_applied (NULL),
166 AspectMarker_set (&myDefaultAspectMarker),
167 AspectMarker_applied (NULL),
168 AspectText_set (&myDefaultAspectText),
169 AspectText_applied (NULL),
170 TextParam_set (&myDefaultTextParam),
171 TextParam_applied (NULL),
172 ViewMatrix_applied (&myDefaultMatrix),
173 StructureMatrix_applied (&myDefaultMatrix),
3b1817a9 174 myCullingMode (TelCullUndefined),
0f8c0fb8 175 myModelViewMatrix (myDefaultMatrix),
550f3b8b 176 PolygonOffset_applied (THE_DEFAULT_POFFSET)
2166f0fa 177{
73192b37 178 myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
38a0206f 179 myMainSceneFbos[0] = new OpenGl_FrameBuffer();
180 myMainSceneFbos[1] = new OpenGl_FrameBuffer();
181 myImmediateSceneFbos[0] = new OpenGl_FrameBuffer();
182 myImmediateSceneFbos[1] = new OpenGl_FrameBuffer();
73192b37 183
184 if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
185 {
186 // share and register for release once the resource is no longer used
187 myLineAttribs = new OpenGl_LineAttributes();
188 myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs);
189 myLineAttribs->Init (myGlContext);
190 }
2166f0fa
SK
191
192 // General initialization of the context
193
ca3c13d1 194#if !defined(GL_ES_VERSION_2_0)
4e1523ef 195 if (myGlContext->core11 != NULL)
196 {
197 // Eviter d'avoir les faces mal orientees en noir.
198 // Pourrait etre utiliser pour detecter les problemes d'orientation
199 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
200
201 // Optimisation pour le Fog et l'antialiasing
202 glHint (GL_FOG_HINT, GL_FASTEST);
203 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
204 }
2166f0fa 205
2166f0fa
SK
206 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
207 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
ca3c13d1 208#endif
2166f0fa 209
73192b37 210 // AA mode
211 const char* anAaEnv = ::getenv ("CALL_OPENGL_ANTIALIASING_MODE");
212 if (anAaEnv != NULL)
213 {
214 int v;
215 if (sscanf (anAaEnv, "%d", &v) > 0) myAntiAliasingMode = v;
216 }
2166f0fa
SK
217}
218
1981cb22 219// =======================================================================
220// function : SetImmediateModeDrawToFront
221// purpose :
222// =======================================================================
223Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
224{
225 const Standard_Boolean aPrevMode = myTransientDrawToFront;
226 myTransientDrawToFront = theDrawToFrontBuffer;
227 return aPrevMode;
228}
229
38a0206f 230inline void nullifyGlResource (Handle(OpenGl_Resource)& theResource,
231 const Handle(OpenGl_Context)& theCtx)
232{
233 if (!theResource.IsNull())
234 {
235 theResource->Release (theCtx.operator->());
236 theResource.Nullify();
237 }
238}
239
2166f0fa
SK
240// =======================================================================
241// function : ~OpenGl_Workspace
242// purpose :
243// =======================================================================
244OpenGl_Workspace::~OpenGl_Workspace()
245{
73192b37 246 if (!myLineAttribs.IsNull())
247 {
248 myLineAttribs.Nullify();
249 myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
250 }
251
38a0206f 252 nullifyGlResource (myMainSceneFbos[0], myGlContext);
253 nullifyGlResource (myMainSceneFbos[1], myGlContext);
254 nullifyGlResource (myImmediateSceneFbos[0], myGlContext);
255 nullifyGlResource (myImmediateSceneFbos[1], myGlContext);
256
257 myFullScreenQuad.Release (myGlContext.operator->());
2166f0fa
SK
258}
259
260// =======================================================================
261// function : Activate
262// purpose :
263// =======================================================================
264Standard_Boolean OpenGl_Workspace::Activate()
265{
266 if (!OpenGl_Window::Activate())
267 return Standard_False;
268
2166f0fa
SK
269 ViewMatrix_applied = &myDefaultMatrix;
270 StructureMatrix_applied = &myDefaultMatrix;
26395493 271
272 ResetAppliedAspect();
273
274 return Standard_True;
2166f0fa
SK
275}
276
26395493 277//=======================================================================
278//function : ResetAppliedAspect
279//purpose : Sets default values of GL parameters in accordance with default aspects
280//=======================================================================
281void OpenGl_Workspace::ResetAppliedAspect()
282{
4e1523ef 283 myGlContext->BindDefaultVao();
284
bf75be98 285 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
0adbd30f 286 HighlightColor = &THE_WHITE_COLOR;
26395493 287 AspectLine_set = &myDefaultAspectLine;
288 AspectLine_applied = NULL;
289 AspectFace_set = &myDefaultAspectFace;
290 AspectFace_applied = NULL;
291 AspectMarker_set = &myDefaultAspectMarker;
292 AspectMarker_applied = NULL;
293 AspectText_set = &myDefaultAspectText;
294 AspectText_applied = NULL;
295 TextParam_set = &myDefaultTextParam;
296 TextParam_applied = NULL;
550f3b8b 297 PolygonOffset_applied = THE_DEFAULT_POFFSET;
3b1817a9 298 myCullingMode = TelCullUndefined;
26395493 299
300 AspectLine(Standard_True);
301 AspectFace(Standard_True);
302 AspectMarker(Standard_True);
303 AspectText(Standard_True);
ac116c22 304
305 myGlContext->SetTypeOfLine (myDefaultAspectLine.Type());
306 myGlContext->SetLineWidth (myDefaultAspectLine.Width());
26395493 307}
bf75be98 308
309// =======================================================================
310// function : DisableTexture
311// purpose :
312// =======================================================================
313Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
314{
315 if (myTextureBound.IsNull())
316 {
317 return myTextureBound;
318 }
319
e3414ada 320 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
321 if (!aSampler.IsNull())
322 {
323 aSampler->Unbind (*myGlContext);
324 }
325
ca3c13d1 326#if !defined(GL_ES_VERSION_2_0)
bf75be98 327 // reset texture matrix because some code may expect it is identity
4e1523ef 328 if (myGlContext->core11 != NULL)
329 {
330 GLint aMatrixMode = GL_TEXTURE;
331 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
332 glMatrixMode (GL_TEXTURE);
333 glLoadIdentity();
334 glMatrixMode (aMatrixMode);
335 }
ca3c13d1 336#endif
bf75be98 337
338 myTextureBound->Unbind (myGlContext);
339 switch (myTextureBound->GetTarget())
340 {
ca3c13d1 341 #if !defined(GL_ES_VERSION_2_0)
bf75be98 342 case GL_TEXTURE_1D:
343 {
4e1523ef 344 if (myGlContext->core11 != NULL)
bf75be98 345 {
4e1523ef 346 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
347 {
348 glDisable (GL_TEXTURE_GEN_S);
349 }
350 glDisable (GL_TEXTURE_1D);
bf75be98 351 }
bf75be98 352 break;
353 }
ca3c13d1 354 #endif
bf75be98 355 case GL_TEXTURE_2D:
356 {
ca3c13d1 357 #if !defined(GL_ES_VERSION_2_0)
4e1523ef 358 if (myGlContext->core11 != NULL)
bf75be98 359 {
4e1523ef 360 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
a577aaab 361 {
4e1523ef 362 glDisable (GL_TEXTURE_GEN_S);
363 glDisable (GL_TEXTURE_GEN_T);
364 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
365 {
366 glDisable (GL_POINT_SPRITE);
367 }
a577aaab 368 }
4e1523ef 369 glDisable (GL_TEXTURE_2D);
bf75be98 370 }
05e2200b 371 #endif
bf75be98 372 break;
373 }
374 default: break;
375 }
376
377 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
378 myTextureBound.Nullify();
379 return aPrevTexture;
380}
381
382// =======================================================================
383// function : setTextureParams
384// purpose :
385// =======================================================================
386void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
387 const Handle(Graphic3d_TextureParams)& theParams)
388{
389 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
390 if (aParams.IsNull())
391 {
392 return;
393 }
394
ca3c13d1 395#if !defined(GL_ES_VERSION_2_0)
bf75be98 396 GLint aMatrixMode = GL_TEXTURE;
4e1523ef 397 if (myGlContext->core11 != NULL)
398 {
399 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
400
401 // setup texture matrix
402 glMatrixMode (GL_TEXTURE);
403 OpenGl_Mat4 aTextureMat;
404 const Graphic3d_Vec2& aScale = aParams->Scale();
405 const Graphic3d_Vec2& aTrans = aParams->Translation();
406 OpenGl_Utils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f);
407 OpenGl_Utils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
408 OpenGl_Utils::Rotate (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f);
409 glLoadMatrixf (aTextureMat);
410
411 GLint anEnvMode = GL_MODULATE; // lighting mode
412 if (!aParams->IsModulate())
076ca35c 413 {
4e1523ef 414 anEnvMode = GL_DECAL;
415 if (theTexture->GetFormat() == GL_ALPHA
416 || theTexture->GetFormat() == GL_LUMINANCE)
417 {
418 anEnvMode = GL_REPLACE;
419 }
076ca35c 420 }
076ca35c 421
4e1523ef 422 // setup generation of texture coordinates
423 switch (aParams->GenMode())
bf75be98 424 {
4e1523ef 425 case Graphic3d_TOTM_OBJECT:
bf75be98 426 {
4e1523ef 427 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
428 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
429 if (theTexture->GetTarget() != GL_TEXTURE_1D)
430 {
431 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
432 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
433 }
434 break;
bf75be98 435 }
4e1523ef 436 case Graphic3d_TOTM_SPHERE:
bf75be98 437 {
4e1523ef 438 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
439 if (theTexture->GetTarget() != GL_TEXTURE_1D)
440 {
441 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
442 }
443 break;
bf75be98 444 }
4e1523ef 445 case Graphic3d_TOTM_EYE:
446 {
447 myGlContext->WorldViewState.Push();
c827ea3a 448
4e1523ef 449 myGlContext->WorldViewState.SetIdentity();
450 myGlContext->ApplyWorldViewMatrix();
bf75be98 451
4e1523ef 452 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
453 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
bf75be98 454
4e1523ef 455 if (theTexture->GetTarget() != GL_TEXTURE_1D)
456 {
457 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
458 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
459 }
c827ea3a 460
4e1523ef 461 myGlContext->WorldViewState.Pop();
c827ea3a 462
4e1523ef 463 break;
464 }
465 case Graphic3d_TOTM_SPRITE:
a577aaab 466 {
4e1523ef 467 if (GetGlContext()->core20fwd != NULL)
468 {
469 glEnable (GL_POINT_SPRITE);
470 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
471 anEnvMode = GL_REPLACE;
472 GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
473 }
474 break;
a577aaab 475 }
4e1523ef 476 case Graphic3d_TOTM_MANUAL:
477 default: break;
a577aaab 478 }
bf75be98 479
4e1523ef 480 // setup lighting
481 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
482 }
ca3c13d1 483#endif
bf75be98 484
25ef750e 485 // get active sampler object to override default texture parameters
486 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
487
bf75be98 488 // setup texture filtering and wrapping
489 //if (theTexture->GetParams() != theParams)
490 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
ca3c13d1 491 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
bf75be98 492 switch (theTexture->GetTarget())
493 {
ca3c13d1 494 #if !defined(GL_ES_VERSION_2_0)
bf75be98 495 case GL_TEXTURE_1D:
496 {
25ef750e 497 if (aSampler.IsNull() || !aSampler->IsValid())
498 {
499 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
500 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
501 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
502 }
503 else
504 {
505 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
506 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
507 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
508 }
509
bf75be98 510 break;
511 }
ca3c13d1 512 #endif
bf75be98 513 case GL_TEXTURE_2D:
514 {
515 GLenum aFilterMin = aFilter;
516 if (theTexture->HasMipmaps())
517 {
518 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
519 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
520 {
521 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
522 }
523 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
524 {
525 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
526 }
527
528 if (myGlContext->extAnis)
529 {
530 // setup degree of anisotropy filter
531 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
25ef750e 532 GLint aDegree;
bf75be98 533 switch (aParams->AnisoFilter())
534 {
535 case Graphic3d_LOTA_QUALITY:
536 {
25ef750e 537 aDegree = aMaxDegree;
bf75be98 538 break;
539 }
540 case Graphic3d_LOTA_MIDDLE:
541 {
25ef750e 542 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
bf75be98 543 break;
544 }
545 case Graphic3d_LOTA_FAST:
546 {
25ef750e 547 aDegree = 2;
bf75be98 548 break;
549 }
550 case Graphic3d_LOTA_OFF:
551 default:
552 {
25ef750e 553 aDegree = 1;
bf75be98 554 break;
555 }
556 }
25ef750e 557
558 if (aSampler.IsNull() || !aSampler->IsValid())
559 {
560 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
561 }
562 else
563 {
564 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
565 }
bf75be98 566 }
567 }
25ef750e 568
569 if (aSampler.IsNull() || !aSampler->IsValid())
570 {
571 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
572 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
573 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
574 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
575 }
576 else
577 {
578 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
579 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
580 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
581 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
582 }
583
bf75be98 584 break;
585 }
586 default: break;
587 }
588
589 switch (theTexture->GetTarget())
590 {
ca3c13d1 591 #if !defined(GL_ES_VERSION_2_0)
bf75be98 592 case GL_TEXTURE_1D:
593 {
4e1523ef 594 if (myGlContext->core11 != NULL)
bf75be98 595 {
4e1523ef 596 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
597 {
598 glEnable (GL_TEXTURE_GEN_S);
599 }
600 glEnable (GL_TEXTURE_1D);
bf75be98 601 }
bf75be98 602 break;
603 }
ca3c13d1 604 #endif
bf75be98 605 case GL_TEXTURE_2D:
606 {
ca3c13d1 607 #if !defined(GL_ES_VERSION_2_0)
4e1523ef 608 if (myGlContext->core11 != NULL)
bf75be98 609 {
4e1523ef 610 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
611 {
612 glEnable (GL_TEXTURE_GEN_S);
613 glEnable (GL_TEXTURE_GEN_T);
614 }
615 glEnable (GL_TEXTURE_2D);
bf75be98 616 }
05e2200b 617 #endif
bf75be98 618 break;
619 }
620 default: break;
621 }
622
ca3c13d1 623#if !defined(GL_ES_VERSION_2_0)
4e1523ef 624 if (myGlContext->core11 != NULL)
625 {
626 glMatrixMode (aMatrixMode); // turn back active matrix
627 }
ca3c13d1 628#endif
bf75be98 629 theTexture->SetParams (aParams);
630}
631
632// =======================================================================
633// function : EnableTexture
634// purpose :
635// =======================================================================
636Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
637 const Handle(Graphic3d_TextureParams)& theParams)
638{
639 if (theTexture.IsNull() || !theTexture->IsValid())
640 {
641 return DisableTexture();
642 }
643
bca1d6e2 644 if (myTextureBound == theTexture
645 && (theParams.IsNull() || theParams == theTexture->GetParams()))
bf75be98 646 {
bca1d6e2 647 // already bound
648 return myTextureBound;
bf75be98 649 }
650
651 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
652 myTextureBound = theTexture;
653 myTextureBound->Bind (myGlContext);
654 setTextureParams (myTextureBound, theParams);
655
25ef750e 656 // If custom sampler object is available it will be
657 // used for overriding default texture parameters
658 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
659
660 if (!aSampler.IsNull() && aSampler->IsValid())
661 {
662 aSampler->Bind (*myGlContext);
663 }
664
bf75be98 665 return aPrevTexture;
666}
a174a3c5 667
38a0206f 668// =======================================================================
669// function : bindDefaultFbo
670// purpose :
671// =======================================================================
672void OpenGl_Workspace::bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo)
673{
674 OpenGl_FrameBuffer* anFbo = (theCustomFbo != NULL && theCustomFbo->IsValid())
675 ? theCustomFbo
676 : (!myGlContext->DefaultFrameBuffer().IsNull()
677 && myGlContext->DefaultFrameBuffer()->IsValid()
678 ? myGlContext->DefaultFrameBuffer().operator->()
679 : NULL);
680 if (anFbo != NULL)
681 {
682 anFbo->BindBuffer (myGlContext);
683 }
684 else
685 {
686 #if !defined(GL_ES_VERSION_2_0)
687 myGlContext->SetReadDrawBuffer (GL_BACK);
688 #else
689 if (myGlContext->arbFBO != NULL)
690 {
691 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
692 }
693 #endif
694 }
695 myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
696}
697
698// =======================================================================
699// function : blitBuffers
700// purpose :
701// =======================================================================
702bool OpenGl_Workspace::blitBuffers (OpenGl_FrameBuffer* theReadFbo,
703 OpenGl_FrameBuffer* theDrawFbo)
704{
705 if (theReadFbo == NULL)
706 {
707 return false;
708 }
709
710 // clear destination before blitting
711 if (theDrawFbo != NULL
712 && theDrawFbo->IsValid())
713 {
714 theDrawFbo->BindBuffer (myGlContext);
715 }
716 else
717 {
718 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
719 }
720#if !defined(GL_ES_VERSION_2_0)
721 myGlContext->core20fwd->glClearDepth (1.0);
722#else
723 myGlContext->core20fwd->glClearDepthf (1.0f);
724#endif
725 myGlContext->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
726
727/*#if !defined(GL_ES_VERSION_2_0)
728 if (myGlContext->arbFBOBlit != NULL)
729 {
730 theReadFbo->BindReadBuffer (myGlContext);
731 if (theDrawFbo != NULL
732 && theDrawFbo->IsValid())
733 {
734 theDrawFbo->BindDrawBuffer (myGlContext);
735 }
736 else
737 {
738 myGlContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
739 }
740 // we don't copy stencil buffer here... does it matter for performance?
741 myGlContext->arbFBOBlit->glBlitFramebuffer (0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
742 0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
743 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
744
745 if (theDrawFbo != NULL
746 && theDrawFbo->IsValid())
747 {
748 theDrawFbo->BindBuffer (myGlContext);
749 }
750 else
751 {
752 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
753 }
754 }
755 else
756#endif*/
757 {
758 myGlContext->core20fwd->glDepthFunc (GL_ALWAYS);
759 myGlContext->core20fwd->glDepthMask (GL_TRUE);
760 myGlContext->core20fwd->glEnable (GL_DEPTH_TEST);
761
762 DisableTexture();
763 if (!myFullScreenQuad.IsValid())
764 {
765 OpenGl_Vec4 aQuad[4] =
766 {
767 OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f),
768 OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f),
769 OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f),
770 OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f)
771 };
772 myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData());
773 }
774
775 const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager();
776 if (myFullScreenQuad.IsValid()
777 && aManager->BindFboBlitProgram())
778 {
779 theReadFbo->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0);
780 theReadFbo->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
fe3a29bc 781 myFullScreenQuad.BindVertexAttrib (myGlContext, Graphic3d_TOA_POS);
38a0206f 782
783 myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
784
fe3a29bc 785 myFullScreenQuad.UnbindVertexAttrib (myGlContext, Graphic3d_TOA_POS);
38a0206f 786 theReadFbo->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
787 theReadFbo->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0);
788 }
789 else
790 {
791 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
792 + "Error! FBO blitting has failed";
793 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
794 GL_DEBUG_TYPE_ERROR_ARB,
795 0,
796 GL_DEBUG_SEVERITY_HIGH_ARB,
797 aMsg);
798 myHasFboBlit = Standard_False;
799 theReadFbo->Release (myGlContext.operator->());
800 return true;
801 }
802 }
803 return true;
804}
805
806// =======================================================================
807// function : drawStereoPair
808// purpose :
809// =======================================================================
810void OpenGl_Workspace::drawStereoPair()
811{
812 OpenGl_FrameBuffer* aPair[2] =
813 {
814 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
815 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
816 };
817 if (aPair[0] == NULL
818 || aPair[1] == NULL)
819 {
820 aPair[0] = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
821 aPair[1] = myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL;
822 }
823
824 if (aPair[0] == NULL
825 || aPair[1] == NULL)
826 {
827 return;
828 }
829
830 myGlContext->core20fwd->glDepthFunc (GL_ALWAYS);
831 myGlContext->core20fwd->glDepthMask (GL_TRUE);
832 myGlContext->core20fwd->glEnable (GL_DEPTH_TEST);
833
834 DisableTexture();
835 if (!myFullScreenQuad.IsValid())
836 {
837 OpenGl_Vec4 aQuad[4] =
838 {
839 OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f),
840 OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f),
841 OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f),
842 OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f)
843 };
844 myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData());
845 }
846
847 const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager();
848 if (myFullScreenQuad.IsValid()
849 && aManager->BindAnaglyphProgram())
850 {
851 aPair[0]->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + 0);
852 aPair[1]->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
853 myFullScreenQuad.BindVertexAttrib (myGlContext, 0);
854
855 myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
856
857 myFullScreenQuad.UnbindVertexAttrib (myGlContext, 0);
858 aPair[1]->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
859 aPair[0]->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + 0);
860 }
861 else
862 {
863 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
864 + "Error! Anaglyph has failed";
865 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
866 GL_DEBUG_TYPE_ERROR_ARB,
867 0,
868 GL_DEBUG_SEVERITY_HIGH_ARB,
869 aMsg);
870 }
871}
872
a174a3c5 873// =======================================================================
874// function : Redraw
875// purpose :
876// =======================================================================
877void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
878 const Aspect_CLayer2d& theCUnderLayer,
879 const Aspect_CLayer2d& theCOverLayer)
880{
881 if (!Activate())
882 {
883 return;
884 }
885
a89742cf 886 ++myFrameCounter;
b7cd4ba7 887 myIsCullingEnabled = theCView.IsCullingEnabled;
888
a174a3c5 889 // release pending GL resources
ee51a9fe 890 myGlContext->ReleaseDelayed();
a174a3c5 891
b5ac8292 892 // fetch OpenGl context state
ee51a9fe 893 myGlContext->FetchState();
a174a3c5 894
a174a3c5 895 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
ee51a9fe 896 bool toSwap = myGlContext->IsRender()
897 && !myGlContext->caps->buffersNoSwap
898 && aFrameBuffer == NULL;
a174a3c5 899
b86bb3df 900 Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
901 Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
902
38a0206f 903 if ( aFrameBuffer == NULL
904 && !myGlContext->DefaultFrameBuffer().IsNull()
905 && myGlContext->DefaultFrameBuffer()->IsValid())
a2e4f780 906 {
38a0206f 907 aFrameBuffer = myGlContext->DefaultFrameBuffer().operator->();
a2e4f780 908 }
909
ee51a9fe 910 if (myHasFboBlit
911 && myTransientDrawToFront)
b86bb3df 912 {
38a0206f 913 if (myMainSceneFbos[0]->GetVPSizeX() != aSizeX
914 || myMainSceneFbos[0]->GetVPSizeY() != aSizeY)
760c21c2 915 {
ee51a9fe 916 // prepare FBOs containing main scene
917 // for further blitting and rendering immediate presentations on top
918 if (myGlContext->core20fwd != NULL)
919 {
38a0206f 920 myMainSceneFbos[0]->Init (myGlContext, aSizeX, aSizeY);
ee51a9fe 921 }
922 }
b86bb3df 923 }
ee51a9fe 924 else
b86bb3df 925 {
38a0206f 926 myMainSceneFbos [0]->Release (myGlContext.operator->());
927 myMainSceneFbos [1]->Release (myGlContext.operator->());
928 myImmediateSceneFbos[0]->Release (myGlContext.operator->());
929 myImmediateSceneFbos[1]->Release (myGlContext.operator->());
930 myMainSceneFbos [0]->ChangeViewport (0, 0);
931 myMainSceneFbos [1]->ChangeViewport (0, 0);
932 myImmediateSceneFbos[0]->ChangeViewport (0, 0);
933 myImmediateSceneFbos[1]->ChangeViewport (0, 0);
b86bb3df 934 }
935
91c60b57 936 // draw entire frame using normal OpenGL pipeline
38a0206f 937 const Handle(Graphic3d_Camera)& aCamera = myView->Camera();
938 Graphic3d_Camera::Projection aProjectType = aCamera->ProjectionType();
939 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
a89742cf 940 {
38a0206f 941 if (aFrameBuffer != NULL
942 || !myGlContext->IsRender())
943 {
944 // implicitly switch to mono camera for image dump
945 aProjectType = Graphic3d_Camera::Projection_Perspective;
946 }
947 else if (myMainSceneFbos[0]->IsValid())
948 {
949 myMainSceneFbos[1]->InitLazy (myGlContext, aSizeX, aSizeY);
950 if (!myMainSceneFbos[1]->IsValid())
951 {
952 // no enough memory?
953 aProjectType = Graphic3d_Camera::Projection_Perspective;
954 }
955 else if (!myGlContext->HasStereoBuffers())
956 {
957 myImmediateSceneFbos[0]->InitLazy (myGlContext, aSizeX, aSizeY);
958 myImmediateSceneFbos[1]->InitLazy (myGlContext, aSizeX, aSizeY);
959 if (!myImmediateSceneFbos[0]->IsValid()
960 || !myImmediateSceneFbos[1]->IsValid())
961 {
962 aProjectType = Graphic3d_Camera::Projection_Perspective;
963 }
964 }
965 }
91c60b57 966 }
e276548b 967
38a0206f 968 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
91c60b57 969 {
38a0206f 970 OpenGl_FrameBuffer* aMainFbos[2] =
971 {
972 myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL,
973 myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL
974 };
975 OpenGl_FrameBuffer* anImmFbos[2] =
976 {
977 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
978 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
979 };
a174a3c5 980
38a0206f 981 #if !defined(GL_ES_VERSION_2_0)
982 myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
983 #endif
984 redraw1 (theCView, theCUnderLayer, theCOverLayer,
985 aMainFbos[0], Graphic3d_Camera::Projection_MonoLeftEye);
986 myBackBufferRestored = Standard_True;
987 myIsImmediateDrawn = Standard_False;
988 #if !defined(GL_ES_VERSION_2_0)
989 myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
990 #endif
991 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbos[0], aProjectType, anImmFbos[0]))
992 {
993 toSwap = false;
994 }
995
996 #if !defined(GL_ES_VERSION_2_0)
997 myGlContext->SetReadDrawBuffer (GL_BACK_RIGHT);
998 #endif
999 redraw1 (theCView, theCUnderLayer, theCOverLayer,
1000 aMainFbos[1], Graphic3d_Camera::Projection_MonoRightEye);
1001 myBackBufferRestored = Standard_True;
1002 myIsImmediateDrawn = Standard_False;
1003 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbos[1], aProjectType, anImmFbos[1]))
1004 {
1005 toSwap = false;
1006 }
1007
1008 if (anImmFbos[0] != NULL)
1009 {
1010 bindDefaultFbo (aFrameBuffer);
1011 drawStereoPair();
1012 }
1013 }
1014 else
a174a3c5 1015 {
38a0206f 1016 OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
1017 #if !defined(GL_ES_VERSION_2_0)
1018 if (aMainFbo == NULL
1019 && aFrameBuffer == NULL)
1020 {
1021 myGlContext->SetReadDrawBuffer (GL_BACK);
1022 }
1023 #endif
1024 redraw1 (theCView, theCUnderLayer, theCOverLayer,
1025 aMainFbo != NULL ? aMainFbo : aFrameBuffer, aProjectType);
1026 myBackBufferRestored = Standard_True;
1027 myIsImmediateDrawn = Standard_False;
1028 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbo, aProjectType, aFrameBuffer))
1029 {
1030 toSwap = false;
1031 }
a174a3c5 1032 }
1033
679ecdee 1034#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
a174a3c5 1035 if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow))
1036 {
1037 GLint params[4];
1038 glGetIntegerv (GL_VIEWPORT, params);
1039 int nWidth = params[2] & ~0x7;
1040 int nHeight = params[3] & ~0x7;
1041
1042 const int nBitsPerPixel = 24;
1043 GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
1044
1045 glPixelStorei (GL_PACK_ALIGNMENT, 1);
1046 glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
1047 OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
1048 delete[] aDumpData;
1049 }
1050#endif
1051
38a0206f 1052 // bind default FBO
1053 bindDefaultFbo();
1054
ee51a9fe 1055 // Swap the buffers
1056 if (toSwap)
1057 {
1058 GetGlContext()->SwapBuffers();
38a0206f 1059 if (!myMainSceneFbos[0]->IsValid())
ee51a9fe 1060 {
1061 myBackBufferRestored = Standard_False;
1062 }
1063 }
1064 else
1065 {
1066 myGlContext->core11fwd->glFlush();
1067 }
1068
a174a3c5 1069 // reset render mode state
ee51a9fe 1070 myGlContext->FetchState();
a174a3c5 1071}
679ecdee 1072
1073// =======================================================================
1074// function : redraw1
1075// purpose :
1076// =======================================================================
38a0206f 1077void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
1078 const Aspect_CLayer2d& theCUnderLayer,
1079 const Aspect_CLayer2d& theCOverLayer,
1080 OpenGl_FrameBuffer* theReadDrawFbo,
1081 const Graphic3d_Camera::Projection theProjection)
679ecdee 1082{
73192b37 1083 if (myView.IsNull())
679ecdee 1084 {
1085 return;
1086 }
1087
38a0206f 1088 if (theReadDrawFbo != NULL)
1089 {
1090 theReadDrawFbo->BindBuffer (myGlContext);
1091 theReadDrawFbo->SetupViewport (myGlContext);
1092 }
1093 else
1094 {
1095 myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
1096 }
1097
679ecdee 1098 // request reset of material
1099 NamedStatus |= OPENGL_NS_RESMAT;
1100
eae454e3 1101 myUseZBuffer = Standard_True;
1102 myUseDepthWrite = Standard_True;
1103 GLbitfield toClear = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
1104 glDepthFunc (GL_LEQUAL);
1105 glDepthMask (GL_TRUE);
1106 glEnable (GL_DEPTH_TEST);
679ecdee 1107
eae454e3 1108#if !defined(GL_ES_VERSION_2_0)
1109 glClearDepth (1.0);
1110#else
1111 glClearDepthf (1.0f);
1112#endif
679ecdee 1113
91c60b57 1114 if (NamedStatus & OPENGL_NS_WHITEBACK)
679ecdee 1115 {
91c60b57 1116 // set background to white
1117 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
679ecdee 1118 }
1119 else
1120 {
91c60b57 1121 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
679ecdee 1122 }
91c60b57 1123
679ecdee 1124 glClear (toClear);
1125
1126 Handle(OpenGl_Workspace) aWS (this);
38a0206f 1127 myView->Render (myPrintContext, aWS, theReadDrawFbo, theProjection, theCView, theCUnderLayer, theCOverLayer, Standard_False);
679ecdee 1128}
1129
1130// =======================================================================
1131// function : copyBackToFront
1132// purpose :
1133// =======================================================================
1134void OpenGl_Workspace::copyBackToFront()
1135{
ca3c13d1 1136#if !defined(GL_ES_VERSION_2_0)
ca3c13d1 1137
c827ea3a 1138 OpenGl_Mat4 aProjectMat;
1139 OpenGl_Utils::Ortho2D<Standard_ShortReal> (aProjectMat,
1140 0.f, static_cast<GLfloat> (myWidth), 0.f, static_cast<GLfloat> (myHeight));
1141
1142 myGlContext->WorldViewState.Push();
1143 myGlContext->ProjectionState.Push();
1144
1145 myGlContext->WorldViewState.SetIdentity();
1146 myGlContext->ProjectionState.SetCurrent (aProjectMat);
1147
1148 myGlContext->ApplyProjectionMatrix();
1149 myGlContext->ApplyWorldViewMatrix();
679ecdee 1150
1151 DisableFeatures();
1152
38a0206f 1153 switch (myGlContext->DrawBuffer())
1154 {
1155 case GL_BACK_LEFT:
1156 {
1157 myGlContext->SetReadBuffer (GL_BACK_LEFT);
1158 myGlContext->SetDrawBuffer (GL_FRONT_LEFT);
1159 break;
1160 }
1161 case GL_BACK_RIGHT:
1162 {
1163 myGlContext->SetReadBuffer (GL_BACK_RIGHT);
1164 myGlContext->SetDrawBuffer (GL_FRONT_RIGHT);
1165 break;
1166 }
1167 default:
1168 {
1169 myGlContext->SetReadBuffer (GL_BACK);
1170 myGlContext->SetDrawBuffer (GL_FRONT);
1171 break;
1172 }
1173 }
679ecdee 1174
1175 glRasterPos2i (0, 0);
1176 glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR);
a1954302 1177 //glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_DEPTH);
679ecdee 1178
1179 EnableFeatures();
1180
c827ea3a 1181 myGlContext->WorldViewState.Pop();
1182 myGlContext->ProjectionState.Pop();
1183 myGlContext->ApplyProjectionMatrix();
679ecdee 1184
38a0206f 1185 // read/write from front buffer now
1186 myGlContext->SetReadBuffer (myGlContext->DrawBuffer());
ca3c13d1 1187#endif
679ecdee 1188 myIsImmediateDrawn = Standard_False;
1189}
1190
1191// =======================================================================
1192// function : DisplayCallback
1193// purpose :
1194// =======================================================================
1195void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
1196 Standard_Integer theReason)
1197{
1198 if (theCView.GDisplayCB == NULL)
1199 {
1200 return;
1201 }
1202
1203 Aspect_GraphicCallbackStruct aCallData;
1204 aCallData.reason = theReason;
4e1523ef 1205 aCallData.glContext = myGlContext;
679ecdee 1206 aCallData.wsID = theCView.WsId;
1207 aCallData.viewID = theCView.ViewId;
4e1523ef 1208 aCallData.IsCoreProfile = (myGlContext->core11 == NULL);
679ecdee 1209 theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
1210}
1211
1212// =======================================================================
1213// function : RedrawImmediate
1214// purpose :
1215// =======================================================================
1216void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
1217 const Aspect_CLayer2d& theCUnderLayer,
ee51a9fe 1218 const Aspect_CLayer2d& theCOverLayer)
679ecdee 1219{
38a0206f 1220 const Handle(Graphic3d_Camera)& aCamera = myView->Camera();
1221 Graphic3d_Camera::Projection aProjectType = aCamera->ProjectionType();
1222 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
1223 if ( aFrameBuffer == NULL
1224 && !myGlContext->DefaultFrameBuffer().IsNull()
1225 && myGlContext->DefaultFrameBuffer()->IsValid())
1226 {
1227 aFrameBuffer = myGlContext->DefaultFrameBuffer().operator->();
1228 }
1229
1230 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
1231 {
1232 if (aFrameBuffer != NULL)
1233 {
1234 // implicitly switch to mono camera for image dump
1235 aProjectType = Graphic3d_Camera::Projection_Perspective;
1236 }
1237 else if (myMainSceneFbos[0]->IsValid()
1238 && !myMainSceneFbos[1]->IsValid())
1239 {
1240 aProjectType = Graphic3d_Camera::Projection_Perspective;
1241 }
1242 }
1243
ee51a9fe 1244 if (!myTransientDrawToFront
1245 || !myBackBufferRestored
38a0206f 1246 || (myGlContext->caps->buffersNoSwap && !myMainSceneFbos[0]->IsValid()))
679ecdee 1247 {
ee51a9fe 1248 Redraw (theCView, theCUnderLayer, theCOverLayer);
679ecdee 1249 return;
1250 }
ee51a9fe 1251 else if (!Activate())
679ecdee 1252 {
679ecdee 1253 return;
1254 }
1255
38a0206f 1256 bool toSwap = false;
1257 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
1258 {
1259 OpenGl_FrameBuffer* aMainFbos[2] =
1260 {
1261 myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL,
1262 myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL
1263 };
1264 OpenGl_FrameBuffer* anImmFbos[2] =
1265 {
1266 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
1267 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
1268 };
1269
1270 if (myGlContext->arbFBO != NULL)
1271 {
1272 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1273 }
1274 #if !defined(GL_ES_VERSION_2_0)
1275 if (anImmFbos[0] == NULL)
1276 {
1277 myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
1278 }
1279 #endif
1280 toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
1281 aMainFbos[0],
1282 Graphic3d_Camera::Projection_MonoLeftEye,
1283 anImmFbos[0],
1284 Standard_True) || toSwap;
1285
1286 if (myGlContext->arbFBO != NULL)
1287 {
1288 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1289 }
1290 #if !defined(GL_ES_VERSION_2_0)
1291 if (anImmFbos[1] == NULL)
1292 {
1293 myGlContext->SetReadDrawBuffer (GL_BACK_RIGHT);
1294 }
1295 #endif
1296 toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
1297 aMainFbos[1],
1298 Graphic3d_Camera::Projection_MonoRightEye,
1299 anImmFbos[1],
1300 Standard_True) || toSwap;
1301 if (anImmFbos[0] != NULL)
1302 {
1303 bindDefaultFbo (aFrameBuffer);
1304 drawStereoPair();
1305 }
1306 }
1307 else
a2e4f780 1308 {
38a0206f 1309 OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
1310 #if !defined(GL_ES_VERSION_2_0)
1311 if (aMainFbo == NULL)
1312 {
1313 myGlContext->SetReadDrawBuffer (GL_BACK);
1314 }
1315 #endif
1316 toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
1317 aMainFbo,
1318 aProjectType,
1319 aFrameBuffer,
1320 Standard_True) || toSwap;
a2e4f780 1321 }
1322
38a0206f 1323 // bind default FBO
1324 bindDefaultFbo();
1325
1326 if (toSwap
ef0bfc15 1327 && !myGlContext->caps->buffersNoSwap)
b86bb3df 1328 {
ee51a9fe 1329 myGlContext->SwapBuffers();
1330 }
1331 else
1332 {
1333 myGlContext->core11fwd->glFlush();
ee51a9fe 1334 }
1335}
b86bb3df 1336
ee51a9fe 1337// =======================================================================
1338// function : redrawImmediate
1339// purpose :
1340// =======================================================================
1341bool OpenGl_Workspace::redrawImmediate (const Graphic3d_CView& theCView,
1342 const Aspect_CLayer2d& theCUnderLayer,
1343 const Aspect_CLayer2d& theCOverLayer,
38a0206f 1344 OpenGl_FrameBuffer* theReadFbo,
1345 const Graphic3d_Camera::Projection theProjection,
1346 OpenGl_FrameBuffer* theDrawFbo,
ee51a9fe 1347 const Standard_Boolean theIsPartialUpdate)
1348{
1349 GLboolean toCopyBackToFront = GL_FALSE;
1350 if (!myTransientDrawToFront)
1351 {
1352 myBackBufferRestored = Standard_False;
1353 }
38a0206f 1354 else if (theReadFbo != NULL
1355 && theReadFbo->IsValid()
ee51a9fe 1356 && myGlContext->IsRender())
1357 {
38a0206f 1358 if (!blitBuffers (theReadFbo, theDrawFbo))
b86bb3df 1359 {
38a0206f 1360 return true;
b86bb3df 1361 }
1362 }
38a0206f 1363 else if (theDrawFbo == NULL)
679ecdee 1364 {
ee51a9fe 1365 #if !defined(GL_ES_VERSION_2_0)
1366 myGlContext->core11fwd->glGetBooleanv (GL_DOUBLEBUFFER, &toCopyBackToFront);
1367 #endif
1368 if (toCopyBackToFront)
679ecdee 1369 {
ee51a9fe 1370 if (!myView->HasImmediateStructures()
1371 && !theIsPartialUpdate)
1372 {
1373 // prefer Swap Buffers within Redraw in compatibility mode (without FBO)
1374 return true;
1375 }
1376 copyBackToFront();
ee51a9fe 1377 }
1378 else
1379 {
1380 myBackBufferRestored = Standard_False;
679ecdee 1381 }
679ecdee 1382 }
1383 else
1384 {
1385 myBackBufferRestored = Standard_False;
1386 }
1387 myIsImmediateDrawn = Standard_True;
1388
679ecdee 1389 Handle(OpenGl_Workspace) aWS (this);
a1954302 1390
eae454e3 1391 myUseZBuffer = Standard_True;
1392 myUseDepthWrite = Standard_True;
1393 glDepthFunc (GL_LEQUAL);
1394 glDepthMask (GL_TRUE);
1395 glEnable (GL_DEPTH_TEST);
1396#if !defined(GL_ES_VERSION_2_0)
1397 glClearDepth (1.0);
1398#else
1399 glClearDepthf (1.0f);
1400#endif
a1954302 1401
38a0206f 1402 myView->Render (myPrintContext, aWS, theDrawFbo, theProjection,
1403 theCView, theCUnderLayer, theCOverLayer, Standard_True);
a1954302 1404 if (!myView->ImmediateStructures().IsEmpty())
1405 {
eae454e3 1406 myUseZBuffer = Standard_False;
a1954302 1407 glDisable (GL_DEPTH_TEST);
1408 }
9f112210 1409 for (OpenGl_IndexedMapOfStructure::Iterator anIter (myView->ImmediateStructures()); anIter.More(); anIter.Next())
679ecdee 1410 {
1411 const OpenGl_Structure* aStructure = anIter.Value();
a1954302 1412 if (!aStructure->IsVisible())
1413 {
1414 continue;
1415 }
1416
679ecdee 1417 aStructure->Render (aWS);
1418 }
1419
38a0206f 1420 return !toCopyBackToFront;
679ecdee 1421}
91c60b57 1422
1423IMPLEMENT_STANDARD_HANDLE (OpenGl_RaytraceFilter, OpenGl_RenderFilter)
1424IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
1425
1426// =======================================================================
1427// function : CanRender
1428// purpose :
1429// =======================================================================
1430Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
1431{
1432 Standard_Boolean aPrevFilterResult = Standard_True;
1433 if (!myPrevRenderFilter.IsNull())
1434 {
1435 aPrevFilterResult = myPrevRenderFilter->CanRender (theElement);
1436 }
1437 return aPrevFilterResult &&
1438 !OpenGl_Raytrace::IsRaytracedElement (theElement);
1439}