1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0024437: Efficient HLR visualization based on OpenGL and GLSL

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
This commit is contained in:
asl
2018-05-17 16:10:30 +03:00
parent fc87027267
commit 746677a0f0
12 changed files with 229 additions and 14 deletions

View File

@@ -32,7 +32,8 @@ Aspect_IS_HOLLOW,
Aspect_IS_HATCH,
Aspect_IS_SOLID,
Aspect_IS_HIDDENLINE,
Aspect_IS_POINT
Aspect_IS_POINT,
Aspect_IS_OUTLINE
};
#endif // _Aspect_InteriorStyle_HeaderFile

View File

@@ -33,6 +33,7 @@
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_Workspace.hxx>
#include <OpenGl_AspectFace.hxx>
#include <OpenGl_View.hxx>
#include <Graphic3d_TransformUtils.hxx>
#include <Graphic3d_RenderingParams.hxx>
@@ -3447,6 +3448,79 @@ void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
#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 :

View File

@@ -45,6 +45,8 @@
#include <NCollection_Shared.hxx>
class OpenGl_Workspace;
//! Forward declarations
#if defined(__APPLE__)
#import <TargetConditionals.h>
@@ -722,6 +724,12 @@ public: //! @name methods to alter or retrieve current state
//! 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();

View File

@@ -24,6 +24,7 @@
#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>
@@ -810,7 +811,39 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
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;
}
}
@@ -868,8 +901,9 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
}
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);
@@ -1026,3 +1060,4 @@ void OpenGl_PrimitiveArray::InitBuffers (const Handle(OpenGl_Context)& th
setDrawMode (theType);
}

View File

@@ -34,7 +34,8 @@ enum OpenGl_ProgramOptions
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

View File

@@ -1603,13 +1603,58 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
}
}
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"}";

View File

@@ -87,7 +87,8 @@ public:
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)
@@ -99,7 +100,7 @@ public:
&& (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);
}
@@ -401,7 +402,8 @@ protected:
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;
@@ -444,6 +446,11 @@ protected:
{
aBits |= OpenGl_PO_WriteOit;
}
if (theStyle == Aspect_IS_OUTLINE)
{
aBits |= OpenGl_PO_OUTLINE;
}
return aBits;
}
@@ -452,7 +459,8 @@ protected:
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)

View File

@@ -74,7 +74,13 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
"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

View File

@@ -74,6 +74,13 @@ enum OpenGl_StateVariable
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
};

View File

@@ -761,7 +761,7 @@ void OpenGl_Text::drawRect (const Handle(OpenGl_Context)& theCtx,
// 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

View File

@@ -1575,14 +1575,18 @@ static int VSetInteriorStyle (Draw_Interpretor& theDI,
{
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;

26
tests/bugs/vis/bug24437 Normal file
View File

@@ -0,0 +1,26 @@
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