0032143: Visualization - add option excluding transparent object from sorting
authorkgv <kgv@opencascade.com>
Mon, 1 Mar 2021 12:16:52 +0000 (15:16 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 4 Mar 2021 16:38:16 +0000 (19:38 +0300)
Added option Graphic3d_AlphaMode_MaskBlend combining Mask (no sorting)
and Blend (enable blending with background) behavior.

15 files changed:
src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialDriver.cxx
src/Graphic3d/Graphic3d_AlphaMode.hxx
src/Graphic3d/Graphic3d_AspectText3d.cxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_GraduatedTrihedron.cxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_Text.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/RWGltf/RWGltf_GltfMaterialMap.cxx
src/ViewerTest/ViewerTest.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
src/XDEDRAW/XDEDRAW_Colors.cxx
src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialDriver.cxx
tests/bugs/vis/bug32143 [new file with mode: 0644]

index a6c0355..85c7565 100644 (file)
@@ -27,6 +27,7 @@ static Standard_Byte alphaModeToChar (Graphic3d_AlphaMode theMode)
     case Graphic3d_AlphaMode_Opaque:    return 'O';
     case Graphic3d_AlphaMode_Mask:      return 'M';
     case Graphic3d_AlphaMode_Blend:     return 'B';
+    case Graphic3d_AlphaMode_MaskBlend: return 'b';
     case Graphic3d_AlphaMode_BlendAuto: return 'A';
   }
   return 'A';
@@ -40,6 +41,7 @@ static Graphic3d_AlphaMode alphaModeFromChar (Standard_Byte theMode)
     case 'O': return Graphic3d_AlphaMode_Opaque;
     case 'M': return Graphic3d_AlphaMode_Mask;
     case 'B': return Graphic3d_AlphaMode_Blend;
+    case 'b': return Graphic3d_AlphaMode_MaskBlend;
     case 'A': return Graphic3d_AlphaMode_BlendAuto;
   }
   return Graphic3d_AlphaMode_BlendAuto;
index 4839417..19c142c 100644 (file)
@@ -20,6 +20,7 @@ enum Graphic3d_AlphaMode
   Graphic3d_AlphaMode_Opaque = 0,     //!< rendered output is fully opaque and alpha value is ignored
   Graphic3d_AlphaMode_Mask,           //!< rendered output is either fully opaque or fully transparent depending on the alpha value and the alpha cutoff value
   Graphic3d_AlphaMode_Blend,          //!< rendered output is combined with the background
+  Graphic3d_AlphaMode_MaskBlend,      //!< performs in-place blending (without implicit reordering of opaque objects) with alpha-test
 
   Graphic3d_AlphaMode_BlendAuto = -1, //!< special value defined for backward compatibility - it is equal to Graphic3d_AlphaMode_Blend when Material transparency is not zero and Graphic3d_AlphaMode_Opaque otherwise;
                                       //   since this check ignores possible transparency defined by per-vertex colors and textures - NOT recommended to use!
