// Created on: 2011-09-20 // Created by: Sergey ZERCHANINOV // Copyright (c) 2011-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define EPSI 0.0001 namespace { static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f }; static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f; static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f; }; extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx /*----------------------------------------------------------------------*/ struct OPENGL_CLIP_PLANE { GLboolean isEnabled; GLdouble Equation[4]; DEFINE_STANDARD_ALLOC }; /*----------------------------------------------------------------------*/ /* * Fonctions privees */ #if !defined(GL_ES_VERSION_2_0) /*-----------------------------------------------------------------*/ /* * Set des lumieres */ static void bindLight (const OpenGl_Light& theLight, GLenum& theLightGlId, Graphic3d_Vec4& theAmbientColor, const Handle(OpenGl_Workspace)& theWorkspace) { // Only 8 lights in OpenGL... if (theLightGlId > GL_LIGHT7) { return; } if (theLight.Type == Visual3d_TOLS_AMBIENT) { // add RGBA intensity of the ambient light theAmbientColor += theLight.Color; return; } const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); // the light is a headlight? if (theLight.IsHeadlight) { aContext->WorldViewState.Push(); aContext->WorldViewState.SetIdentity(); aContext->ApplyWorldViewMatrix(); } // setup light type switch (theLight.Type) { case Visual3d_TOLS_DIRECTIONAL: { // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one const OpenGl_Vec4 anInfDir = -theLight.Direction; // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE. glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData()); glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR); glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT); glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF); break; } case Visual3d_TOLS_POSITIONAL: { // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData()); glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR); glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT); glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF); glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation()); glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation()); glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0); break; } case Visual3d_TOLS_SPOT: { glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData()); glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData()); glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f); glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI)); glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation()); glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation()); glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f); break; } } // restore matrix in case of headlight if (theLight.IsHeadlight) { aContext->WorldViewState.Pop(); } glEnable (theLightGlId++); } #endif /*----------------------------------------------------------------------*/ void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace) { const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background || (!myBgTextureArray->IsDefined() // no texture && !myBgGradientArray->IsDefined())) // no gradient { return; } aCtx->core11fwd->glDisable (GL_DEPTH_TEST); aCtx->WorldViewState.Push(); aCtx->ProjectionState.Push(); aCtx->WorldViewState.SetIdentity(); aCtx->ProjectionState.SetIdentity(); aCtx->ApplyProjectionMatrix(); aCtx->ApplyWorldViewMatrix(); // Drawing background gradient if: // - gradient fill type is not Aspect_GFM_NONE and // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode if (myBgGradientArray->IsDefined() && (!myBgTextureArray->IsDefined() || myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED || myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE)) { #if !defined(GL_ES_VERSION_2_0) GLint aShadingModelOld = GL_SMOOTH; if (aCtx->core11 != NULL) { aCtx->core11fwd->glDisable (GL_LIGHTING); aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld); aCtx->core11->glShadeModel (GL_SMOOTH); } #endif if (myBgGradientArray->IsDataChanged()) { myBgGradientArray->Init (theWorkspace); } myBgGradientArray->Render (theWorkspace); #if !defined(GL_ES_VERSION_2_0) if (aCtx->core11 != NULL) { aCtx->core11->glShadeModel (aShadingModelOld); } #endif } // Drawing background image if it is defined // (texture is defined and fill type is not Aspect_FM_NONE) if (myBgTextureArray->IsDefined() && myTextureParams->DoTextureMap()) { aCtx->core11fwd->glDisable (GL_BLEND); const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams); if (myBgTextureArray->IsDataChanged() || myBgTextureArray->IsViewSizeChanged (theWorkspace)) { myBgTextureArray->Init (theWorkspace); } myBgTextureArray->Render (theWorkspace); // restore aspects theWorkspace->SetAspectFace (anOldAspectFace); } aCtx->WorldViewState.Pop(); aCtx->ProjectionState.Pop(); aCtx->ApplyProjectionMatrix(); if (theWorkspace->UseZBuffer()) { aCtx->core11fwd->glEnable (GL_DEPTH_TEST); } } /*----------------------------------------------------------------------*/ //call_func_redraw_all_structs_proc void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext, const Handle(OpenGl_Workspace)& theWorkspace, const Graphic3d_CView& theCView, const Aspect_CLayer2d& theCUnderLayer, const Aspect_CLayer2d& theCOverLayer, const Standard_Boolean theToDrawImmediate) { // ================================== // Step 1: Prepare for redraw // ================================== const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); #if !defined(GL_ES_VERSION_2_0) // store and disable current clipping planes const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes(); NCollection_Array1 aOldPlanes (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + aMaxPlanes - 1); if (aContext->core11 != NULL) { for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId) { OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId); aContext->core11->glGetClipPlane (aClipPlaneId, aPlane.Equation); if (aPlane.isEnabled) { aContext->core11fwd->glDisable (aClipPlaneId); aPlane.isEnabled = GL_TRUE; } else { aPlane.isEnabled = GL_FALSE; } } } #endif // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm). Standard_Boolean isProjectionMatUpdateNeeded = Standard_False; Standard_Boolean isOrientationMatUpdateNeeded = Standard_False; if (myBVHSelector.ProjectionState() != myCamera->ProjectionState()) { isProjectionMatUpdateNeeded = Standard_True; myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState(); } if (myBVHSelector.ModelViewState() != myCamera->ModelViewState()) { isOrientationMatUpdateNeeded = Standard_True; myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState(); } if (isProjectionMatUpdateNeeded || isOrientationMatUpdateNeeded) { myBVHSelector.SetViewVolume (myCamera); } const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager(); const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState) { aManager->UpdateLightSourceStateTo (&myLights); myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()); } if (myProjectionState != myCamera->ProjectionState() || !isSameView) { myProjectionState = myCamera->ProjectionState(); aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF()); aContext->ApplyProjectionMatrix(); } if (myModelViewState != myCamera->ModelViewState() || !isSameView) { myModelViewState = myCamera->ModelViewState(); aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF()); aContext->ApplyWorldViewMatrix(); } if (aManager->ModelWorldState().Index() == 0) { aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4()); } // ==================================== // Step 2: Redraw background // ==================================== // Render background if (theWorkspace->ToRedrawGL() && !theToDrawImmediate) { DrawBackground (theWorkspace); } #if !defined(GL_ES_VERSION_2_0) // Switch off lighting by default glDisable(GL_LIGHTING); #endif // ================================= // Step 3: Draw underlayer // ================================= if (!theToDrawImmediate) { RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCUnderLayer); } // ================================= // Step 4: Redraw main plane // ================================= // Setup face culling GLboolean isCullFace = GL_FALSE; if ( myBackfacing ) { isCullFace = glIsEnabled( GL_CULL_FACE ); if ( myBackfacing < 0 ) { glEnable( GL_CULL_FACE ); glCullFace( GL_BACK ); } else glDisable( GL_CULL_FACE ); } #if !defined(GL_ES_VERSION_2_0) // if the view is scaled normal vectors are scaled to unit // length for correct displaying of shaded objects const gp_Pnt anAxialScale = myCamera->AxialScale(); if (anAxialScale.X() != 1.F || anAxialScale.Y() != 1.F || anAxialScale.Z() != 1.F) { aContext->SetGlNormalizeEnabled (Standard_True); } else { aContext->SetGlNormalizeEnabled (Standard_False); } // Apply Fog if ( myFog.IsOn ) { Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance(); if (myCamera->ZFar() < aFogFrontConverted) { aFogFrontConverted = myCamera->ZFar(); myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance()); } Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance(); if (myCamera->ZFar() < aFogFrontConverted) { aFogBackConverted = myCamera->ZFar(); myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance()); } if (aFogFrontConverted > aFogBackConverted) { myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance()); myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance()); } glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted); glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted); glFogfv(GL_FOG_COLOR, myFog.Color.rgb); glEnable(GL_FOG); } else glDisable(GL_FOG); // Apply InteriorShadingMethod aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH); #endif aManager->SetShadingModel (myShadingModel); // Apply AntiAliasing if (myAntiAliasing) theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING; else theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING; if (!aManager->IsEmpty()) { aManager->UpdateClippingState(); } // Redraw 3d scene if (!myCamera->IsStereo() || !aContext->HasStereoBuffers()) { // single-pass monographic rendering // redraw scene with normal orientation and projection RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate); } else { // two stereographic passes // safely switch to left Eye buffer aContext->SetDrawBufferLeft(); aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF()); aContext->ApplyProjectionMatrix(); // redraw left Eye RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate); // reset depth buffer of first rendering pass if (theWorkspace->UseDepthTest()) { glClear (GL_DEPTH_BUFFER_BIT); } // safely switch to right Eye buffer aContext->SetDrawBufferRight(); aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF()); aContext->ApplyProjectionMatrix(); // redraw right Eye RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate); // switch back to monographic rendering aContext->SetDrawBufferMono(); } // =============================== // Step 5: Trihedron // =============================== // Resetting GL parameters according to the default aspects // in order to synchronize GL state with the graphic driver state // before drawing auxiliary stuff (trihedrons, overlayer) // and invoking optional callbacks theWorkspace->ResetAppliedAspect(); aContext->ChangeClipping().RemoveAll(); if (!aManager->IsEmpty()) { aManager->ResetMaterialStates(); aManager->RevertClippingState(); // We need to disable (unbind) all shaders programs to ensure // that all objects without specified aspect will be drawn // correctly (such as background) aContext->BindProgram (NULL); } // Render trihedron if (theWorkspace->ToRedrawGL() && !theToDrawImmediate) { RedrawTrihedron (theWorkspace); // Restore face culling if ( myBackfacing ) { if ( isCullFace ) { glEnable ( GL_CULL_FACE ); glCullFace ( GL_BACK ); } else glDisable ( GL_CULL_FACE ); } } // =============================== // Step 6: Redraw overlay // =============================== if (!theToDrawImmediate) { const int aMode = 0; theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY)); RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer); theWorkspace->DisplayCallback (theCView, aMode); } // =============================== // Step 7: Finalize // =============================== #if !defined(GL_ES_VERSION_2_0) // restore clipping planes if (aContext->core11 != NULL) { for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId) { const OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId); aContext->core11->glClipPlane (aClipPlaneId, aPlane.Equation); if (aPlane.isEnabled) aContext->core11fwd->glEnable (aClipPlaneId); else aContext->core11fwd->glDisable (aClipPlaneId); } } #endif // ============================================================== // Step 8: Keep shader manager informed about last View // ============================================================== if (!aManager.IsNull()) { aManager->SetLastView (this); } } // ======================================================================= // function : InvalidateBVHData // purpose : // ======================================================================= void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId) { myZLayers.InvalidateBVHData (theLayerId); } /*----------------------------------------------------------------------*/ //ExecuteViewDisplay void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& AWorkspace, const Standard_Boolean theToDrawImmediate) { if ( myZLayers.NbStructures() <= 0 ) return; #if !defined(GL_ES_VERSION_2_0) glPushAttrib ( GL_DEPTH_BUFFER_BIT ); #endif //TsmPushAttri(); /* save previous graphics context */ if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 ) { #if !defined(GL_ES_VERSION_2_0) const int antiAliasingMode = AWorkspace->AntiAliasingMode(); #endif if ( !myAntiAliasing ) { #if !defined(GL_ES_VERSION_2_0) glDisable(GL_POINT_SMOOTH); glDisable(GL_LINE_SMOOTH); if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH); #endif glBlendFunc (GL_ONE, GL_ZERO); glDisable (GL_BLEND); } else { #if !defined(GL_ES_VERSION_2_0) glEnable(GL_POINT_SMOOTH); glEnable(GL_LINE_SMOOTH); if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH); #endif glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_BLEND); } } myZLayers.Render (AWorkspace, theToDrawImmediate); #if !defined(GL_ES_VERSION_2_0) //TsmPopAttri(); /* restore previous graphics context; before update lights */ glPopAttrib(); #endif } /*----------------------------------------------------------------------*/ //call_togl_redraw_layer2d void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext, const Handle(OpenGl_Workspace)& theWorkspace, const Graphic3d_CView& /*ACView*/, const Aspect_CLayer2d& ACLayer) { #if !defined(GL_ES_VERSION_2_0) if (&ACLayer == NULL || ACLayer.ptrLayer == NULL || ACLayer.ptrLayer->listIndex == 0) return; const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); GLsizei dispWidth = (GLsizei )ACLayer.viewport[0]; GLsizei dispHeight = (GLsizei )ACLayer.viewport[1]; aContext->WorldViewState.Push(); aContext->ProjectionState.Push(); aContext->WorldViewState.SetIdentity(); aContext->ProjectionState.SetIdentity(); aContext->ApplyWorldViewMatrix(); aContext->ApplyProjectionMatrix(); if (!ACLayer.sizeDependent) aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight); float left = ACLayer.ortho[0]; float right = ACLayer.ortho[1]; float bottom = ACLayer.ortho[2]; float top = ACLayer.ortho[3]; int attach = ACLayer.attach; const float ratio = !ACLayer.sizeDependent ? float(dispWidth) / float(dispHeight) : float(theWorkspace->Width()) / float(theWorkspace->Height()); float delta; if (ratio >= 1.0) { delta = (float )((top - bottom)/2.0); switch (attach) { case 0: /* Aspect_TOC_BOTTOM_LEFT */ top = bottom + 2*delta/ratio; break; case 1: /* Aspect_TOC_BOTTOM_RIGHT */ top = bottom + 2*delta/ratio; break; case 2: /* Aspect_TOC_TOP_LEFT */ bottom = top - 2*delta/ratio; break; case 3: /* Aspect_TOC_TOP_RIGHT */ bottom = top - 2*delta/ratio; break; } } else { delta = (float )((right - left)/2.0); switch (attach) { case 0: /* Aspect_TOC_BOTTOM_LEFT */ right = left + 2*delta*ratio; break; case 1: /* Aspect_TOC_BOTTOM_RIGHT */ left = right - 2*delta*ratio; break; case 2: /* Aspect_TOC_TOP_LEFT */ right = left + 2*delta*ratio; break; case 3: /* Aspect_TOC_TOP_RIGHT */ left = right - 2*delta*ratio; break; } } #ifdef _WIN32 // Check printer context that exists only for print operation if (!thePrintContext.IsNull()) { // additional transformation matrix could be applied to // render only those parts of viewport that will be // passed to a printer as a current "frame" to provide // tiling; scaling of graphics by matrix helps render a // part of a view (frame) in same viewport, but with higher // resolution // set printing scale/tiling transformation aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation()); aContext->ApplyProjectionMatrix(); // printing operation also assumes other viewport dimension // to comply with transformation matrix or graphics scaling // factors for tiling for layer redraw GLsizei anViewportX = 0; GLsizei anViewportY = 0; thePrintContext->GetLayerViewport (anViewportX, anViewportY); if (anViewportX != 0 && anViewportY != 0) aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY); } #endif glOrtho (left, right, bottom, top, -1.0, 1.0); glPushAttrib ( GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT ); glDisable (GL_DEPTH_TEST); glDisable (GL_TEXTURE_1D); glDisable (GL_TEXTURE_2D); glDisable (GL_LIGHTING); // TODO: Obsolete code, the display list is always empty now, to be removed glCallList (ACLayer.ptrLayer->listIndex); //calling dynamic render of LayerItems if ( ACLayer.ptrLayer->layerData ) { InitLayerProp (ACLayer.ptrLayer->listIndex); ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems(); InitLayerProp (0); } glPopAttrib (); aContext->WorldViewState.Pop(); aContext->ProjectionState.Pop(); aContext->ApplyProjectionMatrix(); aContext->ApplyWorldViewMatrix(); if (!ACLayer.sizeDependent) aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height()); glFlush (); #endif } /*----------------------------------------------------------------------*/ void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace) { // display global trihedron if (myTrihedron != NULL) { myTrihedron->Render (theWorkspace); } if (myGraduatedTrihedron != NULL) { myGraduatedTrihedron->Render (theWorkspace); } } /*----------------------------------------------------------------------*/ //call_togl_create_bg_texture void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath, const Aspect_FillMethod theFillStyle) { // Prepare aspect for texture storage Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d(); Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath)); aTextureMap->EnableRepeat(); aTextureMap->DisableModulate(); aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL, Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f), Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f)); anAspect->SetTextureMap (aTextureMap); anAspect->SetInteriorStyle (Aspect_IS_SOLID); // Enable texture mapping if (aTextureMap->IsDone()) { anAspect->SetTextureMapOn(); } else { anAspect->SetTextureMapOff(); return; } // Set texture parameters myTextureParams->SetAspect (anAspect); myBgTextureArray->SetTextureParameters (theFillStyle); } /*----------------------------------------------------------------------*/ //call_togl_set_bg_texture_style void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod theFillStyle) { myBgTextureArray->SetTextureFillMethod (theFillStyle); } /*----------------------------------------------------------------------*/ //call_togl_gradient_background void OpenGl_View::SetBackgroundGradient (const Quantity_Color& theColor1, const Quantity_Color& theColor2, const Aspect_GradientFillMethod theType) { myBgGradientArray->SetGradientParameters (theColor1, theColor2, theType); } /*----------------------------------------------------------------------*/ //call_togl_set_gradient_type void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod theType) { myBgGradientArray->SetGradientFillMethod (theType); } //======================================================================= //function : AddZLayer //purpose : //======================================================================= void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId) { myZLayers.AddLayer (theLayerId); } //======================================================================= //function : RemoveZLayer //purpose : //======================================================================= void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId) { myZLayers.RemoveLayer (theLayerId); } //======================================================================= //function : DisplayStructure //purpose : //======================================================================= void OpenGl_View::DisplayStructure (const Handle(Graphic3d_Structure)& theStructure, const Standard_Integer thePriority) { const OpenGl_Structure* aStruct = reinterpret_cast (theStructure->CStructure().operator->()); const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer(); myZLayers.AddStructure (aStruct, aZLayer, thePriority); } //======================================================================= //function : DisplayImmediateStructure //purpose : //======================================================================= void OpenGl_View::DisplayImmediateStructure (const Handle(Graphic3d_Structure)& theStructure) { const OpenGl_Structure* aStruct = reinterpret_cast (theStructure->CStructure().operator->()); for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList); anIter.More(); anIter.Next()) { if (anIter.Value() == aStruct) { return; } } myImmediateList.Append (aStruct); } //======================================================================= //function : EraseStructure //purpose : //======================================================================= void OpenGl_View::EraseStructure (const Handle(Graphic3d_Structure)& theStructure) { myZLayers.RemoveStructure (theStructure); } //======================================================================= //function : EraseImmediateStructure //purpose : //======================================================================= void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure) { for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList); anIter.More(); anIter.Next()) { if (anIter.Value() == theStructure) { myImmediateList.Remove (anIter); return; } } } //======================================================================= //function : ChangeZLayer //purpose : //======================================================================= void OpenGl_View::ChangeZLayer (const OpenGl_Structure* theStructure, const Graphic3d_ZLayerId theNewLayerId) { const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer(); myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId); } //======================================================================= //function : SetZLayerSettings //purpose : //======================================================================= void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings) { myZLayers.SetLayerSettings (theLayerId, theSettings); } //======================================================================= //function : ChangePriority //purpose : //======================================================================= void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure, const Standard_Integer theNewPriority) { const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer(); myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority); } //======================================================================= //function : RedrawScene //purpose : //======================================================================= void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext, const Handle(OpenGl_Workspace)& theWorkspace, const Standard_Boolean theToDrawImmediate) { const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); if (myZClip.Back.IsOn || myZClip.Front.IsOn) { Handle(Graphic3d_ClipPlane) aPlaneBack; Handle(Graphic3d_ClipPlane) aPlaneFront; if (myZClip.Back.IsOn) { Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance(); if (myCamera->ZFar() < aClipBackConverted) { aClipBackConverted = myCamera->ZFar(); myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance()); } const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted); aPlaneBack = new Graphic3d_ClipPlane (aBackEquation); } if (myZClip.Front.IsOn) { Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance(); if (myCamera->ZNear() > aClipFrontConverted) { aClipFrontConverted = myCamera->ZNear(); myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance()); } const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted); aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation); } // Specify slicing planes with identity transformation if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull()) { Graphic3d_SequenceOfHClipPlane aSlicingPlanes; if (!aPlaneBack.IsNull()) { aSlicingPlanes.Append (aPlaneBack); } if (!aPlaneFront.IsNull()) { aSlicingPlanes.Append (aPlaneFront); } // add planes at loaded view matrix state aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace); } } #ifdef _WIN32 // set printing scale/tiling transformation if (!thePrintContext.IsNull()) { aContext->ProjectionState.Push(); aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current()); aContext->ApplyProjectionMatrix(); } #endif // Specify clipping planes in view transformation space if (!myClipPlanes.IsEmpty()) { Graphic3d_SequenceOfHClipPlane aUserPlanes; Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes); for (; aClippingIt.More(); aClippingIt.Next()) { const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value(); if (aClipPlane->IsOn()) { aUserPlanes.Append (aClipPlane); } } if (!aUserPlanes.IsEmpty()) { aContext->ChangeClipping().AddWorld (aUserPlanes); } if (!aContext->ShaderManager()->IsEmpty()) { aContext->ShaderManager()->UpdateClippingState(); } } #if !defined(GL_ES_VERSION_2_0) // Apply Lights { // setup lights Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0], THE_DEFAULT_AMBIENT[1], THE_DEFAULT_AMBIENT[2], THE_DEFAULT_AMBIENT[3]); GLenum aLightGlId = GL_LIGHT0; for (OpenGl_ListOfLight::Iterator aLightIt (myLights); aLightIt.More(); aLightIt.Next()) { bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace); } // apply accumulated ambient color anAmbientColor.a() = 1.0f; glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData()); if (aLightGlId != GL_LIGHT0) { glEnable (GL_LIGHTING); } // switch off unused lights for (; aLightGlId <= GL_LIGHT7; ++aLightGlId) { glDisable (aLightGlId); } } #endif // Clear status bitfields theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO); // Added PCT for handling of textures switch (mySurfaceDetail) { case Visual3d_TOD_NONE: theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX; theWorkspace->DisableTexture(); // Render the view RenderStructs (theWorkspace, theToDrawImmediate); break; case Visual3d_TOD_ENVIRONMENT: theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX; theWorkspace->EnableTexture (myTextureEnv); // Render the view RenderStructs (theWorkspace, theToDrawImmediate); theWorkspace->DisableTexture(); break; case Visual3d_TOD_ALL: // First pass theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX; // Render the view RenderStructs (theWorkspace, theToDrawImmediate); theWorkspace->DisableTexture(); // Second pass if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) { theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO; theWorkspace->EnableTexture (myTextureEnv); // Remember OpenGl properties GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA; GLint aSaveZbuffFunc; GLboolean aSaveZbuffWrite; glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite); glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc); #if !defined(GL_ES_VERSION_2_0) glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst); glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc); #endif GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST); GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND); // Change the properties for second rendering pass glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_BLEND); glDepthFunc (GL_EQUAL); glDepthMask (GL_FALSE); glEnable (GL_DEPTH_TEST); theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX; // Render the view RenderStructs (theWorkspace, theToDrawImmediate); theWorkspace->DisableTexture(); // Restore properties back glBlendFunc (aSaveBlendSrc, aSaveBlendDst); if (!wasBlendEnabled) glDisable (GL_BLEND); glDepthFunc (aSaveZbuffFunc); glDepthMask (aSaveZbuffWrite); if (!wasZbuffEnabled) glDisable (GL_DEPTH_FUNC); } break; } // Apply restored view matrix. aContext->ApplyWorldViewMatrix(); #ifdef _WIN32 // set printing scale/tiling transformation if (!thePrintContext.IsNull()) { aContext->ProjectionState.Pop(); aContext->ApplyProjectionMatrix(); } #endif }