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:
@@ -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
|
||||
|
@@ -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 :
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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"}";
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -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
|
||||
|
@@ -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
26
tests/bugs/vis/bug24437
Normal 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
|
Reference in New Issue
Block a user