index 22ace08..f4b9224 100644 (file)
@@ -23,10 +23,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_AspectText3d, Graphic3d_Aspects)
 // =======================================================================
 Graphic3d_AspectText3d::Graphic3d_AspectText3d()
 {
-  // actually this should be a special state Graphic3d_AlphaMode_MaskBlend
-  // since text is drawn in usual order with normal opaque objects (thanks to alpha test),
-  // but blending is also enabled to smoothen boundaries
-  SetAlphaMode (Graphic3d_AlphaMode_Mask, 0.285f);
+  SetAlphaMode (Graphic3d_AlphaMode_MaskBlend, 0.285f);
   myShadingModel = Graphic3d_TOSM_UNLIT;
   myInteriorColor.SetRGB (Quantity_NOC_YELLOW);
   myEdgeColor.SetRGB (Quantity_NOC_WHITE);
@@ -43,7 +40,7 @@ Graphic3d_AspectText3d::Graphic3d_AspectText3d (const Quantity_Color& theColor,
                                                 Aspect_TypeOfStyleText   theStyle,
                                                 Aspect_TypeOfDisplayText theDisplayType)
 {
-  SetAlphaMode (Graphic3d_AlphaMode_Mask, 0.285f);
+  SetAlphaMode (Graphic3d_AlphaMode_MaskBlend, 0.285f);
   myShadingModel = Graphic3d_TOSM_UNLIT;
   myTextStyle = theStyle;
   myTextDisplayType = theDisplayType;
index 15a8c4e..1496f18 100644 (file)
@@ -2445,7 +2445,8 @@ void OpenGl_Context::SetShadingMaterial (const OpenGl_Aspects* theAspect,
   // do not update material properties in case of zero reflection mode,
   // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
   const OpenGl_MaterialState& aMatState = myShaderManager->MaterialState();
-  float anAlphaCutoff = anAspect->AlphaMode() == Graphic3d_AlphaMode_Mask
+  float anAlphaCutoff = (anAspect->AlphaMode() == Graphic3d_AlphaMode_Mask
+                      || anAspect->AlphaMode() == Graphic3d_AlphaMode_MaskBlend)
                       ? anAspect->AlphaCutoff()
                       : ShortRealLast();
   if (anAspect->ToDrawEdges())
@@ -2513,6 +2514,7 @@ Standard_Boolean OpenGl_Context::CheckIsTransparent (const OpenGl_Aspects* theAs
     return theAlphaFront < 1.0f
         || theAlphaBack  < 1.0f;
   }
+  // Graphic3d_AlphaMode_Mask and Graphic3d_AlphaMode_MaskBlend are not considered transparent here
   return anAspect->AlphaMode() == Graphic3d_AlphaMode_Blend;
 }
 
index 34111b2..78b4eea 100755 (executable)
@@ -109,11 +109,13 @@ void OpenGl_GraduatedTrihedron::initGlResources (const Handle(OpenGl_Context)& t
 
   myLabelValues.SetFontSize (theCtx, myData.ValuesSize());
 
+  myAspectLabels.Aspect()->SetAlphaMode (Graphic3d_AlphaMode_MaskBlend, 0.285f);
   myAspectLabels.Aspect()->SetTextFontAspect (myData.NamesFontAspect());
   myAspectLabels.Aspect()->SetTextFont (!myData.NamesFont().IsEmpty()
                                        ? new TCollection_HAsciiString (myData.NamesFont())
                                        : Handle(TCollection_HAsciiString )());
 
+  myAspectValues.Aspect()->SetAlphaMode (Graphic3d_AlphaMode_MaskBlend, 0.285f);
   myAspectValues.Aspect()->SetTextFontAspect (myData.ValuesFontAspect());
   myAspectValues.Aspect()->SetTextFont (!myData.ValuesFont().IsEmpty()
                                        ? new TCollection_HAsciiString (myData.ValuesFont())
index 9a1a255..ac51789 100644 (file)
@@ -1009,6 +1009,13 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
     }
     aCtx->SetSampleAlphaToCoverage (aCtx->ShaderManager()->MaterialState().HasAlphaCutoff());
 
+    const bool isForcedBlend = anAspectFace->Aspect()->AlphaMode() == Graphic3d_AlphaMode_MaskBlend;
+    if (isForcedBlend)
+    {
+      aCtx->core11fwd->glEnable (GL_BLEND);
+      aCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    }
+
     const Graphic3d_Vec4* aFaceColors = !myBounds.IsNull() && !toHilight && anAspectFace->Aspect()->InteriorStyle() != Aspect_IS_HIDDENLINE
                                       ?  myBounds->Colors
                                       :  NULL;
@@ -1024,6 +1031,10 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
       }
 
       drawArray (theWorkspace, aFaceColors, hasColorAttrib);
+      if (isForcedBlend)
+      {
+        aCtx->core11fwd->glDisable (GL_BLEND);
+      }
       return;
     }
 
@@ -1049,6 +1060,11 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
 
       aCtx->core11fwd->glCullFace (GL_BACK);
     }
+
+    if (isForcedBlend)
+    {
+      aCtx->core11fwd->glDisable (GL_BLEND);
+    }
   }
 
 #if !defined(GL_ES_VERSION_2_0)
