0029517: Visualization - introduce AlphaMode property defining alpha value handling...
authorkgv <kgv@opencascade.com>
Tue, 20 Feb 2018 13:32:52 +0000 (16:32 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 2 Mar 2018 12:27:53 +0000 (15:27 +0300)
29 files changed:
src/AIS/AIS_RubberBand.cxx
src/Graphic3d/FILES
src/Graphic3d/Graphic3d_AlphaMode.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_AspectFillArea3d.cxx
src/Graphic3d/Graphic3d_AspectFillArea3d.hxx
src/Graphic3d/Graphic3d_RenderingParams.hxx
src/Graphic3d/Graphic3d_ShaderProgram.cxx
src/Graphic3d/Graphic3d_ShaderProgram.hxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_MaterialState.hxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_SetOfShaderPrograms.hxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_ShaderProgram.cxx
src/OpenGl/OpenGl_ShaderProgram.hxx
src/OpenGl/OpenGl_Text.cxx
src/OpenGl/OpenGl_View_Redraw.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/Shaders/Declarations.glsl
src/Shaders/DeclarationsImpl.glsl
src/Shaders/Shaders_DeclarationsImpl_glsl.pxx
src/Shaders/Shaders_Declarations_glsl.pxx
src/ViewerTest/ViewerTest.cxx
src/ViewerTest/ViewerTest_OpenGlCommands.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/glsl/alpha_mask [new file with mode: 0644]

index 1d7f1ab..f4a97ab 100644 (file)
@@ -45,6 +45,7 @@ AIS_RubberBand::AIS_RubberBand()
   myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
   myDrawer->ShadingAspect()->SetMaterial (Graphic3d_NOM_PLASTIC);
   myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_EMPTY);
+  myDrawer->ShadingAspect()->Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Blend);
   myDrawer->ShadingAspect()->SetTransparency (1.0);
   myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
 
@@ -66,6 +67,7 @@ AIS_RubberBand::AIS_RubberBand (const Quantity_Color& theLineColor,
   myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
   myDrawer->ShadingAspect()->SetMaterial (Graphic3d_NOM_PLASTIC);
   myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_EMPTY);
+  myDrawer->ShadingAspect()->Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Blend);
   myDrawer->ShadingAspect()->SetTransparency (1.0);
   myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
 
@@ -90,6 +92,7 @@ AIS_RubberBand::AIS_RubberBand (const Quantity_Color& theLineColor,
   myDrawer->ShadingAspect()->SetMaterial (Graphic3d_NOM_PLASTIC);
   myDrawer->ShadingAspect()->SetColor (theFillColor);
   myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
+  myDrawer->ShadingAspect()->Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Blend);
   myDrawer->ShadingAspect()->SetTransparency (theTransparency);
 
   SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
index 3f7ab9f..25ebb5a 100755 (executable)
@@ -1,3 +1,4 @@
+Graphic3d_AlphaMode.hxx
 Graphic3d_ArrayOfPoints.hxx
 Graphic3d_ArrayOfPolygons.hxx
 Graphic3d_ArrayOfPolylines.hxx
diff --git a/src/Graphic3d/Graphic3d_AlphaMode.hxx b/src/Graphic3d/Graphic3d_AlphaMode.hxx
new file mode 100644 (file)
index 0000000..4839417
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright (c) 2018 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.
+
+#ifndef _Graphic3d_AlphaMode_HeaderFile
+#define _Graphic3d_AlphaMode_HeaderFile
+
+//! Defines how alpha value of base color / texture should be treated.
+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_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!
+};
+
+#endif // _Graphic3d_AlphaModeHeaderFile
index 5398fe2..a4e1cb0 100644 (file)
@@ -27,6 +27,8 @@ Graphic3d_AspectFillArea3d::Graphic3d_AspectFillArea3d()
   myEdgeColor           (Quantity_NOC_WHITE),
   myInteriorStyle       (Aspect_IS_EMPTY),
   myShadingModel        (Graphic3d_TOSM_DEFAULT),
+  myAlphaMode           (Graphic3d_AlphaMode_BlendAuto),
+  myAlphaCutoff         (0.5f),
   myEdgeType            (Aspect_TOL_SOLID),
   myEdgeWidth           (1.0f),
   myHatchStyle          (Handle(Graphic3d_HatchStyle)()),
