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