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