1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
19 #include <OpenGl_GlCore11.hxx>
20 #include <OpenGl_tgl_funcs.hxx>
22 #include <Graphic3d_TextureParams.hxx>
23 #include <Graphic3d_Texture2Dmanual.hxx>
24 #include <Image_AlienPixMap.hxx>
25 #include <Visual3d_Layer.hxx>
27 #include <NCollection_Mat4.hxx>
29 #include <OpenGl_AspectLine.hxx>
30 #include <OpenGl_Context.hxx>
31 #include <OpenGl_Matrix.hxx>
32 #include <OpenGl_Workspace.hxx>
33 #include <OpenGl_View.hxx>
34 #include <OpenGl_Trihedron.hxx>
35 #include <OpenGl_GraduatedTrihedron.hxx>
36 #include <OpenGl_PrimitiveArray.hxx>
37 #include <OpenGl_PrinterContext.hxx>
38 #include <OpenGl_ShaderManager.hxx>
39 #include <OpenGl_ShaderProgram.hxx>
40 #include <OpenGl_Structure.hxx>
41 #include <OpenGl_ArbFBO.hxx>
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;
55 extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
57 /*----------------------------------------------------------------------*/
59 struct OPENGL_CLIP_PLANE
66 /*----------------------------------------------------------------------*/
71 #if !defined(GL_ES_VERSION_2_0)
72 /*-----------------------------------------------------------------*/
76 static void bindLight (const OpenGl_Light& theLight,
78 Graphic3d_Vec4& theAmbientColor,
79 const Handle(OpenGl_Workspace)& theWorkspace)
81 // Only 8 lights in OpenGL...
82 if (theLightGlId > GL_LIGHT7)
87 if (theLight.Type == Visual3d_TOLS_AMBIENT)
89 // add RGBA intensity of the ambient light
90 theAmbientColor += theLight.Color;
94 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
96 // the light is a headlight?
97 if (theLight.IsHeadlight)
100 aContext->WorldViewState.Push();
101 aContext->WorldViewState.SetIdentity();
103 aContext->ApplyWorldViewMatrix();
107 switch (theLight.Type)
109 case Visual3d_TOLS_DIRECTIONAL:
111 // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
112 const OpenGl_Vec4 anInfDir = -theLight.Direction;
114 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
115 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
116 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
117 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
118 glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
119 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
120 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
121 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
124 case Visual3d_TOLS_POSITIONAL:
126 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
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, THE_DEFAULT_SPOT_DIR);
132 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
133 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
134 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
135 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
136 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
139 case Visual3d_TOLS_SPOT:
141 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
142 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
143 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
144 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
145 glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
146 glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
147 glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
148 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
149 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
150 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
155 // restore matrix in case of headlight
156 if (theLight.IsHeadlight)
158 aContext->WorldViewState.Pop();
161 glEnable (theLightGlId++);
165 /*----------------------------------------------------------------------*/
167 void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
169 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
171 if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background
172 || (!myBgTextureArray->IsDefined() // no texture
173 && !myBgGradientArray->IsDefined())) // no gradient
178 aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
180 aCtx->WorldViewState.Push();
181 aCtx->ProjectionState.Push();
182 aCtx->WorldViewState.SetIdentity();
183 aCtx->ProjectionState.SetIdentity();
184 aCtx->ApplyProjectionMatrix();
185 aCtx->ApplyWorldViewMatrix();
187 // Drawing background gradient if:
188 // - gradient fill type is not Aspect_GFM_NONE and
189 // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
190 if (myBgGradientArray->IsDefined()
191 && (!myTextureParams->DoTextureMap()
192 || myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED
193 || myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE))
195 #if !defined(GL_ES_VERSION_2_0)
196 GLint aShadingModelOld = GL_SMOOTH;
197 if (aCtx->core11 != NULL)
199 aCtx->core11fwd->glDisable (GL_LIGHTING);
200 aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld);
201 aCtx->core11->glShadeModel (GL_SMOOTH);
205 if (myBgGradientArray->IsDataChanged())
207 myBgGradientArray->Init (theWorkspace);
210 myBgGradientArray->Render (theWorkspace);
212 #if !defined(GL_ES_VERSION_2_0)
213 if (aCtx->core11 != NULL)
215 aCtx->core11->glShadeModel (aShadingModelOld);
220 // Drawing background image if it is defined
221 // (texture is defined and fill type is not Aspect_FM_NONE)
222 if (myBgTextureArray->IsDefined()
223 && myTextureParams->DoTextureMap())
225 aCtx->core11fwd->glDisable (GL_BLEND);
227 const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams);
229 if (myBgTextureArray->IsDataChanged()
230 || myBgTextureArray->IsViewSizeChanged (theWorkspace))
232 myBgTextureArray->Init (theWorkspace);
235 myBgTextureArray->Render (theWorkspace);
238 theWorkspace->SetAspectFace (anOldAspectFace);
241 aCtx->WorldViewState.Pop();
242 aCtx->ProjectionState.Pop();
243 aCtx->ApplyProjectionMatrix();
245 if (theWorkspace->UseZBuffer())
247 aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
251 /*----------------------------------------------------------------------*/
253 //call_func_redraw_all_structs_proc
254 void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
255 const Handle(OpenGl_Workspace)& theWorkspace,
256 const Graphic3d_CView& theCView,
257 const Aspect_CLayer2d& theCUnderLayer,
258 const Aspect_CLayer2d& theCOverLayer,
259 const Standard_Boolean theToDrawImmediate)
261 // ==================================
262 // Step 1: Prepare for redraw
263 // ==================================
265 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
267 #if !defined(GL_ES_VERSION_2_0)
268 // store and disable current clipping planes
269 const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
270 NCollection_Array1<OPENGL_CLIP_PLANE> aOldPlanes (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + aMaxPlanes - 1);
271 if (aContext->core11 != NULL)
273 for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
275 OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
276 aContext->core11->glGetClipPlane (aClipPlaneId, aPlane.Equation);
277 if (aPlane.isEnabled)
279 aContext->core11fwd->glDisable (aClipPlaneId);
280 aPlane.isEnabled = GL_TRUE;
284 aPlane.isEnabled = GL_FALSE;
290 // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
291 Standard_Boolean isProjectionMatUpdateNeeded = Standard_False;
292 Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
293 if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
295 isProjectionMatUpdateNeeded = Standard_True;
296 myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState();
298 if (myBVHSelector.ModelViewState() != myCamera->ModelViewState())
300 isOrientationMatUpdateNeeded = Standard_True;
301 myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
304 if (isProjectionMatUpdateNeeded
305 || isOrientationMatUpdateNeeded)
307 myBVHSelector.SetViewVolume (myCamera);
310 const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager();
311 const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed
312 if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
314 aManager->UpdateLightSourceStateTo (&myLights);
315 myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
318 if (myProjectionState != myCamera->ProjectionState()
321 myProjectionState = myCamera->ProjectionState();
322 aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
323 aContext->ApplyProjectionMatrix();
326 if (myModelViewState != myCamera->ModelViewState()
329 myModelViewState = myCamera->ModelViewState();
330 aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF());
331 aContext->ApplyWorldViewMatrix();
334 if (aManager->ModelWorldState().Index() == 0)
336 aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
339 // ====================================
340 // Step 2: Redraw background
341 // ====================================
344 if (!theToDrawImmediate)
346 DrawBackground (theWorkspace);
349 #if !defined(GL_ES_VERSION_2_0)
350 // Switch off lighting by default
351 if (aContext->core11 != NULL)
353 glDisable(GL_LIGHTING);
357 // =================================
358 // Step 3: Draw underlayer
359 // =================================
360 if (!theToDrawImmediate)
362 RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCUnderLayer);
365 // =================================
366 // Step 4: Redraw main plane
367 // =================================
369 // Setup face culling
370 GLboolean isCullFace = GL_FALSE;
373 isCullFace = glIsEnabled( GL_CULL_FACE );
374 if ( myBackfacing < 0 )
376 glEnable( GL_CULL_FACE );
377 glCullFace( GL_BACK );
380 glDisable( GL_CULL_FACE );
383 #if !defined(GL_ES_VERSION_2_0)
384 // if the view is scaled normal vectors are scaled to unit
385 // length for correct displaying of shaded objects
386 const gp_Pnt anAxialScale = myCamera->AxialScale();
387 if (anAxialScale.X() != 1.F ||
388 anAxialScale.Y() != 1.F ||
389 anAxialScale.Z() != 1.F)
391 aContext->SetGlNormalizeEnabled (Standard_True);
395 aContext->SetGlNormalizeEnabled (Standard_False);
400 && aContext->core11 != NULL)
402 Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
403 if (myCamera->ZFar() < aFogFrontConverted)
405 aFogFrontConverted = myCamera->ZFar();
406 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
409 Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
410 if (myCamera->ZFar() < aFogFrontConverted)
412 aFogBackConverted = myCamera->ZFar();
413 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
416 if (aFogFrontConverted > aFogBackConverted)
418 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
419 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
422 glFogi(GL_FOG_MODE, GL_LINEAR);
423 glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
424 glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
425 glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
428 else if (aContext->core11 != NULL)
433 // Apply InteriorShadingMethod
434 if (aContext->core11 != NULL)
436 aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET
437 || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH);
441 aManager->SetShadingModel (myShadingModel);
443 // Apply AntiAliasing
445 theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
447 theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
449 if (!aManager->IsEmpty())
451 aManager->UpdateClippingState();
455 if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
457 // single-pass monographic rendering
458 // redraw scene with normal orientation and projection
459 RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
463 // two stereographic passes
465 // safely switch to left Eye buffer
466 aContext->SetDrawBufferLeft();
468 aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF());
469 aContext->ApplyProjectionMatrix();
472 RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
474 // reset depth buffer of first rendering pass
475 if (theWorkspace->UseDepthTest())
477 glClear (GL_DEPTH_BUFFER_BIT);
479 // safely switch to right Eye buffer
480 aContext->SetDrawBufferRight();
482 aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF());
483 aContext->ApplyProjectionMatrix();
486 RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
488 // switch back to monographic rendering
489 aContext->SetDrawBufferMono();
492 // ===============================
494 // ===============================
496 // Resetting GL parameters according to the default aspects
497 // in order to synchronize GL state with the graphic driver state
498 // before drawing auxiliary stuff (trihedrons, overlayer)
499 // and invoking optional callbacks
500 theWorkspace->ResetAppliedAspect();
502 aContext->ChangeClipping().RemoveAll();
504 if (!aManager->IsEmpty())
506 aManager->ResetMaterialStates();
507 aManager->RevertClippingState();
509 // We need to disable (unbind) all shaders programs to ensure
510 // that all objects without specified aspect will be drawn
511 // correctly (such as background)
512 aContext->BindProgram (NULL);
516 if (!theToDrawImmediate)
518 RedrawTrihedron (theWorkspace);
520 // Restore face culling
525 glEnable ( GL_CULL_FACE );
526 glCullFace ( GL_BACK );
529 glDisable ( GL_CULL_FACE );
533 // ===============================
534 // Step 6: Redraw overlay
535 // ===============================
536 if (!theToDrawImmediate)
539 theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
541 RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer);
543 theWorkspace->DisplayCallback (theCView, aMode);
546 // ===============================
548 // ===============================
550 #if !defined(GL_ES_VERSION_2_0)
551 // restore clipping planes
552 if (aContext->core11 != NULL)
554 for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
556 const OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
557 aContext->core11->glClipPlane (aClipPlaneId, aPlane.Equation);
558 if (aPlane.isEnabled)
559 aContext->core11fwd->glEnable (aClipPlaneId);
561 aContext->core11fwd->glDisable (aClipPlaneId);
566 // ==============================================================
567 // Step 8: Keep shader manager informed about last View
568 // ==============================================================
570 if (!aManager.IsNull())
572 aManager->SetLastView (this);
576 // =======================================================================
577 // function : InvalidateBVHData
579 // =======================================================================
580 void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
582 myZLayers.InvalidateBVHData (theLayerId);
585 /*----------------------------------------------------------------------*/
588 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& theWorkspace,
589 const Graphic3d_CView& theCView,
590 const Standard_Boolean theToDrawImmediate)
592 if ( myZLayers.NbStructures() <= 0 )
595 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
597 if ( (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
599 #if !defined(GL_ES_VERSION_2_0)
600 const int anAntiAliasingMode = theWorkspace->AntiAliasingMode();
603 if ( !myAntiAliasing )
605 #if !defined(GL_ES_VERSION_2_0)
606 if (aCtx->core11 != NULL)
608 glDisable (GL_POINT_SMOOTH);
610 glDisable(GL_LINE_SMOOTH);
611 if( anAntiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
613 glBlendFunc (GL_ONE, GL_ZERO);
614 glDisable (GL_BLEND);
618 #if !defined(GL_ES_VERSION_2_0)
619 if (aCtx->core11 != NULL)
621 glEnable(GL_POINT_SMOOTH);
623 glEnable(GL_LINE_SMOOTH);
624 if( anAntiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
626 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
631 Standard_Boolean toRenderGL = theToDrawImmediate ||
632 theCView.RenderParams.Method != Graphic3d_RM_RAYTRACING || myRaytraceInitStatus == OpenGl_RT_FAIL;
636 toRenderGL = !initRaytraceResources (theCView, aCtx) ||
637 !updateRaytraceGeometry (OpenGl_GUM_CHECK, theWorkspace->ActiveViewId(), aCtx);
639 OpenGl_FrameBuffer* anOutputFBO = NULL;
641 if (theWorkspace->ResultFBO()->IsValid())
643 anOutputFBO = theWorkspace->ResultFBO().operator->();
645 else if (theCView.ptrFBO != NULL)
647 anOutputFBO = (OpenGl_FrameBuffer* )theCView.ptrFBO;
651 //toRenderGL = Standard_True; // failed to get valid FBO
654 if (!toRenderGL && myIsRaytraceDataValid)
656 const Standard_Integer aSizeX = anOutputFBO != NULL ?
657 anOutputFBO->GetVPSizeX() : theWorkspace->Width();
658 const Standard_Integer aSizeY = anOutputFBO != NULL ?
659 anOutputFBO->GetVPSizeY() : theWorkspace->Height();
661 if (myOpenGlFBO.IsNull())
662 myOpenGlFBO = new OpenGl_FrameBuffer;
664 if (myOpenGlFBO->GetVPSizeX() != aSizeX
665 || myOpenGlFBO->GetVPSizeY() != aSizeY)
667 myOpenGlFBO->Init (aCtx, aSizeX, aSizeY);
670 if (myRaytraceFilter.IsNull())
671 myRaytraceFilter = new OpenGl_RaytraceFilter;
673 myRaytraceFilter->SetPrevRenderFilter (theWorkspace->GetRenderFilter());
675 if (anOutputFBO != NULL)
676 anOutputFBO->UnbindBuffer (aCtx);
678 // Prepare preliminary OpenGL output
679 if (aCtx->arbFBOBlit != NULL)
681 // Render bottom OSD layer
682 myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Bottom);
684 theWorkspace->SetRenderFilter (myRaytraceFilter);
686 if (anOutputFBO != NULL)
688 anOutputFBO->BindReadBuffer (aCtx);
692 aCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
695 myOpenGlFBO->BindDrawBuffer (aCtx);
697 aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, aSizeX, aSizeY,
698 0, 0, aSizeX, aSizeY,
699 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
702 // Render non-polygonal elements in default layer
703 myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Default);
705 theWorkspace->SetRenderFilter (myRaytraceFilter->PrevRenderFilter());
708 if (anOutputFBO != NULL)
710 anOutputFBO->BindBuffer (aCtx);
714 aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, 0);
717 // Ray-tracing polygonal primitive arrays
718 raytrace (theCView, aSizeX, aSizeY, anOutputFBO, aCtx);
720 // Render upper (top and topmost) OpenGL layers
721 myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Upper);
725 // Redraw 3D scene using OpenGL in standard
726 // mode or in case of ray-tracing failure
729 myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_All);
731 // Set flag that scene was redrawn by standard pipeline
732 theCView.WasRedrawnGL = Standard_True;
736 /*----------------------------------------------------------------------*/
738 //call_togl_redraw_layer2d
739 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
740 const Handle(OpenGl_Workspace)& theWorkspace,
741 const Graphic3d_CView& /*ACView*/,
742 const Aspect_CLayer2d& ACLayer)
744 #if !defined(GL_ES_VERSION_2_0)
746 || ACLayer.ptrLayer == NULL
747 || ACLayer.ptrLayer->listIndex == 0) return;
749 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
750 if (aContext->core11 == NULL)
755 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
756 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
758 aContext->WorldViewState.Push();
759 aContext->ProjectionState.Push();
761 aContext->WorldViewState.SetIdentity();
762 aContext->ProjectionState.SetIdentity();
764 aContext->ApplyWorldViewMatrix();
765 aContext->ApplyProjectionMatrix();
767 if (!ACLayer.sizeDependent)
768 aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight);
770 float left = ACLayer.ortho[0];
771 float right = ACLayer.ortho[1];
772 float bottom = ACLayer.ortho[2];
773 float top = ACLayer.ortho[3];
775 int attach = ACLayer.attach;
777 const float ratio = !ACLayer.sizeDependent
778 ? float(dispWidth) / float(dispHeight)
779 : float(theWorkspace->Width()) / float(theWorkspace->Height());
783 delta = (float )((top - bottom)/2.0);
785 case 0: /* Aspect_TOC_BOTTOM_LEFT */
786 top = bottom + 2*delta/ratio;
788 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
789 top = bottom + 2*delta/ratio;
791 case 2: /* Aspect_TOC_TOP_LEFT */
792 bottom = top - 2*delta/ratio;
794 case 3: /* Aspect_TOC_TOP_RIGHT */
795 bottom = top - 2*delta/ratio;
800 delta = (float )((right - left)/2.0);
802 case 0: /* Aspect_TOC_BOTTOM_LEFT */
803 right = left + 2*delta*ratio;
805 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
806 left = right - 2*delta*ratio;
808 case 2: /* Aspect_TOC_TOP_LEFT */
809 right = left + 2*delta*ratio;
811 case 3: /* Aspect_TOC_TOP_RIGHT */
812 left = right - 2*delta*ratio;
818 // Check printer context that exists only for print operation
819 if (!thePrintContext.IsNull())
821 // additional transformation matrix could be applied to
822 // render only those parts of viewport that will be
823 // passed to a printer as a current "frame" to provide
824 // tiling; scaling of graphics by matrix helps render a
825 // part of a view (frame) in same viewport, but with higher
828 // set printing scale/tiling transformation
829 aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation());
830 aContext->ApplyProjectionMatrix();
832 // printing operation also assumes other viewport dimension
833 // to comply with transformation matrix or graphics scaling
834 // factors for tiling for layer redraw
835 GLsizei anViewportX = 0;
836 GLsizei anViewportY = 0;
837 thePrintContext->GetLayerViewport (anViewportX, anViewportY);
838 if (anViewportX != 0 && anViewportY != 0)
839 aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY);
843 glOrtho (left, right, bottom, top, -1.0, 1.0);
846 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
847 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
849 glDisable (GL_DEPTH_TEST);
850 glDisable (GL_TEXTURE_1D);
851 glDisable (GL_TEXTURE_2D);
852 glDisable (GL_LIGHTING);
854 // TODO: Obsolete code, the display list is always empty now, to be removed
855 glCallList (ACLayer.ptrLayer->listIndex);
857 //calling dynamic render of LayerItems
858 if ( ACLayer.ptrLayer->layerData )
860 InitLayerProp (ACLayer.ptrLayer->listIndex);
861 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
867 aContext->WorldViewState.Pop();
868 aContext->ProjectionState.Pop();
870 aContext->ApplyProjectionMatrix();
871 aContext->ApplyWorldViewMatrix();
873 if (!ACLayer.sizeDependent)
874 aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height());
880 /*----------------------------------------------------------------------*/
882 void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
884 // display global trihedron
885 if (myToShowTrihedron)
887 myTrihedron.Render (theWorkspace);
889 if (myToShowGradTrihedron)
891 myGraduatedTrihedron.Render (theWorkspace);
895 /*----------------------------------------------------------------------*/
897 //call_togl_create_bg_texture
898 void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
899 const Aspect_FillMethod theFillStyle)
901 // Prepare aspect for texture storage
902 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
903 Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
904 aTextureMap->EnableRepeat();
905 aTextureMap->DisableModulate();
906 aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
907 Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
908 Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
909 anAspect->SetTextureMap (aTextureMap);
910 anAspect->SetInteriorStyle (Aspect_IS_SOLID);
911 // Enable texture mapping
912 if (aTextureMap->IsDone())
914 anAspect->SetTextureMapOn();
918 anAspect->SetTextureMapOff();
923 // Set texture parameters
924 myTextureParams->SetAspect (anAspect);
926 myBgTextureArray->SetTextureParameters (theFillStyle);
929 /*----------------------------------------------------------------------*/
931 //call_togl_set_bg_texture_style
932 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod theFillStyle)
934 myBgTextureArray->SetTextureFillMethod (theFillStyle);
937 /*----------------------------------------------------------------------*/
939 //call_togl_gradient_background
940 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& theColor1,
941 const Quantity_Color& theColor2,
942 const Aspect_GradientFillMethod theType)
944 myBgGradientArray->SetGradientParameters (theColor1, theColor2, theType);
947 /*----------------------------------------------------------------------*/
949 //call_togl_set_gradient_type
950 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod theType)
952 myBgGradientArray->SetGradientFillMethod (theType);
955 //=======================================================================
956 //function : AddZLayer
958 //=======================================================================
960 void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
962 myZLayers.AddLayer (theLayerId);
965 //=======================================================================
966 //function : RemoveZLayer
968 //=======================================================================
970 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
972 myZLayers.RemoveLayer (theLayerId);
975 //=======================================================================
976 //function : DisplayStructure
978 //=======================================================================
980 void OpenGl_View::DisplayStructure (const Handle(Graphic3d_Structure)& theStructure,
981 const Standard_Integer thePriority)
983 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
984 const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
985 myZLayers.AddStructure (aStruct, aZLayer, thePriority);
988 //=======================================================================
989 //function : DisplayImmediateStructure
991 //=======================================================================
993 void OpenGl_View::DisplayImmediateStructure (const Handle(Graphic3d_Structure)& theStructure)
995 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
996 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
997 anIter.More(); anIter.Next())
999 if (anIter.Value() == aStruct)
1005 myImmediateList.Append (aStruct);
1008 //=======================================================================
1009 //function : EraseStructure
1011 //=======================================================================
1013 void OpenGl_View::EraseStructure (const Handle(Graphic3d_Structure)& theStructure)
1015 myZLayers.RemoveStructure (theStructure);
1018 //=======================================================================
1019 //function : EraseImmediateStructure
1021 //=======================================================================
1023 void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
1025 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1026 anIter.More(); anIter.Next())
1028 if (anIter.Value() == theStructure)
1030 myImmediateList.Remove (anIter);
1036 //=======================================================================
1037 //function : ChangeZLayer
1039 //=======================================================================
1041 void OpenGl_View::ChangeZLayer (const OpenGl_Structure* theStructure,
1042 const Graphic3d_ZLayerId theNewLayerId)
1044 const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
1045 myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
1048 //=======================================================================
1049 //function : SetZLayerSettings
1051 //=======================================================================
1052 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
1053 const Graphic3d_ZLayerSettings& theSettings)
1055 myZLayers.SetLayerSettings (theLayerId, theSettings);
1058 //=======================================================================
1059 //function : ChangePriority
1061 //=======================================================================
1062 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
1063 const Standard_Integer theNewPriority)
1065 const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
1066 myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
1069 //=======================================================================
1070 //function : RedrawScene
1072 //=======================================================================
1074 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
1075 const Handle(OpenGl_Workspace)& theWorkspace,
1076 const Graphic3d_CView& theCView,
1077 const Standard_Boolean theToDrawImmediate)
1079 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
1081 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
1083 Handle(Graphic3d_ClipPlane) aPlaneBack;
1084 Handle(Graphic3d_ClipPlane) aPlaneFront;
1086 if (myZClip.Back.IsOn)
1088 Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1089 if (myCamera->ZFar() < aClipBackConverted)
1091 aClipBackConverted = myCamera->ZFar();
1092 myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1094 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1095 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1098 if (myZClip.Front.IsOn)
1100 Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1101 if (myCamera->ZNear() > aClipFrontConverted)
1103 aClipFrontConverted = myCamera->ZNear();
1104 myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1106 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1107 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1110 // Specify slicing planes with identity transformation
1111 if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1113 Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1114 if (!aPlaneBack.IsNull())
1116 aSlicingPlanes.Append (aPlaneBack);
1119 if (!aPlaneFront.IsNull())
1121 aSlicingPlanes.Append (aPlaneFront);
1124 // add planes at loaded view matrix state
1125 aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1130 // set printing scale/tiling transformation
1131 if (!thePrintContext.IsNull())
1133 aContext->ProjectionState.Push();
1134 aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current());
1135 aContext->ApplyProjectionMatrix();
1139 // Specify clipping planes in view transformation space
1140 if (!myClipPlanes.IsEmpty())
1142 Graphic3d_SequenceOfHClipPlane aUserPlanes;
1143 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1144 for (; aClippingIt.More(); aClippingIt.Next())
1146 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1147 if (aClipPlane->IsOn())
1149 aUserPlanes.Append (aClipPlane);
1153 if (!aUserPlanes.IsEmpty())
1155 aContext->ChangeClipping().AddWorld (aUserPlanes);
1158 if (!aContext->ShaderManager()->IsEmpty())
1160 aContext->ShaderManager()->UpdateClippingState();
1164 #if !defined(GL_ES_VERSION_2_0)
1166 if (aContext->core11 != NULL)
1169 Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1170 THE_DEFAULT_AMBIENT[1],
1171 THE_DEFAULT_AMBIENT[2],
1172 THE_DEFAULT_AMBIENT[3]);
1173 GLenum aLightGlId = GL_LIGHT0;
1174 for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1175 aLightIt.More(); aLightIt.Next())
1177 bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace);
1180 // apply accumulated ambient color
1181 anAmbientColor.a() = 1.0f;
1182 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1184 if (aLightGlId != GL_LIGHT0)
1186 glEnable (GL_LIGHTING);
1188 // switch off unused lights
1189 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1191 glDisable (aLightGlId);
1196 // Clear status bitfields
1197 theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1199 // Update state of surface detail level
1200 theWorkspace->GetGlContext()->ShaderManager()->UpdateSurfaceDetailStateTo (mySurfaceDetail);
1202 // Added PCT for handling of textures
1203 switch (mySurfaceDetail)
1205 case Visual3d_TOD_NONE:
1206 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1207 theWorkspace->DisableTexture();
1209 RenderStructs (theWorkspace, theCView, theToDrawImmediate);
1212 case Visual3d_TOD_ENVIRONMENT:
1213 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1214 theWorkspace->EnableTexture (myTextureEnv);
1216 RenderStructs (theWorkspace, theCView, theToDrawImmediate);
1217 theWorkspace->DisableTexture();
1220 case Visual3d_TOD_ALL:
1222 theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1224 RenderStructs (theWorkspace, theCView, theToDrawImmediate);
1225 theWorkspace->DisableTexture();
1228 if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1230 theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1231 theWorkspace->EnableTexture (myTextureEnv);
1233 // Remember OpenGl properties
1234 GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
1235 GLint aSaveZbuffFunc;
1236 GLboolean aSaveZbuffWrite;
1237 glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1238 glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1239 #if !defined(GL_ES_VERSION_2_0)
1240 glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1241 glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1243 GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1244 GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1246 // Change the properties for second rendering pass
1247 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1248 glEnable (GL_BLEND);
1250 glDepthFunc (GL_EQUAL);
1251 glDepthMask (GL_FALSE);
1252 glEnable (GL_DEPTH_TEST);
1254 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1257 RenderStructs (theWorkspace, theCView, theToDrawImmediate);
1258 theWorkspace->DisableTexture();
1260 // Restore properties back
1261 glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1262 if (!wasBlendEnabled)
1263 glDisable (GL_BLEND);
1265 glDepthFunc (aSaveZbuffFunc);
1266 glDepthMask (aSaveZbuffWrite);
1267 if (!wasZbuffEnabled)
1268 glDisable (GL_DEPTH_FUNC);
1273 // Apply restored view matrix.
1274 aContext->ApplyWorldViewMatrix();
1277 // set printing scale/tiling transformation
1278 if (!thePrintContext.IsNull())
1280 aContext->ProjectionState.Pop();
1281 aContext->ApplyProjectionMatrix();