@@ -56,6 +58,8 @@ Graphic3d_AspectFillArea3d::Graphic3d_AspectFillArea3d (const Aspect_InteriorSty
   myEdgeColor           (theEdgeColor),
   myInteriorStyle       (theInteriorStyle),
   myShadingModel        (Graphic3d_TOSM_DEFAULT),
+  myAlphaMode           (Graphic3d_AlphaMode_BlendAuto),
+  myAlphaCutoff         (0.5f),
   myEdgeType            (theEdgeLineType),
   myEdgeWidth           ((float )theEdgeLineWidth),
   myHatchStyle          (Handle(Graphic3d_HatchStyle)()),
index dcd532b..f7e46e1 100644 (file)
@@ -21,6 +21,7 @@
 #include <Aspect_PolygonOffsetMode.hxx>
 #include <Aspect_InteriorStyle.hxx>
 #include <Aspect_TypeOfLine.hxx>
+#include <Graphic3d_AlphaMode.hxx>
 #include <Graphic3d_HatchStyle.hxx>
 #include <Graphic3d_MaterialAspect.hxx>
 #include <Graphic3d_PolygonOffset.hxx>
@@ -84,6 +85,20 @@ public:
   //! Sets shading model
   void SetShadingModel (const Graphic3d_TypeOfShadingModel theShadingModel) { myShadingModel = theShadingModel; }
 
+  //! Returns the way how alpha value should be treated (Graphic3d_AlphaMode_BlendAuto by default, for backward compatibility).
+  Graphic3d_AlphaMode AlphaMode() const { return myAlphaMode; }
+
+  //! Returns alpha cutoff threshold, for discarding fragments within Graphic3d_AlphaMode_Mask mode (0.5 by default).
+  //! If the alpha value is greater than or equal to this value then it is rendered as fully opaque, otherwise, it is rendered as fully transparent.
+  Standard_ShortReal AlphaCutoff() const { return myAlphaCutoff; }
+
+  //! Defines the way how alpha value should be treated.
+  void SetAlphaMode (Graphic3d_AlphaMode theMode, Standard_ShortReal theAlphaCutoff = 0.5f)
+  {
+    myAlphaMode = theMode;
+    myAlphaCutoff = theAlphaCutoff;
+  }
+
   //! Return interior color.
   const Quantity_Color& InteriorColor() const { return myInteriorColor.GetRGB(); }
 
@@ -345,6 +360,8 @@ protected:
   Quantity_ColorRGBA           myEdgeColor;
   Aspect_InteriorStyle         myInteriorStyle;
   Graphic3d_TypeOfShadingModel myShadingModel;
+  Graphic3d_AlphaMode          myAlphaMode;
+  Standard_ShortReal           myAlphaCutoff;
   Aspect_TypeOfLine            myEdgeType;
   Standard_ShortReal           myEdgeWidth;
   Handle(Graphic3d_HatchStyle) myHatchStyle;
index 17f4913..6c53b3f 100644 (file)
@@ -80,6 +80,7 @@ public:
     NbMsaaSamples               (0),
     RenderResolutionScale       (1.0f),
     ToEnableDepthPrepass        (Standard_False),
+    ToEnableAlphaToCoverage     (Standard_False),
     // ray tracing parameters
     IsGlobalIlluminationEnabled (Standard_False),
     RaytracingDepth             (THE_DEFAULT_DEPTH),
@@ -147,6 +148,7 @@ public:
   Standard_ShortReal                RenderResolutionScale;       //!< rendering resolution scale factor, 1 by default;
                                                                  //!  incompatible with MSAA (e.g. NbMsaaSamples should be set to 0)
   Standard_Boolean                  ToEnableDepthPrepass;        //!< enables/disables depth pre-pass, False by default
+  Standard_Boolean                  ToEnableAlphaToCoverage;     //!< enables/disables alpha to coverage, False by default
 
   Standard_Boolean                  IsGlobalIlluminationEnabled; //!< enables/disables global illumination effects (path tracing)
   Standard_Integer                  SamplesPerPixel;             //!< number of samples per pixel (SPP)
index 4ed1051..c7638c1 100755 (executable)
@@ -80,6 +80,7 @@ Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
 : myNbLightsMax (THE_MAX_LIGHTS_DEFAULT),
   myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT),
   myNbFragOutputs (THE_NB_FRAG_OUTPUTS),
+  myHasAlphaTest (false),
   myHasWeightOitOutput (false)
 {
   myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_")
index 324465e..0e2cd15 100755 (executable)
@@ -126,6 +126,13 @@ public:
   //! Should be done before GLSL program initialization.
   void SetNbFragmentOutputs (const Standard_Integer theNbOutputs) { myNbFragOutputs = theNbOutputs; }
 
+  //! Return true if Fragment Shader should perform alpha test; FALSE by default.
+  Standard_Boolean HasAlphaTest() const { return myHasAlphaTest; }
+
+  //! Set if Fragment Shader should perform alpha test.
+  //! Note that this flag is designed for usage with - custom shader program may discard fragment regardless this flag.
+  void SetAlphaTest (Standard_Boolean theAlphaTest) { myHasAlphaTest = theAlphaTest; }
+
   //! Return true if Fragment Shader color should output the weighted OIT coverage; FALSE by default.
   Standard_Boolean HasWeightOitOutput() const { return myHasWeightOitOutput; }
 
@@ -183,6 +190,7 @@ private:
   Standard_Integer              myNbLightsMax;   //!< length of array of light sources (THE_MAX_LIGHTS)
   Standard_Integer              myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
   Standard_Integer              myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
+  Standard_Boolean              myHasAlphaTest;       //!< flag indicating that Fragment Shader performs alpha test
   Standard_Boolean              myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
 
 };
index ed61534..18cbea0 100644 (file)
@@ -191,6 +191,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   myDrawBuffers (1),
   myDefaultVao (0),
   myColorMask (true),
+  myAlphaToCoverage (false),
   myIsGlDebugCtx (Standard_False),
   myResolution (Graphic3d_RenderingParams::THE_DEFAULT_RESOLUTION),
   myResolutionRatio (1.0f),
@@ -3193,20 +3194,27 @@ void OpenGl_Context::SetShadingMaterial (const OpenGl_AspectFace* 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();
+  const float anAlphaCutoff = anAspect->AlphaMode() == Graphic3d_AlphaMode_Mask
+                            ? anAspect->AlphaCutoff()
+                            : ShortRealLast();
   if (theAspect->ShadingModel() == Graphic3d_TOSM_UNLIT)
   {
-    return;
+    if (anAlphaCutoff == aMatState.AlphaCutoff())
+    {
+      return;
+    }
   }
-
-  if (myMatFront    == myShaderManager->MaterialState().FrontMaterial()
-   && myMatBack     == myShaderManager->MaterialState().BackMaterial()
-   && toDistinguish == myShaderManager->MaterialState().ToDistinguish()
-   && toMapTexture  == myShaderManager->MaterialState().ToMapTexture())
+  else if (myMatFront    == aMatState.FrontMaterial()
+        && myMatBack     == aMatState.BackMaterial()
+        && toDistinguish == aMatState.ToDistinguish()
+        && toMapTexture  == aMatState.ToMapTexture()
+        && anAlphaCutoff == aMatState.AlphaCutoff())
   {
     return;
   }
 
-  myShaderManager->UpdateMaterialStateTo (myMatFront, myMatBack, toDistinguish, toMapTexture);
+  myShaderManager->UpdateMaterialStateTo (myMatFront, myMatBack, anAlphaCutoff, toDistinguish, toMapTexture);
 }
 
 // =======================================================================
@@ -3241,9 +3249,12 @@ Standard_Boolean OpenGl_Context::CheckIsTransparent (const OpenGl_AspectFace* th
     theAlphaBack  = aMatBackSrc .Alpha();
   }
 
-  const bool isTransparent = theAlphaFront < 1.0f
-                          || theAlphaBack  < 1.0f;
-  return isTransparent;
+  if (anAspect->AlphaMode() == Graphic3d_AlphaMode_BlendAuto)
+  {
+    return theAlphaFront < 1.0f
+        || theAlphaBack  < 1.0f;
+  }
+  return anAspect->AlphaMode() == Graphic3d_AlphaMode_Blend;
 }
 
 // =======================================================================
@@ -3752,3 +3763,32 @@ bool OpenGl_Context::SetColorMask (bool theToWriteColor)
   myColorMask = theToWriteColor;
   return anOldValue;
 }
