Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Visualization - Physicalised Marker Scale, Line Rendering (Using a geometry shader) #130

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions src/Graphic3d/Graphic3d_Aspects.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Graphic3d_Aspects::Graphic3d_Aspects()
myLinePattern (0xFFFF),
myMarkerType (Aspect_TOM_POINT),
myMarkerScale (1.0f),
myMarkerPhysical (false),
myTextStyle (Aspect_TOST_NORMAL),
myTextDisplayType (Aspect_TODT_NORMAL),
myTextFontAspect (Font_FontAspect_Regular),
Expand Down
10 changes: 10 additions & 0 deletions src/Graphic3d/Graphic3d_Aspects.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,14 @@ public:
myMarkerScale = theScale;
}

//! Whether the marker is rendered as a physical sphere in view space
Standard_Boolean MarkerPhysical() const { return myMarkerPhysical; }

void SetMarkerPhysical (const Standard_Boolean theMarkerPhysical)
{
myMarkerPhysical = theMarkerPhysical;
}

//! Returns marker's image texture.
//! Could be null handle if marker aspect has been initialized as default type of marker.
const Handle(Graphic3d_MarkerImage)& MarkerImage() const { return myMarkerImage; }
Expand Down Expand Up @@ -509,6 +517,7 @@ public:
&& myLinePattern == theOther.myLinePattern
&& myMarkerType == theOther.myMarkerType
&& myMarkerScale == theOther.myMarkerScale
&& myMarkerPhysical == theOther.myMarkerPhysical
&& myHatchStyle == theOther.myHatchStyle
&& myTextFont == theOther.myTextFont
&& myPolygonOffset == theOther.myPolygonOffset
Expand Down Expand Up @@ -580,6 +589,7 @@ protected:

Aspect_TypeOfMarker myMarkerType;
Standard_ShortReal myMarkerScale;
Standard_Boolean myMarkerPhysical;

Aspect_TypeOfStyleText myTextStyle;
Aspect_TypeOfDisplayText myTextDisplayType;
Expand Down
9 changes: 6 additions & 3 deletions src/Graphic3d/Graphic3d_ShaderFlags.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ enum Graphic3d_ShaderFlags
Graphic3d_ShaderFlags_AlphaTest = 0x0400, //!< discard fragment by alpha test (defined by cutoff value)
Graphic3d_ShaderFlags_WriteOit = 0x0800, //!< write coverage buffer for Blended Order-Independent Transparency
Graphic3d_ShaderFlags_OitDepthPeeling = 0x1000, //!< handle Depth Peeling OIT
Graphic3d_ShaderFlags_PointCircle = 0x2000, //!< output points as circle billboards with diameter (gl_PointSize) instead
Graphic3d_ShaderFlags_LineWidth = 0x4000, //!< expand line primitives in screen space using triangles
//
Graphic3d_ShaderFlags_NB = 0x2000, //!< overall number of combinations
Graphic3d_ShaderFlags_IsPoint = Graphic3d_ShaderFlags_PointSimple|Graphic3d_ShaderFlags_PointSprite|Graphic3d_ShaderFlags_PointSpriteA,
Graphic3d_ShaderFlags_NB = 0x8000, //!< overall number of combinations
Graphic3d_ShaderFlags_IsPoint = Graphic3d_ShaderFlags_PointSimple|Graphic3d_ShaderFlags_PointSprite|
Graphic3d_ShaderFlags_PointSpriteA|Graphic3d_ShaderFlags_PointCircle,
Graphic3d_ShaderFlags_HasTextures = Graphic3d_ShaderFlags_TextureRGB|Graphic3d_ShaderFlags_TextureEnv,
Graphic3d_ShaderFlags_NeedsGeomShader = Graphic3d_ShaderFlags_MeshEdges,
Graphic3d_ShaderFlags_NeedsGeomShader = Graphic3d_ShaderFlags_MeshEdges|Graphic3d_ShaderFlags_PointCircle|Graphic3d_ShaderFlags_LineWidth,
};

#endif // _Graphic3d_ShaderFlags_HeaderFile
270 changes: 219 additions & 51 deletions src/Graphic3d/Graphic3d_ShaderManager.cxx

Large diffs are not rendered by default.

