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() && theWorkspace->ToRedrawGL())
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)& theWorkspace,
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 myZLayers.Render (theWorkspace, theToDrawImmediate);
634 /*----------------------------------------------------------------------*/
636 //call_togl_redraw_layer2d
637 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
638 const Handle(OpenGl_Workspace)& theWorkspace,
639 const Graphic3d_CView& /*ACView*/,
640 const Aspect_CLayer2d& ACLayer)
642 #if !defined(GL_ES_VERSION_2_0)
644 || ACLayer.ptrLayer == NULL
645 || ACLayer.ptrLayer->listIndex == 0) return;
647 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
648 if (aContext->core11 == NULL)
653 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
654 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
656 aContext->WorldViewState.Push();
657 aContext->ProjectionState.Push();
659 aContext->WorldViewState.SetIdentity();
660 aContext->ProjectionState.SetIdentity();
662 aContext->ApplyWorldViewMatrix();
663 aContext->ApplyProjectionMatrix();
665 if (!ACLayer.sizeDependent)
666 aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight);
668 float left = ACLayer.ortho[0];
669 float right = ACLayer.ortho[1];
670 float bottom = ACLayer.ortho[2];
671 float top = ACLayer.ortho[3];
673 int attach = ACLayer.attach;
675 const float ratio = !ACLayer.sizeDependent
676 ? float(dispWidth) / float(dispHeight)
677 : float(theWorkspace->Width()) / float(theWorkspace->Height());
681 delta = (float )((top - bottom)/2.0);
683 case 0: /* Aspect_TOC_BOTTOM_LEFT */
684 top = bottom + 2*delta/ratio;
686 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
687 top = bottom + 2*delta/ratio;
689 case 2: /* Aspect_TOC_TOP_LEFT */
690 bottom = top - 2*delta/ratio;
692 case 3: /* Aspect_TOC_TOP_RIGHT */
693 bottom = top - 2*delta/ratio;
698 delta = (float )((right - left)/2.0);
700 case 0: /* Aspect_TOC_BOTTOM_LEFT */
701 right = left + 2*delta*ratio;
703 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
704 left = right - 2*delta*ratio;
706 case 2: /* Aspect_TOC_TOP_LEFT */
707 right = left + 2*delta*ratio;
709 case 3: /* Aspect_TOC_TOP_RIGHT */
710 left = right - 2*delta*ratio;
716 // Check printer context that exists only for print operation
717 if (!thePrintContext.IsNull())
719 // additional transformation matrix could be applied to
720 // render only those parts of viewport that will be
721 // passed to a printer as a current "frame" to provide
722 // tiling; scaling of graphics by matrix helps render a
723 // part of a view (frame) in same viewport, but with higher
726 // set printing scale/tiling transformation
727 aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation());
728 aContext->ApplyProjectionMatrix();
730 // printing operation also assumes other viewport dimension
731 // to comply with transformation matrix or graphics scaling
732 // factors for tiling for layer redraw
733 GLsizei anViewportX = 0;
734 GLsizei anViewportY = 0;
735 thePrintContext->GetLayerViewport (anViewportX, anViewportY);
736 if (anViewportX != 0 && anViewportY != 0)
737 aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY);
741 glOrtho (left, right, bottom, top, -1.0, 1.0);
744 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
745 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
747 glDisable (GL_DEPTH_TEST);
748 glDisable (GL_TEXTURE_1D);
749 glDisable (GL_TEXTURE_2D);
750 glDisable (GL_LIGHTING);
752 // TODO: Obsolete code, the display list is always empty now, to be removed
753 glCallList (ACLayer.ptrLayer->listIndex);
755 //calling dynamic render of LayerItems
756 if ( ACLayer.ptrLayer->layerData )
758 InitLayerProp (ACLayer.ptrLayer->listIndex);
759 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
765 aContext->WorldViewState.Pop();
766 aContext->ProjectionState.Pop();
768 aContext->ApplyProjectionMatrix();
769 aContext->ApplyWorldViewMatrix();
771 if (!ACLayer.sizeDependent)
772 aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height());
778 /*----------------------------------------------------------------------*/
780 void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
782 // display global trihedron
783 if (myTrihedron != NULL)
785 myTrihedron->Render (theWorkspace);
787 if (myGraduatedTrihedron != NULL)
789 myGraduatedTrihedron->Render (theWorkspace);
793 /*----------------------------------------------------------------------*/
795 //call_togl_create_bg_texture
796 void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
797 const Aspect_FillMethod theFillStyle)
799 // Prepare aspect for texture storage
800 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
801 Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
802 aTextureMap->EnableRepeat();
803 aTextureMap->DisableModulate();
804 aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
805 Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
806 Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
807 anAspect->SetTextureMap (aTextureMap);
808 anAspect->SetInteriorStyle (Aspect_IS_SOLID);
809 // Enable texture mapping
810 if (aTextureMap->IsDone())
812 anAspect->SetTextureMapOn();
816 anAspect->SetTextureMapOff();
821 // Set texture parameters
822 myTextureParams->SetAspect (anAspect);
824 myBgTextureArray->SetTextureParameters (theFillStyle);
827 /*----------------------------------------------------------------------*/
829 //call_togl_set_bg_texture_style
830 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod theFillStyle)
832 myBgTextureArray->SetTextureFillMethod (theFillStyle);
835 /*----------------------------------------------------------------------*/
837 //call_togl_gradient_background
838 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& theColor1,
839 const Quantity_Color& theColor2,
840 const Aspect_GradientFillMethod theType)
842 myBgGradientArray->SetGradientParameters (theColor1, theColor2, theType);
845 /*----------------------------------------------------------------------*/
847 //call_togl_set_gradient_type
848 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod theType)
850 myBgGradientArray->SetGradientFillMethod (theType);
853 //=======================================================================
854 //function : AddZLayer
856 //=======================================================================
858 void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
860 myZLayers.AddLayer (theLayerId);
863 //=======================================================================
864 //function : RemoveZLayer
866 //=======================================================================
868 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
870 myZLayers.RemoveLayer (theLayerId);
873 //=======================================================================
874 //function : DisplayStructure
876 //=======================================================================
878 void OpenGl_View::DisplayStructure (const Handle(Graphic3d_Structure)& theStructure,
879 const Standard_Integer thePriority)
881 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
882 const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
883 myZLayers.AddStructure (aStruct, aZLayer, thePriority);
886 //=======================================================================
887 //function : DisplayImmediateStructure
889 //=======================================================================
891 void OpenGl_View::DisplayImmediateStructure (const Handle(Graphic3d_Structure)& theStructure)
893 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
894 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
895 anIter.More(); anIter.Next())
897 if (anIter.Value() == aStruct)
903 myImmediateList.Append (aStruct);
906 //=======================================================================
907 //function : EraseStructure
909 //=======================================================================
911 void OpenGl_View::EraseStructure (const Handle(Graphic3d_Structure)& theStructure)
913 myZLayers.RemoveStructure (theStructure);
916 //=======================================================================
917 //function : EraseImmediateStructure
919 //=======================================================================
921 void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
923 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
924 anIter.More(); anIter.Next())
926 if (anIter.Value() == theStructure)
928 myImmediateList.Remove (anIter);
934 //=======================================================================
935 //function : ChangeZLayer
937 //=======================================================================
939 void OpenGl_View::ChangeZLayer (const OpenGl_Structure* theStructure,
940 const Graphic3d_ZLayerId theNewLayerId)
942 const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
943 myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
946 //=======================================================================
947 //function : SetZLayerSettings
949 //=======================================================================
950 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
951 const Graphic3d_ZLayerSettings& theSettings)
953 myZLayers.SetLayerSettings (theLayerId, theSettings);
956 //=======================================================================
957 //function : ChangePriority
959 //=======================================================================
960 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
961 const Standard_Integer theNewPriority)
963 const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
964 myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
967 //=======================================================================
968 //function : RedrawScene
970 //=======================================================================
972 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
973 const Handle(OpenGl_Workspace)& theWorkspace,
974 const Standard_Boolean theToDrawImmediate)
976 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
978 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
980 Handle(Graphic3d_ClipPlane) aPlaneBack;
981 Handle(Graphic3d_ClipPlane) aPlaneFront;
983 if (myZClip.Back.IsOn)
985 Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
986 if (myCamera->ZFar() < aClipBackConverted)
988 aClipBackConverted = myCamera->ZFar();
989 myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
991 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
992 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
995 if (myZClip.Front.IsOn)
997 Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
998 if (myCamera->ZNear() > aClipFrontConverted)
1000 aClipFrontConverted = myCamera->ZNear();
1001 myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1003 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1004 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1007 // Specify slicing planes with identity transformation
1008 if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1010 Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1011 if (!aPlaneBack.IsNull())
1013 aSlicingPlanes.Append (aPlaneBack);
1016 if (!aPlaneFront.IsNull())
1018 aSlicingPlanes.Append (aPlaneFront);
1021 // add planes at loaded view matrix state
1022 aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1027 // set printing scale/tiling transformation
1028 if (!thePrintContext.IsNull())
1030 aContext->ProjectionState.Push();
1031 aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current());
1032 aContext->ApplyProjectionMatrix();
1036 // Specify clipping planes in view transformation space
1037 if (!myClipPlanes.IsEmpty())
1039 Graphic3d_SequenceOfHClipPlane aUserPlanes;
1040 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1041 for (; aClippingIt.More(); aClippingIt.Next())
1043 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1044 if (aClipPlane->IsOn())
1046 aUserPlanes.Append (aClipPlane);
1050 if (!aUserPlanes.IsEmpty())
1052 aContext->ChangeClipping().AddWorld (aUserPlanes);
1055 if (!aContext->ShaderManager()->IsEmpty())
1057 aContext->ShaderManager()->UpdateClippingState();
1061 #if !defined(GL_ES_VERSION_2_0)
1063 if (aContext->core11 != NULL)
1066 Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1067 THE_DEFAULT_AMBIENT[1],
1068 THE_DEFAULT_AMBIENT[2],
1069 THE_DEFAULT_AMBIENT[3]);
1070 GLenum aLightGlId = GL_LIGHT0;
1071 for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1072 aLightIt.More(); aLightIt.Next())
1074 bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace);
1077 // apply accumulated ambient color
1078 anAmbientColor.a() = 1.0f;
1079 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1081 if (aLightGlId != GL_LIGHT0)
1083 glEnable (GL_LIGHTING);
1085 // switch off unused lights
1086 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1088 glDisable (aLightGlId);
1093 // Clear status bitfields
1094 theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1096 // Update state of surface detail level
1097 theWorkspace->GetGlContext()->ShaderManager()->UpdateSurfaceDetailStateTo (mySurfaceDetail);
1099 // Added PCT for handling of textures
1100 switch (mySurfaceDetail)
1102 case Visual3d_TOD_NONE:
1103 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1104 theWorkspace->DisableTexture();
1106 RenderStructs (theWorkspace, theToDrawImmediate);
1109 case Visual3d_TOD_ENVIRONMENT:
1110 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1111 theWorkspace->EnableTexture (myTextureEnv);
1113 RenderStructs (theWorkspace, theToDrawImmediate);
1114 theWorkspace->DisableTexture();
1117 case Visual3d_TOD_ALL:
1119 theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1121 RenderStructs (theWorkspace, theToDrawImmediate);
1122 theWorkspace->DisableTexture();
1125 if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1127 theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1128 theWorkspace->EnableTexture (myTextureEnv);
1130 // Remember OpenGl properties
1131 GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
1132 GLint aSaveZbuffFunc;
1133 GLboolean aSaveZbuffWrite;
1134 glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1135 glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1136 #if !defined(GL_ES_VERSION_2_0)
1137 glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1138 glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1140 GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1141 GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1143 // Change the properties for second rendering pass
1144 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1145 glEnable (GL_BLEND);
1147 glDepthFunc (GL_EQUAL);
1148 glDepthMask (GL_FALSE);
1149 glEnable (GL_DEPTH_TEST);
1151 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1154 RenderStructs (theWorkspace, theToDrawImmediate);
1155 theWorkspace->DisableTexture();
1157 // Restore properties back
1158 glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1159 if (!wasBlendEnabled)
1160 glDisable (GL_BLEND);
1162 glDepthFunc (aSaveZbuffFunc);
1163 glDepthMask (aSaveZbuffWrite);
1164 if (!wasZbuffEnabled)
1165 glDisable (GL_DEPTH_FUNC);
1170 // Apply restored view matrix.
1171 aContext->ApplyWorldViewMatrix();
1174 // set printing scale/tiling transformation
1175 if (!thePrintContext.IsNull())
1177 aContext->ProjectionState.Pop();
1178 aContext->ApplyProjectionMatrix();