New interior style Aspect_IS_OUTLINE is supported for Graphic3d_AspectFillArea3d.
If this style is set, the triangles primitive array is drawn using the outline shader
Aspect_IS_HATCH,
Aspect_IS_SOLID,
Aspect_IS_HIDDENLINE,
-Aspect_IS_POINT
+Aspect_IS_POINT,
+Aspect_IS_OUTLINE
};
#endif // _Aspect_InteriorStyle_HeaderFile
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_Workspace.hxx>
#include <OpenGl_AspectFace.hxx>
+#include <OpenGl_View.hxx>
#include <Graphic3d_TransformUtils.hxx>
#include <Graphic3d_RenderingParams.hxx>
#endif
}
+// =======================================================================
+// function : PushOrthoScale
+// purpose :
+// =======================================================================
+void OpenGl_Context::PushOrthoScale (const Handle(OpenGl_Workspace)& theWorkspace)
+{
+ if (!myActiveProgram.IsNull() && !theWorkspace.IsNull())
+ {
+ Standard_ShortReal aScale = (Standard_ShortReal)theWorkspace->View()->Camera()->Scale();
+ myActiveProgram->SetUniform(this, myActiveProgram->GetStateLocation(OpenGl_OCCT_ORTHO_SCALE), aScale);
+ }
+}
+
+// =======================================================================
+// function : SetIsSilhouettePass
+// purpose :
+// =======================================================================
+void OpenGl_Context::SetIsSilhouettePass (Standard_Boolean isSilhouettePass)
+{
+ if (!myActiveProgram.IsNull() )
+ {
+ myActiveProgram->SetUniform(this,
+ myActiveProgram->GetStateLocation(OpenGl_OCCT_IS_SILHOUETTE_PASS),
+ isSilhouettePass ? 1.0f : 0.0f);
+ }
+}
+
+// =======================================================================
+// function : PushBackgroundColor
+// purpose :
+// =======================================================================
+void OpenGl_Context::PushBackgroundColor (const Handle(OpenGl_Workspace)& theWorkspace)
+{
+ if (!myActiveProgram.IsNull() && !theWorkspace.IsNull())
+ {
+ const Quantity_Color& aBackground = theWorkspace->View()->BackgroundColor().GetRGB();
+ myActiveProgram->SetUniform(this,
+ myActiveProgram->GetStateLocation(OpenGl_OCCT_BACKGROUND_COLOR),
+ OpenGl_Vec3((Standard_ShortReal)aBackground.Red(),
+ (Standard_ShortReal)aBackground.Green(),
+ (Standard_ShortReal)aBackground.Blue()));
+ }
+}
+
+// =======================================================================
+// function : SetSilhouetteColor
+// purpose :
+// =======================================================================
+void OpenGl_Context::SetSilhouetteColor (const Quantity_Color& theColor)
+{
+ if (!myActiveProgram.IsNull())
+ {
+ myActiveProgram->SetUniform(this,
+ myActiveProgram->GetStateLocation(OpenGl_OCCT_SILHOUETTE_COLOR),
+ OpenGl_Vec3((Standard_ShortReal)theColor.Red(),
+ (Standard_ShortReal)theColor.Green(),
+ (Standard_ShortReal)theColor.Blue()));
+ }
+}
+
+// =======================================================================
+// function : SetSilhouetteThickness
+// purpose :
+// =======================================================================
+void OpenGl_Context::SetSilhouetteThickness (Standard_ShortReal theThickness)
+{
+ if (!myActiveProgram.IsNull())
+ {
+ myActiveProgram->SetUniform(this,
+ myActiveProgram->GetStateLocation(OpenGl_OCCT_SILHOUETTE_THICKNESS), theThickness);
+ }
+}
+
// =======================================================================
// function : SetPointSpriteOrigin
// purpose :
#include <NCollection_Shared.hxx>
+class OpenGl_Workspace;
+
//! Forward declarations
#if defined(__APPLE__)
#import <TargetConditionals.h>
//! Setup texture matrix to active GLSL program or to FFP global state using glMatrixMode (GL_TEXTURE).
Standard_EXPORT void SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams);
+ Standard_EXPORT void PushOrthoScale (const Handle(OpenGl_Workspace)& theWorkspace);
+ Standard_EXPORT void SetIsSilhouettePass (Standard_Boolean);
+ Standard_EXPORT void PushBackgroundColor (const Handle(OpenGl_Workspace)& theWorkspace);
+ Standard_EXPORT void SetSilhouetteColor (const Quantity_Color&);
+ Standard_EXPORT void SetSilhouetteThickness (Standard_ShortReal);
+
//! Bind default Vertex Array Object
Standard_EXPORT void BindDefaultVao();
#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_Structure.hxx>
#include <OpenGl_VertexBufferCompat.hxx>
+#include <OpenGl_View.hxx>
#include <OpenGl_Workspace.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <NCollection_AlignedAllocator.hxx>
anAspectFace->Aspect()->AlphaMode(),
hasVertColor,
toEnableEnvMap,
- anAspectFace->ShaderProgramRes (aCtx));
+ anAspectFace->ShaderProgramRes (aCtx),
+ anAspectFace->Aspect()->InteriorStyle());
+
+ if (anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_OUTLINE)
+ {
+ const Graphic3d_Vec4* aFaceColors = !myBounds.IsNull() && !toHilight && anAspectFace->Aspect()->InteriorStyle() != Aspect_IS_HIDDENLINE
+ ? myBounds->Colors
+ : NULL;
+
+ aCtx->PushOrthoScale(theWorkspace);
+ aCtx->PushBackgroundColor(theWorkspace);
+ aCtx->SetSilhouetteColor(anAspectFace->Aspect()->EdgeColor());
+
+ Standard_Integer aViewWidth, aViewHeight;
+ theWorkspace->View()->Window()->Size(aViewWidth, aViewHeight);
+ Standard_Integer aMin = aViewWidth < aViewHeight ? aViewWidth : aViewHeight;
+
+ Standard_ShortReal anEdgeWidth = (Standard_ShortReal)anAspectFace->Aspect()->EdgeWidth() / (Standard_ShortReal)aMin;
+ aCtx->SetSilhouetteThickness(anEdgeWidth);
+
+ aCtx->SetIsSilhouettePass(Standard_True);
+ GLboolean isCull = glIsEnabled(GL_CULL_FACE);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_FRONT);
+ drawArray(theWorkspace, aFaceColors, hasColorAttrib);
+
+ aCtx->SetIsSilhouettePass(Standard_False);
+ glCullFace(GL_BACK);
+ drawArray(theWorkspace, aFaceColors, hasColorAttrib);
+
+ if (!isCull)
+ glDisable(GL_CULL_FACE);
+ }
break;
}
}
}
else
{
- if (anAspectFace->Aspect()->ToDrawEdges()
- || anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_HIDDENLINE)
+ if ((anAspectFace->Aspect()->ToDrawEdges()
+ || anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_HIDDENLINE)
+ && anAspectFace->Aspect()->InteriorStyle() != Aspect_IS_OUTLINE)
{
const OpenGl_Vec4& anEdgeColor = theWorkspace->EdgeColor();
drawEdges (anEdgeColor, theWorkspace);
setDrawMode (theType);
}
+
OpenGl_PO_ClipPlanesN = 0x100, //!< handle N clipping planes
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
+ OpenGl_PO_OUTLINE = 0x800, //!< HLR presentation (outline shader)
+ OpenGl_PO_NB = 0x1000 //!< overall number of combinations
};
//! Alias to programs array of predefined length
}
}
+ if ((theBits & OpenGl_PO_OUTLINE) != 0)
+ {
+ aSrcVertExtraOut +=
+ EOL"uniform float occOrthoScale;"
+ EOL"uniform float occIsSilhouettePass;"
+ EOL"uniform float occSilhouetteThickness;"
+ EOL""
+ EOL"THE_SHADER_IN vec4 normal;"
+ ;
+
+ aSrcVertExtraMain +=
+ EOL" vec3 delta = vec3(0.0, 0.0, 0.0);"
+ EOL" if (occIsSilhouettePass > 0.1)"
+ EOL" {"
+ EOL" float aShift = occSilhouetteThickness;"
+ EOL" if (occOrthoScale > 0.0)"
+ EOL" {"
+ EOL" aShift *= occOrthoScale;"
+ EOL" delta = normal.xyz * aShift;"
+ EOL" }"
+ EOL" else"
+ EOL" {"
+ EOL" vec4 pos = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * vertex;"
+ EOL" delta = normal.xyz * aShift * pos.w;"
+ EOL" }"
+ EOL" }"
+ EOL" vertex += vec4(delta, 0.0);"
+ ;
+
+ aSrcFragExtraOut +=
+ EOL"uniform float occIsSilhouettePass;"
+ EOL"uniform vec3 occBackgroundColor;"
+ EOL"uniform vec3 occSilhouetteColor;"
+ ;
+
+ aSrcFragExtraMain +=
+ EOL" vec3 aColor = occBackgroundColor;"
+ EOL" if (occIsSilhouettePass > 0.1)"
+ EOL" aColor = occSilhouetteColor;"
+ ;
+
+ aSrcFragWriteOit = EOL" occSetFragColor(vec4(aColor, 1.0));";
+ }
+
aSrcVert =
aSrcVertExtraFunc
+ aSrcVertExtraOut
+ EOL"void main()"
EOL"{"
+ EOL" vec4 vertex = occVertex;"
+ aSrcVertExtraMain
- + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
+ + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * vertex;"
+ aSrcVertEndMain
+ EOL"}";
const Graphic3d_AlphaMode theAlphaMode,
const Standard_Boolean theHasVertColor,
const Standard_Boolean theEnableEnvMap,
- const Handle(OpenGl_ShaderProgram)& theCustomProgram)
+ const Handle(OpenGl_ShaderProgram)& theCustomProgram,
+ const Aspect_InteriorStyle theStyle)
{
if (!theCustomProgram.IsNull()
|| myContext->caps->ffpEnable)
&& (theTextures.IsNull() || theTextures->IsModulate())
? theShadingModel
: Graphic3d_TOSM_UNLIT;
- const Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, theHasVertColor, theEnableEnvMap);
+ const Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, theHasVertColor, theEnableEnvMap, theStyle);
Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (aShadeModelOnFace, aBits);
return bindProgramWithState (aProgram);
}
Standard_Integer getProgramBits (const Handle(OpenGl_TextureSet)& theTextures,
Graphic3d_AlphaMode theAlphaMode,
Standard_Boolean theHasVertColor,
- Standard_Boolean theEnableEnvMap)
+ Standard_Boolean theEnableEnvMap,
+ Aspect_InteriorStyle theStyle=Aspect_IS_EMPTY)
{
Standard_Integer aBits = 0;
{
aBits |= OpenGl_PO_WriteOit;
}
+
+ if (theStyle == Aspect_IS_OUTLINE)
+ {
+ aBits |= OpenGl_PO_OUTLINE;
+ }
return aBits;
}
Standard_Integer theBits)
{
if (theShadingModel == Graphic3d_TOSM_UNLIT
- || (theBits & OpenGl_PO_TextureEnv) != 0)
+ || (theBits & OpenGl_PO_TextureEnv) != 0
+ || (theBits & OpenGl_PO_OUTLINE) != 0)
{
// If environment map is enabled lighting calculations are
// not needed (in accordance with default OCCT behavior)
"occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
"occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
- "occPointSize" // OpenGl_OCCT_POINT_SIZE
+ "occPointSize", // OpenGl_OCCT_POINT_SIZE
+
+ "occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE
+ "occIsSilhouettePass", // OpenGl_OCCT_IS_SILHOUETTE_PASS
+ "occBackgroundColor", // OpenGl_OCCT_BACKGROUND_COLOR
+ "occSilhouetteColor", // OpenGl_OCCT_SILHOUETTE_COLOR
+ "occSilhouetteThickness" // OpenGl_OCCT_SILHOUETTE_THICKNESS
};
namespace
OpenGl_OCCT_TEXTURE_TRSF2D,
OpenGl_OCCT_POINT_SIZE,
+ // Parameters of outline (silhouette) shader
+ OpenGl_OCCT_ORTHO_SCALE,
+ OpenGl_OCCT_IS_SILHOUETTE_PASS,
+ OpenGl_OCCT_BACKGROUND_COLOR,
+ OpenGl_OCCT_SILHOUETTE_COLOR,
+ OpenGl_OCCT_SILHOUETTE_THICKNESS,
+
// DON'T MODIFY THIS ITEM (insert new items before it)
OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES
};
// bind unlit program
theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_TextureSet)(), Graphic3d_TOSM_UNLIT,
Graphic3d_AlphaMode_Opaque, Standard_False, Standard_False,
- Handle(OpenGl_ShaderProgram)());
+ Handle(OpenGl_ShaderProgram)(), Aspect_IS_SOLID);
#if !defined(GL_ES_VERSION_2_0)
if (theCtx->core11 != NULL
{
anInterStyle = Aspect_IS_POINT;
}
+ else if (aStyleArg == "outline")
+ {
+ anInterStyle = Aspect_IS_OUTLINE;
+ }
else
{
const Standard_Integer anIntStyle = aStyleArg.IntegerValue();
if (anIntStyle < Aspect_IS_EMPTY
- || anIntStyle > Aspect_IS_POINT)
+ || anIntStyle > Aspect_IS_OUTLINE)
{
std::cout << "Error: style must be within a range [0 (Aspect_IS_EMPTY), "
- << Aspect_IS_POINT << " (Aspect_IS_POINT)]\n";
+ << Aspect_IS_OUTLINE << " (Aspect_IS_OUTLINE)]\n";
return 1;
}
anInterStyle = (Aspect_InteriorStyle )anIntStyle;
--- /dev/null
+puts "========"
+puts "0024437: Efficient HLR visualization based on OpenGL and GLSL"
+puts "========"
+puts ""
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+vsetcolorbg 220 220 220
+
+psphere sph 1.0
+box b 1 2 3
+ttranslate b 2 -2 -2
+
+vdisplay -dispMode 1 b
+vsetinteriorstyle b outline
+vshowfaceboundary b 1 255 0 0 1.0
+vsetedgetype b -color 255 0 0
+vfit
+
+vdisplay -dispMode 1 sph
+vsetinteriorstyle sph outline
+vshowfaceboundary sph 1 255 0 0 1.0
+vsetedgetype sph -color 255 0 0
+vfit