+
+// =======================================================================
+// function : SetSampleAlphaToCoverage
+// purpose  :
+// =======================================================================
+bool OpenGl_Context::SetSampleAlphaToCoverage (bool theToEnable)
+{
+  if (myAlphaToCoverage == theToEnable)
+  {
+    return myAlphaToCoverage;
+  }
+
+  if (core15fwd != NULL)
+  {
+    if (theToEnable)
+    {
+      //core15fwd->core15fwd->glSampleCoverage (1.0f, GL_FALSE);
+      core15fwd->glEnable (GL_SAMPLE_ALPHA_TO_COVERAGE);
+    }
+    else
+    {
+      core15fwd->glDisable (GL_SAMPLE_ALPHA_TO_COVERAGE);
+    }
+  }
+
+  const bool anOldValue = myAlphaToCoverage;
+  myAlphaToCoverage = theToEnable;
+  return anOldValue;
+}
index 353aa8d..96ac263 100644 (file)
@@ -646,6 +646,12 @@ public: //! @name methods to alter or retrieve current state
   //! Enable/disable writing into color buffer (wrapper for glColorMask).
   Standard_EXPORT bool SetColorMask (bool theToWriteColor);
 
+  //! Return GL_SAMPLE_ALPHA_TO_COVERAGE state.
+  bool SampleAlphaToCoverage() const { return myAlphaToCoverage; }
+
+  //! Enable/disable GL_SAMPLE_ALPHA_TO_COVERAGE.
+  Standard_EXPORT bool SetSampleAlphaToCoverage (bool theToEnable);
+
   //! Return back face culling state.
   bool ToCullBackFaces() const { return myToCullBackFaces; }
 
@@ -929,6 +935,7 @@ private: //! @name fields tracking current state
   OpenGl_DrawBuffers            myDrawBuffers;     //!< current draw buffers
   unsigned int                  myDefaultVao;      //!< default Vertex Array Object
   Standard_Boolean              myColorMask;       //!< flag indicating writing into color buffer is enabled or disabled (glColorMask)
+  Standard_Boolean              myAlphaToCoverage; //!< flag indicating GL_SAMPLE_ALPHA_TO_COVERAGE state
   Standard_Boolean              myIsGlDebugCtx;    //!< debug context initialization state
   TCollection_AsciiString       myVendor;          //!< Graphics Driver's vendor
   TColStd_PackedMapOfInteger    myFilters[6];      //!< messages suppressing filter (for sources from GL_DEBUG_SOURCE_API_ARB to GL_DEBUG_SOURCE_OTHER_ARB)
index 3781995..daf59c8 100644 (file)
@@ -25,16 +25,18 @@ class OpenGl_MaterialState : public OpenGl_StateInterface
 public:
 
   //! Creates new material state.
-  OpenGl_MaterialState() : myToDistinguish (false), myToMapTexture (false) {}
+  OpenGl_MaterialState() : myAlphaCutoff (0.5f), myToDistinguish (false), myToMapTexture (false) {}
 
   //! Sets new material aspect.
   void Set (const OpenGl_Material& theFrontMat,
             const OpenGl_Material& theBackMat,
+            const float theAlphaCutoff,
             const bool theToDistinguish,
             const bool theToMapTexture)
   {
     myMatFront      = theFrontMat;
     myMatBack       = theBackMat;
+    myAlphaCutoff   = theAlphaCutoff;
     myToDistinguish = theToDistinguish;
     myToMapTexture  = theToMapTexture;
   }
@@ -45,6 +47,9 @@ public:
   //! Return back material.
   const OpenGl_Material& BackMaterial()  const { return myMatBack; }
 
+  //! Alpha cutoff value.
+  float AlphaCutoff() const { return myAlphaCutoff; }
+
   //! Distinguish front/back flag.
   bool ToDistinguish() const { return myToDistinguish; }
 
@@ -55,6 +60,7 @@ private:
 
   OpenGl_Material myMatFront;      //!< front material
   OpenGl_Material myMatBack;       //!< back  material
+  float           myAlphaCutoff;   //!< alpha cutoff value
   bool            myToDistinguish; //!< distinguish front/back flag
   bool            myToMapTexture;  //!< flag for mapping a texture
 
index fa805f2..71c96fe 100644 (file)
@@ -458,10 +458,8 @@ void OpenGl_PrimitiveArray::drawEdges (const OpenGl_Vec4&              theEdgeCo
 
   if (aGlContext->core20fwd != NULL)
   {
-    aGlContext->ShaderManager()->BindLineProgram (NULL,
-                                                  anAspect->Aspect()->Type(),
-                                                  Graphic3d_TOSM_UNLIT,
-                                                  Standard_False,
+    aGlContext->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), anAspect->Aspect()->Type(),
+                                                  Graphic3d_TOSM_UNLIT, Graphic3d_AlphaMode_Opaque, Standard_False,
                                                   anAspect->ShaderProgramRes (aGlContext));
   }
   const GLenum aDrawMode = !aGlContext->ActiveProgram().IsNull()
