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