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 <Graphic3d_GraphicDriver.hxx>
25 #include <Image_AlienPixMap.hxx>
26 #include <Visual3d_Layer.hxx>
28 #include <NCollection_Mat4.hxx>
30 #include <OpenGl_AspectLine.hxx>
31 #include <OpenGl_Context.hxx>
32 #include <OpenGl_Matrix.hxx>
33 #include <OpenGl_Workspace.hxx>
34 #include <OpenGl_View.hxx>
35 #include <OpenGl_Trihedron.hxx>
36 #include <OpenGl_GraduatedTrihedron.hxx>
37 #include <OpenGl_PrimitiveArray.hxx>
38 #include <OpenGl_PrinterContext.hxx>
39 #include <OpenGl_ShaderManager.hxx>
40 #include <OpenGl_ShaderProgram.hxx>
41 #include <OpenGl_Structure.hxx>
42 #include <OpenGl_ArbFBO.hxx>
49 static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
50 static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
51 static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
52 static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
56 extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
58 /*----------------------------------------------------------------------*/
63 #if !defined(GL_ES_VERSION_2_0)
64 /*-----------------------------------------------------------------*/
68 static void bindLight (const OpenGl_Light& theLight,
70 Graphic3d_Vec4& theAmbientColor,
71 const Handle(OpenGl_Workspace)& theWorkspace)
73 // Only 8 lights in OpenGL...
74 if (theLightGlId > GL_LIGHT7)
79 if (theLight.Type == Visual3d_TOLS_AMBIENT)
81 // add RGBA intensity of the ambient light
82 theAmbientColor += theLight.Color;
86 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
88 // the light is a headlight?
89 if (theLight.IsHeadlight)
92 aContext->WorldViewState.Push();
93 aContext->WorldViewState.SetIdentity();
95 aContext->ApplyWorldViewMatrix();
99 switch (theLight.Type)
101 case Visual3d_TOLS_DIRECTIONAL:
103 // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
104 const OpenGl_Vec4 anInfDir = -theLight.Direction;
106 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
107 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
108 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
109 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
110 glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
111 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
112 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
113 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
116 case Visual3d_TOLS_POSITIONAL:
118 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
119 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
120 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
121 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
122 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
123 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
124 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
125 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
126 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
127 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
128 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
131 case Visual3d_TOLS_SPOT:
133 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
134 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
135 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
136 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
137 glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
138 glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
139 glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
140 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
141 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
142 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
147 // restore matrix in case of headlight
148 if (theLight.IsHeadlight)
150 aContext->WorldViewState.Pop();
153 glEnable (theLightGlId++);
157 /*----------------------------------------------------------------------*/
159 void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
161 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
163 if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background
164 || (!myBgTextureArray->IsDefined() // no texture
165 && !myBgGradientArray->IsDefined())) // no gradient
170 const Standard_Boolean wasUsedZBuffer = theWorkspace->SetUseZBuffer (Standard_False);
173 aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
176 aCtx->WorldViewState.Push();
177 aCtx->ProjectionState.Push();
178 aCtx->WorldViewState.SetIdentity();
179 aCtx->ProjectionState.SetIdentity();
180 aCtx->ApplyProjectionMatrix();
181 aCtx->ApplyWorldViewMatrix();
183 // Drawing background gradient if:
184 // - gradient fill type is not Aspect_GFM_NONE and
185 // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
186 if (myBgGradientArray->IsDefined()
187 && (!myTextureParams->DoTextureMap()
188 || myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED
189 || myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE))
191 #if !defined(GL_ES_VERSION_2_0)
192 GLint aShadingModelOld = GL_SMOOTH;
193 if (aCtx->core11 != NULL)
195 aCtx->core11fwd->glDisable (GL_LIGHTING);
196 aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld);
197 aCtx->core11->glShadeModel (GL_SMOOTH);
201 if (myBgGradientArray->IsDataChanged())
203 myBgGradientArray->Init (theWorkspace);
206 myBgGradientArray->Render (theWorkspace);
208 #if !defined(GL_ES_VERSION_2_0)
209 if (aCtx->core11 != NULL)
211 aCtx->core11->glShadeModel (aShadingModelOld);
216 // Drawing background image if it is defined
217 // (texture is defined and fill type is not Aspect_FM_NONE)
218 if (myBgTextureArray->IsDefined()
219 && myTextureParams->DoTextureMap())
221 aCtx->core11fwd->glDisable (GL_BLEND);
223 const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams);
225 if (myBgTextureArray->IsDataChanged()
226 || myBgTextureArray->IsViewSizeChanged (theWorkspace))
228 myBgTextureArray->Init (theWorkspace);
231 myBgTextureArray->Render (theWorkspace);
234 theWorkspace->SetAspectFace (anOldAspectFace);
237 aCtx->WorldViewState.Pop();
238 aCtx->ProjectionState.Pop();
239 aCtx->ApplyProjectionMatrix();
240 aCtx->ApplyWorldViewMatrix();
244 theWorkspace->SetUseZBuffer (Standard_True);
245 aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
249 /*----------------------------------------------------------------------*/
251 //call_func_redraw_all_structs_proc
252 void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
253 const Handle(OpenGl_Workspace)& theWorkspace,
254 OpenGl_FrameBuffer* theOutputFBO,
255 Graphic3d_Camera::Projection theProjection,
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 // Disable current clipping planes
269 if (aContext->core11 != NULL)
271 const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
272 for (Standard_Integer aClipPlaneId = GL_CLIP_PLANE0; aClipPlaneId < GL_CLIP_PLANE0 + aMaxPlanes; ++aClipPlaneId)
274 aContext->core11fwd->glDisable (aClipPlaneId);
279 Graphic3d_WorldViewProjState aWVPState = myCamera->WorldViewProjState();
281 // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
282 myBVHSelector.SetViewVolume (myCamera);
284 const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager();
285 if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
287 aManager->UpdateLightSourceStateTo (&myLights);
288 myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
291 if (myWorldViewProjState != aWVPState)
293 aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
294 aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF());
295 aContext->ApplyProjectionMatrix();
296 aContext->ApplyWorldViewMatrix();
297 myWorldViewProjState = aWVPState;
300 if (aManager->ModelWorldState().Index() == 0)
302 aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
306 // ====================================
307 // Step 2: Redraw background
308 // ====================================
311 if (!theToDrawImmediate)
313 DrawBackground (theWorkspace);
316 #if !defined(GL_ES_VERSION_2_0)
317 // Switch off lighting by default
318 if (aContext->core11 != NULL)
320 glDisable(GL_LIGHTING);
324 // =================================
325 // Step 3: Draw underlayer
326 // =================================
327 if (!theToDrawImmediate)
329 RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCUnderLayer);
332 // =================================
333 // Step 4: Redraw main plane
334 // =================================
336 // Setup face culling
337 GLboolean isCullFace = GL_FALSE;
340 isCullFace = glIsEnabled( GL_CULL_FACE );
341 if ( myBackfacing < 0 )
343 glEnable( GL_CULL_FACE );
344 glCullFace( GL_BACK );
347 glDisable( GL_CULL_FACE );
350 #if !defined(GL_ES_VERSION_2_0)
351 // if the view is scaled normal vectors are scaled to unit
352 // length for correct displaying of shaded objects
353 const gp_Pnt anAxialScale = myCamera->AxialScale();
354 if (anAxialScale.X() != 1.F ||
355 anAxialScale.Y() != 1.F ||
356 anAxialScale.Z() != 1.F)
358 aContext->SetGlNormalizeEnabled (Standard_True);
362 aContext->SetGlNormalizeEnabled (Standard_False);
367 && aContext->core11 != NULL)
369 Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
370 if (myCamera->ZFar() < aFogFrontConverted)
372 aFogFrontConverted = myCamera->ZFar();
373 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
376 Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
377 if (myCamera->ZFar() < aFogFrontConverted)
379 aFogBackConverted = myCamera->ZFar();
380 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
383 if (aFogFrontConverted > aFogBackConverted)
385 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
386 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
389 glFogi(GL_FOG_MODE, GL_LINEAR);
390 glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
391 glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
392 glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
395 else if (aContext->core11 != NULL)
400 // Apply InteriorShadingMethod
401 if (aContext->core11 != NULL)
403 aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET
404 || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH);
408 aManager->SetShadingModel (myShadingModel);
410 // Apply AntiAliasing
412 theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
414 theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
416 if (!aManager->IsEmpty())
418 aManager->UpdateClippingState();
422 if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye)
424 aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF());
425 aContext->ApplyProjectionMatrix();
427 else if (theProjection == Graphic3d_Camera::Projection_MonoRightEye)
429 aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF());
430 aContext->ApplyProjectionMatrix();
432 RedrawScene (thePrintContext, theWorkspace, theOutputFBO, theCView, theToDrawImmediate);
434 // ===============================
436 // ===============================
438 // Resetting GL parameters according to the default aspects
439 // in order to synchronize GL state with the graphic driver state
440 // before drawing auxiliary stuff (trihedrons, overlayer)
441 // and invoking optional callbacks
442 theWorkspace->ResetAppliedAspect();
444 aContext->ChangeClipping().RemoveAll();
446 if (!aManager->IsEmpty())
448 aManager->ResetMaterialStates();
449 aManager->RevertClippingState();
451 // We need to disable (unbind) all shaders programs to ensure
452 // that all objects without specified aspect will be drawn
453 // correctly (such as background)
454 aContext->BindProgram (NULL);
458 if (!theToDrawImmediate)
460 RedrawTrihedron (theWorkspace);
462 // Restore face culling
467 glEnable ( GL_CULL_FACE );
468 glCullFace ( GL_BACK );
471 glDisable ( GL_CULL_FACE );
475 // ===============================
476 // Step 6: Redraw overlay
477 // ===============================
478 if (!theToDrawImmediate)
481 theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
483 RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer);
485 theWorkspace->DisplayCallback (theCView, aMode);
488 // ==============================================================
489 // Step 7: Keep shader manager informed about last View
490 // ==============================================================
492 if (!aManager.IsNull())
494 aManager->SetLastView (this);
498 // =======================================================================
499 // function : InvalidateBVHData
501 // =======================================================================
502 void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
504 myZLayers.InvalidateBVHData (theLayerId);
507 /*----------------------------------------------------------------------*/
510 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& theWorkspace,
511 OpenGl_FrameBuffer* theReadDrawFbo,
512 const Graphic3d_CView& theCView,
513 const Standard_Boolean theToDrawImmediate)
515 if ( myZLayers.NbStructures() <= 0 )
518 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
520 if ( (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
522 #if !defined(GL_ES_VERSION_2_0)
523 const int anAntiAliasingMode = theWorkspace->AntiAliasingMode();
526 if ( !myAntiAliasing )
528 #if !defined(GL_ES_VERSION_2_0)
529 if (aCtx->core11 != NULL)
531 glDisable (GL_POINT_SMOOTH);
533 glDisable(GL_LINE_SMOOTH);
534 if( anAntiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
536 glBlendFunc (GL_ONE, GL_ZERO);
537 glDisable (GL_BLEND);
541 #if !defined(GL_ES_VERSION_2_0)
542 if (aCtx->core11 != NULL)
544 glEnable(GL_POINT_SMOOTH);
546 glEnable(GL_LINE_SMOOTH);
547 if( anAntiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
549 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
554 Standard_Boolean toRenderGL = theToDrawImmediate ||
555 theCView.RenderParams.Method != Graphic3d_RM_RAYTRACING ||
556 myRaytraceInitStatus == OpenGl_RT_FAIL ||
561 toRenderGL = !initRaytraceResources (theCView, aCtx) ||
562 !updateRaytraceGeometry (OpenGl_GUM_CHECK, theWorkspace->ActiveViewId(), aCtx);
564 toRenderGL |= !myIsRaytraceDataValid; // if no ray-trace data use OpenGL
568 const Standard_Integer aSizeX = theReadDrawFbo != NULL ?
569 theReadDrawFbo->GetVPSizeX() : theWorkspace->Width();
570 const Standard_Integer aSizeY = theReadDrawFbo != NULL ?
571 theReadDrawFbo->GetVPSizeY() : theWorkspace->Height();
573 if (myOpenGlFBO.IsNull())
574 myOpenGlFBO = new OpenGl_FrameBuffer;
576 if (myOpenGlFBO->GetVPSizeX() != aSizeX
577 || myOpenGlFBO->GetVPSizeY() != aSizeY)
579 myOpenGlFBO->Init (aCtx, aSizeX, aSizeY);
582 if (myRaytraceFilter.IsNull())
583 myRaytraceFilter = new OpenGl_RaytraceFilter;
585 myRaytraceFilter->SetPrevRenderFilter (theWorkspace->GetRenderFilter());
587 if (theReadDrawFbo != NULL)
588 theReadDrawFbo->UnbindBuffer (aCtx);
590 // Prepare preliminary OpenGL output
591 if (aCtx->arbFBOBlit != NULL)
593 // Render bottom OSD layer
594 myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Bottom);
596 theWorkspace->SetRenderFilter (myRaytraceFilter);
598 if (theReadDrawFbo != NULL)
600 theReadDrawFbo->BindReadBuffer (aCtx);
604 aCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
607 myOpenGlFBO->BindDrawBuffer (aCtx);
609 aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, aSizeX, aSizeY,
610 0, 0, aSizeX, aSizeY,
611 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
614 // Render non-polygonal elements in default layer
615 myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Default);
617 theWorkspace->SetRenderFilter (myRaytraceFilter->PrevRenderFilter());
620 if (theReadDrawFbo != NULL)
622 theReadDrawFbo->BindBuffer (aCtx);
626 aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, 0);
629 // Ray-tracing polygonal primitive arrays
630 raytrace (theCView, aSizeX, aSizeY, theReadDrawFbo, aCtx);
632 // Render upper (top and topmost) OpenGL layers
633 myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Upper);
637 // Redraw 3D scene using OpenGL in standard
638 // mode or in case of ray-tracing failure
641 myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_All);
643 // Set flag that scene was redrawn by standard pipeline
644 theCView.WasRedrawnGL = Standard_True;
648 /*----------------------------------------------------------------------*/
650 //call_togl_redraw_layer2d
651 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
652 const Handle(OpenGl_Workspace)& theWorkspace,
653 const Graphic3d_CView& /*ACView*/,
654 const Aspect_CLayer2d& ACLayer)
656 #if !defined(GL_ES_VERSION_2_0)
658 || ACLayer.ptrLayer == NULL
659 || ACLayer.ptrLayer->listIndex == 0) return;
661 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
662 if (aContext->core11 == NULL)
667 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
668 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
670 aContext->WorldViewState.Push();
671 aContext->ProjectionState.Push();
673 aContext->WorldViewState.SetIdentity();
674 aContext->ProjectionState.SetIdentity();
676 aContext->ApplyWorldViewMatrix();
677 aContext->ApplyProjectionMatrix();
679 if (!ACLayer.sizeDependent)
680 aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight);
682 float left = ACLayer.ortho[0];
683 float right = ACLayer.ortho[1];
684 float bottom = ACLayer.ortho[2];
685 float top = ACLayer.ortho[3];
687 int attach = ACLayer.attach;
689 const float ratio = !ACLayer.sizeDependent
690 ? float(dispWidth) / float(dispHeight)
691 : float(theWorkspace->Width()) / float(theWorkspace->Height());
695 delta = (float )((top - bottom)/2.0);
697 case 0: /* Aspect_TOC_BOTTOM_LEFT */
698 top = bottom + 2*delta/ratio;
700 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
701 top = bottom + 2*delta/ratio;
703 case 2: /* Aspect_TOC_TOP_LEFT */
704 bottom = top - 2*delta/ratio;
706 case 3: /* Aspect_TOC_TOP_RIGHT */
707 bottom = top - 2*delta/ratio;
712 delta = (float )((right - left)/2.0);
714 case 0: /* Aspect_TOC_BOTTOM_LEFT */
715 right = left + 2*delta*ratio;
717 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
718 left = right - 2*delta*ratio;
720 case 2: /* Aspect_TOC_TOP_LEFT */
721 right = left + 2*delta*ratio;
723 case 3: /* Aspect_TOC_TOP_RIGHT */
724 left = right - 2*delta*ratio;
730 // Check printer context that exists only for print operation
731 if (!thePrintContext.IsNull())
733 // additional transformation matrix could be applied to
734 // render only those parts of viewport that will be
735 // passed to a printer as a current "frame" to provide
736 // tiling; scaling of graphics by matrix helps render a
737 // part of a view (frame) in same viewport, but with higher
740 // set printing scale/tiling transformation
741 aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation());
742 aContext->ApplyProjectionMatrix();
744 // printing operation also assumes other viewport dimension
745 // to comply with transformation matrix or graphics scaling
746 // factors for tiling for layer redraw
747 GLsizei anViewportX = 0;
748 GLsizei anViewportY = 0;
749 thePrintContext->GetLayerViewport (anViewportX, anViewportY);
750 if (anViewportX != 0 && anViewportY != 0)
751 aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY);
755 glOrtho (left, right, bottom, top, -1.0, 1.0);
758 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
759 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
761 glDisable (GL_DEPTH_TEST);
762 glDisable (GL_TEXTURE_1D);
763 glDisable (GL_TEXTURE_2D);
764 glDisable (GL_LIGHTING);
766 // TODO: Obsolete code, the display list is always empty now, to be removed
767 glCallList (ACLayer.ptrLayer->listIndex);
769 //calling dynamic render of LayerItems
770 if ( ACLayer.ptrLayer->layerData )
772 InitLayerProp (ACLayer.ptrLayer->listIndex);
773 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
779 aContext->WorldViewState.Pop();
780 aContext->ProjectionState.Pop();
782 aContext->ApplyProjectionMatrix();
783 aContext->ApplyWorldViewMatrix();
785 if (!ACLayer.sizeDependent)
786 aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height());
792 /*----------------------------------------------------------------------*/
794 void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
796 // display global trihedron
797 if (myToShowTrihedron)
799 myTrihedron.Render (theWorkspace);
801 if (myToShowGradTrihedron)
803 myGraduatedTrihedron.Render (theWorkspace);
807 /*----------------------------------------------------------------------*/
809 //call_togl_create_bg_texture
810 void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
811 const Aspect_FillMethod theFillStyle)
813 // Prepare aspect for texture storage
814 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
815 Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
816 aTextureMap->EnableRepeat();
817 aTextureMap->DisableModulate();
818 aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
819 Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
820 Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
821 anAspect->SetTextureMap (aTextureMap);
822 anAspect->SetInteriorStyle (Aspect_IS_SOLID);
823 // Enable texture mapping
824 if (aTextureMap->IsDone())
826 anAspect->SetTextureMapOn();
830 anAspect->SetTextureMapOff();
835 // Set texture parameters
836 myTextureParams->SetAspect (anAspect);
838 myBgTextureArray->SetTextureParameters (theFillStyle);
841 /*----------------------------------------------------------------------*/
843 //call_togl_set_bg_texture_style
844 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod theFillStyle)
846 myBgTextureArray->SetTextureFillMethod (theFillStyle);
849 /*----------------------------------------------------------------------*/
851 //call_togl_gradient_background
852 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& theColor1,
853 const Quantity_Color& theColor2,
854 const Aspect_GradientFillMethod theType)
856 myBgGradientArray->SetGradientParameters (theColor1, theColor2, theType);
859 /*----------------------------------------------------------------------*/
861 //call_togl_set_gradient_type
862 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod theType)
864 myBgGradientArray->SetGradientFillMethod (theType);
867 //=======================================================================
868 //function : AddZLayer
870 //=======================================================================
872 void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
874 myZLayers.AddLayer (theLayerId);
877 //=======================================================================
878 //function : RemoveZLayer
880 //=======================================================================
882 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
884 myZLayers.RemoveLayer (theLayerId);
887 //=======================================================================
888 //function : DisplayStructure
890 //=======================================================================
892 void OpenGl_View::DisplayStructure (const Handle(Graphic3d_Structure)& theStructure,
893 const Standard_Integer thePriority)
895 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
896 const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
897 myZLayers.AddStructure (aStruct, aZLayer, thePriority);
900 //=======================================================================
901 //function : EraseStructure
903 //=======================================================================
905 void OpenGl_View::EraseStructure (const Handle(Graphic3d_Structure)& theStructure)
907 myZLayers.RemoveStructure (theStructure);
910 //=======================================================================
911 //function : ChangeZLayer
913 //=======================================================================
915 void OpenGl_View::ChangeZLayer (const OpenGl_Structure* theStructure,
916 const Graphic3d_ZLayerId theNewLayerId)
918 const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
919 myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
922 //=======================================================================
923 //function : SetZLayerSettings
925 //=======================================================================
926 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
927 const Graphic3d_ZLayerSettings& theSettings)
929 myZLayers.SetLayerSettings (theLayerId, theSettings);
932 //=======================================================================
933 //function : ChangePriority
935 //=======================================================================
936 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
937 const Standard_Integer theNewPriority)
939 const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
940 myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
943 //=======================================================================
944 //function : RedrawScene
946 //=======================================================================
948 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
949 const Handle(OpenGl_Workspace)& theWorkspace,
950 OpenGl_FrameBuffer* theReadDrawFbo,
951 const Graphic3d_CView& theCView,
952 const Standard_Boolean theToDrawImmediate)
954 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
956 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
958 Handle(Graphic3d_ClipPlane) aPlaneBack;
959 Handle(Graphic3d_ClipPlane) aPlaneFront;
961 if (myZClip.Back.IsOn)
963 Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
964 if (myCamera->ZFar() < aClipBackConverted)
966 aClipBackConverted = myCamera->ZFar();
967 myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
969 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
970 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
973 if (myZClip.Front.IsOn)
975 Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
976 if (myCamera->ZNear() > aClipFrontConverted)
978 aClipFrontConverted = myCamera->ZNear();
979 myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
981 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
982 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
985 // Specify slicing planes with identity transformation
986 if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
988 Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
989 if (!aPlaneBack.IsNull())
991 aSlicingPlanes.Append (aPlaneBack);
994 if (!aPlaneFront.IsNull())
996 aSlicingPlanes.Append (aPlaneFront);
999 // add planes at loaded view matrix state
1000 aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1005 // set printing scale/tiling transformation
1006 if (!thePrintContext.IsNull())
1008 aContext->ProjectionState.Push();
1009 aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current());
1010 aContext->ApplyProjectionMatrix();
1014 // Specify clipping planes in view transformation space
1015 if (!myClipPlanes.IsEmpty())
1017 Graphic3d_SequenceOfHClipPlane aUserPlanes;
1018 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1019 for (; aClippingIt.More(); aClippingIt.Next())
1021 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1022 if (aClipPlane->IsOn())
1024 aUserPlanes.Append (aClipPlane);
1028 if (!aUserPlanes.IsEmpty())
1030 aContext->ChangeClipping().AddWorld (aUserPlanes);
1033 if (!aContext->ShaderManager()->IsEmpty())
1035 aContext->ShaderManager()->UpdateClippingState();
1039 #if !defined(GL_ES_VERSION_2_0)
1041 if (aContext->core11 != NULL)
1044 Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1045 THE_DEFAULT_AMBIENT[1],
1046 THE_DEFAULT_AMBIENT[2],
1047 THE_DEFAULT_AMBIENT[3]);
1048 GLenum aLightGlId = GL_LIGHT0;
1049 for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1050 aLightIt.More(); aLightIt.Next())
1052 bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace);
1055 // apply accumulated ambient color
1056 anAmbientColor.a() = 1.0f;
1057 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1059 if (aLightGlId != GL_LIGHT0)
1061 glEnable (GL_LIGHTING);
1063 // switch off unused lights
1064 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1066 glDisable (aLightGlId);
1071 // Clear status bitfields
1072 theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1074 // Update state of surface detail level
1075 theWorkspace->GetGlContext()->ShaderManager()->UpdateSurfaceDetailStateTo (mySurfaceDetail);
1077 // Added PCT for handling of textures
1078 switch (mySurfaceDetail)
1080 case Visual3d_TOD_NONE:
1081 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1082 theWorkspace->DisableTexture();
1084 RenderStructs (theWorkspace, theReadDrawFbo, theCView, theToDrawImmediate);
1087 case Visual3d_TOD_ENVIRONMENT:
1088 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1089 theWorkspace->EnableTexture (myTextureEnv);
1091 RenderStructs (theWorkspace, theReadDrawFbo, theCView, theToDrawImmediate);
1092 theWorkspace->DisableTexture();
1095 case Visual3d_TOD_ALL:
1097 theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1099 RenderStructs (theWorkspace, theReadDrawFbo, theCView, theToDrawImmediate);
1100 theWorkspace->DisableTexture();
1103 if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1105 theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1106 theWorkspace->EnableTexture (myTextureEnv);
1108 // Remember OpenGl properties
1109 GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
1110 GLint aSaveZbuffFunc;
1111 GLboolean aSaveZbuffWrite;
1112 glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1113 glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1114 #if !defined(GL_ES_VERSION_2_0)
1115 glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1116 glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1118 GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1119 GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1121 // Change the properties for second rendering pass
1122 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1123 glEnable (GL_BLEND);
1125 glDepthFunc (GL_EQUAL);
1126 glDepthMask (GL_FALSE);
1127 glEnable (GL_DEPTH_TEST);
1129 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1132 RenderStructs (theWorkspace, theReadDrawFbo, theCView, theToDrawImmediate);
1133 theWorkspace->DisableTexture();
1135 // Restore properties back
1136 glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1137 if (!wasBlendEnabled)
1138 glDisable (GL_BLEND);
1140 glDepthFunc (aSaveZbuffFunc);
1141 glDepthMask (aSaveZbuffWrite);
1142 if (!wasZbuffEnabled)
1143 glDisable (GL_DEPTH_FUNC);
1148 // Apply restored view matrix.
1149 aContext->ApplyWorldViewMatrix();
1152 // set printing scale/tiling transformation
1153 if (!thePrintContext.IsNull())
1155 aContext->ProjectionState.Pop();
1156 aContext->ApplyProjectionMatrix();