@@ -569,7 +567,14 @@ void OpenGl_PrimitiveArray::drawMarkers (const Handle(OpenGl_Workspace)& theWork
   #if !defined(GL_ES_VERSION_2_0)
     if (aCtx->core11 != NULL)
     {
-      aCtx->core11fwd->glDisable (GL_ALPHA_TEST);
+      if (aCtx->ShaderManager()->MaterialState().AlphaCutoff() >= ShortRealLast())
+      {
+        aCtx->core11fwd->glDisable (GL_ALPHA_TEST);
+      }
+      else
+      {
+        aCtx->core11fwd->glAlphaFunc (GL_GEQUAL, aCtx->ShaderManager()->MaterialState().AlphaCutoff());
+      }
     }
   #endif
     aCtx->SetPointSize (1.0f);
@@ -775,11 +780,11 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
                                                    ? anAspectMarker->SpriteHighlightRes (aCtx)
                                                    : aSpriteNormRes;
           aCtx->BindTextures (aSprite);
-          aCtx->ShaderManager()->BindMarkerProgram (aSprite, aShadingModel, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
+          aCtx->ShaderManager()->BindMarkerProgram (aSprite, aShadingModel, Graphic3d_AlphaMode_Opaque, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
         }
         else
         {
-          aCtx->ShaderManager()->BindMarkerProgram (Handle(OpenGl_TextureSet)(), aShadingModel, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
+          aCtx->ShaderManager()->BindMarkerProgram (Handle(OpenGl_TextureSet)(), aShadingModel, Graphic3d_AlphaMode_Opaque, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
         }
         break;
       }
@@ -790,6 +795,7 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
         aCtx->ShaderManager()->BindLineProgram (NULL,
                                                 anAspectLine->Aspect()->Type(),
                                                 aShadingModel,
+                                                Graphic3d_AlphaMode_Opaque,
                                                 hasVertColor,
                                                 anAspectLine->ShaderProgramRes (aCtx));
         break;
@@ -801,6 +807,7 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
         const Standard_Boolean toEnableEnvMap = (!aTextures.IsNull() && (aTextures == theWorkspace->EnvironmentTexture()));
         aCtx->ShaderManager()->BindFaceProgram (aTextures,
                                                 aShadingModel,
+                                                anAspectFace->Aspect()->AlphaMode(),
                                                 hasVertColor,
                                                 toEnableEnvMap,
                                                 anAspectFace->ShaderProgramRes (aCtx));
index d3b667f..f04c547 100644 (file)
@@ -32,8 +32,9 @@ enum OpenGl_ProgramOptions
   OpenGl_PO_ClipPlanes1 = 0x040, //!< handle 1 clipping plane
   OpenGl_PO_ClipPlanes2 = 0x080, //!< handle 2 clipping planes
   OpenGl_PO_ClipPlanesN = 0x100, //!< handle N clipping planes
-  OpenGl_PO_WriteOit    = 0x200, //!< write coverage buffer for Blended Order-Independent Transparency
-  OpenGl_PO_NB          = 0x400  //!< overall number of combinations
+  OpenGl_PO_AlphaTest   = 0x200, //!< discard fragment by alpha test (defined by cutoff value)
+  OpenGl_PO_WriteOit    = 0x400, //!< write coverage buffer for Blended Order-Independent Transparency
+  OpenGl_PO_NB          = 0x800  //!< overall number of combinations
 };
 
 //! Alias to programs array of predefined length
index 3ce8652..a83169c 100644 (file)
@@ -1064,6 +1064,16 @@ void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)
       return;
     }
 
+    if (myMaterialState.AlphaCutoff() < ShortRealLast())
+    {
+      glAlphaFunc (GL_GEQUAL, myMaterialState.AlphaCutoff());
+      glEnable (GL_ALPHA_TEST);
+    }
+    else
+    {
+      glDisable (GL_ALPHA_TEST);
+    }
+
     const GLenum aFrontFace = myMaterialState.ToDistinguish() ? GL_FRONT : GL_FRONT_AND_BACK;
     myContext->core11->glMaterialfv(aFrontFace, GL_AMBIENT,   aFrontMat.Ambient.GetData());
     myContext->core11->glMaterialfv(aFrontFace, GL_DIFFUSE,   aFrontMat.Diffuse.GetData());
@@ -1083,6 +1093,9 @@ void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)
   }
 
   theProgram->SetUniform (myContext,
+                          theProgram->GetStateLocation (OpenGl_OCCT_ALPHA_CUTOFF),
+                          myMaterialState.AlphaCutoff());
+  theProgram->SetUniform (myContext,
                           theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
                           myMaterialState.ToMapTexture()  ? 1 : 0);
   theProgram->SetUniform (myContext,
@@ -1626,6 +1639,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
 #endif
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
+  aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
 
@@ -1952,6 +1966,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
 #endif
   aProgramSrc->SetNbLightsMax (aNbLights);
   aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
+  aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
   TCollection_AsciiString aKey;
@@ -2131,6 +2146,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
 #endif
   aProgramSrc->SetNbLightsMax (aNbLights);
   aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
+  aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
   TCollection_AsciiString aKey;
index 115f067..1727030 100644 (file)
@@ -84,6 +84,7 @@ public:
   //! Bind program for filled primitives rendering
   Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures,
                                     const Graphic3d_TypeOfShadingModel  theShadingModel,
+                                    const Graphic3d_AlphaMode           theAlphaMode,
                                     const Standard_Boolean              theHasVertColor,
                                     const Standard_Boolean              theEnableEnvMap,
                                     const Handle(OpenGl_ShaderProgram)& theCustomProgram)
@@ -98,7 +99,7 @@ public:
                                                         && (theTextures.IsNull() || theTextures->IsModulate())
                                                         ? theShadingModel
                                                         : Graphic3d_TOSM_UNLIT;
-    const Standard_Integer        aBits    = getProgramBits (theTextures, theHasVertColor, theEnableEnvMap);
+    const Standard_Integer        aBits    = getProgramBits (theTextures, theAlphaMode, theHasVertColor, theEnableEnvMap);
     Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (aShadeModelOnFace, aBits);
     return bindProgramWithState (aProgram);
   }
@@ -107,6 +108,7 @@ public:
   Standard_Boolean BindLineProgram (const Handle(OpenGl_TextureSet)&    theTextures,
                                     const Aspect_TypeOfLine             theLineType,
                                     const Graphic3d_TypeOfShadingModel  theShadingModel,
+                                    const Graphic3d_AlphaMode           theAlphaMode,
                                     const Standard_Boolean              theHasVertColor,
                                     const Handle(OpenGl_ShaderProgram)& theCustomProgram)
   {
@@ -116,7 +118,7 @@ public:
       return bindProgramWithState (theCustomProgram);
     }
 
-    Standard_Integer aBits = getProgramBits (theTextures, theHasVertColor);
+    Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, theHasVertColor, false);
     if (theLineType != Aspect_TOL_SOLID)
     {
       aBits |= OpenGl_PO_StippleLine;
@@ -129,6 +131,7 @@ public:
   //! Bind program for point rendering
   Standard_Boolean BindMarkerProgram (const Handle(OpenGl_TextureSet)&    theTextures,
                                       const Graphic3d_TypeOfShadingModel  theShadingModel,
+                                      const Graphic3d_AlphaMode           theAlphaMode,
                                       const Standard_Boolean              theHasVertColor,
                                       const Handle(OpenGl_ShaderProgram)& theCustomProgram)
   {
@@ -138,7 +141,7 @@ public:
       return bindProgramWithState (theCustomProgram);
     }
 
-    const Standard_Integer        aBits    = getProgramBits (theTextures, theHasVertColor) | OpenGl_PO_Point;
+    const Standard_Integer        aBits    = getProgramBits (theTextures, theAlphaMode, theHasVertColor, false) | OpenGl_PO_Point;
     Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theShadingModel, aBits);
     return bindProgramWithState (aProgram);
   }
