0026886: Visualization, TKV3d - eliminate global variables
[occt.git] / src / OpenGl / OpenGl_View_Redraw.cxx
CommitLineData
c357e426 1// Created on: 2011-09-20
2// Created by: Sergey ZERCHANINOV
3// Copyright (c) 2011-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
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
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.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <stdio.h>
17#include <stdlib.h>
18
19#include <OpenGl_GlCore11.hxx>
c357e426 20
21#include <Graphic3d_GraphicDriver.hxx>
22#include <Graphic3d_TextureParams.hxx>
23#include <Graphic3d_Texture2Dmanual.hxx>
24#include <Graphic3d_TransformUtils.hxx>
25#include <Image_AlienPixMap.hxx>
26
27#include <NCollection_Mat4.hxx>
28
29#include <OpenGl_AspectLine.hxx>
30#include <OpenGl_Context.hxx>
31#include <OpenGl_Matrix.hxx>
32#include <OpenGl_Workspace.hxx>
33#include <OpenGl_View.hxx>
34#include <OpenGl_Trihedron.hxx>
35#include <OpenGl_GraduatedTrihedron.hxx>
36#include <OpenGl_PrimitiveArray.hxx>
37#include <OpenGl_PrinterContext.hxx>
38#include <OpenGl_ShaderManager.hxx>
39#include <OpenGl_ShaderProgram.hxx>
40#include <OpenGl_Structure.hxx>
41#include <OpenGl_ArbFBO.hxx>
42
43#define EPSI 0.0001
44
45namespace
46{
47 static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
48 static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
49 static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
50 static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
51}
52
53extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
54
55#if !defined(GL_ES_VERSION_2_0)
56
57//=======================================================================
58//function : bindLight
59//purpose :
60//=======================================================================
61static void bindLight (const OpenGl_Light& theLight,
62 GLenum& theLightGlId,
63 Graphic3d_Vec4& theAmbientColor,
64 const Handle(OpenGl_Workspace)& theWorkspace)
65{
66 // Only 8 lights in OpenGL...
67 if (theLightGlId > GL_LIGHT7)
68 {
69 return;
70 }
71
72 if (theLight.Type == Graphic3d_TOLS_AMBIENT)
73 {
74 // add RGBA intensity of the ambient light
75 theAmbientColor += theLight.Color;
76 return;
77 }
78
79 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
80
81 // the light is a headlight?
82 if (theLight.IsHeadlight)
83 {
84 aContext->WorldViewState.Push();
85 aContext->WorldViewState.SetIdentity();
86
87 aContext->ApplyWorldViewMatrix();
88 }
89
90 // setup light type
91 switch (theLight.Type)
92 {
93 case Graphic3d_TOLS_AMBIENT : break; // handled by separate if-clause at beginning of method
94 case Graphic3d_TOLS_DIRECTIONAL:
95 {
96 // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
97 const OpenGl_Vec4 anInfDir = -theLight.Direction;
98
99 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
100 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
101 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
102 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
103 glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
104 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
105 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
106 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
107 break;
108 }
109 case Graphic3d_TOLS_POSITIONAL:
110 {
111 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
112 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
113 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
114 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
115 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
116 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
117 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
118 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
119 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
120 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
121 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
122 break;
123 }
124 case Graphic3d_TOLS_SPOT:
125 {
126 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
127 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
128 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
129 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
130 glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
131 glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
132 glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
133 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
134 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
135 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
136 break;
137 }
138 }
139
140 // restore matrix in case of headlight
141 if (theLight.IsHeadlight)
142 {
143 aContext->WorldViewState.Pop();
144 }
145
146 glEnable (theLightGlId++);
147}
148#endif
149
150//=======================================================================
a521d90d 151//function : drawBackground
c357e426 152//purpose :
153//=======================================================================
a521d90d 154void OpenGl_View::drawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
c357e426 155{
156 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
157
158 if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background
159 || (!myBgTextureArray->IsDefined() // no texture
160 && !myBgGradientArray->IsDefined())) // no gradient
161 {
162 return;
163 }
164
165 const Standard_Boolean wasUsedZBuffer = theWorkspace->SetUseZBuffer (Standard_False);
166 if (wasUsedZBuffer)
167 {
168 aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
169 }
170
171 aCtx->ProjectionState.Push();
172 aCtx->WorldViewState.Push();
173 aCtx->ModelWorldState.Push();
174 aCtx->ProjectionState.SetIdentity();
175 aCtx->WorldViewState.SetIdentity();
176 aCtx->ModelWorldState.SetIdentity();
177 aCtx->ApplyProjectionMatrix();
178 aCtx->ApplyModelViewMatrix();
179
180 // Drawing background gradient if:
181 // - gradient fill type is not Aspect_GFM_NONE and
182 // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
183 if (myBgGradientArray->IsDefined()
184 && (!myTextureParams->DoTextureMap()
185 || myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED
186 || myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE))
187 {
188 #if !defined(GL_ES_VERSION_2_0)
189 GLint aShadingModelOld = GL_SMOOTH;
190 if (aCtx->core11 != NULL)
191 {
192 aCtx->core11fwd->glDisable (GL_LIGHTING);
193 aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld);
194 aCtx->core11->glShadeModel (GL_SMOOTH);
195 }
196 #endif
197
198 if (myBgGradientArray->IsDataChanged())
199 {
200 myBgGradientArray->Init (theWorkspace);
201 }
202
203 myBgGradientArray->Render (theWorkspace);
204
205 #if !defined(GL_ES_VERSION_2_0)
206 if (aCtx->core11 != NULL)
207 {
208 aCtx->core11->glShadeModel (aShadingModelOld);
209 }
210 #endif
211 }
212
213 // Drawing background image if it is defined
214 // (texture is defined and fill type is not Aspect_FM_NONE)
215 if (myBgTextureArray->IsDefined()
216 && myTextureParams->DoTextureMap())
217 {
218 aCtx->core11fwd->glDisable (GL_BLEND);
219
220 const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams);
221
222 if (myBgTextureArray->IsDataChanged()
223 || myBgTextureArray->IsViewSizeChanged (theWorkspace))
224 {
225 myBgTextureArray->Init (theWorkspace);
226 }
227
228 myBgTextureArray->Render (theWorkspace);
229
230 // restore aspects
231 theWorkspace->SetAspectFace (anOldAspectFace);
232 }
233
234 aCtx->ModelWorldState.Pop();
235 aCtx->WorldViewState.Pop();
236 aCtx->ProjectionState.Pop();
237 aCtx->ApplyProjectionMatrix();
238 aCtx->ApplyModelViewMatrix();
239
240 if (wasUsedZBuffer)
241 {
242 theWorkspace->SetUseZBuffer (Standard_True);
243 aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
244 }
245}
246
247//=======================================================================
248//function : Redraw
249//purpose :
250//=======================================================================
251void OpenGl_View::Redraw()
252{
253 if (myRenderParams.Method == Graphic3d_RM_RAYTRACING
254 && !myCaps->vboDisable
255 && !myCaps->keepArrayData)
256 {
257 if (myWasRedrawnGL)
258 {
259 myDeviceLostFlag = Standard_True;
260 }
261
262 myCaps->keepArrayData = Standard_True;
263 }
264
265 if (!myWorkspace->Activate())
266 {
267 return;
268 }
269
270 myWindow->SetSwapInterval();
271
272 ++myFrameCounter;
273 const Graphic3d_StereoMode aStereoMode = myRenderParams.StereoMode;
274 Graphic3d_Camera::Projection aProjectType = myCamera->ProjectionType();
275 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
276
277 // release pending GL resources
278 aCtx->ReleaseDelayed();
279
280 // fetch OpenGl context state
281 aCtx->FetchState();
282
75c262a9 283 // set resolution ratio
284 aCtx->SetResolutionRatio (RenderingParams().ResolutionRatio());
285
b128c892 286 OpenGl_FrameBuffer* aFrameBuffer = myFBO.operator->();
c357e426 287 bool toSwap = aCtx->IsRender()
288 && !aCtx->caps->buffersNoSwap
289 && aFrameBuffer == NULL;
290
291 Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWindow->Width();
292 Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myWindow->Height();
293
3c4b62a4 294 // determine multisampling parameters
295 Standard_Integer aNbSamples = Max (Min (myRenderParams.NbMsaaSamples, aCtx->MaxMsaaSamples()), 0);
296 if (aNbSamples != 0)
297 {
298 aNbSamples = OpenGl_Context::GetPowerOfTwo (aNbSamples, aCtx->MaxMsaaSamples());
299 }
300
c357e426 301 if ( aFrameBuffer == NULL
302 && !aCtx->DefaultFrameBuffer().IsNull()
303 && aCtx->DefaultFrameBuffer()->IsValid())
304 {
305 aFrameBuffer = aCtx->DefaultFrameBuffer().operator->();
306 }
307
308 if (myHasFboBlit
3c4b62a4 309 && (myTransientDrawToFront
310 || aProjectType == Graphic3d_Camera::Projection_Stereo
311 || aNbSamples != 0))
c357e426 312 {
313 if (myMainSceneFbos[0]->GetVPSizeX() != aSizeX
3c4b62a4 314 || myMainSceneFbos[0]->GetVPSizeY() != aSizeY
315 || myMainSceneFbos[0]->NbSamples() != aNbSamples)
c357e426 316 {
317 // prepare FBOs containing main scene
318 // for further blitting and rendering immediate presentations on top
319 if (aCtx->core20fwd != NULL)
320 {
3c4b62a4 321 myMainSceneFbos[0]->Init (aCtx, aSizeX, aSizeY, myFboColorFormat, myFboDepthFormat, aNbSamples);
c357e426 322 }
323 if (!aCtx->caps->useSystemBuffer && myMainSceneFbos[0]->IsValid())
324 {
3c4b62a4 325 myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0]);
c357e426 326 }
327 }
328 }
329 else
330 {
331 myMainSceneFbos [0]->Release (aCtx.operator->());
332 myMainSceneFbos [1]->Release (aCtx.operator->());
333 myImmediateSceneFbos[0]->Release (aCtx.operator->());
334 myImmediateSceneFbos[1]->Release (aCtx.operator->());
335 myMainSceneFbos [0]->ChangeViewport (0, 0);
336 myMainSceneFbos [1]->ChangeViewport (0, 0);
337 myImmediateSceneFbos[0]->ChangeViewport (0, 0);
338 myImmediateSceneFbos[1]->ChangeViewport (0, 0);
339 }
340
341 if (aProjectType == Graphic3d_Camera::Projection_Stereo
342 && myMainSceneFbos[0]->IsValid())
343 {
3c4b62a4 344 myMainSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0]);
c357e426 345 if (!myMainSceneFbos[1]->IsValid())
346 {
347 // no enough memory?
348 aProjectType = Graphic3d_Camera::Projection_Perspective;
349 }
350 else if (!myTransientDrawToFront)
351 {
352 //
353 }
354 else if (!aCtx->HasStereoBuffers() || aStereoMode != Graphic3d_StereoMode_QuadBuffer)
355 {
3c4b62a4 356 myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0]);
357 myImmediateSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0]);
c357e426 358 if (!myImmediateSceneFbos[0]->IsValid()
359 || !myImmediateSceneFbos[1]->IsValid())
360 {
361 aProjectType = Graphic3d_Camera::Projection_Perspective;
362 }
363 }
364 }
365
366 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
367 {
368 OpenGl_FrameBuffer* aMainFbos[2] =
369 {
370 myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL,
371 myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL
372 };
373 OpenGl_FrameBuffer* anImmFbos[2] =
374 {
375 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
376 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
377 };
378
379 if (!myTransientDrawToFront)
380 {
381 anImmFbos[0] = aMainFbos[0];
382 anImmFbos[1] = aMainFbos[1];
383 }
384 else if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip
385 || aStereoMode == Graphic3d_StereoMode_QuadBuffer)
386 {
387 anImmFbos[0] = NULL;
388 anImmFbos[1] = NULL;
389 }
390
391 #if !defined(GL_ES_VERSION_2_0)
392 aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK);
393 #endif
394 redraw (Graphic3d_Camera::Projection_MonoLeftEye, aMainFbos[0]);
395 myBackBufferRestored = Standard_True;
396 myIsImmediateDrawn = Standard_False;
397 #if !defined(GL_ES_VERSION_2_0)
398 aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK);
399 #endif
b0dc79bc 400 if (!redrawImmediate (Graphic3d_Camera::Projection_MonoLeftEye, aMainFbos[0], anImmFbos[0]))
c357e426 401 {
402 toSwap = false;
403 }
404 else if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip && toSwap)
405 {
406 aCtx->SwapBuffers();
407 }
408
409 #if !defined(GL_ES_VERSION_2_0)
410 aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_RIGHT : GL_BACK);
411 #endif
412 redraw (Graphic3d_Camera::Projection_MonoRightEye, aMainFbos[1]);
413 myBackBufferRestored = Standard_True;
414 myIsImmediateDrawn = Standard_False;
b0dc79bc 415 if (!redrawImmediate (Graphic3d_Camera::Projection_MonoRightEye, aMainFbos[1], anImmFbos[1]))
c357e426 416 {
417 toSwap = false;
418 }
419
420 if (anImmFbos[0] != NULL)
421 {
3c4b62a4 422 drawStereoPair (aFrameBuffer);
c357e426 423 }
424 }
425 else
426 {
427 OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
428 OpenGl_FrameBuffer* anImmFbo = aFrameBuffer;
429 if (!aCtx->caps->useSystemBuffer && myImmediateSceneFbos[0]->IsValid())
430 {
431 anImmFbo = myImmediateSceneFbos[0].operator->();
432 }
433
434 #if !defined(GL_ES_VERSION_2_0)
435 if (aMainFbo == NULL
436 && aFrameBuffer == NULL)
437 {
438 aCtx->SetReadDrawBuffer (GL_BACK);
439 }
440 #endif
441 redraw (aProjectType, aMainFbo != NULL ? aMainFbo : aFrameBuffer);
442 myBackBufferRestored = Standard_True;
443 myIsImmediateDrawn = Standard_False;
444 if (!redrawImmediate (aProjectType, aMainFbo, anImmFbo))
445 {
446 toSwap = false;
447 }
448
449 if (anImmFbo != NULL
450 && anImmFbo != aFrameBuffer)
451 {
452 blitBuffers (anImmFbo, aFrameBuffer, myToFlipOutput);
453 }
454 }
455
456#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
457 if (OpenGl_AVIWriter_AllowWriting (myWindow->PlatformWindow()->NativeHandle()))
458 {
459 GLint params[4];
460 glGetIntegerv (GL_VIEWPORT, params);
461 int nWidth = params[2] & ~0x7;
462 int nHeight = params[3] & ~0x7;
463
464 const int nBitsPerPixel = 24;
465 GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
466
467 glPixelStorei (GL_PACK_ALIGNMENT, 1);
468 glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
469 OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
470 delete[] aDumpData;
471 }
472#endif
473
bf02aa7d 474 if (myRenderParams.Method == Graphic3d_RM_RAYTRACING
475 && myRenderParams.IsGlobalIlluminationEnabled)
476 {
477 myAccumFrames++;
478 }
479
c357e426 480 // bind default FBO
481 bindDefaultFbo();
482
483 // Swap the buffers
484 if (toSwap)
485 {
486 aCtx->SwapBuffers();
487 if (!myMainSceneFbos[0]->IsValid())
488 {
489 myBackBufferRestored = Standard_False;
490 }
491 }
492 else
493 {
494 aCtx->core11fwd->glFlush();
495 }
496
497 // reset render mode state
498 aCtx->FetchState();
499
500 myWasRedrawnGL = Standard_True;
501}
502
503// =======================================================================
504// function : RedrawImmediate
505// purpose :
506// =======================================================================
507void OpenGl_View::RedrawImmediate()
508{
509 if (!myWorkspace->Activate())
510 return;
511
512 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
513 if (!myTransientDrawToFront
514 || !myBackBufferRestored
515 || (aCtx->caps->buffersNoSwap && !myMainSceneFbos[0]->IsValid()))
516 {
517 Redraw();
518 return;
519 }
520
521 const Graphic3d_StereoMode aStereoMode = myRenderParams.StereoMode;
522 Graphic3d_Camera::Projection aProjectType = myCamera->ProjectionType();
b128c892 523 OpenGl_FrameBuffer* aFrameBuffer = myFBO.operator->();
c357e426 524
525 if ( aFrameBuffer == NULL
526 && !aCtx->DefaultFrameBuffer().IsNull()
527 && aCtx->DefaultFrameBuffer()->IsValid())
528 {
529 aFrameBuffer = aCtx->DefaultFrameBuffer().operator->();
530 }
531
532 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
533 {
534 if (myMainSceneFbos[0]->IsValid()
535 && !myMainSceneFbos[1]->IsValid())
536 {
537 aProjectType = Graphic3d_Camera::Projection_Perspective;
538 }
539 }
540
541 bool toSwap = false;
542 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
543 {
544 OpenGl_FrameBuffer* aMainFbos[2] =
545 {
546 myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL,
547 myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL
548 };
549 OpenGl_FrameBuffer* anImmFbos[2] =
550 {
551 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
552 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
553 };
554 if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip
555 || aStereoMode == Graphic3d_StereoMode_QuadBuffer)
556 {
557 anImmFbos[0] = NULL;
558 anImmFbos[1] = NULL;
559 }
560
561 if (aCtx->arbFBO != NULL)
562 {
563 aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
564 }
565 #if !defined(GL_ES_VERSION_2_0)
566 if (anImmFbos[0] == NULL)
567 {
568 aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK);
569 }
570 #endif
571 toSwap = redrawImmediate (Graphic3d_Camera::Projection_MonoLeftEye,
572 aMainFbos[0],
573 anImmFbos[0],
574 Standard_True) || toSwap;
575 if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip
576 && toSwap
577 && !aCtx->caps->buffersNoSwap)
578 {
579 aCtx->SwapBuffers();
580 }
581
582 if (aCtx->arbFBO != NULL)
583 {
584 aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
585 }
586 #if !defined(GL_ES_VERSION_2_0)
587 if (anImmFbos[1] == NULL)
588 {
589 aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_RIGHT : GL_BACK);
590 }
591 #endif
592 toSwap = redrawImmediate (Graphic3d_Camera::Projection_MonoRightEye,
593 aMainFbos[1],
594 anImmFbos[1],
595 Standard_True) || toSwap;
596 if (anImmFbos[0] != NULL)
597 {
3c4b62a4 598 drawStereoPair (aFrameBuffer);
c357e426 599 }
600 }
601 else
602 {
603 OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
604 OpenGl_FrameBuffer* anImmFbo = aFrameBuffer;
605 if (!aCtx->caps->useSystemBuffer && myImmediateSceneFbos[0]->IsValid())
606 {
607 anImmFbo = myImmediateSceneFbos[0].operator->();
608 }
609 #if !defined(GL_ES_VERSION_2_0)
610 if (aMainFbo == NULL)
611 {
612 aCtx->SetReadDrawBuffer (GL_BACK);
613 }
614 #endif
615 toSwap = redrawImmediate (aProjectType,
616 aMainFbo,
617 anImmFbo,
618 Standard_True) || toSwap;
619 if (anImmFbo != NULL
620 && anImmFbo != aFrameBuffer)
621 {
622 blitBuffers (anImmFbo, aFrameBuffer, myToFlipOutput);
623 }
624 }
625
626 // bind default FBO
627 bindDefaultFbo();
628
629 if (toSwap && !aCtx->caps->buffersNoSwap)
630 {
631 aCtx->SwapBuffers();
632 }
633 else
634 {
635 aCtx->core11fwd->glFlush();
636 }
637
638 myWasRedrawnGL = Standard_True;
639}
640
641// =======================================================================
642// function : redraw
643// purpose :
644// =======================================================================
645void OpenGl_View::redraw (const Graphic3d_Camera::Projection theProjection, OpenGl_FrameBuffer* theReadDrawFbo)
646{
647 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
648 if (theReadDrawFbo != NULL)
649 {
650 theReadDrawFbo->BindBuffer (aCtx);
651 theReadDrawFbo->SetupViewport (aCtx);
652 }
653 else
654 {
655 aCtx->core11fwd->glViewport (0, 0, myWindow->Width(), myWindow->Height());
656 }
657
658 // request reset of material
659 myWorkspace->NamedStatus |= OPENGL_NS_RESMAT;
660 myWorkspace->UseZBuffer() = Standard_True;
661 myWorkspace->UseDepthWrite() = Standard_True;
662 GLbitfield toClear = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
663 glDepthFunc (GL_LEQUAL);
664 glDepthMask (GL_TRUE);
665 glEnable (GL_DEPTH_TEST);
666
667#if !defined(GL_ES_VERSION_2_0)
668 glClearDepth (1.0);
669#else
670 glClearDepthf (1.0f);
671#endif
672
673 if (myWorkspace->NamedStatus & OPENGL_NS_WHITEBACK)
674 {
675 // set background to white
676 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
677 }
678 else
679 {
680 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
681 }
682
683 glClear (toClear);
684
685 render (theProjection, theReadDrawFbo, Standard_False);
686}
687
688// =======================================================================
689// function : redrawMonoImmediate
690// purpose :
691// =======================================================================
692bool OpenGl_View::redrawImmediate (const Graphic3d_Camera::Projection theProjection,
693 OpenGl_FrameBuffer* theReadFbo,
694 OpenGl_FrameBuffer* theDrawFbo,
695 const Standard_Boolean theIsPartialUpdate)
696{
697 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
698 GLboolean toCopyBackToFront = GL_FALSE;
699 if (!myTransientDrawToFront)
700 {
701 myBackBufferRestored = Standard_False;
702 }
703 else if (theReadFbo != NULL
704 && theReadFbo->IsValid()
705 && aCtx->IsRender())
706 {
707 if (!blitBuffers (theReadFbo, theDrawFbo))
708 {
709 return true;
710 }
711 }
712 else if (theDrawFbo == NULL)
713 {
714 #if !defined(GL_ES_VERSION_2_0)
715 aCtx->core11fwd->glGetBooleanv (GL_DOUBLEBUFFER, &toCopyBackToFront);
716 #endif
717 if (toCopyBackToFront)
718 {
719 if (!HasImmediateStructures()
720 && !theIsPartialUpdate)
721 {
722 // prefer Swap Buffers within Redraw in compatibility mode (without FBO)
723 return true;
724 }
725 copyBackToFront();
726 }
727 else
728 {
729 myBackBufferRestored = Standard_False;
730 }
731 }
732 else
733 {
734 myBackBufferRestored = Standard_False;
735 }
736 myIsImmediateDrawn = Standard_True;
737
738 myWorkspace->UseZBuffer() = Standard_True;
739 myWorkspace->UseDepthWrite() = Standard_True;
740 glDepthFunc (GL_LEQUAL);
741 glDepthMask (GL_TRUE);
742 glEnable (GL_DEPTH_TEST);
743#if !defined(GL_ES_VERSION_2_0)
744 glClearDepth (1.0);
745#else
746 glClearDepthf (1.0f);
747#endif
748
749 render (theProjection, theDrawFbo, Standard_True);
750
751 return !toCopyBackToFront;
752}
753
754//=======================================================================
755//function : Render
756//purpose :
757//=======================================================================
758void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
759 OpenGl_FrameBuffer* theOutputFBO,
760 const Standard_Boolean theToDrawImmediate)
761{
762 // ==================================
763 // Step 1: Prepare for render
764 // ==================================
765
766 const Handle(OpenGl_Context)& aContext = myWorkspace->GetGlContext();
767
768#if !defined(GL_ES_VERSION_2_0)
769 // Disable current clipping planes
770 if (aContext->core11 != NULL)
771 {
772 const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
773 for (Standard_Integer aClipPlaneId = GL_CLIP_PLANE0; aClipPlaneId < GL_CLIP_PLANE0 + aMaxPlanes; ++aClipPlaneId)
774 {
775 aContext->core11fwd->glDisable (aClipPlaneId);
776 }
777 }
778#endif
779
780 // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
781 myBVHSelector.SetViewVolume (myCamera);
782
783 const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager();
784 if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
785 {
016e5959 786 aManager->UpdateLightSourceStateTo (myShadingModel == Graphic3d_TOSM_NONE ? &myNoShadingLight : &myLights);
c357e426 787 myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
788 }
789
790 // Update matrices if camera has changed.
791 Graphic3d_WorldViewProjState aWVPState = myCamera->WorldViewProjState();
792 const Standard_Boolean isCameraChanged = myWorldViewProjState != aWVPState;
793 const Standard_Boolean isSameView = aManager->IsSameView (this);
794 if (isCameraChanged)
795 {
796 aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
797 aContext->WorldViewState .SetCurrent (myCamera->OrientationMatrixF());
bf02aa7d 798 myAccumFrames = 0;
c357e426 799 }
800
801 // Apply new matrix state if camera has changed or this view differs from the one
802 // that was previously used for configuring matrices of shader manager
803 // (ApplyProjectionMatrix and ApplyWorldViewMatrix will affect the manager).
804 if (isCameraChanged || !isSameView)
805 {
806 aContext->ApplyProjectionMatrix();
807 aContext->ApplyWorldViewMatrix();
808 }
809
810 if (aManager->ModelWorldState().Index() == 0)
811 {
812 aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
813 }
814
815 myWorldViewProjState = aWVPState;
816
817 // ====================================
818 // Step 2: Redraw background
819 // ====================================
820
821 // Render background
822 if (!theToDrawImmediate)
823 {
a521d90d 824 drawBackground (myWorkspace);
c357e426 825 }
826
827#if !defined(GL_ES_VERSION_2_0)
828 // Switch off lighting by default
829 if (aContext->core11 != NULL)
830 {
831 glDisable(GL_LIGHTING);
832 }
833#endif
834
835 // =================================
836 // Step 3: Redraw main plane
837 // =================================
838
839 // Setup face culling
840 GLboolean isCullFace = GL_FALSE;
841 if (myBackfacing != Graphic3d_TOBM_AUTOMATIC)
842 {
843 isCullFace = glIsEnabled (GL_CULL_FACE);
844 if (myBackfacing == Graphic3d_TOBM_DISABLE)
845 {
846 glEnable (GL_CULL_FACE);
847 glCullFace (GL_BACK);
848 }
849 else
850 glDisable (GL_CULL_FACE);
851 }
852
853#if !defined(GL_ES_VERSION_2_0)
854 // if the view is scaled normal vectors are scaled to unit
855 // length for correct displaying of shaded objects
856 const gp_Pnt anAxialScale = myCamera->AxialScale();
857 if (anAxialScale.X() != 1.F ||
858 anAxialScale.Y() != 1.F ||
859 anAxialScale.Z() != 1.F)
860 {
861 aContext->SetGlNormalizeEnabled (Standard_True);
862 }
863 else
864 {
865 aContext->SetGlNormalizeEnabled (Standard_False);
866 }
867
868 // Apply Fog
869 if (myFog.IsOn
870 && aContext->core11 != NULL)
871 {
872 Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
873 if (myCamera->ZFar() < aFogFrontConverted)
874 {
875 aFogFrontConverted = myCamera->ZFar();
876 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
877 }
878
879 Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
880 if (myCamera->ZFar() < aFogFrontConverted)
881 {
882 aFogBackConverted = myCamera->ZFar();
883 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
884 }
885
886 if (aFogFrontConverted > aFogBackConverted)
887 {
888 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
889 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
890 }
891
892 glFogi(GL_FOG_MODE, GL_LINEAR);
893 glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
894 glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
895 glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
896 glEnable(GL_FOG);
897 }
898 else if (aContext->core11 != NULL)
899 {
900 glDisable (GL_FOG);
901 }
902
903 // Apply InteriorShadingMethod
904 if (aContext->core11 != NULL)
905 {
906 aContext->core11->glShadeModel (myShadingModel == Graphic3d_TOSM_FACET
907 || myShadingModel == Graphic3d_TOSM_NONE ? GL_FLAT : GL_SMOOTH);
908 }
909#endif
910
911 aManager->SetShadingModel (myShadingModel);
912
913 // Apply AntiAliasing
914 if (myAntiAliasing)
915 myWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
916 else
917 myWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
918
919 if (!aManager->IsEmpty())
920 {
921 aManager->UpdateClippingState();
922 }
923
924 // Redraw 3d scene
925 if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye)
926 {
927 aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF());
928 aContext->ApplyProjectionMatrix();
929 }
930 else if (theProjection == Graphic3d_Camera::Projection_MonoRightEye)
931 {
932 aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF());
933 aContext->ApplyProjectionMatrix();
934 }
83da37b1 935
936 myWorkspace->SetEnvironmentTexture (myTextureEnv);
937
bf02aa7d 938 renderScene (theProjection, theOutputFBO, theToDrawImmediate);
c357e426 939
83da37b1 940 myWorkspace->SetEnvironmentTexture (Handle(OpenGl_Texture)());
941
c357e426 942 // ===============================
943 // Step 4: Trihedron
944 // ===============================
945
946 // Resetting GL parameters according to the default aspects
947 // in order to synchronize GL state with the graphic driver state
948 // before drawing auxiliary stuff (trihedrons, overlayer)
c357e426 949 myWorkspace->ResetAppliedAspect();
950
79f4f036 951 aContext->ChangeClipping().RemoveAll (aContext);
c357e426 952
953 if (!aManager->IsEmpty())
954 {
955 aManager->ResetMaterialStates();
956 aManager->RevertClippingState();
957
958 // We need to disable (unbind) all shaders programs to ensure
959 // that all objects without specified aspect will be drawn
960 // correctly (such as background)
961 aContext->BindProgram (NULL);
962 }
963
964 // Render trihedron
965 if (!theToDrawImmediate)
966 {
967 renderTrihedron (myWorkspace);
968
969 // Restore face culling
970 if (myBackfacing != Graphic3d_TOBM_AUTOMATIC)
971 {
972 if (isCullFace)
973 {
974 glEnable (GL_CULL_FACE);
975 glCullFace (GL_BACK);
976 }
977 else
978 glDisable (GL_CULL_FACE);
979 }
980 }
981
982 // ==============================================================
c357e426 983 // Step 6: Keep shader manager informed about last View
984 // ==============================================================
985
986 if (!aManager.IsNull())
987 {
988 aManager->SetLastView (this);
989 }
990}
991
992// =======================================================================
993// function : InvalidateBVHData
994// purpose :
995// =======================================================================
996void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
997{
998 myZLayers.InvalidateBVHData (theLayerId);
999}
1000
1001//=======================================================================
1002//function : renderStructs
1003//purpose :
1004//=======================================================================
bf02aa7d 1005void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection,
1006 OpenGl_FrameBuffer* theReadDrawFbo,
1007 const Standard_Boolean theToDrawImmediate)
c357e426 1008{
1009 if ( myZLayers.NbStructures() <= 0 )
1010 return;
1011
1012 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
1013 if ( (myWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
1014 {
1015 #if !defined(GL_ES_VERSION_2_0)
1016 const int anAntiAliasingMode = myWorkspace->AntiAliasingMode();
1017 #endif
1018
1019 if ( !myAntiAliasing )
1020 {
1021 #if !defined(GL_ES_VERSION_2_0)
1022 if (aCtx->core11 != NULL)
1023 {
1024 glDisable (GL_POINT_SMOOTH);
1025 }
1026 glDisable(GL_LINE_SMOOTH);
1027 if( anAntiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
1028 #endif
1029 glBlendFunc (GL_ONE, GL_ZERO);
1030 glDisable (GL_BLEND);
1031 }
1032 else
1033 {
1034 #if !defined(GL_ES_VERSION_2_0)
1035 if (aCtx->core11 != NULL)
1036 {
1037 glEnable(GL_POINT_SMOOTH);
1038 }
1039 glEnable(GL_LINE_SMOOTH);
1040 if( anAntiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
1041 #endif
1042 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1043 glEnable (GL_BLEND);
1044 }
1045 }
1046
1047 Standard_Boolean toRenderGL = theToDrawImmediate ||
1048 myRenderParams.Method != Graphic3d_RM_RAYTRACING ||
1049 myRaytraceInitStatus == OpenGl_RT_FAIL ||
1050 aCtx->IsFeedback();
1051
1052 if (!toRenderGL)
1053 {
1054 toRenderGL = !initRaytraceResources (aCtx) ||
1055 !updateRaytraceGeometry (OpenGl_GUM_CHECK, myId, aCtx);
1056
1057 toRenderGL |= !myIsRaytraceDataValid; // if no ray-trace data use OpenGL
1058
1059 if (!toRenderGL)
1060 {
1061 const Standard_Integer aSizeX = theReadDrawFbo != NULL ? theReadDrawFbo->GetVPSizeX() : myWindow->Width();
1062 const Standard_Integer aSizeY = theReadDrawFbo != NULL ? theReadDrawFbo->GetVPSizeY() : myWindow->Height();
3c4b62a4 1063 myOpenGlFBO ->InitLazy (aCtx, aSizeX, aSizeY, myFboColorFormat, myFboDepthFormat, 0);
c357e426 1064
1065 if (myRaytraceFilter.IsNull())
1066 myRaytraceFilter = new OpenGl_RaytraceFilter;
1067
1068 myRaytraceFilter->SetPrevRenderFilter (myWorkspace->GetRenderFilter());
1069
1070 if (theReadDrawFbo != NULL)
1071 theReadDrawFbo->UnbindBuffer (aCtx);
1072
1073 // Prepare preliminary OpenGL output
1074 if (aCtx->arbFBOBlit != NULL)
1075 {
1076 // Render bottom OSD layer
1077 myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Bottom);
1078
1079 myWorkspace->SetRenderFilter (myRaytraceFilter);
1080 {
1081 if (theReadDrawFbo != NULL)
1082 {
1083 theReadDrawFbo->BindReadBuffer (aCtx);
1084 }
1085 else
1086 {
1087 aCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
1088 }
1089
1090 myOpenGlFBO->BindDrawBuffer (aCtx);
1091
1092 aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, aSizeX, aSizeY,
1093 0, 0, aSizeX, aSizeY,
1094 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
1095 GL_NEAREST);
1096
1097 // Render non-polygonal elements in default layer
1098 myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Default);
1099 }
1100 myWorkspace->SetRenderFilter (myRaytraceFilter->PrevRenderFilter());
1101 }
1102
1103 if (theReadDrawFbo != NULL)
1104 {
1105 theReadDrawFbo->BindBuffer (aCtx);
1106 }
1107 else
1108 {
1109 aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, 0);
1110 }
1111
f55ba97f 1112 // Reset OpenGl aspects state to default to avoid enabling of
1113 // backface culling which is not supported in ray-tracing.
1114 myWorkspace->ResetAppliedAspect();
1115
c357e426 1116 // Ray-tracing polygonal primitive arrays
bf02aa7d 1117 raytrace (aSizeX, aSizeY, theProjection, theReadDrawFbo, aCtx);
c357e426 1118
1119 // Render upper (top and topmost) OpenGL layers
1120 myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Upper);
1121 }
1122 }
1123
1124 // Redraw 3D scene using OpenGL in standard
1125 // mode or in case of ray-tracing failure
1126 if (toRenderGL)
1127 {
1128 myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_All);
1129
1130 // Set flag that scene was redrawn by standard pipeline
1131 myWasRedrawnGL = Standard_True;
1132 }
1133}
1134
1135//=======================================================================
1136//function : renderTrihedron
1137//purpose :
1138//=======================================================================
1139void OpenGl_View::renderTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
1140{
1141 // display global trihedron
1142 if (myToShowTrihedron)
1143 {
83da37b1 1144 // disable environment texture
1145 Handle(OpenGl_Texture) anEnvironmentTexture = theWorkspace->EnvironmentTexture();
1146 theWorkspace->SetEnvironmentTexture (Handle(OpenGl_Texture)());
1147
c357e426 1148 myTrihedron.Render (theWorkspace);
83da37b1 1149
1150 // restore environment texture
1151 theWorkspace->SetEnvironmentTexture (anEnvironmentTexture);
c357e426 1152 }
1153 if (myToShowGradTrihedron)
1154 {
1155 myGraduatedTrihedron.Render (theWorkspace);
1156 }
1157}
1158
1159// =======================================================================
1160// function : Invalidate
1161// purpose :
1162// =======================================================================
1163void OpenGl_View::Invalidate()
1164{
1165 myBackBufferRestored = Standard_False;
1166}
1167
1168//=======================================================================
1169//function : renderScene
1170//purpose :
1171//=======================================================================
bf02aa7d 1172void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection,
1173 OpenGl_FrameBuffer* theReadDrawFbo,
1174 const Standard_Boolean theToDrawImmediate)
c357e426 1175{
1176 const Handle(OpenGl_Context)& aContext = myWorkspace->GetGlContext();
1177
1178 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
1179 {
1180 Handle(Graphic3d_ClipPlane) aPlaneBack;
1181 Handle(Graphic3d_ClipPlane) aPlaneFront;
1182
1183 if (myZClip.Back.IsOn)
1184 {
1185 Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1186 if (myCamera->ZFar() < aClipBackConverted)
1187 {
1188 aClipBackConverted = myCamera->ZFar();
1189 myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1190 }
1191 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1192 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1193 }
1194
1195 if (myZClip.Front.IsOn)
1196 {
1197 Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1198 if (myCamera->ZNear() > aClipFrontConverted)
1199 {
1200 aClipFrontConverted = myCamera->ZNear();
1201 myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1202 }
1203 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1204 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1205 }
1206
1207 // Specify slicing planes with identity transformation
1208 if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1209 {
1210 Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1211 if (!aPlaneBack.IsNull())
1212 {
1213 aSlicingPlanes.Append (aPlaneBack);
1214 }
1215
1216 if (!aPlaneFront.IsNull())
1217 {
1218 aSlicingPlanes.Append (aPlaneFront);
1219 }
1220
1221 // add planes at loaded view matrix state
79f4f036 1222 aContext->ChangeClipping().AddView (aContext, aSlicingPlanes);
c357e426 1223 }
1224 }
1225
1226#ifdef _WIN32
1227 // set printing scale/tiling transformation
1228 Handle(OpenGl_PrinterContext) aPrintContext = myWorkspace->PrinterContext();
1229 if (!aPrintContext.IsNull())
1230 {
1231 aContext->ProjectionState.Push();
1232 aContext->ProjectionState.SetCurrent (aPrintContext->ProjTransformation() * aContext->ProjectionState.Current());
1233 aContext->ApplyProjectionMatrix();
1234 }
1235#endif
1236
1237 // Specify clipping planes in view transformation space
1238 if (!myClipPlanes.IsEmpty())
1239 {
1240 Graphic3d_SequenceOfHClipPlane aUserPlanes;
1241 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1242 for (; aClippingIt.More(); aClippingIt.Next())
1243 {
1244 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1245 if (aClipPlane->IsOn())
1246 {
1247 aUserPlanes.Append (aClipPlane);
1248 }
1249 }
1250
1251 if (!aUserPlanes.IsEmpty())
1252 {
79f4f036 1253 aContext->ChangeClipping().AddWorldLazy (aContext, aUserPlanes);
c357e426 1254 }
1255
1256 if (!aContext->ShaderManager()->IsEmpty())
1257 {
1258 aContext->ShaderManager()->UpdateClippingState();
1259 }
1260 }
1261
1262#if !defined(GL_ES_VERSION_2_0)
1263 // Apply Lights
1264 if (aContext->core11 != NULL)
1265 {
1266 // setup lights
1267 Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1268 THE_DEFAULT_AMBIENT[1],
1269 THE_DEFAULT_AMBIENT[2],
1270 THE_DEFAULT_AMBIENT[3]);
1271 GLenum aLightGlId = GL_LIGHT0;
1272
016e5959 1273 OpenGl_ListOfLight::Iterator aLightIt (myShadingModel == Graphic3d_TOSM_NONE ? myNoShadingLight : myLights);
c357e426 1274 for (; aLightIt.More(); aLightIt.Next())
1275 {
1276 bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, myWorkspace);
1277 }
1278
1279 // apply accumulated ambient color
1280 anAmbientColor.a() = 1.0f;
1281 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1282
1283 if (aLightGlId != GL_LIGHT0)
1284 {
1285 glEnable (GL_LIGHTING);
1286 }
1287 // switch off unused lights
1288 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1289 {
1290 glDisable (aLightGlId);
1291 }
1292 }
1293#endif
1294
1295 // Clear status bitfields
1296 myWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1297
83da37b1 1298 // First pass
1299 renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
1300 myWorkspace->DisableTexture();
c357e426 1301
83da37b1 1302 // Second pass
1303 if (myWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
c357e426 1304 {
83da37b1 1305 myWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
c357e426 1306
83da37b1 1307 // Remember OpenGl properties
1308 GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
1309 GLint aSaveZbuffFunc;
1310 GLboolean aSaveZbuffWrite;
1311 glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1312 glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1313 #if !defined(GL_ES_VERSION_2_0)
1314 glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1315 glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1316 #endif
1317 GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1318 GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
c357e426 1319
83da37b1 1320 // Change the properties for second rendering pass
1321 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1322 glEnable (GL_BLEND);
c357e426 1323
83da37b1 1324 glDepthFunc (GL_EQUAL);
1325 glDepthMask (GL_FALSE);
1326 glEnable (GL_DEPTH_TEST);
c357e426 1327
83da37b1 1328 // Render the view
1329 renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
1330 myWorkspace->DisableTexture();
1331
1332 // Restore properties back
1333 glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1334 if (!wasBlendEnabled)
1335 glDisable (GL_BLEND);
1336
1337 glDepthFunc (aSaveZbuffFunc);
1338 glDepthMask (aSaveZbuffWrite);
1339 if (!wasZbuffEnabled)
1340 glDisable (GL_DEPTH_FUNC);
c357e426 1341 }
1342
1343 // Apply restored view matrix.
1344 aContext->ApplyWorldViewMatrix();
1345
1346#ifdef _WIN32
1347 // set printing scale/tiling transformation
1348 if (!aPrintContext.IsNull())
1349 {
1350 aContext->ProjectionState.Pop();
1351 aContext->ApplyProjectionMatrix();
1352 }
1353#endif
1354}
1355
1356// =======================================================================
1357// function : bindDefaultFbo
1358// purpose :
1359// =======================================================================
1360void OpenGl_View::bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo)
1361{
1362 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
1363 OpenGl_FrameBuffer* anFbo = (theCustomFbo != NULL && theCustomFbo->IsValid())
1364 ? theCustomFbo
1365 : (!aCtx->DefaultFrameBuffer().IsNull()
1366 && aCtx->DefaultFrameBuffer()->IsValid()
1367 ? aCtx->DefaultFrameBuffer().operator->()
1368 : NULL);
1369 if (anFbo != NULL)
1370 {
1371 anFbo->BindBuffer (aCtx);
1372 }
1373 else
1374 {
1375 #if !defined(GL_ES_VERSION_2_0)
1376 aCtx->SetReadDrawBuffer (GL_BACK);
1377 #else
1378 if (aCtx->arbFBO != NULL)
1379 {
1380 aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1381 }
1382 #endif
1383 }
1384 aCtx->core11fwd->glViewport (0, 0, myWindow->Width(), myWindow->Height());
1385}
1386
1387// =======================================================================
1388// function : initBlitQuad
1389// purpose :
1390// =======================================================================
1391OpenGl_VertexBuffer* OpenGl_View::initBlitQuad (const Standard_Boolean theToFlip)
1392{
1393 OpenGl_VertexBuffer* aVerts = NULL;
1394 if (!theToFlip)
1395 {
1396 aVerts = &myFullScreenQuad;
1397 if (!aVerts->IsValid())
1398 {
1399 OpenGl_Vec4 aQuad[4] =
1400 {
1401 OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f),
1402 OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f),
1403 OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f),
1404 OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f)
1405 };
1406 aVerts->Init (myWorkspace->GetGlContext(), 4, 4, aQuad[0].GetData());
1407 }
1408 }
1409 else
1410 {
1411 aVerts = &myFullScreenQuadFlip;
1412 if (!aVerts->IsValid())
1413 {
1414 OpenGl_Vec4 aQuad[4] =
1415 {
1416 OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 1.0f),
1417 OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 0.0f),
1418 OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
1419 OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 0.0f)
1420 };
1421 aVerts->Init (myWorkspace->GetGlContext(), 4, 4, aQuad[0].GetData());
1422 }
1423 }
1424 return aVerts;
1425}
1426
1427// =======================================================================
1428// function : blitBuffers
1429// purpose :
1430// =======================================================================
1431bool OpenGl_View::blitBuffers (OpenGl_FrameBuffer* theReadFbo,
1432 OpenGl_FrameBuffer* theDrawFbo,
1433 const Standard_Boolean theToFlip)
1434{
1435 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
1436 if (theReadFbo == NULL || aCtx->IsFeedback())
1437 {
1438 return false;
1439 }
1440 else if (theReadFbo == theDrawFbo)
1441 {
1442 return true;
1443 }
1444
1445 // clear destination before blitting
1446 if (theDrawFbo != NULL
1447 && theDrawFbo->IsValid())
1448 {
1449 theDrawFbo->BindBuffer (aCtx);
1450 }
1451 else
1452 {
1453 aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1454 }
1455#if !defined(GL_ES_VERSION_2_0)
1456 aCtx->core20fwd->glClearDepth (1.0);
1457#else
1458 aCtx->core20fwd->glClearDepthf (1.0f);
1459#endif
1460 aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1461
3c4b62a4 1462#if !defined(GL_ES_VERSION_2_0)
1463 if (aCtx->arbFBOBlit != NULL
1464 && theReadFbo->NbSamples() != 0)
c357e426 1465 {
3c4b62a4 1466 GLbitfield aCopyMask = 0;
c357e426 1467 theReadFbo->BindReadBuffer (aCtx);
1468 if (theDrawFbo != NULL
1469 && theDrawFbo->IsValid())
1470 {
1471 theDrawFbo->BindDrawBuffer (aCtx);
3c4b62a4 1472 if (theDrawFbo->HasColor()
1473 && theReadFbo->HasColor())
1474 {
1475 aCopyMask |= GL_COLOR_BUFFER_BIT;
1476 }
1477 if (theDrawFbo->HasDepth()
1478 && theReadFbo->HasDepth())
1479 {
1480 aCopyMask |= GL_DEPTH_BUFFER_BIT;
1481 }
c357e426 1482 }
1483 else
1484 {
3c4b62a4 1485 if (theReadFbo->HasColor())
1486 {
1487 aCopyMask |= GL_COLOR_BUFFER_BIT;
1488 }
1489 if (theReadFbo->HasDepth())
1490 {
1491 aCopyMask |= GL_DEPTH_BUFFER_BIT;
1492 }
c357e426 1493 aCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1494 }
3c4b62a4 1495
c357e426 1496 // we don't copy stencil buffer here... does it matter for performance?
1497 aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
1498 0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
3c4b62a4 1499 aCopyMask, GL_NEAREST);
c357e426 1500 if (theDrawFbo != NULL
3c4b62a4 1501 && theDrawFbo->IsValid())
c357e426 1502 {
1503 theDrawFbo->BindBuffer (aCtx);
1504 }
1505 else
1506 {
1507 aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1508 }
1509 }
1510 else
3c4b62a4 1511#endif
c357e426 1512 {
1513 aCtx->core20fwd->glDepthFunc (GL_ALWAYS);
1514 aCtx->core20fwd->glDepthMask (GL_TRUE);
1515 aCtx->core20fwd->glEnable (GL_DEPTH_TEST);
1516
1517 myWorkspace->DisableTexture();
1518
1519 OpenGl_VertexBuffer* aVerts = initBlitQuad (theToFlip);
1520 const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
1521 if (aVerts->IsValid()
1522 && aManager->BindFboBlitProgram())
1523 {
1524 theReadFbo->ColorTexture() ->Bind (aCtx, GL_TEXTURE0 + 0);
1525 theReadFbo->DepthStencilTexture()->Bind (aCtx, GL_TEXTURE0 + 1);
1526 aVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS);
1527
1528 aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
1529
1530 aVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS);
1531 theReadFbo->DepthStencilTexture()->Unbind (aCtx, GL_TEXTURE0 + 1);
1532 theReadFbo->ColorTexture() ->Unbind (aCtx, GL_TEXTURE0 + 0);
a521d90d 1533 aCtx->BindProgram (NULL);
c357e426 1534 }
1535 else
1536 {
1537 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
1538 + "Error! FBO blitting has failed";
3b523c4c 1539 aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1540 GL_DEBUG_TYPE_ERROR,
c357e426 1541 0,
3b523c4c 1542 GL_DEBUG_SEVERITY_HIGH,
c357e426 1543 aMsg);
1544 myHasFboBlit = Standard_False;
1545 theReadFbo->Release (aCtx.operator->());
1546 return true;
1547 }
1548 }
1549 return true;
1550}
1551
1552// =======================================================================
1553// function : drawStereoPair
1554// purpose :
1555// =======================================================================
3c4b62a4 1556void OpenGl_View::drawStereoPair (OpenGl_FrameBuffer* theDrawFbo)
c357e426 1557{
3c4b62a4 1558 const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
1559 bindDefaultFbo (theDrawFbo);
c357e426 1560 OpenGl_FrameBuffer* aPair[2] =
1561 {
1562 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
1563 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
1564 };
1565 if (aPair[0] == NULL
1566 || aPair[1] == NULL
1567 || !myTransientDrawToFront)
1568 {
1569 aPair[0] = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
1570 aPair[1] = myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL;
1571 }
1572
1573 if (aPair[0] == NULL
1574 || aPair[1] == NULL)
1575 {
1576 return;
1577 }
1578
3c4b62a4 1579 if (aPair[0]->NbSamples() != 0)
1580 {
1581 // resolve MSAA buffers before drawing
1582 if (!myOpenGlFBO ->InitLazy (aCtx, aPair[0]->GetVPSizeX(), aPair[0]->GetVPSizeY(), myFboColorFormat, myFboDepthFormat, 0)
1583 || !myOpenGlFBO2->InitLazy (aCtx, aPair[0]->GetVPSizeX(), aPair[0]->GetVPSizeY(), myFboColorFormat, 0, 0))
1584 {
82f443b6 1585 aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1586 GL_DEBUG_TYPE_ERROR,
3c4b62a4 1587 0,
82f443b6 1588 GL_DEBUG_SEVERITY_HIGH,
3c4b62a4 1589 "Error! Unable to allocate FBO for blitting stereo pair");
1590 bindDefaultFbo (theDrawFbo);
1591 return;
1592 }
1593
1594 if (!blitBuffers (aPair[0], myOpenGlFBO .operator->(), Standard_False)
1595 || !blitBuffers (aPair[1], myOpenGlFBO2.operator->(), Standard_False))
1596 {
1597 bindDefaultFbo (theDrawFbo);
1598 return;
1599 }
1600
1601 aPair[0] = myOpenGlFBO .operator->();
1602 aPair[1] = myOpenGlFBO2.operator->();
1603 bindDefaultFbo (theDrawFbo);
1604 }
1605
c357e426 1606 struct
1607 {
1608 Standard_Integer left;
1609 Standard_Integer top;
1610 Standard_Integer right;
1611 Standard_Integer bottom;
1612 Standard_Integer dx() { return right - left; }
1613 Standard_Integer dy() { return bottom - top; }
1614 } aGeom;
1615
1616 myWindow->PlatformWindow()->Position (aGeom.left, aGeom.top, aGeom.right, aGeom.bottom);
1617
1618 Standard_Boolean toReverse = myRenderParams.ToReverseStereo;
1619 const Standard_Boolean isOddY = (aGeom.top + aGeom.dy()) % 2 == 1;
1620 const Standard_Boolean isOddX = aGeom.left % 2 == 1;
1621 if (isOddY
1622 && (myRenderParams.StereoMode == Graphic3d_StereoMode_RowInterlaced
1623 || myRenderParams.StereoMode == Graphic3d_StereoMode_ChessBoard))
1624 {
1625 toReverse = !toReverse;
1626 }
1627 if (isOddX
1628 && (myRenderParams.StereoMode == Graphic3d_StereoMode_ColumnInterlaced
1629 || myRenderParams.StereoMode == Graphic3d_StereoMode_ChessBoard))
1630 {
1631 toReverse = !toReverse;
1632 }
1633
1634 if (toReverse)
1635 {
1636 std::swap (aPair[0], aPair[1]);
1637 }
1638
c357e426 1639 aCtx->core20fwd->glDepthFunc (GL_ALWAYS);
1640 aCtx->core20fwd->glDepthMask (GL_TRUE);
1641 aCtx->core20fwd->glEnable (GL_DEPTH_TEST);
1642
1643 myWorkspace->DisableTexture();
1644 OpenGl_VertexBuffer* aVerts = initBlitQuad (myToFlipOutput);
1645
1646 const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
1647 if (aVerts->IsValid()
1648 && aManager->BindStereoProgram (myRenderParams.StereoMode))
1649 {
1650 if (myRenderParams.StereoMode == Graphic3d_StereoMode_Anaglyph)
1651 {
1652 OpenGl_Mat4 aFilterL, aFilterR;
1653 aFilterL.SetDiagonal (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
1654 aFilterR.SetDiagonal (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
1655 switch (myRenderParams.AnaglyphFilter)
1656 {
1657 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple:
1658 {
1659 aFilterL.SetRow (0, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f));
1660 aFilterR.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f));
1661 aFilterR.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f));
1662 break;
1663 }
1664 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized:
1665 {
1666 aFilterL.SetRow (0, Graphic3d_Vec4 ( 0.4154f, 0.4710f, 0.16666667f, 0.0f));
1667 aFilterL.SetRow (1, Graphic3d_Vec4 (-0.0458f, -0.0484f, -0.0257f, 0.0f));
1668 aFilterL.SetRow (2, Graphic3d_Vec4 (-0.0547f, -0.0615f, 0.0128f, 0.0f));
1669 aFilterL.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f));
1670 aFilterR.SetRow (0, Graphic3d_Vec4 (-0.01090909f, -0.03636364f, -0.00606061f, 0.0f));
1671 aFilterR.SetRow (1, Graphic3d_Vec4 ( 0.37560000f, 0.73333333f, 0.01111111f, 0.0f));
1672 aFilterR.SetRow (2, Graphic3d_Vec4 (-0.06510000f, -0.12870000f, 1.29710000f, 0.0f));
1673 aFilterR.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f));
1674 break;
1675 }
1676 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple:
1677 {
1678 aFilterL.SetRow (0, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f));
1679 aFilterL.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f));
1680 aFilterR.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f));
1681 break;
1682 }
1683 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized:
1684 {
1685 aFilterL.SetRow (0, Graphic3d_Vec4 ( 1.062f, -0.205f, 0.299f, 0.0f));
1686 aFilterL.SetRow (1, Graphic3d_Vec4 (-0.026f, 0.908f, 0.068f, 0.0f));
1687 aFilterL.SetRow (2, Graphic3d_Vec4 (-0.038f, -0.173f, 0.022f, 0.0f));
1688 aFilterL.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f));
1689 aFilterR.SetRow (0, Graphic3d_Vec4 (-0.016f, -0.123f, -0.017f, 0.0f));
1690 aFilterR.SetRow (1, Graphic3d_Vec4 ( 0.006f, 0.062f, -0.017f, 0.0f));
1691 aFilterR.SetRow (2, Graphic3d_Vec4 ( 0.094f, 0.185f, 0.911f, 0.0f));
1692 aFilterR.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f));
1693 break;
1694 }
1695 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple:
1696 {
1697 aFilterR.SetRow (0, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f));
1698 aFilterL.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f));
1699 aFilterR.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f));
1700 break;
1701 }
1702 case Graphic3d_RenderingParams::Anaglyph_UserDefined:
1703 {
1704 aFilterL = myRenderParams.AnaglyphLeft;
1705 aFilterR = myRenderParams.AnaglyphRight;
1706 break;
1707 }
1708 }
1709 aCtx->ActiveProgram()->SetUniform (aCtx, "uMultL", aFilterL);
1710 aCtx->ActiveProgram()->SetUniform (aCtx, "uMultR", aFilterR);
1711 }
1712
1713 aPair[0]->ColorTexture()->Bind (aCtx, GL_TEXTURE0 + 0);
1714 aPair[1]->ColorTexture()->Bind (aCtx, GL_TEXTURE0 + 1);
1715 aVerts->BindVertexAttrib (aCtx, 0);
1716
1717 aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
1718
1719 aVerts->UnbindVertexAttrib (aCtx, 0);
1720 aPair[1]->ColorTexture()->Unbind (aCtx, GL_TEXTURE0 + 1);
1721 aPair[0]->ColorTexture()->Unbind (aCtx, GL_TEXTURE0 + 0);
1722 }
1723 else
1724 {
1725 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
1726 + "Error! Anaglyph has failed";
3b523c4c 1727 aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1728 GL_DEBUG_TYPE_ERROR,
c357e426 1729 0,
3b523c4c 1730 GL_DEBUG_SEVERITY_HIGH,
c357e426 1731 aMsg);
1732 }
1733}
1734
1735// =======================================================================
1736// function : copyBackToFront
1737// purpose :
1738// =======================================================================
1739void OpenGl_View::copyBackToFront()
1740{
1741#if !defined(GL_ES_VERSION_2_0)
1742
1743 OpenGl_Mat4 aProjectMat;
1744 Graphic3d_TransformUtils::Ortho2D (aProjectMat,
1745 0.f, static_cast<GLfloat> (myWindow->Width()), 0.f, static_cast<GLfloat> (myWindow->Height()));
1746
1747 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
1748 aCtx->WorldViewState.Push();
1749 aCtx->ProjectionState.Push();
1750
1751 aCtx->WorldViewState.SetIdentity();
1752 aCtx->ProjectionState.SetCurrent (aProjectMat);
1753
1754 aCtx->ApplyProjectionMatrix();
1755 aCtx->ApplyWorldViewMatrix();
1756
1757 aCtx->DisableFeatures();
1758
1759 switch (aCtx->DrawBuffer())
1760 {
1761 case GL_BACK_LEFT:
1762 {
1763 aCtx->SetReadBuffer (GL_BACK_LEFT);
1764 aCtx->SetDrawBuffer (GL_FRONT_LEFT);
1765 break;
1766 }
1767 case GL_BACK_RIGHT:
1768 {
1769 aCtx->SetReadBuffer (GL_BACK_RIGHT);
1770 aCtx->SetDrawBuffer (GL_FRONT_RIGHT);
1771 break;
1772 }
1773 default:
1774 {
1775 aCtx->SetReadBuffer (GL_BACK);
1776 aCtx->SetDrawBuffer (GL_FRONT);
1777 break;
1778 }
1779 }
1780
1781 glRasterPos2i (0, 0);
1782 glCopyPixels (0, 0, myWindow->Width() + 1, myWindow->Height() + 1, GL_COLOR);
1783 //glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_DEPTH);
1784
1785 aCtx->EnableFeatures();
1786
1787 aCtx->WorldViewState.Pop();
1788 aCtx->ProjectionState.Pop();
1789 aCtx->ApplyProjectionMatrix();
1790
1791 // read/write from front buffer now
1792 aCtx->SetReadBuffer (aCtx->DrawBuffer());
1793#endif
1794 myIsImmediateDrawn = Standard_False;
1795}