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>
47 static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
48 static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
49 static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
50 static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
54 extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
56 /*----------------------------------------------------------------------*/
58 struct OPENGL_CLIP_PLANE
65 /*----------------------------------------------------------------------*/
70 #if !defined(GL_ES_VERSION_2_0)
71 /*-----------------------------------------------------------------*/
75 static void bindLight (const OpenGl_Light& theLight,
77 Graphic3d_Vec4& theAmbientColor,
78 const Handle(OpenGl_Workspace)& theWorkspace)
80 // Only 8 lights in OpenGL...
81 if (theLightGlId > GL_LIGHT7)
86 if (theLight.Type == Visual3d_TOLS_AMBIENT)
88 // add RGBA intensity of the ambient light
89 theAmbientColor += theLight.Color;
93 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
95 // the light is a headlight?
96 if (theLight.IsHeadlight)
99 aContext->WorldViewState.Push();
100 aContext->WorldViewState.SetIdentity();
102 aContext->ApplyWorldViewMatrix();
106 switch (theLight.Type)
108 case Visual3d_TOLS_DIRECTIONAL:
110 // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
111 const OpenGl_Vec4 anInfDir = -theLight.Direction;
113 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
114 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
115 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
116 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
117 glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
118 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
119 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
120 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
123 case Visual3d_TOLS_POSITIONAL:
125 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
126 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
127 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
128 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
129 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
130 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
131 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
132 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
133 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
134 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
135 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
138 case Visual3d_TOLS_SPOT:
140 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
141 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
142 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
143 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
144 glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
145 glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
146 glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
147 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
148 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
149 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
154 // restore matrix in case of headlight
155 if (theLight.IsHeadlight)
157 aContext->WorldViewState.Pop();
160 glEnable (theLightGlId++);
164 /*----------------------------------------------------------------------*/
166 void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
168 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
170 if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background
171 || (!myBgTextureArray->IsDefined() // no texture
172 && !myBgGradientArray->IsDefined())) // no gradient
177 aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
179 aCtx->WorldViewState.Push();
180 aCtx->ProjectionState.Push();
181 aCtx->WorldViewState.SetIdentity();
182 aCtx->ProjectionState.SetIdentity();
183 aCtx->ApplyProjectionMatrix();
184 aCtx->ApplyWorldViewMatrix();
186 // Drawing background gradient if:
187 // - gradient fill type is not Aspect_GFM_NONE and
188 // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
189 if (myBgGradientArray->IsDefined()
190 && (!myTextureParams->DoTextureMap()
191 || myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED
192 || myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE))
194 #if !defined(GL_ES_VERSION_2_0)
195 GLint aShadingModelOld = GL_SMOOTH;
196 if (aCtx->core11 != NULL)
198 aCtx->core11fwd->glDisable (GL_LIGHTING);
199 aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld);
200 aCtx->core11->glShadeModel (GL_SMOOTH);
204 if (myBgGradientArray->IsDataChanged())
206 myBgGradientArray->Init (theWorkspace);
209 myBgGradientArray->Render (theWorkspace);
211 #if !defined(GL_ES_VERSION_2_0)
212 if (aCtx->core11 != NULL)
214 aCtx->core11->glShadeModel (aShadingModelOld);
219 // Drawing background image if it is defined
220 // (texture is defined and fill type is not Aspect_FM_NONE)
221 if (myBgTextureArray->IsDefined()
222 && myTextureParams->DoTextureMap())
224 aCtx->core11fwd->glDisable (GL_BLEND);
226 const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams);
228 if (myBgTextureArray->IsDataChanged()
229 || myBgTextureArray->IsViewSizeChanged (theWorkspace))
231 myBgTextureArray->Init (theWorkspace);
234 myBgTextureArray->Render (theWorkspace);
237 theWorkspace->SetAspectFace (anOldAspectFace);
240 aCtx->WorldViewState.Pop();
241 aCtx->ProjectionState.Pop();
242 aCtx->ApplyProjectionMatrix();
244 if (theWorkspace->UseZBuffer())
246 aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
250 /*----------------------------------------------------------------------*/
252 //call_func_redraw_all_structs_proc
253 void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
254 const Handle(OpenGl_Workspace)& theWorkspace,
255 const Graphic3d_CView& theCView,
256 const Aspect_CLayer2d& theCUnderLayer,
257 const Aspect_CLayer2d& theCOverLayer,
258 const Standard_Boolean theToDrawImmediate)
260 // ==================================
261 // Step 1: Prepare for redraw
262 // ==================================
264 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
266 #if !defined(GL_ES_VERSION_2_0)
267 // store and disable current clipping planes
268 const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
269 NCollection_Array1<OPENGL_CLIP_PLANE> aOldPlanes (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + aMaxPlanes - 1);
270 if (aContext->core11 != NULL)
272 for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
274 OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
275 aContext->core11->glGetClipPlane (aClipPlaneId, aPlane.Equation);
276 if (aPlane.isEnabled)
278 aContext->core11fwd->glDisable (aClipPlaneId);
279 aPlane.isEnabled = GL_TRUE;
283 aPlane.isEnabled = GL_FALSE;
289 // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
290 Standard_Boolean isProjectionMatUpdateNeeded = Standard_False;
291 Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
292 if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
294 isProjectionMatUpdateNeeded = Standard_True;
295 myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState();
297 if (myBVHSelector.ModelViewState() != myCamera->ModelViewState())
299 isOrientationMatUpdateNeeded = Standard_True;
300 myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
303 if (isProjectionMatUpdateNeeded
304 || isOrientationMatUpdateNeeded)
306 myBVHSelector.SetViewVolume (myCamera);
309 const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager();
310 const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed
311 if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
313 aManager->UpdateLightSourceStateTo (&myLights);
314 myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
317 if (myProjectionState != myCamera->ProjectionState()
320 myProjectionState = myCamera->ProjectionState();
321 aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
322 aContext->ApplyProjectionMatrix();
325 if (myModelViewState != myCamera->ModelViewState()
328 myModelViewState = myCamera->ModelViewState();
329 aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF());
330 aContext->ApplyWorldViewMatrix();
333 if (aManager->ModelWorldState().Index() == 0)
335 aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
338 // ====================================
339 // Step 2: Redraw background
340 // ====================================
343 if (theWorkspace->ToRedrawGL()
344 && !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, 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, 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, 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 (theWorkspace->ToRedrawGL()
517 && !theToDrawImmediate)
519 RedrawTrihedron (theWorkspace);
521 // Restore face culling
526 glEnable ( GL_CULL_FACE );
527 glCullFace ( GL_BACK );
530 glDisable ( GL_CULL_FACE );
534 // ===============================
535 // Step 6: Redraw overlay
536 // ===============================
537 if (!theToDrawImmediate)
540 theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
542 RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer);
544 theWorkspace->DisplayCallback (theCView, aMode);
547 // ===============================
549 // ===============================
551 #if !defined(GL_ES_VERSION_2_0)
552 // restore clipping planes
553 if (aContext->core11 != NULL)
555 for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
557 const OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
558 aContext->core11->glClipPlane (aClipPlaneId, aPlane.Equation);
559 if (aPlane.isEnabled)
560 aContext->core11fwd->glEnable (aClipPlaneId);
562 aContext->core11fwd->glDisable (aClipPlaneId);
567 // ==============================================================
568 // Step 8: Keep shader manager informed about last View
569 // ==============================================================
571 if (!aManager.IsNull())
573 aManager->SetLastView (this);
577 // =======================================================================
578 // function : InvalidateBVHData
580 // =======================================================================
581 void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
583 myZLayers.InvalidateBVHData (theLayerId);
586 /*----------------------------------------------------------------------*/
589 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& AWorkspace,
590 const Standard_Boolean theToDrawImmediate)
592 if ( myZLayers.NbStructures() <= 0 )
595 const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
596 #if !defined(GL_ES_VERSION_2_0)
597 if (aCtx->core11 != NULL)
599 aCtx->core11->glPushAttrib (GL_DEPTH_BUFFER_BIT);
603 //TsmPushAttri(); /* save previous graphics context */
605 if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
607 #if !defined(GL_ES_VERSION_2_0)
608 const int antiAliasingMode = AWorkspace->AntiAliasingMode();
611 if ( !myAntiAliasing )
613 #if !defined(GL_ES_VERSION_2_0)
614 if (aCtx->core11 != NULL)
616 glDisable (GL_POINT_SMOOTH);
618 glDisable(GL_LINE_SMOOTH);
619 if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
621 glBlendFunc (GL_ONE, GL_ZERO);
622 glDisable (GL_BLEND);
626 #if !defined(GL_ES_VERSION_2_0)
627 if (aCtx->core11 != NULL)
629 glEnable(GL_POINT_SMOOTH);
631 glEnable(GL_LINE_SMOOTH);
632 if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
634 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
639 myZLayers.Render (AWorkspace, theToDrawImmediate);
641 #if !defined(GL_ES_VERSION_2_0)
642 if (aCtx->core11 != NULL)
644 aCtx->core11->glPopAttrib();
649 /*----------------------------------------------------------------------*/
651 //call_togl_redraw_layer2d
652 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
653 const Handle(OpenGl_Workspace)& theWorkspace,
654 const Graphic3d_CView& /*ACView*/,
655 const Aspect_CLayer2d& ACLayer)
657 #if !defined(GL_ES_VERSION_2_0)
659 || ACLayer.ptrLayer == NULL
660 || ACLayer.ptrLayer->listIndex == 0) return;
662 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
663 if (aContext->core11 == NULL)
668 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
669 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
671 aContext->WorldViewState.Push();
672 aContext->ProjectionState.Push();
674 aContext->WorldViewState.SetIdentity();
675 aContext->ProjectionState.SetIdentity();
677 aContext->ApplyWorldViewMatrix();
678 aContext->ApplyProjectionMatrix();
680 if (!ACLayer.sizeDependent)
681 aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight);
683 float left = ACLayer.ortho[0];
684 float right = ACLayer.ortho[1];
685 float bottom = ACLayer.ortho[2];
686 float top = ACLayer.ortho[3];
688 int attach = ACLayer.attach;
690 const float ratio = !ACLayer.sizeDependent
691 ? float(dispWidth) / float(dispHeight)
692 : float(theWorkspace->Width()) / float(theWorkspace->Height());
696 delta = (float )((top - bottom)/2.0);
698 case 0: /* Aspect_TOC_BOTTOM_LEFT */
699 top = bottom + 2*delta/ratio;
701 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
702 top = bottom + 2*delta/ratio;
704 case 2: /* Aspect_TOC_TOP_LEFT */
705 bottom = top - 2*delta/ratio;
707 case 3: /* Aspect_TOC_TOP_RIGHT */
708 bottom = top - 2*delta/ratio;
713 delta = (float )((right - left)/2.0);
715 case 0: /* Aspect_TOC_BOTTOM_LEFT */
716 right = left + 2*delta*ratio;
718 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
719 left = right - 2*delta*ratio;
721 case 2: /* Aspect_TOC_TOP_LEFT */
722 right = left + 2*delta*ratio;
724 case 3: /* Aspect_TOC_TOP_RIGHT */
725 left = right - 2*delta*ratio;
731 // Check printer context that exists only for print operation
732 if (!thePrintContext.IsNull())
734 // additional transformation matrix could be applied to
735 // render only those parts of viewport that will be
736 // passed to a printer as a current "frame" to provide
737 // tiling; scaling of graphics by matrix helps render a
738 // part of a view (frame) in same viewport, but with higher
741 // set printing scale/tiling transformation
742 aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation());
743 aContext->ApplyProjectionMatrix();
745 // printing operation also assumes other viewport dimension
746 // to comply with transformation matrix or graphics scaling
747 // factors for tiling for layer redraw
748 GLsizei anViewportX = 0;
749 GLsizei anViewportY = 0;
750 thePrintContext->GetLayerViewport (anViewportX, anViewportY);
751 if (anViewportX != 0 && anViewportY != 0)
752 aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY);
756 glOrtho (left, right, bottom, top, -1.0, 1.0);
759 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
760 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
762 glDisable (GL_DEPTH_TEST);
763 glDisable (GL_TEXTURE_1D);
764 glDisable (GL_TEXTURE_2D);
765 glDisable (GL_LIGHTING);
767 // TODO: Obsolete code, the display list is always empty now, to be removed
768 glCallList (ACLayer.ptrLayer->listIndex);
770 //calling dynamic render of LayerItems
771 if ( ACLayer.ptrLayer->layerData )
773 InitLayerProp (ACLayer.ptrLayer->listIndex);
774 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
780 aContext->WorldViewState.Pop();
781 aContext->ProjectionState.Pop();
783 aContext->ApplyProjectionMatrix();
784 aContext->ApplyWorldViewMatrix();
786 if (!ACLayer.sizeDependent)
787 aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height());
793 /*----------------------------------------------------------------------*/
795 void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
797 // display global trihedron
798 if (myTrihedron != NULL)
800 myTrihedron->Render (theWorkspace);
802 if (myGraduatedTrihedron != NULL)
804 myGraduatedTrihedron->Render (theWorkspace);
808 /*----------------------------------------------------------------------*/
810 //call_togl_create_bg_texture
811 void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
812 const Aspect_FillMethod theFillStyle)
814 // Prepare aspect for texture storage
815 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
816 Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
817 aTextureMap->EnableRepeat();
818 aTextureMap->DisableModulate();
819 aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
820 Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
821 Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
822 anAspect->SetTextureMap (aTextureMap);
823 anAspect->SetInteriorStyle (Aspect_IS_SOLID);
824 // Enable texture mapping
825 if (aTextureMap->IsDone())
827 anAspect->SetTextureMapOn();
831 anAspect->SetTextureMapOff();
836 // Set texture parameters
837 myTextureParams->SetAspect (anAspect);
839 myBgTextureArray->SetTextureParameters (theFillStyle);
842 /*----------------------------------------------------------------------*/
844 //call_togl_set_bg_texture_style
845 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod theFillStyle)
847 myBgTextureArray->SetTextureFillMethod (theFillStyle);
850 /*----------------------------------------------------------------------*/
852 //call_togl_gradient_background
853 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& theColor1,
854 const Quantity_Color& theColor2,
855 const Aspect_GradientFillMethod theType)
857 myBgGradientArray->SetGradientParameters (theColor1, theColor2, theType);
860 /*----------------------------------------------------------------------*/
862 //call_togl_set_gradient_type
863 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod theType)
865 myBgGradientArray->SetGradientFillMethod (theType);
868 //=======================================================================
869 //function : AddZLayer
871 //=======================================================================
873 void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
875 myZLayers.AddLayer (theLayerId);
878 //=======================================================================
879 //function : RemoveZLayer
881 //=======================================================================
883 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
885 myZLayers.RemoveLayer (theLayerId);
888 //=======================================================================
889 //function : DisplayStructure
891 //=======================================================================
893 void OpenGl_View::DisplayStructure (const Handle(Graphic3d_Structure)& theStructure,
894 const Standard_Integer thePriority)
896 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
897 const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
898 myZLayers.AddStructure (aStruct, aZLayer, thePriority);
901 //=======================================================================
902 //function : DisplayImmediateStructure
904 //=======================================================================
906 void OpenGl_View::DisplayImmediateStructure (const Handle(Graphic3d_Structure)& theStructure)
908 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
909 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
910 anIter.More(); anIter.Next())
912 if (anIter.Value() == aStruct)
918 myImmediateList.Append (aStruct);
921 //=======================================================================
922 //function : EraseStructure
924 //=======================================================================
926 void OpenGl_View::EraseStructure (const Handle(Graphic3d_Structure)& theStructure)
928 myZLayers.RemoveStructure (theStructure);
931 //=======================================================================
932 //function : EraseImmediateStructure
934 //=======================================================================
936 void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
938 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
939 anIter.More(); anIter.Next())
941 if (anIter.Value() == theStructure)
943 myImmediateList.Remove (anIter);
949 //=======================================================================
950 //function : ChangeZLayer
952 //=======================================================================
954 void OpenGl_View::ChangeZLayer (const OpenGl_Structure* theStructure,
955 const Graphic3d_ZLayerId theNewLayerId)
957 const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
958 myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
961 //=======================================================================
962 //function : SetZLayerSettings
964 //=======================================================================
965 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
966 const Graphic3d_ZLayerSettings& theSettings)
968 myZLayers.SetLayerSettings (theLayerId, theSettings);
971 //=======================================================================
972 //function : ChangePriority
974 //=======================================================================
975 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
976 const Standard_Integer theNewPriority)
978 const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
979 myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
982 //=======================================================================
983 //function : RedrawScene
985 //=======================================================================
987 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
988 const Handle(OpenGl_Workspace)& theWorkspace,
989 const Standard_Boolean theToDrawImmediate)
991 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
993 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
995 Handle(Graphic3d_ClipPlane) aPlaneBack;
996 Handle(Graphic3d_ClipPlane) aPlaneFront;
998 if (myZClip.Back.IsOn)
1000 Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1001 if (myCamera->ZFar() < aClipBackConverted)
1003 aClipBackConverted = myCamera->ZFar();
1004 myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1006 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1007 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1010 if (myZClip.Front.IsOn)
1012 Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1013 if (myCamera->ZNear() > aClipFrontConverted)
1015 aClipFrontConverted = myCamera->ZNear();
1016 myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1018 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1019 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1022 // Specify slicing planes with identity transformation
1023 if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1025 Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1026 if (!aPlaneBack.IsNull())
1028 aSlicingPlanes.Append (aPlaneBack);
1031 if (!aPlaneFront.IsNull())
1033 aSlicingPlanes.Append (aPlaneFront);
1036 // add planes at loaded view matrix state
1037 aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1042 // set printing scale/tiling transformation
1043 if (!thePrintContext.IsNull())
1045 aContext->ProjectionState.Push();
1046 aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current());
1047 aContext->ApplyProjectionMatrix();
1051 // Specify clipping planes in view transformation space
1052 if (!myClipPlanes.IsEmpty())
1054 Graphic3d_SequenceOfHClipPlane aUserPlanes;
1055 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1056 for (; aClippingIt.More(); aClippingIt.Next())
1058 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1059 if (aClipPlane->IsOn())
1061 aUserPlanes.Append (aClipPlane);
1065 if (!aUserPlanes.IsEmpty())
1067 aContext->ChangeClipping().AddWorld (aUserPlanes);
1070 if (!aContext->ShaderManager()->IsEmpty())
1072 aContext->ShaderManager()->UpdateClippingState();
1076 #if !defined(GL_ES_VERSION_2_0)
1078 if (aContext->core11 != NULL)
1081 Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1082 THE_DEFAULT_AMBIENT[1],
1083 THE_DEFAULT_AMBIENT[2],
1084 THE_DEFAULT_AMBIENT[3]);
1085 GLenum aLightGlId = GL_LIGHT0;
1086 for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1087 aLightIt.More(); aLightIt.Next())
1089 bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace);
1092 // apply accumulated ambient color
1093 anAmbientColor.a() = 1.0f;
1094 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1096 if (aLightGlId != GL_LIGHT0)
1098 glEnable (GL_LIGHTING);
1100 // switch off unused lights
1101 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1103 glDisable (aLightGlId);
1108 // Clear status bitfields
1109 theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1111 // Added PCT for handling of textures
1112 switch (mySurfaceDetail)
1114 case Visual3d_TOD_NONE:
1115 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1116 theWorkspace->DisableTexture();
1118 RenderStructs (theWorkspace, theToDrawImmediate);
1121 case Visual3d_TOD_ENVIRONMENT:
1122 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1123 theWorkspace->EnableTexture (myTextureEnv);
1125 RenderStructs (theWorkspace, theToDrawImmediate);
1126 theWorkspace->DisableTexture();
1129 case Visual3d_TOD_ALL:
1131 theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1133 RenderStructs (theWorkspace, theToDrawImmediate);
1134 theWorkspace->DisableTexture();
1137 if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1139 theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1140 theWorkspace->EnableTexture (myTextureEnv);
1142 // Remember OpenGl properties
1143 GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
1144 GLint aSaveZbuffFunc;
1145 GLboolean aSaveZbuffWrite;
1146 glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1147 glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1148 #if !defined(GL_ES_VERSION_2_0)
1149 glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1150 glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1152 GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1153 GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1155 // Change the properties for second rendering pass
1156 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1157 glEnable (GL_BLEND);
1159 glDepthFunc (GL_EQUAL);
1160 glDepthMask (GL_FALSE);
1161 glEnable (GL_DEPTH_TEST);
1163 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1166 RenderStructs (theWorkspace, theToDrawImmediate);
1167 theWorkspace->DisableTexture();
1169 // Restore properties back
1170 glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1171 if (!wasBlendEnabled)
1172 glDisable (GL_BLEND);
1174 glDepthFunc (aSaveZbuffFunc);
1175 glDepthMask (aSaveZbuffWrite);
1176 if (!wasZbuffEnabled)
1177 glDisable (GL_DEPTH_FUNC);
1182 // Apply restored view matrix.
1183 aContext->ApplyWorldViewMatrix();
1186 // set printing scale/tiling transformation
1187 if (!thePrintContext.IsNull())
1189 aContext->ProjectionState.Pop();
1190 aContext->ApplyProjectionMatrix();