@@ -267,10 +270,11 @@ public:
   //! Updates state of material.
   void UpdateMaterialStateTo (const OpenGl_Material& theFrontMat,
                               const OpenGl_Material& theBackMat,
+                              const float theAlphaCutoff,
                               const bool theToDistinguish,
                               const bool theToMapTexture)
   {
-    myMaterialState.Set (theFrontMat, theBackMat, theToDistinguish, theToMapTexture);
+    myMaterialState.Set (theFrontMat, theBackMat, theAlphaCutoff, theToDistinguish, theToMapTexture);
     myMaterialState.Update();
   }
 
@@ -392,11 +396,16 @@ protected:
 
   //! Define program bits.
   Standard_Integer getProgramBits (const Handle(OpenGl_TextureSet)& theTextures,
-                                   const Standard_Boolean theHasVertColor,
-                                   const Standard_Boolean theEnableEnvMap = Standard_False)
+                                   Graphic3d_AlphaMode theAlphaMode,
+                                   Standard_Boolean theHasVertColor,
+                                   Standard_Boolean theEnableEnvMap)
 
   {
     Standard_Integer aBits = 0;
+    if (theAlphaMode == Graphic3d_AlphaMode_Mask)
+    {
+      aBits |= OpenGl_PO_AlphaTest;
+    }
 
     const Standard_Integer aNbPlanes = myContext->Clipping().NbClippingOrCappingOn();
     if (aNbPlanes > 0)
index 1463fee..784dc52 100755 (executable)
@@ -67,6 +67,7 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
   "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
   "occFrontMaterial",      // OpenGl_OCCT_FRONT_MATERIAL
   "occBackMaterial",       // OpenGl_OCCT_BACK_MATERIAL
+  "occAlphaCutoff",        // OpenGl_OCCT_ALPHA_CUTOFF
   "occColor",              // OpenGl_OCCT_COLOR
 
   "occOitOutput",          // OpenGl_OCCT_OIT_OUTPUT
@@ -152,6 +153,7 @@ OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram
   myNbLightsMax (0),
   myNbClipPlanesMax (0),
   myNbFragOutputs (1),
+  myHasAlphaTest (false),
   myHasWeightOitOutput (false),
   myHasTessShader (false)
 {
@@ -183,6 +185,7 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
   }
   myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
   myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
+  myHasAlphaTest  = !myProxy.IsNull() && myProxy->HasAlphaTest();
   myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
 
   // detect the minimum GLSL version required for defined Shader Objects
@@ -308,6 +311,10 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
         }
       }
     }
+    if (myHasAlphaTest)
+    {
+      anExtensions += "#define OCC_ALPHA_TEST\n";
+    }
 
     if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions)
     {
index 86a239c..87941ff 100755 (executable)
@@ -63,6 +63,7 @@ enum OpenGl_StateVariable
   OpenGl_OCCT_DISTINGUISH_MODE,
   OpenGl_OCCT_FRONT_MATERIAL,
   OpenGl_OCCT_BACK_MATERIAL,
+  OpenGl_OCCT_ALPHA_CUTOFF,
   OpenGl_OCCT_COLOR,
 
   // Weighted, Blended Order-Independent Transparency rendering state
@@ -230,6 +231,9 @@ public:
   //! to be used for initialization occFragColorArray/occFragColorN.
   Standard_Integer NbFragmentOutputs() const { return myNbFragOutputs; }
 
+  //! Return true if Fragment Shader should perform alpha test; FALSE by default.
+  Standard_Boolean HasAlphaTest() const { return myHasAlphaTest; }
+
   //! Return true if Fragment Shader color should output the weighted OIT coverage; FALSE by default.
   Standard_Boolean HasWeightOitOutput() const { return myHasWeightOitOutput; }
 
@@ -577,6 +581,7 @@ protected:
   Standard_Integer                myNbLightsMax;   //!< length of array of light sources (THE_MAX_LIGHTS)
   Standard_Integer                myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
   Standard_Integer                myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
+  Standard_Boolean                myHasAlphaTest;  //!< flag indicating that Fragment Shader should perform alpha-test
   Standard_Boolean                myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
   Standard_Boolean                myHasTessShader; //!< flag indicating that program defines tessellation stage
 
index 233d64d..9f162cc 100644 (file)
@@ -453,11 +453,12 @@ void OpenGl_Text::StringSize (const Handle(OpenGl_Context)& theCtx,
 // =======================================================================
 void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
+  theWorkspace->SetAspectFace (&theWorkspace->FontFaceAspect());
+  theWorkspace->ApplyAspectFace();
   const OpenGl_AspectText*      aTextAspect  = theWorkspace->ApplyAspectText();
   const Handle(OpenGl_Context)& aCtx         = theWorkspace->GetGlContext();
   const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
 
-
   // Bind custom shader program or generate default version
   aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx));
 
@@ -757,8 +758,10 @@ void OpenGl_Text::drawRect (const Handle(OpenGl_Context)& theCtx,
     myBndVertsVbo->Init (theCtx, 2, 4, aQuad[0].GetData());
   }
 