index 4350e8f..ec48717 100644 (file)
@@ -578,7 +578,8 @@ protected:
                                    Standard_Boolean theEnableMeshEdges) const
   {
     Standard_Integer aBits = 0;
-    if (theAlphaMode == Graphic3d_AlphaMode_Mask)
+    if (theAlphaMode == Graphic3d_AlphaMode_Mask
+     || theAlphaMode == Graphic3d_AlphaMode_MaskBlend)
     {
       aBits |= Graphic3d_ShaderFlags_AlphaTest;
     }
index bbdb850..589095a 100644 (file)
@@ -759,7 +759,7 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
                          && theTextAspect.Aspect()->TextStyle() != Aspect_TOST_ANNOTATION;
   if (!hasDepthTest)
   {
-    glDisable (GL_DEPTH_TEST);
+    theCtx->core11fwd->glDisable (GL_DEPTH_TEST);
   }
 
   if (theCtx->core15fwd != NULL)
@@ -782,8 +782,11 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
 #endif
 
   // setup blending
-  glEnable (GL_BLEND);
-  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  if (theTextAspect.Aspect()->AlphaMode() == Graphic3d_AlphaMode_MaskBlend)
+  {
+    theCtx->core11fwd->glEnable (GL_BLEND);
+    theCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  }
 
   // alpha to coverage makes text too thin
   theCtx->SetSampleAlphaToCoverage (false);
@@ -854,7 +857,10 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
 
   if (theTextAspect.Aspect()->TextDisplayType() == Aspect_TODT_DIMENSION)
   {
-    glDisable (GL_BLEND);
+    if (theTextAspect.Aspect()->AlphaMode() == Graphic3d_AlphaMode_MaskBlend)
+    {
+      glDisable (GL_BLEND);
+    }
     if (!myIs2d)
     {
       glDisable (GL_DEPTH_TEST);
@@ -880,7 +886,10 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
   }
 
   // reset OpenGL state
-  glDisable (GL_BLEND);
+  if (theTextAspect.Aspect()->AlphaMode() == Graphic3d_AlphaMode_MaskBlend)
+  {
+    theCtx->core11fwd->glDisable (GL_BLEND);
+  }
   glDisable (GL_STENCIL_TEST);
 #if !defined(GL_ES_VERSION_2_0)
   glDisable (GL_COLOR_LOGIC_OP);
index 8ef92f8..c39c76c 100644 (file)
@@ -261,6 +261,7 @@ const OpenGl_Aspects* OpenGl_Workspace::ApplyAspects (bool theToBindTextures)
       if (myAspectsSet->Aspect()->InteriorStyle() == Aspect_IS_HATCH
        || myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Blend
        || myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Mask
+       || myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_MaskBlend
        || (myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_BlendAuto
         && myAspectsSet->Aspect()->FrontMaterial().Transparency() != 0.0f))
       {
index b143e5b..e541e6f 100644 (file)
@@ -516,6 +516,7 @@ void RWGltf_GltfMaterialMap::DefineMaterial (const XCAFPrs_Style& theStyle,
         break;
       }
       case Graphic3d_AlphaMode_Blend:
+      case Graphic3d_AlphaMode_MaskBlend:
       {
         myWriter->Key ("alphaMode");
         myWriter->String ("BLEND");
index adf3114..3a3ed1c 100644 (file)
@@ -2552,6 +2552,11 @@ static Standard_Integer VAspects (Draw_Interpretor& theDI,
         {
           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Blend;
         }
+        else if (aParam == "maskblend"
+              || aParam == "blendmask")
+        {
+          aChangeSet->AlphaMode = Graphic3d_AlphaMode_MaskBlend;
+        }
         else if (aParam == "blendauto"
               || aParam == "auto")
         {
@@ -6689,7 +6694,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
       "\n\t\t:          [-faceBoundaryWidth LineWidth] [-faceBoundaryColor R G B] [-faceBoundaryType LineType]"
       "\n\t\t:          [-drawEdges {0|1}] [-edgeType LineType] [-edgeColor R G B] [-quadEdges {0|1}]"
       "\n\t\t:          [-drawSilhouette {0|1}]"
-      "\n\t\t:          [-alphaMode {opaque|mask|blend|blendauto} [alphaCutOff=0.5]]"
+      "\n\t\t:          [-alphaMode {opaque|mask|blend|maskblend|blendauto} [alphaCutOff=0.5]]"
       "\n\t\t:          [-dumpJson]"
       "\n\t\t:          [-dumpCompact {0|1}]"
       "\n\t\t:          [-dumpDepth depth]"
index 5e37d27..1ddf765 100644 (file)
@@ -9640,6 +9640,11 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
         {
           aMode = Graphic3d_AlphaMode_Blend;
         }
+        else if (aValStr == "maskblend"
+              || aValStr == "blendmask")
+        {
+          aMode = Graphic3d_AlphaMode_MaskBlend;
+        }
         else if (aValStr == "blendauto")
         {
           aMode = Graphic3d_AlphaMode_BlendAuto;
index 1baa41b..a74a0d9 100644 (file)
@@ -87,6 +87,7 @@ static const char* alphaModeToString (Graphic3d_AlphaMode theMode)
     case Graphic3d_AlphaMode_Opaque:    return "Opaque";
     case Graphic3d_AlphaMode_Mask:      return "Mask";
     case Graphic3d_AlphaMode_Blend:     return "Blend";
+    case Graphic3d_AlphaMode_MaskBlend: return "MaskBlend";
     case Graphic3d_AlphaMode_BlendAuto: return "BlendAuto";
   }
   return "";
@@ -986,6 +987,11 @@ static Standard_Integer XAddVisMaterial (Draw_Interpretor& , Standard_Integer th
       {
         anAlphaMode = Graphic3d_AlphaMode_Blend;
       }
+      else if (aModeStr == "maskblend"
+            || aModeStr == "blendmask")
+      {
+        anAlphaMode = Graphic3d_AlphaMode_MaskBlend;
+      }
       else if (aModeStr == "blendauto")
       {
         anAlphaMode = Graphic3d_AlphaMode_BlendAuto;
index 1656fe7..cc000c8 100644 (file)
@@ -51,6 +51,7 @@ static const char* alphaModeToString (Graphic3d_AlphaMode theMode)
     case Graphic3d_AlphaMode_Opaque:    return "Opaque";
     case Graphic3d_AlphaMode_Mask:      return "Mask";
     case Graphic3d_AlphaMode_Blend:     return "Blend";
+    case Graphic3d_AlphaMode_MaskBlend: return "MaskBlend";
     case Graphic3d_AlphaMode_BlendAuto: return "Auto";
   }
   return "Auto";
@@ -59,12 +60,25 @@ static const char* alphaModeToString (Graphic3d_AlphaMode theMode)
 //! Decode alpha mode from string.
 static Graphic3d_AlphaMode alphaModeFromString (const char* theMode)
 {
-  switch (*theMode)
+  if (strcasecmp (theMode, "Opaque") == 0)
   {
-    case 'O': return Graphic3d_AlphaMode_Opaque;
-    case 'M': return Graphic3d_AlphaMode_Mask;
-    case 'B': return Graphic3d_AlphaMode_Blend;
-    case 'A': return Graphic3d_AlphaMode_BlendAuto;
+    return Graphic3d_AlphaMode_Opaque;
+  }
+  else if (strcasecmp (theMode, "Mask") == 0)
+  {
+    return Graphic3d_AlphaMode_Mask;
+  }
+  else if (strcasecmp (theMode, "Blend") == 0)
+  {
+    return Graphic3d_AlphaMode_Blend;
+  }
+  else if (strcasecmp (theMode, "MaskBlend") == 0)
+  {
+    return Graphic3d_AlphaMode_MaskBlend;
+  }
+  else if (strcasecmp (theMode, "Auto") == 0)
+  {
+    return Graphic3d_AlphaMode_BlendAuto;
   }
   return Graphic3d_AlphaMode_BlendAuto;
 }
diff --git a/tests/bugs/vis/bug32143 b/tests/bugs/vis/bug32143
new file mode 100644 (file)
index 0000000..d37fcfa
--- /dev/null
@@ -0,0 +1,25 @@
+puts "============"
+puts "0032143: Visualization - add option excluding transparent object from sorting"
+puts "============"
+puts ""
+
+pload MODELING VISUALIZATION
+vclear
+vinit View1 -width 512 -height 512
+vbackground -gradient GRAY20 GRAY80
+restore [locate_data_file Ball.brep] b
+vdisplay -dispMode 1 b
+vfit
+
+set dx 220; set dy 74
+set logoPath "$::env(CSF_OCCTResourcePath)/DrawResources/OCC_logo.png"
+box logo $dx $dy 0 -preview
+vdisplay -dispMode 1 logo -topmost -2d bottomRight [expr $dx+25] 25
+vtexture logo "$logoPath"
+vaspects logo -alphaMode BLEND -shadingModel UNLIT
+vdisplay logo -underlay
+if { [vreadpixel 320 440 -rgb -name] != "DEEPSKYBLUE3" } { puts "Error: Unexpected color for BLEND" }
+vaspects logo -alphaMode MASKBLEND 0.001 -shadingModel UNLIT
+if { [vreadpixel 320 440 -rgb -name] != "DARKGOLDENROD" } { puts "Error: Unexpected color for MASKBLEND" }
+
+vdump ${imagedir}/${casename}.png