31 changes: 27 additions & 4 deletions src/Graphic3d/Graphic3d_ShaderObject.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ Handle(Graphic3d_ShaderObject) Graphic3d_ShaderObject::CreateFromSource (TCollec
const ShaderVariableList& theStageInOuts,
const TCollection_AsciiString& theInName,
const TCollection_AsciiString& theOutName,
Standard_Integer theNbGeomInputVerts)
Standard_Integer theNbGeomInputVerts,
Standard_Integer theNbGeomOutputVerts,
Graphic3d_TypeOfPrimitiveArray theGeometryInputType)
{
if (theSource.IsEmpty())
{
Expand Down Expand Up @@ -135,7 +137,7 @@ Handle(Graphic3d_ShaderObject) Graphic3d_ShaderObject::CreateFromSource (TCollec
continue;
}

const Standard_Boolean hasGeomStage = theNbGeomInputVerts > 0
const Standard_Boolean hasGeomStage = theNbGeomOutputVerts > 0
&& aStageLower < Graphic3d_TOS_GEOMETRY
&& aStageUpper >= Graphic3d_TOS_GEOMETRY;
const Standard_Boolean isAllStagesVar = aStageLower == Graphic3d_TOS_VERTEX
Expand Down Expand Up @@ -192,9 +194,29 @@ Handle(Graphic3d_ShaderObject) Graphic3d_ShaderObject::CreateFromSource (TCollec

if (theType == Graphic3d_TOS_GEOMETRY)
{
TCollection_AsciiString aGeomShaderInput;

switch (theGeometryInputType) {
case Graphic3d_TOPA_POLYLINES:
case Graphic3d_TOPA_SEGMENTS:
aGeomShaderInput = "lines";
break;
case Graphic3d_TOPA_LINE_STRIP_ADJACENCY:
case Graphic3d_TOPA_LINES_ADJACENCY:
aGeomShaderInput = "lines_adjacency";
break;
case Graphic3d_TOPA_POINTS:
aGeomShaderInput = "points";
break;
case Graphic3d_TOPA_TRIANGLES:
default:
aGeomShaderInput = "triangles";
break;
}

aSrcUniforms.Prepend (TCollection_AsciiString()
+ "\nlayout (triangles) in;"
"\nlayout (triangle_strip, max_vertices = " + theNbGeomInputVerts + ") out;");
+ "\nlayout (" + aGeomShaderInput + ") in;"
"\nlayout (triangle_strip, max_vertices = " + theNbGeomOutputVerts + ") out;");
}
if (!aSrcInStructs.IsEmpty()
&& theType == Graphic3d_TOS_GEOMETRY)
Expand Down Expand Up @@ -223,5 +245,6 @@ Handle(Graphic3d_ShaderObject) Graphic3d_ShaderObject::CreateFromSource (TCollec
}

theSource.Prepend (aSrcUniforms + aSrcInStructs + aSrcOutStructs + aSrcInOuts);

return Graphic3d_ShaderObject::CreateFromSource (theType, theSource);
}
5 changes: 4 additions & 1 deletion src/Graphic3d/Graphic3d_ShaderObject.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define _Graphic3d_ShaderObject_HeaderFile

#include <Graphic3d_TypeOfShaderObject.hxx>
#include <Graphic3d_TypeOfPrimitiveArray.hxx>
#include <NCollection_Sequence.hxx>
#include <OSD_Path.hxx>

Expand Down Expand Up @@ -72,7 +73,9 @@ public:
const ShaderVariableList& theStageInOuts,
const TCollection_AsciiString& theInName = TCollection_AsciiString(),
const TCollection_AsciiString& theOutName = TCollection_AsciiString(),
Standard_Integer theNbGeomInputVerts = 0);
Standard_Integer theNbGeomInputVerts = 0,
Standard_Integer theNbGeomOutputVerts = 0,
Graphic3d_TypeOfPrimitiveArray theGeometryInputType = Graphic3d_TOPA_TRIANGLES);

private:

Expand Down
11 changes: 7 additions & 4 deletions src/OpenGl/OpenGl_AspectsSprite.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void OpenGl_AspectsSprite::UpdateRediness (const Handle(Graphic3d_Aspects)& theA
{
// update sprite resource bindings
TCollection_AsciiString aSpriteKeyNew, aSpriteAKeyNew;
spriteKeys (theAspect->MarkerImage(), theAspect->MarkerType(), theAspect->MarkerScale(), theAspect->ColorRGBA(), aSpriteKeyNew, aSpriteAKeyNew);
spriteKeys (theAspect->MarkerImage(), theAspect->MarkerType(), theAspect->MarkerScale(), theAspect->MarkerPhysical(), theAspect->ColorRGBA(), aSpriteKeyNew, aSpriteAKeyNew);
const TCollection_AsciiString& aSpriteKeyOld = !mySprite.IsNull() ? mySprite ->ResourceId() : THE_EMPTY_KEY;
const TCollection_AsciiString& aSpriteAKeyOld = !mySpriteA.IsNull() ? mySpriteA->ResourceId() : THE_EMPTY_KEY;
if (aSpriteKeyNew.IsEmpty() || aSpriteKeyOld != aSpriteKeyNew
Expand All @@ -122,7 +122,7 @@ const Handle(OpenGl_PointSprite)& OpenGl_AspectsSprite::Sprite (const Handle(Ope
{
if (!myIsSpriteReady)
{
build (theCtx, theAspects->MarkerImage(), theAspects->MarkerType(), theAspects->MarkerScale(), theAspects->ColorRGBA(), myMarkerSize);
build (theCtx, theAspects->MarkerImage(), theAspects->MarkerType(), theAspects->MarkerScale(), theAspects->MarkerPhysical(), theAspects->ColorRGBA(), myMarkerSize);
myIsSpriteReady = true;
}
return theIsAlphaSprite && !mySpriteA.IsNull() && mySpriteA->IsValid()
Expand All @@ -138,12 +138,13 @@ void OpenGl_AspectsSprite::build (const Handle(OpenGl_Context)& theCtx,
const Handle(Graphic3d_MarkerImage)& theMarkerImage,
Aspect_TypeOfMarker theType,
Standard_ShortReal theScale,
Standard_Boolean thePhysicalScale,
const Graphic3d_Vec4& theColor,
Standard_ShortReal& theMarkerSize)
{
// generate key for shared resource
TCollection_AsciiString aNewKey, aNewKeyA;
spriteKeys (theMarkerImage, theType, theScale, theColor, aNewKey, aNewKeyA);
spriteKeys (theMarkerImage, theType, theScale, thePhysicalScale, theColor, aNewKey, aNewKeyA);

const TCollection_AsciiString& aSpriteKeyOld = !mySprite.IsNull() ? mySprite ->ResourceId() : THE_EMPTY_KEY;
const TCollection_AsciiString& aSpriteAKeyOld = !mySpriteA.IsNull() ? mySpriteA->ResourceId() : THE_EMPTY_KEY;
Expand Down Expand Up @@ -336,6 +337,7 @@ void OpenGl_AspectsSprite::build (const Handle(OpenGl_Context)& theCtx,
void OpenGl_AspectsSprite::spriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
Aspect_TypeOfMarker theType,
Standard_ShortReal theScale,
Standard_Boolean thePhysicalScale,
const Graphic3d_Vec4& theColor,
TCollection_AsciiString& theKey,
TCollection_AsciiString& theKeyA)
Expand All @@ -350,7 +352,8 @@ void OpenGl_AspectsSprite::spriteKeys (const Handle(Graphic3d_MarkerImage)& theM
}
}
else if (theType != Aspect_TOM_POINT
&& theType != Aspect_TOM_EMPTY)
&& theType != Aspect_TOM_EMPTY
&& !thePhysicalScale)
{
// predefined markers are defined with 0.5 step
const Standard_Integer aScale = Standard_Integer(theScale * 10.0f + 0.5f);
Expand Down
6 changes: 6 additions & 0 deletions src/OpenGl/OpenGl_AspectsSprite.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public:

Standard_ShortReal MarkerSize() const { return myMarkerSize; }

Standard_Boolean MarkerPhysical() const { return myMarkerPhysical; }

//! Return TRUE if resource is up-to-date.
bool IsReady() const { return myIsSpriteReady; }

Expand Down Expand Up @@ -63,13 +65,15 @@ private:
const Handle(Graphic3d_MarkerImage)& theMarkerImage,
Aspect_TypeOfMarker theType,
Standard_ShortReal theScale,
Standard_Boolean thePhysicalScale,
const Graphic3d_Vec4& theColor,
Standard_ShortReal& theMarkerSize);

//! Generate resource keys for a sprite.
static void spriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
Aspect_TypeOfMarker theType,
Standard_ShortReal theScale,
Standard_Boolean thePhysicalScale,
const Graphic3d_Vec4& theColor,
TCollection_AsciiString& theKey,
TCollection_AsciiString& theKeyA);
Expand All @@ -78,8 +82,10 @@ private:

Handle(OpenGl_PointSprite) mySprite;
Handle(OpenGl_PointSprite) mySpriteA;

Standard_ShortReal myMarkerSize;
Standard_Boolean myIsSpriteReady;
Standard_Boolean myMarkerPhysical;

};

Expand Down
2 changes: 2 additions & 0 deletions src/OpenGl/OpenGl_Caps.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ OpenGl_Caps::OpenGl_Caps()
keepArrayData (Standard_False),
ffpEnable (Standard_False),
usePolygonMode (Standard_False),
lineGeomDisable (Standard_False),
useSystemBuffer (Standard_False),
swapInterval (1),
useZeroToOneDepth (Standard_False),
Expand Down Expand Up @@ -71,6 +72,7 @@ OpenGl_Caps& OpenGl_Caps::operator= (const OpenGl_Caps& theCopy)
ffpEnable = theCopy.ffpEnable;
useSystemBuffer = theCopy.useSystemBuffer;
swapInterval = theCopy.swapInterval;
lineGeomDisable = theCopy.lineGeomDisable;
useZeroToOneDepth = theCopy.useZeroToOneDepth;
buffersNoSwap = theCopy.buffersNoSwap;
buffersOpaqueAlpha= theCopy.buffersOpaqueAlpha;
Expand Down
1 change: 1 addition & 0 deletions src/OpenGl/OpenGl_Caps.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public: //! @name flags to disable particular functionality, should be used only
Standard_Boolean keepArrayData; //!< Disables freeing CPU memory after building VBOs (OFF by default)
Standard_Boolean ffpEnable; //!< Enables FFP (fixed-function pipeline), do not use built-in GLSL programs (OFF by default)
Standard_Boolean usePolygonMode; //!< Enables Polygon Mode instead of built-in GLSL programs (OFF by default; unsupported on OpenGL ES)
Standard_Boolean lineGeomDisable; //!< Disables GLSL shader for line rendering (OFF by default)
Standard_Boolean useSystemBuffer; //!< Enables usage of system backbuffer for blitting (OFF by default on desktop OpenGL and ON on OpenGL ES for testing)
Standard_Integer swapInterval; //!< controls swap interval - 0 for VSync off and 1 for VSync on, 1 by default
Standard_Boolean useZeroToOneDepth; //!< use [0, 1] depth range instead of [-1, 1] range, when possible (OFF by default)
Expand Down
22 changes: 20 additions & 2 deletions src/OpenGl/OpenGl_PrimitiveArray.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ void OpenGl_PrimitiveArray::drawEdges (const Handle(OpenGl_Workspace)& theWorksp
if (aGlContext->core20fwd != NULL)
{
aGlContext->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), anAspect->Aspect()->EdgeLineType(),
Graphic3d_TypeOfShadingModel_Unlit, Graphic3d_AlphaMode_Opaque, Standard_False,
Graphic3d_TypeOfShadingModel_Unlit, Graphic3d_AlphaMode_Opaque, Standard_False, Standard_False,
anAspect->ShaderProgramRes (aGlContext));
}
aGlContext->SetSampleAlphaToCoverage (aGlContext->ShaderManager()->MaterialState().HasAlphaCutoff());
Expand Down Expand Up @@ -847,7 +847,18 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();

bool toDrawArray = true, toSetLinePolygMode = false;

int toDrawInteriorEdges = 0; // 0 - no edges, 1 - glsl edges, 2 - polygonMode
int toDrawLineGeometry = 1; // 1 - render using FFP, 2 - render using glsl

if (myDrawMode == GL_LINES || myDrawMode == GL_LINE_STRIP)
{
if (aCtx->hasGeometryStage != OpenGl_FeatureNotAvailable && !aCtx->caps->lineGeomDisable)
{
toDrawLineGeometry = 2;
}
}

if (myIsFillType)
{
toDrawArray = anAspectFace->Aspect()->InteriorStyle() != Aspect_IS_EMPTY;
Expand Down Expand Up @@ -932,7 +943,7 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
{
aShadingModel = aCtx->ShaderManager()->ChooseMarkerShadingModel (anAspectFace->ShadingModel(), hasVertNorm);
aCtx->ShaderManager()->BindMarkerProgram (aTextureSet,
aShadingModel, Graphic3d_AlphaMode_Opaque,
aShadingModel, Graphic3d_AlphaMode_Opaque, anAspectFace->Aspect()->MarkerPhysical(),
hasVertColor, anAspectFace->ShaderProgramRes (aCtx));
break;
}
Expand All @@ -945,7 +956,14 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
aShadingModel,
Graphic3d_AlphaMode_Opaque,
hasVertColor,
toDrawLineGeometry == 2,
anAspectFace->ShaderProgramRes (aCtx));

if (toDrawLineGeometry == 2)
{
aCtx->ShaderManager()->PushInteriorState (aCtx->ActiveProgram(), anAspectFace->Aspect());
}

break;
}
default:
Expand Down
6 changes: 6 additions & 0 deletions src/OpenGl/OpenGl_ShaderManager.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,7 @@ Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl
Standard_Boolean OpenGl_ShaderManager::BindMarkerProgram (const Handle(OpenGl_TextureSet)& theTextures,
Graphic3d_TypeOfShadingModel theShadingModel,
Graphic3d_AlphaMode theAlphaMode,
Standard_Boolean theRenderPhysicalCircle,
Standard_Boolean theHasVertColor,
const Handle(OpenGl_ShaderProgram)& theCustomProgram)
{
Expand All @@ -1443,6 +1444,11 @@ Standard_Boolean OpenGl_ShaderManager::BindMarkerProgram (const Handle(OpenGl_Te
{
aBits |= Graphic3d_ShaderFlags_PointSimple;
}

if (theRenderPhysicalCircle) {
aBits |= Graphic3d_ShaderFlags_PointCircle;
}

Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theShadingModel, aBits);
return bindProgramWithState (aProgram, theShadingModel);
}
8 changes: 8 additions & 0 deletions src/OpenGl/OpenGl_ShaderManager.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ public:
const Graphic3d_TypeOfShadingModel theShadingModel,
const Graphic3d_AlphaMode theAlphaMode,
const Standard_Boolean theHasVertColor,
const Standard_Boolean theEnableLineGeometry,
const Handle(OpenGl_ShaderProgram)& theCustomProgram)
{
if (!theCustomProgram.IsNull()
Expand All @@ -144,6 +145,12 @@ public:
}

Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, Aspect_IS_SOLID, theHasVertColor, false, false);

if (theEnableLineGeometry)
{
aBits |= Graphic3d_ShaderFlags_LineWidth;
}

if (theLineType != Aspect_TOL_SOLID)
{
aBits |= Graphic3d_ShaderFlags_StippleLine;
Expand All @@ -157,6 +164,7 @@ public:
Standard_EXPORT Standard_Boolean BindMarkerProgram (const Handle(OpenGl_TextureSet)& theTextures,
Graphic3d_TypeOfShadingModel theShadingModel,
Graphic3d_AlphaMode theAlphaMode,
Standard_Boolean theRenderPhysicalCircle,
Standard_Boolean theHasVertColor,
const Handle(OpenGl_ShaderProgram)& theCustomProgram);

Expand Down
2 changes: 1 addition & 1 deletion src/OpenGl/OpenGl_Structure.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void OpenGl_Structure::renderBoundingBox (const Handle(OpenGl_Workspace)& theWor
OpenGl_Vec3 (aMin.x(), aMin.y(), aMax.z())
};

aCtx->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), Aspect_TOL_SOLID, Graphic3d_TypeOfShadingModel_Unlit, Graphic3d_AlphaMode_Opaque, false, Handle(OpenGl_ShaderProgram)());
aCtx->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), Aspect_TOL_SOLID, Graphic3d_TypeOfShadingModel_Unlit, Graphic3d_AlphaMode_Opaque, false, false, Handle(OpenGl_ShaderProgram)());
aCtx->SetColor4fv (theWorkspace->InteriorColor());
aCtx->core11fwd->glDisable (GL_LIGHTING);
aCtx->core11ffp->glEnableClientState (GL_VERTEX_ARRAY);
Expand Down
2 changes: 1 addition & 1 deletion src/OpenGlTest/OpenGlTest_Commands.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
OpenGl_Vec4 aColor = theWorkspace->InteriorColor();

aCtx->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), Aspect_TOL_SOLID,
Graphic3d_TypeOfShadingModel_Unlit, Graphic3d_AlphaMode_Opaque, false,
Graphic3d_TypeOfShadingModel_Unlit, Graphic3d_AlphaMode_Opaque, false, false,
Handle(OpenGl_ShaderProgram)());
aCtx->SetColor4fv (aColor);

Expand Down