-  // bind flat program
-  theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_TextureSet)(), Graphic3d_TOSM_UNLIT, Standard_False, Standard_False, Handle(OpenGl_ShaderProgram)());
+  // bind unlit program
+  theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_TextureSet)(), Graphic3d_TOSM_UNLIT,
+                                            Graphic3d_AlphaMode_Opaque, Standard_False, Standard_False,
+                                            Handle(OpenGl_ShaderProgram)());
 
 #if !defined(GL_ES_VERSION_2_0)
   if (theCtx->core11 != NULL
@@ -901,10 +904,6 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
   GLint aTexEnvParam = GL_REPLACE;
   if (theCtx->core11 != NULL)
   {
-    // setup alpha test
-    glAlphaFunc (GL_GEQUAL, 0.285f);
-    glEnable (GL_ALPHA_TEST);
-
     glDisable (GL_TEXTURE_1D);
     glEnable  (GL_TEXTURE_2D);
     glGetTexEnviv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &aTexEnvParam);
@@ -918,6 +917,7 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
   // setup blending
   glEnable (GL_BLEND);
   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  const bool anAlphaToCoverageOld = theCtx->SetSampleAlphaToCoverage (false);
 
   // extra drawings
   switch (theTextAspect.Aspect()->DisplayType())
@@ -994,7 +994,6 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
     if (theCtx->core11 != NULL)
     {
       glDisable (GL_TEXTURE_2D);
-      glDisable (GL_ALPHA_TEST);
     }
   #endif
     const bool aColorMaskBack = theCtx->SetColorMask (false);
@@ -1015,15 +1014,12 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
   glDisable (GL_BLEND);
   glDisable (GL_STENCIL_TEST);
 #if !defined(GL_ES_VERSION_2_0)
-  if (theCtx->core11 != NULL)
-  {
-    glDisable (GL_ALPHA_TEST);
-  }
   glDisable (GL_COLOR_LOGIC_OP);
 
   theCtx->SetPolygonMode         (aPrevPolygonMode);
   theCtx->SetPolygonHatchEnabled (aPrevHatchingMode);
 #endif
+  theCtx->SetSampleAlphaToCoverage (anAlphaToCoverageOld);
 
   // model view matrix was modified
   theCtx->WorldViewState.Pop();
index 418f356..d499839 100644 (file)
@@ -869,6 +869,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
   // ==================================
 
   const Handle(OpenGl_Context)& aContext = myWorkspace->GetGlContext();
+  aContext->SetSampleAlphaToCoverage (myRenderParams.ToEnableAlphaToCoverage);
 
 #if !defined(GL_ES_VERSION_2_0)
   // Disable current clipping planes
@@ -1032,6 +1033,9 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
     renderFrameStats();
   }
 
+  myWorkspace->ResetAppliedAspect();
+  aContext->SetSampleAlphaToCoverage (false);
+
   // reset FFP state for safety
   aContext->BindProgram (Handle(OpenGl_ShaderProgram)());
   if (aContext->caps->ffpEnable)
index 3f74b06..10e0ac4 100644 (file)
@@ -169,10 +169,16 @@ OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Wi
 
   myDefaultCappingAlgoFilter = new OpenGl_CappingAlgoFilter();
 
+  myFontFaceAspect.Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Mask, 0.285f);
+  myFontFaceAspect.Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT);
+
   myNoneCulling .Aspect()->SetSuppressBackFaces (false);
   myNoneCulling .Aspect()->SetDrawEdges (false);
+  myNoneCulling .Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Opaque);
+
   myFrontCulling.Aspect()->SetSuppressBackFaces (true);
   myFrontCulling.Aspect()->SetDrawEdges (false);
+  myFrontCulling.Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Opaque);
 }
 
 // =======================================================================
@@ -296,7 +302,10 @@ const OpenGl_AspectFace* OpenGl_Workspace::ApplyAspectFace()
     }
     if (toSuppressBackFaces)
     {
-      if ((float )myAspectFaceSet->Aspect()->FrontMaterial().Transparency() != 0.0f)
+      if (myAspectFaceSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Blend
+       || myAspectFaceSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Mask
+       || (myAspectFaceSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_BlendAuto
+        && myAspectFaceSet->Aspect()->FrontMaterial().Transparency() != 0.0f))
       {
         // disable culling in case of translucent shading aspect
         toSuppressBackFaces = false;
index 0a59ff0..4a3e602 100644 (file)
@@ -257,23 +257,17 @@ public:
   //! @return applied model structure matrix.
   inline const OpenGl_Matrix* ModelMatrix() const { return StructureMatrix_applied; }
 
+  //! Returns face aspect for textured font rendering.
+  const OpenGl_AspectFace& FontFaceAspect() const { return myFontFaceAspect; }
+
   //! Returns capping algorithm rendering filter.
-  const Handle(OpenGl_CappingAlgoFilter)& DefaultCappingAlgoFilter() const
-  {
-    return myDefaultCappingAlgoFilter;
-  }
+  const Handle(OpenGl_CappingAlgoFilter)& DefaultCappingAlgoFilter() const { return myDefaultCappingAlgoFilter; }
 
   //! Returns face aspect for none culling mode.
-  const OpenGl_AspectFace& NoneCulling() const
-  {
-    return myNoneCulling;
-  }
+  const OpenGl_AspectFace& NoneCulling() const { return myNoneCulling; }
 
   //! Returns face aspect for front face culling mode.
-  const OpenGl_AspectFace& FrontCulling() const
-  {
-    return myFrontCulling;
-  }
+  const OpenGl_AspectFace& FrontCulling() const { return myFrontCulling; }
 
   //! Sets a new environment texture.
   void SetEnvironmentTexture (const Handle(OpenGl_TextureSet)& theTexture) { myEnvironmentTexture = theTexture; }
@@ -291,6 +285,7 @@ protected: //! @name protected fields
   Handle(OpenGl_CappingAlgoFilter) myDefaultCappingAlgoFilter;
   OpenGl_AspectFace                myNoneCulling;
   OpenGl_AspectFace                myFrontCulling;
+  OpenGl_AspectFace                myFontFaceAspect;
 
 protected: //! @name fields related to status
 
index 0f5ba70..a3b7e12 100644 (file)
@@ -168,6 +168,7 @@ uniform               float     occPointSize;          //!< point size
 //! Parameters of blended order-independent transparency rendering algorithm
 uniform               int       occOitOutput;      //!< Enable bit for writing output color buffers for OIT (occFragColor, occFragCoverage)
 uniform               float     occOitDepthFactor; //!< Influence of the depth component to the coverage of the accumulated fragment
+uniform               float     occAlphaCutoff;    //!< alpha test cutoff value
 
 //! Parameters of clipping planes
 #if defined(THE_MAX_CLIP_PLANES) && (THE_MAX_CLIP_PLANES > 0)
index d3b1642..34bf584 100644 (file)
 // This file includes implementation of common functions and properties accessors
 
 #if defined(FRAGMENT_SHADER)
-#if defined(OCC_WRITE_WEIGHT_OIT_COVERAGE)
-//! Output color and coverage for accumulation by OIT algorithm.
+//! Output color (and coverage for accumulation by OIT algorithm).
 void occSetFragColor (in vec4 theColor)
 {
+#if defined(OCC_ALPHA_TEST)
+  if (theColor.a < occAlphaCutoff) discard;
+#endif
+#if defined(OCC_WRITE_WEIGHT_OIT_COVERAGE)
   float aWeight     = theColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2);
   occFragCoverage.r = theColor.a * aWeight;
   occFragColor      = vec4 (theColor.rgb * theColor.a * aWeight, theColor.a);
-}
 #else
-//! Output color.
-void occSetFragColor (in vec4 theColor) { occFragColor = theColor; }
+  occFragColor = theColor;
 #endif
+}
 #endif
 
 #if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)
index 4ff7592..796b4e7 100644 (file)
@@ -19,18 +19,20 @@ static const char Shaders_DeclarationsImpl_glsl[] =
   "// This file includes implementation of common functions and properties accessors\n"
   "\n"
   "#if defined(FRAGMENT_SHADER)\n"
-  "#if defined(OCC_WRITE_WEIGHT_OIT_COVERAGE)\n"
-  "//! Output color and coverage for accumulation by OIT algorithm.\n"
+  "//! Output color (and coverage for accumulation by OIT algorithm).\n"
   "void occSetFragColor (in vec4 theColor)\n"
   "{\n"
+  "#if defined(OCC_ALPHA_TEST)\n"
+  "  if (theColor.a < occAlphaCutoff) discard;\n"
+  "#endif\n"
+  "#if defined(OCC_WRITE_WEIGHT_OIT_COVERAGE)\n"
   "  float aWeight     = theColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2);\n"
   "  occFragCoverage.r = theColor.a * aWeight;\n"
   "  occFragColor      = vec4 (theColor.rgb * theColor.a * aWeight, theColor.a);\n"
-  "}\n"
   "#else\n"
-  "//! Output color.\n"
-  "void occSetFragColor (in vec4 theColor) { occFragColor = theColor; }\n"
+  "  occFragColor = theColor;\n"
   "#endif\n"
+  "}\n"
   "#endif\n"
   "\n"
   "#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)\n"
index cec6805..ed3045e 100644 (file)
@@ -171,6 +171,7 @@ static const char Shaders_Declarations_glsl[] =
   "//! Parameters of blended order-independent transparency rendering algorithm\n"
   "uniform               int       occOitOutput;      //!< Enable bit for writing output color buffers for OIT (occFragColor, occFragCoverage)\n"
   "uniform               float     occOitDepthFactor; //!< Influence of the depth component to the coverage of the accumulated fragment\n"
+  "uniform               float     occAlphaCutoff;    //!< alpha test cutoff value\n"
   "\n"
   "//! Parameters of clipping planes\n"
   "#if defined(THE_MAX_CLIP_PLANES) && (THE_MAX_CLIP_PLANES > 0)\n"
index 4f0b48e..6859350 100644 (file)
@@ -1694,6 +1694,10 @@ struct ViewerTest_AspectsChangeSet
   Standard_Integer             ToSetTransparency;
   Standard_Real                Transparency;
 
+  Standard_Integer             ToSetAlphaMode;
+  Graphic3d_AlphaMode          AlphaMode;
+  Standard_ShortReal           AlphaCutoff;
+
   Standard_Integer             ToSetMaterial;
   Graphic3d_NameOfMaterial     Material;
   TCollection_AsciiString      MatName;
@@ -1739,6 +1743,9 @@ struct ViewerTest_AspectsChangeSet
     MarkerSize        (1.0),
     ToSetTransparency (0),
     Transparency      (0.0),
+    ToSetAlphaMode    (0),
+    AlphaMode         (Graphic3d_AlphaMode_BlendAuto),
+    AlphaCutoff       (0.5f),
     ToSetMaterial     (0),
     Material          (Graphic3d_NOM_DEFAULT),
     ToSetShowFreeBoundary      (0),
@@ -1764,6 +1771,7 @@ struct ViewerTest_AspectsChangeSet
     return ToSetVisibility        == 0
         && ToSetLineWidth         == 0
         && ToSetTransparency      == 0
+        && ToSetAlphaMode         == 0
         && ToSetColor             == 0
         && ToSetMaterial          == 0
         && ToSetShowFreeBoundary  == 0
@@ -1797,11 +1805,17 @@ struct ViewerTest_AspectsChangeSet
       isOk = Standard_False;
     }
     if (theIsSubPart
-     && ToSetTransparency)
+     && ToSetTransparency != 0)
     {
       std::cout << "Error: the transparency can not be defined for sub-part of object!\n";
       isOk = Standard_False;
     }
+    if (ToSetAlphaMode == 1
+     && (AlphaCutoff <= 0.0f || AlphaCutoff >= 1.0f))
+    {
+      std::cout << "Error: alpha cutoff value should be within (0; 1) range (specified " << AlphaCutoff << ")\n";
+      isOk = Standard_False;
+    }
     if (ToSetMaterial == 1
      && Material == Graphic3d_NOM_DEFAULT)
     {
@@ -2047,6 +2061,53 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
         aChangeSet->Transparency = 0.0;
       }
     }
+    else if (anArg == "-setalphamode")
+    {
+      if (++anArgIter >= theArgNb)
+      {
+        std::cout << "Error: wrong syntax at " << anArg << "\n";
+        return 1;
+      }
+      aChangeSet->ToSetAlphaMode = 1;
+      aChangeSet->AlphaCutoff = 0.5f;
+      {
+        TCollection_AsciiString aParam (theArgVec[anArgIter]);
+        aParam.LowerCase();
+        if (aParam == "opaque")
+        {
+          aChangeSet->AlphaMode = Graphic3d_AlphaMode_Opaque;
+        }
+        else if (aParam == "mask")
+        {
+          aChangeSet->AlphaMode = Graphic3d_AlphaMode_Mask;
+        }
+        else if (aParam == "blend")
+        {
+          aChangeSet->AlphaMode = Graphic3d_AlphaMode_Blend;
+        }
+        else if (aParam == "blendauto"
+              || aParam == "auto")
+        {
+          aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
+        }
+        else
+        {
+          std::cout << "Error: wrong syntax at " << aParam << "\n";
+          return 1;
+        }
+      }
+
+      if (anArgIter + 1 < theArgNb
+       && theArgVec[anArgIter + 1][0] != '-')
+      {
+        TCollection_AsciiString aParam2 (theArgVec[anArgIter + 1]);
+        if (aParam2.IsRealValue())
+        {
+          aChangeSet->AlphaCutoff = (float )aParam2.RealValue();
+          ++anArgIter;
+        }
+      }
+    }
     else if (anArg == "-setvis"
           || anArg == "-setvisibility")
     {
@@ -2376,6 +2437,9 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
       aChangeSet->MarkerSize = 1.0;
       aChangeSet->ToSetTransparency = -1;
       aChangeSet->Transparency = 0.0;
+      aChangeSet->ToSetAlphaMode = -1;
+      aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
+      aChangeSet->AlphaCutoff = 0.5f;
       aChangeSet->ToSetColor = -1;
       aChangeSet->Color = DEFAULT_COLOR;
       aChangeSet->ToSetMaterial = -1;
@@ -2565,6 +2629,10 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
     {
       aDrawer->ShadingAspect()->SetTransparency (aChangeSet->Transparency);
     }
+    if (aChangeSet->ToSetAlphaMode != 0)
+    {
+      aDrawer->ShadingAspect()->Aspect()->SetAlphaMode (aChangeSet->AlphaMode, aChangeSet->AlphaCutoff);
+    }
     if (aChangeSet->ToSetMaterial != 0)
     {
       aDrawer->ShadingAspect()->SetMaterial (aChangeSet->Material);
@@ -2797,6 +2865,16 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
           aDrawer->SetShadingModel ((aChangeSet->ToSetShadingModel == -1) ? Graphic3d_TOSM_DEFAULT : aChangeSet->ShadingModel, aChangeSet->ToSetShadingModel != -1);
           toRedisplay = Standard_True;
         }
+        if (aChangeSet->ToSetAlphaMode != 0)
+        {
+          if (!aDrawer->HasOwnShadingAspect())
+          {
+            aDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+            *aDrawer->ShadingAspect()->Aspect() = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
+          }
+          aDrawer->ShadingAspect()->Aspect()->SetAlphaMode (aChangeSet->AlphaMode, aChangeSet->AlphaCutoff);
+          toRedisplay = Standard_True;
+        }
       }
 
       for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next())
@@ -6340,6 +6418,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
       "\n\t\t:          [-setHatch HatchStyle]"
       "\n\t\t:          [-setShadingModel {color|flat|gouraud|phong}]"
       "\n\t\t:          [-unsetShadingModel]"
+      "\n\t\t:          [-setAlphaMode {opaque|mask|blend|blendauto} [alphaCutOff=0.5]]"
       "\n\t\t: Manage presentation properties of all, selected or named objects."
       "\n\t\t: When -subshapes is specified than following properties will be"
       "\n\t\t: assigned to specified sub-shapes."
index 4779be6..df4d726 100644 (file)
@@ -164,7 +164,9 @@ void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
   aTA->Aspect()->Font();
   OpenGl_Vec4 aColor = theWorkspace->LineColor();
 
-  aCtx->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), Aspect_TOL_SOLID, Graphic3d_TOSM_UNLIT, false, Handle(OpenGl_ShaderProgram)());
+  aCtx->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), Aspect_TOL_SOLID,
+                                          Graphic3d_TOSM_UNLIT, Graphic3d_AlphaMode_Opaque, false,
+                                          Handle(OpenGl_ShaderProgram)());
   aCtx->SetColor4fv (aColor);
 
   const OpenGl_Vec3 aVertArray[4] =
index d32bf4a..1c1edad 100644 (file)
@@ -10067,6 +10067,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       theDI << "\n";
     }
     theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass        ? "on" : "off") << "\n";
+    theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage  ? "on" : "off") << "\n";
     theDI << "\n";
     return 0;
   }
@@ -10212,6 +10213,21 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
         ++anArgIter;
       }
     }
+    else if (aFlag == "-samplealphatocoverage"
+          || aFlag == "-alphatocoverage")
+    {
+      if (toPrint)
+      {
+        theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
+        continue;
+      }
+      aParams.ToEnableAlphaToCoverage = Standard_True;
+      if (anArgIter + 1 < theArgNb
+       && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
+      {
+        ++anArgIter;
+      }
+    }
     else if (aFlag == "-rendscale"
           || aFlag == "-renderscale"
           || aFlag == "-renderresolutionscale")
@@ -12201,6 +12217,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n      '-msaa         0..4'        Specifies number of samples for MSAA"
     "\n      '-oit          off|0.0-1.0' Enables/disables OIT and sets depth weight factor"
     "\n      '-depthPrePass on|off'      Enables/disables depth pre-pass"
+    "\n      '-alphatocoverage on|off'   Enables/disables alpha to coverage (needs MSAA)"
     "\n      '-rendScale    value        Rendering resolution scale factor"
     "\n      '-rayTrace'                 Enables  GPU ray-tracing"
     "\n      '-rayDepth     0..10'       Defines maximum ray-tracing depth"
diff --git a/tests/v3d/glsl/alpha_mask b/tests/v3d/glsl/alpha_mask
new file mode 100644 (file)
index 0000000..1cfc0bb
--- /dev/null
@@ -0,0 +1,38 @@
+puts "========"
+puts "Alpha test modes"
+puts "========"
+
+# create box
+box b 1 2 3
+
+# draw box
+vinit View1
+vclear
+vzbufftrihedron
+vaxo
+vdisplay -dispMode 1 b
+vfit
+vtexture b [locate_data_file images/marker_box2.png]
+vrotate 0.2 0.0 0.0
+vaspects -setAlphaMode mask 0.5
+vmoveto 250 250
+
+# take snapshots
+vrenderparams -msaa 0 -alphaToCoverage 0
+vcaps -ffp 1
+vdump $::imagedir/${::casename}_msaa0_ffp.png
+
+vcaps -ffp 0
+vdump $::imagedir/${::casename}_msaa0.png
+
+vrenderparams -msaa 2 -alphaToCoverage 0
+vdump $::imagedir/${::casename}_msaa2.png
+
+vrenderparams -msaa 2 -alphaToCoverage 1
+vdump $::imagedir/${::casename}_msaa2_cov.png
+
+vrenderparams -msaa 8 -alphaToCoverage 1
+vdump $::imagedir/${::casename}_msaa8.png
+
+vrenderparams -msaa 8 -alphaToCoverage 1
+vdump $::imagedir/${::casename}_msaa8_cov.png