mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
Compare commits
8 Commits
CR31123
...
CR0_IntSeg
Author | SHA1 | Date | |
---|---|---|---|
|
cb2e41f927 | ||
|
6466cc9eb1 | ||
|
f7fc0c03be | ||
|
67312b7991 | ||
|
f4a7308f61 | ||
|
53d770b3a2 | ||
|
7ed6e985e2 | ||
|
da6b95a075 |
@@ -216,8 +216,7 @@ void GeomSources::DisplaySurface(CGeometryDoc* aDoc,
|
||||
|
||||
void GeomSources::ResetView(CGeometryDoc* aDoc)
|
||||
{
|
||||
aDoc->GetAISContext()->CurrentViewer()->InitActiveViews();
|
||||
Handle(V3d_View) aView = aDoc->GetAISContext()->CurrentViewer()->ActiveView();
|
||||
Handle(V3d_View) aView = aDoc->GetAISContext()->CurrentViewer()->ActiveViews().First();
|
||||
aView->Reset();
|
||||
}
|
||||
|
||||
|
@@ -68,8 +68,7 @@ void TexturesExt_Presentation::DoSample()
|
||||
void TexturesExt_Presentation::Init()
|
||||
{
|
||||
// initialize v3d_view so it displays TexturesExt well
|
||||
getViewer()->InitActiveViews();
|
||||
Handle(V3d_View) aView = getViewer()->ActiveView();
|
||||
Handle(V3d_View) aView = getViewer()->ActiveViews().First();
|
||||
aView->SetSize(ZVIEW_SIZE);
|
||||
|
||||
// getDocument()->UpdateResultMessageDlg("Textured Shape",
|
||||
|
@@ -1020,8 +1020,7 @@ void CViewer3dDoc::OnDumpView()
|
||||
pView->UpdateWindow();
|
||||
}
|
||||
|
||||
myViewer->InitActiveViews();
|
||||
Handle(V3d_View) aView = myViewer->ActiveView();
|
||||
Handle(V3d_View) aView = myViewer->ActiveViews().First();
|
||||
ExportView (aView);
|
||||
}
|
||||
|
||||
|
@@ -1012,65 +1012,61 @@ aParams.NbMsaaSamples = aParams.NbMsaaSamples == 0 ? 8 : 0;\n\
|
||||
GetDocument()->UpdateResultMessageDlg("SetAntialiasingOn/SetAntialiasingOff",Message);
|
||||
}
|
||||
|
||||
void CViewer3dView::OnClearLights()
|
||||
void CViewer3dView::OnClearLights()
|
||||
{
|
||||
// Setting Off all viewer active lights
|
||||
TColStd_ListOfTransient lights;
|
||||
for(myView->Viewer()->InitActiveLights(); myView->Viewer()->MoreActiveLights(); myView->Viewer()->NextActiveLights())
|
||||
// Setting Off all viewer active lights
|
||||
V3d_ListOfLight lights;
|
||||
for (V3d_ListOfLightIterator anIter = myView->Viewer()->ActiveLightIterator(); anIter.More(); anIter.Next())
|
||||
{
|
||||
lights.Append(myView->Viewer()->ActiveLight());
|
||||
lights.Append (anIter.Value());
|
||||
}
|
||||
TColStd_ListIteratorOfListOfTransient itrLights(lights);
|
||||
V3d_ListOfLightIterator itrLights(lights);
|
||||
for (; itrLights.More(); itrLights.Next())
|
||||
{
|
||||
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());
|
||||
myView->Viewer()->SetLightOff(light);
|
||||
myView->Viewer()->SetLightOff (itrLights.Value());
|
||||
}
|
||||
|
||||
// Setting Off all view active lights
|
||||
// Setting Off all view active lights
|
||||
lights.Clear();
|
||||
for(myView->InitActiveLights(); myView->MoreActiveLights(); myView->NextActiveLights())
|
||||
for (V3d_ListOfLightIterator anIter = myView->ActiveLightIterator(); anIter.More(); anIter.Next())
|
||||
{
|
||||
lights.Append(myView->ActiveLight());
|
||||
lights.Append (anIter.Value());
|
||||
}
|
||||
itrLights.Initialize(lights);
|
||||
itrLights.Initialize (lights);
|
||||
for (; itrLights.More(); itrLights.Next())
|
||||
{
|
||||
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());
|
||||
myView->SetLightOff(light);
|
||||
myView->SetLightOff (itrLights.Value());
|
||||
}
|
||||
|
||||
myView->Viewer()->SetDefaultLights();// Setting the default lights on
|
||||
myView->Viewer()->SetDefaultLights(); // Setting the default lights on
|
||||
|
||||
NbActiveLights = 2;// There are 2 default active lights
|
||||
NbActiveLights = 2; // There are 2 default active lights
|
||||
|
||||
myView->Update();
|
||||
myView->Update();
|
||||
|
||||
TCollection_AsciiString Message("\
|
||||
// Setting Off all viewer active lights\n\
|
||||
TColStd_ListOfTransient lights;\n\
|
||||
for(myView->Viewer()->InitActiveLights(); myView->Viewer()->MoreActiveLights(); myView->Viewer()->NextActiveLights())\n\
|
||||
// Setting Off all viewer active lights\n\
|
||||
V3d_ListOfLight lights;\n\
|
||||
for (V3d_ListOfLightIterator anIter = myView->Viewer()->ActiveLightIterator(); anIter.More(); anIter.Next())\n\
|
||||
{\n\
|
||||
lights.Append(myView->Viewer()->ActiveLight());\n\
|
||||
lights.Append (anIter.Value());\n\
|
||||
}\n\
|
||||
TColStd_ListIteratorOfListOfTransient itrLights(lights);\n\
|
||||
V3d_ListOfLightIterator itrLights(lights);\n\
|
||||
for (; itrLights.More(); itrLights.Next())\n\
|
||||
{\n\
|
||||
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());\n\
|
||||
myView->Viewer()->SetLightOff(light);\n\
|
||||
myView->Viewer()->SetLightOff (itrLights.Value())\n\
|
||||
}\n\
|
||||
\n\
|
||||
// Setting Off all view active lights\n\
|
||||
// Setting Off all view active lights\n\
|
||||
lights.Clear();\n\
|
||||
for(myView->InitActiveLights(); myView->MoreActiveLights(); myView->NextActiveLights())\n\
|
||||
for (V3d_ListOfLightIterator anIter = myView->ActiveLightIterator(); anIter.More(); anIter.Next())\n\
|
||||
{\n\
|
||||
lights.Append(myView->ActiveLight());\n\
|
||||
lights.Append (anIter.Value());\n\
|
||||
}\n\
|
||||
itrLights.Initialize(lights);\n\
|
||||
for (; itrLights.More(); itrLights.Next())\n\
|
||||
{\n\
|
||||
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());\n\
|
||||
myView->SetLightOff(light);\n\
|
||||
myView->SetLightOff (itrLights.Value());\n\
|
||||
}\n\
|
||||
\n\
|
||||
myView->Viewer()->SetDefaultLights();// Setting the default lights on\n\
|
||||
|
@@ -413,8 +413,7 @@ void CTriangulationDoc::OnDumpView()
|
||||
pView->UpdateWindow();
|
||||
}
|
||||
|
||||
myViewer->InitActiveViews();
|
||||
Handle(V3d_View) aView = myViewer->ActiveView();
|
||||
Handle(V3d_View) aView = myViewer->ActiveViews().First();
|
||||
ExportView (aView);
|
||||
}
|
||||
|
||||
|
@@ -230,8 +230,7 @@ void COCCDemoDoc::OnDumpView()
|
||||
pView->UpdateWindow();
|
||||
}
|
||||
|
||||
myViewer->InitActiveViews();
|
||||
Handle(V3d_View) aView = myViewer->ActiveView();
|
||||
Handle(V3d_View) aView = myViewer->ActiveViews().First();
|
||||
ExportView (aView);
|
||||
}
|
||||
|
||||
|
@@ -489,8 +489,7 @@ void OCC_3dBaseDoc::OnUpdateV3dButtons (CCmdUI* pCmdUI)
|
||||
// Common function to change raytracing params and redraw view
|
||||
void OCC_3dBaseDoc::OnObjectRayTracingAction()
|
||||
{
|
||||
myAISContext->CurrentViewer()->InitActiveViews();
|
||||
Handle(V3d_View) aView = myAISContext->CurrentViewer()->ActiveView();
|
||||
Handle(V3d_View) aView = myAISContext->CurrentViewer()->ActiveViews().First();
|
||||
Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
|
||||
if (myRayTracingIsOn)
|
||||
aParams.Method = Graphic3d_RM_RAYTRACING;
|
||||
|
@@ -415,11 +415,6 @@ Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
|
||||
//=======================================================================
|
||||
Standard_Integer AIS_ColorScale::computeMaxLabelWidth (const TColStd_SequenceOfExtendedString& theLabels) const
|
||||
{
|
||||
{
|
||||
Handle(V3d_Viewer) aViewer = GetContext()->CurrentViewer();
|
||||
aViewer->InitActiveViews(); // for AIS_ColorScale::TextSize()
|
||||
}
|
||||
|
||||
Standard_Integer aWidthMax = 0;
|
||||
for (TColStd_SequenceOfExtendedString::Iterator aLabIter (theLabels); aLabIter.More(); aLabIter.Next())
|
||||
{
|
||||
|
@@ -137,6 +137,9 @@ AIS_ViewCube::AIS_ViewCube()
|
||||
myBoxEdgeGap (0.0),
|
||||
myBoxFacetExtension (1.0),
|
||||
myAxesPadding (1.0),
|
||||
myAxesRadius (1.0),
|
||||
myAxesConeRadius (3.0),
|
||||
myAxesSphereRadius (4.0),
|
||||
myCornerMinSize (2.0),
|
||||
myRoundRadius (0.0),
|
||||
myToDisplayAxes (true),
|
||||
@@ -599,7 +602,7 @@ void AIS_ViewCube::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
|
||||
anAxisGroup->SetGroupPrimitivesAspect (aDatumAspect->ShadingAspect (aPart)->Aspect());
|
||||
|
||||
const Standard_Real anArrowLength = 0.2 * anAxisSize;
|
||||
Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = Prs3d_Arrow::DrawShaded (anAx1, 1.0, anAxisSize, 3.0, anArrowLength, THE_NB_ARROW_FACETTES);
|
||||
Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = Prs3d_Arrow::DrawShaded (anAx1, myAxesRadius, anAxisSize, myAxesConeRadius, anArrowLength, THE_NB_ARROW_FACETTES);
|
||||
anAxisGroup->AddPrimitiveArray (aTriangleArray);
|
||||
|
||||
TCollection_AsciiString anAxisLabel;
|
||||
@@ -621,7 +624,7 @@ void AIS_ViewCube::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
|
||||
Handle(Prs3d_ShadingAspect) anAspectCen = new Prs3d_ShadingAspect();
|
||||
anAspectCen->SetColor (Quantity_NOC_WHITE);
|
||||
aGroup->SetGroupPrimitivesAspect (anAspectCen->Aspect());
|
||||
Prs3d_ToolSphere aTool (4.0, THE_NB_DISK_SLICES, THE_NB_DISK_SLICES);
|
||||
Prs3d_ToolSphere aTool (myAxesSphereRadius, THE_NB_DISK_SLICES, THE_NB_DISK_SLICES);
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTranslation (gp_Vec (gp::Origin(), aLocation));
|
||||
Handle(Graphic3d_ArrayOfTriangles) aCenterArray;
|
||||
|
@@ -189,6 +189,45 @@ public: //! @name Geometry management API
|
||||
//! The value should be within [0, 0.5] range.
|
||||
Standard_EXPORT void SetRoundRadius (const Standard_Real theValue);
|
||||
|
||||
//! Returns radius of axes of the trihedron; 1.0 by default.
|
||||
Standard_Real AxesRadius() const { return myAxesRadius; }
|
||||
|
||||
//! Sets radius of axes of the trihedron.
|
||||
void SetAxesRadius (const Standard_Real theRadius)
|
||||
{
|
||||
if (Abs (myAxesRadius - theRadius) > Precision::Confusion())
|
||||
{
|
||||
myAxesRadius = theRadius;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns radius of cone of axes of the trihedron; 3.0 by default.
|
||||
Standard_Real AxesConeRadius() const { return myAxesConeRadius; }
|
||||
|
||||
//! Sets radius of cone of axes of the trihedron.
|
||||
void SetAxesConeRadius (Standard_Real theRadius)
|
||||
{
|
||||
if (Abs (myAxesConeRadius - theRadius) > Precision::Confusion())
|
||||
{
|
||||
myAxesConeRadius = theRadius;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns radius of sphere (central point) of the trihedron; 4.0 by default.
|
||||
Standard_Real AxesSphereRadius() const { return myAxesSphereRadius; }
|
||||
|
||||
//! Sets radius of sphere (central point) of the trihedron.
|
||||
void SetAxesSphereRadius (Standard_Real theRadius)
|
||||
{
|
||||
if (Abs (myAxesSphereRadius - theRadius) > Precision::Confusion())
|
||||
{
|
||||
myAxesSphereRadius = theRadius;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! @return TRUE if trihedron is drawn; TRUE by default.
|
||||
Standard_Boolean ToDrawAxes() const { return myToDisplayAxes; }
|
||||
|
||||
@@ -621,6 +660,9 @@ protected:
|
||||
Standard_Real myBoxEdgeGap; //!< gap between box side and box edge
|
||||
Standard_Real myBoxFacetExtension; //!< box facet extension
|
||||
Standard_Real myAxesPadding; //!< Padding between box and axes
|
||||
Standard_Real myAxesRadius; //!< radius of axes of the trihedron; 1.0 by default
|
||||
Standard_Real myAxesConeRadius; //!< radius of cone of axes of the trihedron; 3.0 by default
|
||||
Standard_Real myAxesSphereRadius; //!< radius of sphere (central point) of the trihedron; 4.0 by default
|
||||
Standard_Real myCornerMinSize; //!< minimal size of box corner
|
||||
Standard_Real myRoundRadius; //!< relative round radius within [0; 0.5] range
|
||||
Standard_Boolean myToDisplayAxes; //!< trihedron visibility
|
||||
|
@@ -2434,8 +2434,9 @@ BRepMesh_GeomTool::IntFlag BRepMesh_Delaun::intSegSeg(
|
||||
p3 = GetVertex( theEdg2.FirstNode() ).Coord();
|
||||
p4 = GetVertex( theEdg2.LastNode() ).Coord();
|
||||
|
||||
Standard_Real aIntParams[2];
|
||||
return BRepMesh_GeomTool::IntSegSeg(p1, p2, p3, p4,
|
||||
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt);
|
||||
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt, aIntParams);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@@ -19,191 +19,6 @@
|
||||
#include <OSD_Parallel.hxx>
|
||||
#include <BRepMesh_GeomTool.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
const Standard_Real MaxTangentAngle = 5. * M_PI / 180.;
|
||||
|
||||
//! Functor to be used to fill segments and bounding box tree in parallel.
|
||||
class SegmentsFiller
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
SegmentsFiller(const IMeshData::IFaceHandle& theDFace,
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfSegments)& theWiresSegments,
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& theWiresBndBoxTree)
|
||||
: myDFace(theDFace),
|
||||
myWiresSegments(theWiresSegments),
|
||||
myWiresBndBoxTree(theWiresBndBoxTree)
|
||||
{
|
||||
myWiresSegments = new BRepMesh_FaceChecker::ArrayOfSegments (0, myDFace->WiresNb() - 1);
|
||||
myWiresBndBoxTree = new BRepMesh_FaceChecker::ArrayOfBndBoxTree (0, myDFace->WiresNb() - 1);
|
||||
}
|
||||
|
||||
//! Performs initialization of wire with the given index.
|
||||
void operator()(const Standard_Integer theWireIndex) const
|
||||
{
|
||||
const IMeshData::IWireHandle& aDWire = myDFace->GetWire(theWireIndex);
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc1 = new NCollection_IncAllocator();
|
||||
|
||||
Handle(BRepMesh_FaceChecker::Segments) aSegments =
|
||||
new BRepMesh_FaceChecker::Segments(aDWire->EdgesNb(), aTmpAlloc1);
|
||||
Handle(IMeshData::BndBox2dTree) aBndBoxTree = new IMeshData::BndBox2dTree(aTmpAlloc1);
|
||||
|
||||
myWiresSegments ->ChangeValue(theWireIndex) = aSegments;
|
||||
myWiresBndBoxTree->ChangeValue(theWireIndex) = aBndBoxTree;
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc2 = new NCollection_IncAllocator();
|
||||
IMeshData::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree, aTmpAlloc2);
|
||||
|
||||
for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
|
||||
{
|
||||
// TODO: check 2d wire for consistency.
|
||||
|
||||
const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge(aEdgeIt);
|
||||
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(myDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt));
|
||||
|
||||
for (Standard_Integer aPointIt = 1; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
|
||||
{
|
||||
gp_Pnt2d& aPnt1 = aPCurve->GetPoint(aPointIt - 1);
|
||||
gp_Pnt2d& aPnt2 = aPCurve->GetPoint(aPointIt);
|
||||
|
||||
Bnd_Box2d aBox;
|
||||
aBox.Add(aPnt1);
|
||||
aBox.Add(aPnt2);
|
||||
aBox.Enlarge(Precision::Confusion());
|
||||
|
||||
aBndBoxTreeFiller.Add(aSegments->Size(), aBox);
|
||||
aSegments->Append(BRepMesh_FaceChecker::Segment(aDEdge, &aPnt1, &aPnt2));
|
||||
}
|
||||
}
|
||||
|
||||
aBndBoxTreeFiller.Fill();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SegmentsFiller (const SegmentsFiller& theOther);
|
||||
|
||||
void operator=(const SegmentsFiller& theOther);
|
||||
|
||||
private:
|
||||
|
||||
const IMeshData::IFaceHandle& myDFace;
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfSegments)& myWiresSegments;
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree;
|
||||
};
|
||||
|
||||
//! Selector.
|
||||
//! Used to identify segments with overlapped bounding boxes.
|
||||
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
BndBox2dTreeSelector(const Standard_Real theTolerance)
|
||||
: myMaxLoopSize(M_PI * theTolerance * theTolerance),
|
||||
mySelfSegmentIndex(-1),
|
||||
myIndices(256, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
|
||||
{
|
||||
}
|
||||
|
||||
//! Sets working set of segments.
|
||||
void SetSegments(const Handle(BRepMesh_FaceChecker::Segments)& theSegments)
|
||||
{
|
||||
mySegments = theSegments;
|
||||
}
|
||||
|
||||
//! Resets current selector.
|
||||
void Reset(const BRepMesh_FaceChecker::Segment* theSegment,
|
||||
const Standard_Integer theSelfSegmentIndex)
|
||||
{
|
||||
myIndices.Clear();
|
||||
|
||||
mySelfSegmentIndex = theSelfSegmentIndex;
|
||||
mySegment = theSegment;
|
||||
|
||||
myBox.SetVoid();
|
||||
myBox.Add(*mySegment->Point1);
|
||||
myBox.Add(*mySegment->Point2);
|
||||
myBox.Enlarge(Precision::Confusion());
|
||||
}
|
||||
|
||||
//! Indicates should the given box be rejected or not.
|
||||
virtual Standard_Boolean Reject(const Bnd_Box2d& theBox) const
|
||||
{
|
||||
return myBox.IsOut(theBox);
|
||||
}
|
||||
|
||||
//! Accepts segment with the given index in case if it fits conditions.
|
||||
virtual Standard_Boolean Accept(const Standard_Integer& theSegmentIndex)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aSegment = mySegments->Value(theSegmentIndex);
|
||||
|
||||
gp_Pnt2d aIntPnt;
|
||||
const BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
|
||||
mySegment->Point1->XY(), mySegment->Point2->XY(),
|
||||
aSegment.Point1->XY(), aSegment.Point2->XY(),
|
||||
Standard_False, Standard_False, aIntPnt);
|
||||
|
||||
if (aIntStatus == BRepMesh_GeomTool::Cross)
|
||||
{
|
||||
const Standard_Real aAngle = gp_Vec2d(mySegment->Point1->XY(), mySegment->Point2->XY()).Angle(
|
||||
gp_Vec2d(aSegment.Point1->XY(), aSegment.Point2->XY()));
|
||||
|
||||
if (Abs(aAngle) < MaxTangentAngle)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (mySelfSegmentIndex != -1)
|
||||
{
|
||||
gp_XY aPrevVec;
|
||||
Standard_Real aSumS = 0.;
|
||||
const gp_XY& aRefPnt = aIntPnt.Coord();
|
||||
for (Standard_Integer i = mySelfSegmentIndex; i < theSegmentIndex; ++i)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aCurrSegment = mySegments->Value(i);
|
||||
gp_XY aCurVec = aCurrSegment.Point2->XY() - aRefPnt;
|
||||
|
||||
if (aCurVec.SquareModulus() < gp::Resolution())
|
||||
continue;
|
||||
|
||||
if (aPrevVec.SquareModulus() > gp::Resolution())
|
||||
aSumS += aPrevVec ^ aCurVec;
|
||||
|
||||
aPrevVec = aCurVec;
|
||||
}
|
||||
|
||||
if (Abs(aSumS / 2.) < myMaxLoopSize)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
myIndices.Append(theSegmentIndex);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//! Returns indices of intersecting segments.
|
||||
const IMeshData::VectorOfInteger& Indices() const
|
||||
{
|
||||
return myIndices;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Standard_Real myMaxLoopSize;
|
||||
Standard_Integer mySelfSegmentIndex;
|
||||
Handle(BRepMesh_FaceChecker::Segments) mySegments;
|
||||
const BRepMesh_FaceChecker::Segment* mySegment;
|
||||
Bnd_Box2d myBox;
|
||||
IMeshData::VectorOfInteger myIndices;
|
||||
};
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
@@ -211,8 +26,7 @@ namespace
|
||||
BRepMesh_FaceChecker::BRepMesh_FaceChecker(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
: myDFace(theFace),
|
||||
myParameters(theParameters)
|
||||
: BRepMesh_SegmentedFace (theFace, theParameters)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -230,50 +44,39 @@ BRepMesh_FaceChecker::~BRepMesh_FaceChecker()
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FaceChecker::Perform()
|
||||
{
|
||||
myIntersectingEdges = new IMeshData::MapOfIEdgePtr;
|
||||
collectSegments();
|
||||
|
||||
myIntersectingEdges = new IMeshData::MapOfIEdgePtr;
|
||||
myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1);
|
||||
|
||||
OSD_Parallel::For(0, myDFace->WiresNb(), *this, !isParallel());
|
||||
collectResult();
|
||||
|
||||
myWiresBndBoxTree.Nullify();
|
||||
myWiresSegments.Nullify();
|
||||
myWiresBndBoxTree .Nullify();
|
||||
myWiresSegments .Nullify();
|
||||
myWiresIntersectingEdges.Nullify();
|
||||
return myIntersectingEdges->IsEmpty();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : collectSegments
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FaceChecker::collectSegments()
|
||||
{
|
||||
SegmentsFiller aSegmentsFiller(myDFace, myWiresSegments, myWiresBndBoxTree);
|
||||
OSD_Parallel::For(0, myDFace->WiresNb(), aSegmentsFiller, !isParallel());
|
||||
|
||||
myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
|
||||
{
|
||||
const Handle(Segments)& aSegments1 = myWiresSegments->Value(theWireIndex);
|
||||
const Handle(Segments)& aSegments1 = myWiresSegments ->Value (theWireIndex);
|
||||
Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myWiresIntersectingEdges->ChangeValue(theWireIndex);
|
||||
|
||||
// TODO: Tolerance is set to twice value of face deflection in order to fit regressions.
|
||||
BndBox2dTreeSelector aSelector(2 * myDFace->GetDeflection());
|
||||
BRepMesh_SegmentedFace::BndBox2dTreeSelector aSelector (Standard_False);
|
||||
for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
|
||||
{
|
||||
const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);
|
||||
const Handle(Segments)& aSegments2 = myWiresSegments->Value(aWireIt);
|
||||
const Handle(Segments)& aSegments2 = myWiresSegments ->Value(aWireIt);
|
||||
|
||||
aSelector.SetSegments(aSegments2);
|
||||
for (Standard_Integer aSegmentIt = 0; aSegmentIt < aSegments1->Size(); ++aSegmentIt)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
|
||||
aSelector.Reset(&aSegment1, (aWireIt == theWireIndex) ? aSegmentIt : -1);
|
||||
if (aBndBoxTree2->Select(aSelector) != 0)
|
||||
{
|
||||
@@ -287,7 +90,7 @@ void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
|
||||
const IMeshData::VectorOfInteger& aSegments = aSelector.Indices();
|
||||
for (Standard_Integer aSelIt = 0; aSelIt < aSegments.Size(); ++aSelIt)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
|
||||
aIntersections->Add(aSegment2.EdgePtr);
|
||||
}
|
||||
}
|
||||
|
@@ -16,49 +16,18 @@
|
||||
#ifndef _BRepMesh_FaceChecker_HeaderFile
|
||||
#define _BRepMesh_FaceChecker_HeaderFile
|
||||
|
||||
#include <IMeshTools_Parameters.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <IMeshData_Face.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
#include <BRepMesh_SegmentedFace.hxx>
|
||||
|
||||
//! Auxiliary class checking wires of target face for self-intersections.
|
||||
//! Explodes wires of discrete face on sets of segments using tessellation
|
||||
//! data stored in model. Each segment is then checked for intersection with
|
||||
//! other ones. All collisions are registerd and returned as result of check.
|
||||
class BRepMesh_FaceChecker : public Standard_Transient
|
||||
class BRepMesh_FaceChecker : public BRepMesh_SegmentedFace
|
||||
{
|
||||
public: //! @name mesher API
|
||||
|
||||
//! Identifies segment inside face.
|
||||
struct Segment
|
||||
{
|
||||
IMeshData::IEdgePtr EdgePtr;
|
||||
gp_Pnt2d* Point1; // \ Use explicit pointers to points instead of accessing
|
||||
gp_Pnt2d* Point2; // / using indices.
|
||||
|
||||
Segment()
|
||||
: Point1(NULL)
|
||||
, Point2(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Segment(const IMeshData::IEdgePtr& theEdgePtr,
|
||||
gp_Pnt2d* thePoint1,
|
||||
gp_Pnt2d* thePoint2)
|
||||
: EdgePtr(theEdgePtr)
|
||||
, Point1(thePoint1)
|
||||
, Point2(thePoint2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef NCollection_Shared<NCollection_Vector<Segment> > Segments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(Segments)> > ArrayOfSegments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::BndBox2dTree)> > ArrayOfBndBoxTree;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::MapOfIEdgePtr)> > ArrayOfMapOfIEdgePtr;
|
||||
|
||||
|
||||
//! Default constructor
|
||||
Standard_EXPORT BRepMesh_FaceChecker(const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters);
|
||||
@@ -82,19 +51,10 @@ public: //! @name mesher API
|
||||
perform(theWireIndex);
|
||||
}
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceChecker, Standard_Transient)
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceChecker, BRepMesh_SegmentedFace)
|
||||
|
||||
private:
|
||||
|
||||
//! Returns True in case if check can be performed in parallel mode.
|
||||
inline Standard_Boolean isParallel() const
|
||||
{
|
||||
return (myParameters.InParallel && myDFace->WiresNb() > 1);
|
||||
}
|
||||
|
||||
//! Collects face segments.
|
||||
void collectSegments();
|
||||
|
||||
//! Collects intersecting edges.
|
||||
void collectResult();
|
||||
|
||||
@@ -109,11 +69,6 @@ private:
|
||||
|
||||
private:
|
||||
|
||||
IMeshData::IFaceHandle myDFace;
|
||||
const IMeshTools_Parameters& myParameters;
|
||||
|
||||
Handle(ArrayOfSegments) myWiresSegments;
|
||||
Handle(ArrayOfBndBoxTree) myWiresBndBoxTree;
|
||||
Handle(ArrayOfMapOfIEdgePtr) myWiresIntersectingEdges;
|
||||
Handle(IMeshData::MapOfIEdgePtr) myIntersectingEdges;
|
||||
|
||||
|
100
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.cxx
Normal file
100
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.cxx
Normal file
@@ -0,0 +1,100 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <BRepMesh_FaceIntersectionsSplitter.hxx>
|
||||
#include <IMeshData_Wire.hxx>
|
||||
#include <IMeshData_Edge.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_FaceIntersectionsSplitter::BRepMesh_FaceIntersectionsSplitter(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
: BRepMesh_SegmentedFace (theFace, theParameters)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Destructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_FaceIntersectionsSplitter::~BRepMesh_FaceIntersectionsSplitter()
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FaceIntersectionsSplitter::Perform()
|
||||
{
|
||||
for (Standard_Integer aWireIt = 0; aWireIt < myDFace->WiresNb(); ++aWireIt)
|
||||
{
|
||||
Standard_Boolean isSplit = Standard_True;
|
||||
while (isSplit)
|
||||
{
|
||||
collectSegments();
|
||||
|
||||
isSplit = perform(aWireIt);
|
||||
|
||||
myWiresSegments .Nullify();
|
||||
myWiresBndBoxTree.Nullify();
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FaceIntersectionsSplitter::perform(
|
||||
const Standard_Integer theWireIndex)
|
||||
{
|
||||
const Handle(Segments)& aSegments1 = myWiresSegments->Value (theWireIndex);
|
||||
|
||||
BRepMesh_SegmentedFace::BndBox2dTreeSelector aSelector (Standard_True);
|
||||
for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
|
||||
{
|
||||
const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);
|
||||
const Handle(Segments)& aSegments2 = myWiresSegments ->Value(aWireIt);
|
||||
|
||||
aSelector.SetSegments(aSegments2);
|
||||
for (Standard_Integer aSegmentIt = 0; aSegmentIt < aSegments1->Size(); ++aSegmentIt)
|
||||
{
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
|
||||
aSelector.Reset(&aSegment1, (aWireIt == theWireIndex) ? aSegmentIt : -1);
|
||||
if (aBndBoxTree2->Select(aSelector) != 0)
|
||||
{
|
||||
const IMeshData::VectorOfInteger& aSegments = aSelector.Indices();
|
||||
const BRepMesh_SegmentedFace::VectorOfIntersectionParams& aIntParams = aSelector.IntParams();
|
||||
for (Standard_Integer aSelIt = 0; aSelIt < aSegments.Size(); ++aSelIt)
|
||||
{
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
|
||||
|
||||
//aIntersections->Add(aSegment1.EdgePtr);
|
||||
//aIntersections->Add(aSegment2.EdgePtr);
|
||||
}
|
||||
|
||||
//return Standard_False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
55
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.hxx
Normal file
55
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.hxx
Normal file
@@ -0,0 +1,55 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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 _BRepMesh_FaceIntersectionsSplitter_HeaderFile
|
||||
#define _BRepMesh_FaceIntersectionsSplitter_HeaderFile
|
||||
|
||||
#include <BRepMesh_SegmentedFace.hxx>
|
||||
|
||||
//! Auxiliary class splitting intersecting segments of wires of target face.
|
||||
//! Explodes wires of discrete face on sets of segments using tessellation
|
||||
//! data stored in model. Each segment is then checked for intersection with
|
||||
//! other ones and split on intersection point.
|
||||
class BRepMesh_FaceIntersectionsSplitter : public BRepMesh_SegmentedFace
|
||||
{
|
||||
public: //! @name mesher API
|
||||
|
||||
//! Default constructor
|
||||
Standard_EXPORT BRepMesh_FaceIntersectionsSplitter(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters);
|
||||
|
||||
//! Destructor
|
||||
Standard_EXPORT virtual ~BRepMesh_FaceIntersectionsSplitter();
|
||||
|
||||
//! Performs split of intersecting segments of wires of the face.
|
||||
//! @return True if there is no intersection, False elsewhere.
|
||||
Standard_EXPORT Standard_Boolean Perform();
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceIntersectionsSplitter, BRepMesh_SegmentedFace)
|
||||
|
||||
private:
|
||||
|
||||
//! Splits wire with the given index at first intersection point with others.
|
||||
Standard_Boolean perform(const Standard_Integer theWireIndex);
|
||||
|
||||
private:
|
||||
|
||||
BRepMesh_FaceIntersectionsSplitter (const BRepMesh_FaceIntersectionsSplitter& theOther);
|
||||
|
||||
void operator=(const BRepMesh_FaceIntersectionsSplitter& theOther);
|
||||
};
|
||||
|
||||
#endif
|
@@ -333,7 +333,8 @@ BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
|
||||
const gp_XY& theEndPnt2,
|
||||
const Standard_Boolean isConsiderEndPointTouch,
|
||||
const Standard_Boolean isConsiderPointOnSegment,
|
||||
gp_Pnt2d& theIntPnt)
|
||||
gp_Pnt2d& theIntPnt,
|
||||
Standard_Real (&theParamOnSegment)[2])
|
||||
{
|
||||
Standard_Integer aPointHash[] = {
|
||||
classifyPoint(theStartPnt1, theEndPnt1, theStartPnt2),
|
||||
@@ -393,9 +394,8 @@ BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
|
||||
else if ( aPosHash == 2 )
|
||||
return BRepMesh_GeomTool::Glued;
|
||||
|
||||
Standard_Real aParam[2];
|
||||
IntFlag aIntFlag = IntLinLin(theStartPnt1, theEndPnt1,
|
||||
theStartPnt2, theEndPnt2, theIntPnt.ChangeCoord(), aParam);
|
||||
theStartPnt2, theEndPnt2, theIntPnt.ChangeCoord(), theParamOnSegment);
|
||||
|
||||
if (aIntFlag == BRepMesh_GeomTool::NoIntersection)
|
||||
return BRepMesh_GeomTool::NoIntersection;
|
||||
@@ -416,7 +416,7 @@ BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
|
||||
const Standard_Real aEndPrec = 1 - aPrec;
|
||||
for (Standard_Integer i = 0; i < 2; ++i)
|
||||
{
|
||||
if(aParam[i] < aPrec || aParam[i] > aEndPrec )
|
||||
if(theParamOnSegment[i] < aPrec || theParamOnSegment[i] > aEndPrec )
|
||||
return BRepMesh_GeomTool::NoIntersection;
|
||||
}
|
||||
|
||||
|
@@ -194,7 +194,8 @@ public: //! @name static API
|
||||
const gp_XY& theEndPnt2,
|
||||
const Standard_Boolean isConsiderEndPointTouch,
|
||||
const Standard_Boolean isConsiderPointOnSegment,
|
||||
gp_Pnt2d& theIntPnt);
|
||||
gp_Pnt2d& theIntPnt,
|
||||
Standard_Real (&theParamOnSegment)[2]);
|
||||
|
||||
//! Compute deflection of the given segment.
|
||||
static Standard_Real SquareDeflectionOfSegment(
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <BRepMesh_Deflection.hxx>
|
||||
#include <BRepMesh_ShapeTool.hxx>
|
||||
#include <BRepMesh_FaceChecker.hxx>
|
||||
#include <BRepMesh_FaceIntersectionsSplitter.hxx>
|
||||
#include <BRepMesh_EdgeDiscret.hxx>
|
||||
#include <IMeshData_Face.hxx>
|
||||
#include <IMeshData_Wire.hxx>
|
||||
@@ -150,7 +151,12 @@ Standard_Boolean BRepMesh_ModelHealer::performInternal(
|
||||
{
|
||||
const IMeshData::IFaceHandle aDFace = aFaceIt.Key();
|
||||
aDFace->SetStatus(IMeshData_SelfIntersectingWire);
|
||||
aDFace->SetStatus(IMeshData_Failure);
|
||||
|
||||
BRepMesh_FaceIntersectionsSplitter aSplitter (aDFace, myParameters);
|
||||
if (!aSplitter.Perform())
|
||||
{
|
||||
aDFace->SetStatus(IMeshData_Failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
204
src/BRepMesh/BRepMesh_SegmentedFace.cxx
Normal file
204
src/BRepMesh/BRepMesh_SegmentedFace.cxx
Normal file
@@ -0,0 +1,204 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <BRepMesh_SegmentedFace.hxx>
|
||||
#include <IMeshData_Wire.hxx>
|
||||
#include <IMeshData_Edge.hxx>
|
||||
#include <OSD_Parallel.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
//! Functor to be used to fill segments and bounding box tree in parallel.
|
||||
class SegmentsFiller
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
SegmentsFiller(const IMeshData::IFaceHandle& theDFace,
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfSegments)& theWiresSegments,
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfBndBoxTree)& theWiresBndBoxTree)
|
||||
: myDFace(theDFace),
|
||||
myWiresSegments(theWiresSegments),
|
||||
myWiresBndBoxTree(theWiresBndBoxTree)
|
||||
{
|
||||
myWiresSegments = new BRepMesh_SegmentedFace::ArrayOfSegments (0, myDFace->WiresNb() - 1);
|
||||
myWiresBndBoxTree = new BRepMesh_SegmentedFace::ArrayOfBndBoxTree (0, myDFace->WiresNb() - 1);
|
||||
}
|
||||
|
||||
//! Performs initialization of wire with the given index.
|
||||
void operator()(const Standard_Integer theWireIndex) const
|
||||
{
|
||||
const IMeshData::IWireHandle& aDWire = myDFace->GetWire(theWireIndex);
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc1 = new NCollection_IncAllocator();
|
||||
|
||||
Handle(BRepMesh_SegmentedFace::Segments) aSegments =
|
||||
new BRepMesh_SegmentedFace::Segments(aDWire->EdgesNb(), aTmpAlloc1);
|
||||
Handle(IMeshData::BndBox2dTree) aBndBoxTree = new IMeshData::BndBox2dTree(aTmpAlloc1);
|
||||
|
||||
myWiresSegments ->ChangeValue(theWireIndex) = aSegments;
|
||||
myWiresBndBoxTree->ChangeValue(theWireIndex) = aBndBoxTree;
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc2 = new NCollection_IncAllocator();
|
||||
IMeshData::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree, aTmpAlloc2);
|
||||
|
||||
for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
|
||||
{
|
||||
// TODO: check 2d wire for consistency.
|
||||
|
||||
const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge(aEdgeIt);
|
||||
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(myDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt));
|
||||
|
||||
for (Standard_Integer aPointIt = 1; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
|
||||
{
|
||||
gp_Pnt2d& aPnt1 = aPCurve->GetPoint(aPointIt - 1);
|
||||
gp_Pnt2d& aPnt2 = aPCurve->GetPoint(aPointIt);
|
||||
|
||||
Bnd_Box2d aBox;
|
||||
aBox.Add(aPnt1);
|
||||
aBox.Add(aPnt2);
|
||||
aBox.Enlarge(Precision::Confusion());
|
||||
|
||||
aBndBoxTreeFiller.Add(aSegments->Size(), aBox);
|
||||
aSegments->Append(BRepMesh_SegmentedFace::Segment(
|
||||
aDEdge, aPCurve.get(),
|
||||
&aPnt1, aPointIt - 1,
|
||||
&aPnt2, aPointIt));
|
||||
}
|
||||
}
|
||||
|
||||
aBndBoxTreeFiller.Fill();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SegmentsFiller (const SegmentsFiller& theOther);
|
||||
|
||||
void operator=(const SegmentsFiller& theOther);
|
||||
|
||||
private:
|
||||
|
||||
const IMeshData::IFaceHandle& myDFace;
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfSegments)& myWiresSegments;
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfBndBoxTree)& myWiresBndBoxTree;
|
||||
};
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_SegmentedFace::BndBox2dTreeSelector::BndBox2dTreeSelector(
|
||||
const Standard_Boolean isCollectIntersectionParams)
|
||||
: myCollectIntersectionParams (isCollectIntersectionParams)
|
||||
, mySelfSegmentIndex(-1)
|
||||
, myIndices(256, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Reset
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_SegmentedFace::BndBox2dTreeSelector::Reset(
|
||||
const BRepMesh_SegmentedFace::Segment* theSegment,
|
||||
const Standard_Integer theSelfSegmentIndex)
|
||||
{
|
||||
myIndices .Clear();
|
||||
myIntParams.Clear();
|
||||
|
||||
mySelfSegmentIndex = theSelfSegmentIndex;
|
||||
mySegment = theSegment;
|
||||
|
||||
myBox.SetVoid();
|
||||
myBox.Add(*mySegment->Point1);
|
||||
myBox.Add(*mySegment->Point2);
|
||||
myBox.Enlarge(Precision::Confusion());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Reject
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_SegmentedFace::BndBox2dTreeSelector::Reject(
|
||||
const Bnd_Box2d& theBox) const
|
||||
{
|
||||
return myBox.IsOut(theBox);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Accept
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_SegmentedFace::BndBox2dTreeSelector::Accept(
|
||||
const Standard_Integer& theSegmentIndex)
|
||||
{
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment = mySegments->Value(theSegmentIndex);
|
||||
|
||||
IntersectionParams aIntNode;
|
||||
aIntNode.Type = BRepMesh_GeomTool::IntSegSeg(
|
||||
mySegment->Point1->XY(), mySegment->Point2->XY(),
|
||||
aSegment .Point1->XY(), aSegment .Point2->XY(),
|
||||
Standard_False, Standard_False,
|
||||
aIntNode.Point, aIntNode.Params);
|
||||
|
||||
if (aIntNode.Type == BRepMesh_GeomTool::Cross ||
|
||||
aIntNode.Type == BRepMesh_GeomTool::PointOnSegment ||
|
||||
aIntNode.Type == BRepMesh_GeomTool::Glued)
|
||||
{
|
||||
|
||||
myIndices.Append(theSegmentIndex);
|
||||
|
||||
if (myCollectIntersectionParams)
|
||||
{
|
||||
myIntParams.Append(aIntNode);
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_SegmentedFace::BRepMesh_SegmentedFace(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
: myDFace (theFace),
|
||||
myParameters(theParameters)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Destructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_SegmentedFace::~BRepMesh_SegmentedFace()
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : collectSegments
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_SegmentedFace::collectSegments()
|
||||
{
|
||||
SegmentsFiller aSegmentsFiller(myDFace, myWiresSegments, myWiresBndBoxTree);
|
||||
OSD_Parallel::For(0, myDFace->WiresNb(), aSegmentsFiller, !isParallel());
|
||||
}
|
169
src/BRepMesh/BRepMesh_SegmentedFace.hxx
Normal file
169
src/BRepMesh/BRepMesh_SegmentedFace.hxx
Normal file
@@ -0,0 +1,169 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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 _BRepMesh_SegmentedFace_HeaderFile
|
||||
#define _BRepMesh_SegmentedFace_HeaderFile
|
||||
|
||||
#include <IMeshTools_Parameters.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <IMeshData_Face.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
#include <BRepMesh_GeomTool.hxx>
|
||||
|
||||
//! Auxiliary class providing common functionality for exploding wires of
|
||||
//! discrete face on sets of segments using tessellation data stored in model.
|
||||
class BRepMesh_SegmentedFace : public Standard_Transient
|
||||
{
|
||||
public: //! @name mesher API
|
||||
|
||||
//! Identifies segment inside face.
|
||||
//! Uses explicit pointers to points instead of accessing using indices.
|
||||
struct Segment
|
||||
{
|
||||
IMeshData::IEdgePtr EdgePtr;
|
||||
IMeshData::IPCurvePtr PCurvePtr;
|
||||
gp_Pnt2d* Point1;
|
||||
Standard_Integer Param1;
|
||||
gp_Pnt2d* Point2;
|
||||
Standard_Integer Param2;
|
||||
|
||||
Segment()
|
||||
: EdgePtr (NULL)
|
||||
, PCurvePtr(NULL)
|
||||
, Point1 (NULL)
|
||||
, Param1 (0)
|
||||
, Point2 (NULL)
|
||||
, Param2 (0)
|
||||
{
|
||||
}
|
||||
|
||||
Segment(const IMeshData::IEdgePtr& theEdgePtr,
|
||||
const IMeshData::IPCurvePtr& thePCurvePtr,
|
||||
gp_Pnt2d* thePoint1,
|
||||
const Standard_Integer theParam1,
|
||||
gp_Pnt2d* thePoint2,
|
||||
const Standard_Integer theParam2)
|
||||
: EdgePtr (theEdgePtr)
|
||||
, PCurvePtr(thePCurvePtr)
|
||||
, Point1 (thePoint1)
|
||||
, Param1 (theParam1)
|
||||
, Point2 (thePoint2)
|
||||
, Param2 (theParam2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//! Keeps parameters of intersection of two segments.
|
||||
//! Params are in range relative to distance between points of corresponding segment.
|
||||
struct IntersectionParams
|
||||
{
|
||||
BRepMesh_GeomTool::IntFlag Type;
|
||||
gp_Pnt2d Point;
|
||||
Standard_Real Params[2];
|
||||
};
|
||||
|
||||
typedef NCollection_Vector<IntersectionParams> VectorOfIntersectionParams;
|
||||
typedef NCollection_Shared<NCollection_Vector<Segment> > Segments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(Segments)> > ArrayOfSegments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::BndBox2dTree)> > ArrayOfBndBoxTree;
|
||||
|
||||
|
||||
//! Default constructor
|
||||
Standard_EXPORT BRepMesh_SegmentedFace(const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters);
|
||||
|
||||
//! Destructor
|
||||
Standard_EXPORT virtual ~BRepMesh_SegmentedFace();
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_SegmentedFace, Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
||||
//! Returns True in case if check can be performed in parallel mode.
|
||||
inline Standard_Boolean isParallel() const
|
||||
{
|
||||
return (myParameters.InParallel && myDFace->WiresNb() > 1);
|
||||
}
|
||||
|
||||
//! Collects face segments.
|
||||
void collectSegments();
|
||||
|
||||
private:
|
||||
|
||||
BRepMesh_SegmentedFace (const BRepMesh_SegmentedFace& theOther);
|
||||
|
||||
void operator=(const BRepMesh_SegmentedFace& theOther);
|
||||
|
||||
protected:
|
||||
|
||||
//! Selector.
|
||||
//! Used to identify segments with overlapped bounding boxes.
|
||||
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
BndBox2dTreeSelector(const Standard_Boolean isCollectIntersectionParams);
|
||||
|
||||
//! Sets working set of segments.
|
||||
inline void SetSegments(const Handle(BRepMesh_SegmentedFace::Segments)& theSegments)
|
||||
{
|
||||
mySegments = theSegments;
|
||||
}
|
||||
|
||||
//! Returns indices of intersecting segments.
|
||||
inline const IMeshData::VectorOfInteger& Indices() const
|
||||
{
|
||||
return myIndices;
|
||||
}
|
||||
|
||||
//! Returns intersection parameters.
|
||||
inline const BRepMesh_SegmentedFace::VectorOfIntersectionParams& IntParams() const
|
||||
{
|
||||
return myIntParams;
|
||||
}
|
||||
|
||||
//! Resets current selector.
|
||||
void Reset(const BRepMesh_SegmentedFace::Segment* theSegment,
|
||||
const Standard_Integer theSelfSegmentIndex);
|
||||
|
||||
//! Indicates should the given box be rejected or not.
|
||||
virtual Standard_Boolean Reject(const Bnd_Box2d& theBox) const;
|
||||
|
||||
//! Accepts segment with the given index in case if it fits conditions.
|
||||
virtual Standard_Boolean Accept(const Standard_Integer& theSegmentIndex);
|
||||
|
||||
private:
|
||||
|
||||
Standard_Boolean myCollectIntersectionParams;
|
||||
Standard_Integer mySelfSegmentIndex;
|
||||
Handle(BRepMesh_SegmentedFace::Segments) mySegments;
|
||||
const BRepMesh_SegmentedFace::Segment* mySegment;
|
||||
Bnd_Box2d myBox;
|
||||
IMeshData::VectorOfInteger myIndices;
|
||||
BRepMesh_SegmentedFace::VectorOfIntersectionParams myIntParams;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
IMeshData::IFaceHandle myDFace;
|
||||
const IMeshTools_Parameters& myParameters;
|
||||
|
||||
Handle(ArrayOfSegments) myWiresSegments;
|
||||
Handle(ArrayOfBndBoxTree) myWiresBndBoxTree;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -41,6 +41,8 @@ BRepMesh_EdgeTessellationExtractor.cxx
|
||||
BRepMesh_EdgeTessellationExtractor.hxx
|
||||
BRepMesh_FaceChecker.cxx
|
||||
BRepMesh_FaceChecker.hxx
|
||||
BRepMesh_FaceIntersectionsSplitter.cxx
|
||||
BRepMesh_FaceIntersectionsSplitter.hxx
|
||||
BRepMesh_FaceDiscret.cxx
|
||||
BRepMesh_FaceDiscret.hxx
|
||||
BRepMesh_FactoryError.hxx
|
||||
@@ -68,6 +70,8 @@ BRepMesh_OrientedEdge.hxx
|
||||
BRepMesh_PairOfIndex.hxx
|
||||
BRepMesh_PluginEntryType.hxx
|
||||
BRepMesh_PluginMacro.hxx
|
||||
BRepMesh_SegmentedFace.cxx
|
||||
BRepMesh_SegmentedFace.hxx
|
||||
BRepMesh_SelectorOfDataStructureOfDelaun.cxx
|
||||
BRepMesh_SelectorOfDataStructureOfDelaun.hxx
|
||||
BRepMesh_ShapeTool.cxx
|
||||
|
@@ -1192,35 +1192,42 @@ BiTgte_ContactType BiTgte_Blend::ContactType(const Standard_Integer Index)
|
||||
}
|
||||
BiTgte_ContactType Type = BiTgte_VertexVertex;
|
||||
|
||||
switch (Type1) {
|
||||
|
||||
case TopAbs_VERTEX:
|
||||
switch (Type2) {
|
||||
case TopAbs_VERTEX: Type = BiTgte_VertexVertex; break;
|
||||
case TopAbs_EDGE: Type = BiTgte_EdgeVertex; break;
|
||||
case TopAbs_FACE: Type = BiTgte_FaceVertex; break;
|
||||
switch (Type1)
|
||||
{
|
||||
case TopAbs_VERTEX:
|
||||
switch (Type2)
|
||||
{
|
||||
case TopAbs_VERTEX: Type = BiTgte_VertexVertex; break;
|
||||
case TopAbs_EDGE: Type = BiTgte_EdgeVertex; break;
|
||||
case TopAbs_FACE: Type = BiTgte_FaceVertex; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case TopAbs_EDGE:
|
||||
switch (Type2)
|
||||
{
|
||||
case TopAbs_EDGE: Type = BiTgte_EdgeEdge; break;
|
||||
case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case TopAbs_FACE:
|
||||
switch (Type2)
|
||||
{
|
||||
case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
case TopAbs_EDGE:
|
||||
switch (Type2) {
|
||||
case TopAbs_EDGE: Type = BiTgte_EdgeEdge; break;
|
||||
case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
case TopAbs_FACE:
|
||||
switch (Type2) {
|
||||
case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return Type;
|
||||
}
|
||||
|
||||
|
@@ -20,6 +20,8 @@
|
||||
#include <D3DHost_GraphicDriver.hxx>
|
||||
#include <TCollection_ExtendedString.hxx>
|
||||
|
||||
#include <Standard_WarningDisableFunctionCast.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(D3DHost_View,OpenGl_View)
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -37,6 +37,9 @@
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
#include <tcl.h>
|
||||
|
||||
#include <Standard_WarningDisableFunctionCast.hxx>
|
||||
|
||||
// on MSVC, use #pragma to define name of the Tcl library to link with,
|
||||
// depending on Tcl version number
|
||||
#ifdef _MSC_VER
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
#include <Message_ProgressScale.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <Precision.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
@@ -92,21 +92,34 @@ Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
|
||||
myLastPosition = aPosition;
|
||||
|
||||
// Prepare textual progress info
|
||||
char text[2048];
|
||||
Standard_Integer n = 0;
|
||||
n += Sprintf ( &text[n], "Progress: %.0f%%", 100. * GetPosition() );
|
||||
std::stringstream aText;
|
||||
aText.setf (std::ios::fixed, std:: ios::floatfield);
|
||||
aText.precision(0);
|
||||
aText << "Progress: " << 100. * GetPosition() << "%";
|
||||
for ( Standard_Integer i=GetNbScopes(); i >=1; i-- ) {
|
||||
const Message_ProgressScale &scale = GetScope ( i );
|
||||
if ( scale.GetName().IsNull() ) continue; // skip unnamed scopes
|
||||
aText << " " << scale.GetName()->ToCString() << ": ";
|
||||
|
||||
// if scope has subscopes, print end of subscope as its current position
|
||||
Standard_Real locPos = ( i >1 ? GetScope ( i-1 ).GetLast() : GetPosition() );
|
||||
// print progress info differently for finite and infinite scopes
|
||||
if ( scale.GetInfinite() )
|
||||
n += Sprintf ( &text[n], " %s: %.0f", scale.GetName()->ToCString(),
|
||||
scale.BaseToLocal ( locPos ) );
|
||||
else
|
||||
n += Sprintf ( &text[n], " %s: %.0f / %.0f", scale.GetName()->ToCString(),
|
||||
scale.BaseToLocal ( locPos ), scale.GetMax() );
|
||||
{
|
||||
Standard_Real aVal = scale.BaseToLocal(locPos);
|
||||
if (Precision::IsInfinite(aVal))
|
||||
{
|
||||
aText << "finished";
|
||||
}
|
||||
else
|
||||
{
|
||||
aText << aVal;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aText << scale.BaseToLocal ( locPos ) << " / " << scale.GetMax();
|
||||
}
|
||||
}
|
||||
|
||||
// Show graphic progress bar
|
||||
@@ -117,8 +130,8 @@ Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
|
||||
time_t aTimeT;
|
||||
time ( &aTimeT );
|
||||
Standard_Size aTime = (Standard_Size)aTimeT;
|
||||
n += Sprintf ( &text[n], "\nElapsed/estimated time: %ld/%.0f sec",
|
||||
(long)(aTime - myStartTime), ( aTime - myStartTime ) / GetPosition() );
|
||||
aText << "\nElapsed/estimated time: " << (long)(aTime - myStartTime) <<
|
||||
"/" << ( aTime - myStartTime ) / GetPosition() << " sec";
|
||||
}
|
||||
|
||||
if ( ! myShown ) {
|
||||
@@ -135,20 +148,19 @@ Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
|
||||
((Draw_Interpretor*)myDraw)->Eval ( command );
|
||||
myShown = Standard_True;
|
||||
}
|
||||
char command[1024];
|
||||
Standard_Integer num = 0;
|
||||
num += Sprintf ( &command[num], ".xprogress.bar coords progress 2 2 %.0f 21;",
|
||||
1+400*GetPosition() );
|
||||
num += Sprintf ( &command[num], ".xprogress.bar coords progress_next 2 2 %.0f 21;",
|
||||
1+400*GetScope(1).GetLast() );
|
||||
num += Sprintf ( &command[num], ".xprogress.text configure -text \"%s\";", text );
|
||||
num += Sprintf ( &command[num], "update" );
|
||||
((Draw_Interpretor*)myDraw)->Eval ( command );
|
||||
std::stringstream aCommand;
|
||||
aCommand.setf(std::ios::fixed, std::ios::floatfield);
|
||||
aCommand.precision(0);
|
||||
aCommand << ".xprogress.bar coords progress 2 2 " << (1 + 400 * GetPosition()) << " 21;";
|
||||
aCommand << ".xprogress.bar coords progress_next 2 2 " << (1 + 400 * GetScope(1).GetLast()) << " 21;";
|
||||
aCommand << ".xprogress.text configure -text \"" << aText.str() << "\";";
|
||||
aCommand << "update";
|
||||
((Draw_Interpretor*)myDraw)->Eval (aCommand.str().c_str());
|
||||
}
|
||||
|
||||
// Print textual progress info
|
||||
if ( myTextMode )
|
||||
Message::DefaultMessenger()->Send (text, Message_Info);
|
||||
Message::DefaultMessenger()->Send (aText.str().c_str(), Message_Info);
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
@@ -2003,7 +2003,7 @@ void Segment::Init(Standard_Integer a1, Standard_Integer a2,
|
||||
y2=a4;
|
||||
}
|
||||
|
||||
static DWORD WINAPI tkLoop(VOID);
|
||||
static DWORD WINAPI tkLoop (LPVOID theThreadParameter);
|
||||
#ifdef _TK
|
||||
static Tk_Window mainWindow;
|
||||
#endif
|
||||
@@ -2027,12 +2027,12 @@ Standard_Boolean Init_Appli(HINSTANCE hInst,
|
||||
dwMainThreadId = GetCurrentThreadId();
|
||||
|
||||
//necessary for normal Tk operation
|
||||
hThread = CreateThread(NULL, // no security attributes
|
||||
0, // use default stack size
|
||||
(LPTHREAD_START_ROUTINE) tkLoop, // thread function
|
||||
NULL, // no thread function argument
|
||||
0, // use default creation flags
|
||||
&IDThread);
|
||||
hThread = CreateThread (NULL, // no security attributes
|
||||
0, // use default stack size
|
||||
tkLoop, // thread function
|
||||
NULL, // no thread function argument
|
||||
0, // use default creation flags
|
||||
&IDThread);
|
||||
if (!hThread) {
|
||||
std::cout << "Failed to create Tcl/Tk main loop thread. Switching to batch mode..." << std::endl;
|
||||
Draw_Batch = Standard_True;
|
||||
@@ -2082,8 +2082,9 @@ Standard_Boolean Draw_Interprete (const char*);
|
||||
/*--------------------------------------------------------*\
|
||||
| readStdinThreadFunc
|
||||
\*--------------------------------------------------------*/
|
||||
static DWORD WINAPI readStdinThreadFunc()
|
||||
static DWORD WINAPI readStdinThreadFunc (const LPVOID theThreadParameter)
|
||||
{
|
||||
(void)theThreadParameter;
|
||||
if (!Draw_IsConsoleSubsystem)
|
||||
{
|
||||
return 1;
|
||||
@@ -2246,8 +2247,9 @@ static void ResetStdChannel (int type)
|
||||
/*--------------------------------------------------------*\
|
||||
| tkLoop: implements Tk_Main()-like behaviour in a separate thread
|
||||
\*--------------------------------------------------------*/
|
||||
static DWORD WINAPI tkLoop(VOID)
|
||||
static DWORD WINAPI tkLoop (const LPVOID theThreadParameter)
|
||||
{
|
||||
(void)theThreadParameter;
|
||||
Tcl_CreateExitHandler(exitProc, 0);
|
||||
|
||||
Draw_Interpretor& aCommands = Draw::GetInterpretor();
|
||||
@@ -2309,7 +2311,7 @@ static DWORD WINAPI tkLoop(VOID)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure)
|
||||
catch (const Standard_Failure&)
|
||||
{
|
||||
std::cout << "tkLoop: exception in TK_Init\n";
|
||||
}
|
||||
@@ -2389,12 +2391,12 @@ void Run_Appli(HWND hWnd)
|
||||
DWORD IDThread;
|
||||
HANDLE hThread;
|
||||
if (Draw_IsConsoleSubsystem) {
|
||||
hThread = CreateThread(NULL, // no security attributes
|
||||
0, // use default stack size
|
||||
(LPTHREAD_START_ROUTINE) readStdinThreadFunc, // thread function
|
||||
NULL, // no thread function argument
|
||||
0, // use default creation flags
|
||||
&IDThread); // returns thread identifier
|
||||
hThread = CreateThread (NULL, // no security attributes
|
||||
0, // use default stack size
|
||||
readStdinThreadFunc, // thread function
|
||||
NULL, // no thread function argument
|
||||
0, // use default creation flags
|
||||
&IDThread); // returns thread identifier
|
||||
if (!hThread) {
|
||||
std::cout << "pb in creation of the thread reading stdin" << std::endl;
|
||||
Draw_IsConsoleSubsystem = Standard_False;
|
||||
|
@@ -196,10 +196,12 @@ void GCPnts_TangentialDeflection::PerformLinear (const TheCurve& C) {
|
||||
D0 (C, firstu, P);
|
||||
parameters.Append (firstu);
|
||||
points .Append (P);
|
||||
if (minNbPnts > 2) {
|
||||
if (minNbPnts > 2)
|
||||
{
|
||||
Standard_Real Du = (lastu - firstu) / minNbPnts;
|
||||
Standard_Real U = firstu + Du;
|
||||
for (Standard_Integer i = 2; i <= minNbPnts; i++) {
|
||||
for (Standard_Integer i = 2; i < minNbPnts; i++)
|
||||
{
|
||||
D0 (C, U, P);
|
||||
parameters.Append (U);
|
||||
points .Append (P);
|
||||
@@ -571,14 +573,14 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
|
||||
//-- On rajoute des points aux milieux des segments si le nombre
|
||||
//-- mini de points n'est pas atteint
|
||||
//--
|
||||
Standard_Integer Nbp = points.Length();
|
||||
Standard_Integer MinNb= (9*minNbPnts)/10;
|
||||
//if(MinNb<4) MinNb=4;
|
||||
Standard_Integer Nbp = points.Length();
|
||||
|
||||
//-- if(Nbp < MinNb) { cout<<"\n*"; } else { cout<<"\n."; }
|
||||
while(Nbp < MinNb) {
|
||||
//-- cout<<" \nGCPnts TangentialDeflection : Ajout de Points ("<<Nbp<<" "<<minNbPnts<<" )"<<endl;
|
||||
for (i = 2; i <= Nbp; i += 2) {
|
||||
//std::cout << "GCPnts_TangentialDeflection: Number of Points (" << Nbp << " " << minNbPnts << " )" << std::endl;
|
||||
|
||||
while(Nbp < minNbPnts)
|
||||
{
|
||||
for (i = 2; i <= Nbp; i += 2)
|
||||
{
|
||||
MiddleU = (parameters.Value(i-1)+parameters.Value(i))*0.5;
|
||||
D0 (C, MiddleU, MiddlePoint);
|
||||
parameters.InsertBefore(i,MiddleU);
|
||||
|
@@ -1007,7 +1007,7 @@ static Standard_Integer crvpoints (Draw_Interpretor& di, Standard_Integer /*n*/,
|
||||
|
||||
static Standard_Integer crvtpoints (Draw_Interpretor& di, Standard_Integer n, const char** a)
|
||||
{
|
||||
Standard_Integer i, nbp;
|
||||
Standard_Integer i, nbp, aMinPntsNb = 2;
|
||||
Standard_Real defl, angle = Precision::Angular();
|
||||
|
||||
Handle(Adaptor3d_HCurve) aHCurve;
|
||||
@@ -1030,10 +1030,13 @@ static Standard_Integer crvtpoints (Draw_Interpretor& di, Standard_Integer n, co
|
||||
}
|
||||
defl = Draw::Atof(a[3]);
|
||||
|
||||
if(n > 3)
|
||||
if(n > 4)
|
||||
angle = Draw::Atof(a[4]);
|
||||
|
||||
GCPnts_TangentialDeflection PntGen(aHCurve->Curve(), angle, defl, 2);
|
||||
if(n > 5)
|
||||
aMinPntsNb = Draw::Atoi (a[5]);
|
||||
|
||||
GCPnts_TangentialDeflection PntGen(aHCurve->Curve(), angle, defl, aMinPntsNb);
|
||||
|
||||
nbp = PntGen.NbPoints();
|
||||
di << "Nb points : " << nbp << "\n";
|
||||
|
@@ -110,6 +110,8 @@ Graphic3d_NameOfTexture2D.hxx
|
||||
Graphic3d_NameOfTextureEnv.hxx
|
||||
Graphic3d_NameOfTexturePlane.hxx
|
||||
Graphic3d_NMapOfTransient.hxx
|
||||
Graphic3d_PBRMaterial.cxx
|
||||
Graphic3d_PBRMaterial.hxx
|
||||
Graphic3d_PolygonOffset.cxx
|
||||
Graphic3d_PolygonOffset.hxx
|
||||
Graphic3d_PriorityDefinitionError.hxx
|
||||
|
@@ -15,6 +15,8 @@
|
||||
|
||||
#include <Graphic3d_BSDF.hxx>
|
||||
|
||||
#include <Graphic3d_PBRMaterial.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// =======================================================================
|
||||
@@ -63,6 +65,7 @@ Graphic3d_Fresnel Graphic3d_Fresnel::CreateConductor (const Graphic3d_Vec3& theR
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Graphic3d_BSDF::Graphic3d_BSDF()
|
||||
: Ks (Graphic3d_Vec3 (0.f), 1.f)
|
||||
{
|
||||
FresnelCoat = Graphic3d_Fresnel::CreateConstant (0.f);
|
||||
FresnelBase = Graphic3d_Fresnel::CreateConstant (1.f);
|
||||
@@ -189,4 +192,21 @@ Graphic3d_BSDF Graphic3d_BSDF::CreateGlass (const Graphic3d_Vec3& theWeight,
|
||||
theAbsorptionCoeff);
|
||||
|
||||
return aBSDF;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : CreateMetallicRoughness
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Graphic3d_BSDF Graphic3d_BSDF::CreateMetallicRoughness (const Graphic3d_PBRMaterial& thePbr)
|
||||
{
|
||||
const Graphic3d_Vec3 aDiff = (Graphic3d_Vec3 )thePbr.Color().GetRGB() * thePbr.Alpha();
|
||||
const Standard_ShortReal aRougness2 = thePbr.NormalizedRoughness() * thePbr.NormalizedRoughness();
|
||||
|
||||
Graphic3d_BSDF aBsdf;
|
||||
aBsdf.FresnelBase = Graphic3d_Fresnel::CreateSchlick (aDiff * thePbr.Metallic());
|
||||
aBsdf.Ks.SetValues (Graphic3d_Vec3 (thePbr.Alpha()), aRougness2);
|
||||
aBsdf.Kt = Graphic3d_Vec3 (1.0f - thePbr.Alpha());
|
||||
aBsdf.Kd = aDiff * (1.0f - thePbr.Metallic());
|
||||
return aBsdf;
|
||||
}
|
||||
|
@@ -19,6 +19,8 @@
|
||||
#include <Graphic3d_Vec3.hxx>
|
||||
#include <Graphic3d_Vec4.hxx>
|
||||
|
||||
class Graphic3d_PBRMaterial;
|
||||
|
||||
//! Type of the Fresnel model.
|
||||
enum Graphic3d_FresnelModel
|
||||
{
|
||||
@@ -169,6 +171,9 @@ public:
|
||||
const Standard_ShortReal theAbsorptionCoeff,
|
||||
const Standard_ShortReal theRefractionIndex);
|
||||
|
||||
//! Creates BSDF from PBR metallic-roughness material.
|
||||
static Standard_EXPORT Graphic3d_BSDF CreateMetallicRoughness (const Graphic3d_PBRMaterial& thePbr);
|
||||
|
||||
public:
|
||||
|
||||
//! Creates uninitialized BSDF.
|
||||
|
@@ -378,7 +378,23 @@ public:
|
||||
virtual Handle(Graphic3d_CubeMap) BackgroundCubeMap() const = 0;
|
||||
|
||||
//! Sets environment cubemap as background.
|
||||
virtual void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap) = 0;
|
||||
//! @param theCubeMap cubemap source to be set as background
|
||||
//! @param theToUpdatePBREnv defines whether IBL maps will be generated or not (see 'GeneratePBREnvironment')
|
||||
virtual void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
|
||||
Standard_Boolean theToUpdatePBREnv = Standard_True) = 0;
|
||||
|
||||
//! Generates PBR specular probe and irradiance map
|
||||
//! in order to provide environment indirect illumination in PBR shading model (Image Based Lighting).
|
||||
//! The source of environment data is background cubemap.
|
||||
//! If PBR is unavailable it does nothing.
|
||||
//! If PBR is available but there is no cubemap being set to background it clears all IBL maps (see 'ClearPBREnvironment').
|
||||
virtual void GeneratePBREnvironment() = 0;
|
||||
|
||||
//! Fills PBR specular probe and irradiance map with white color.
|
||||
//! So that environment indirect illumination will be constant
|
||||
//! and will be fully controlled by ambient light sources.
|
||||
//! If PBR is unavailable it does nothing.
|
||||
virtual void ClearPBREnvironment() = 0;
|
||||
|
||||
//! Returns environment texture set for the view.
|
||||
virtual Handle(Graphic3d_TextureEnv) TextureEnv() const = 0;
|
||||
|
@@ -26,21 +26,25 @@ class Graphic3d_CubeMap : public Graphic3d_TextureMap
|
||||
public:
|
||||
|
||||
//! Constructor defining loading cubemap from file.
|
||||
Graphic3d_CubeMap (const TCollection_AsciiString& theFileName) :
|
||||
Graphic3d_CubeMap (const TCollection_AsciiString& theFileName,
|
||||
Standard_Boolean theToGenerateMipmaps = Standard_False) :
|
||||
Graphic3d_TextureMap (theFileName, Graphic3d_TOT_CUBEMAP),
|
||||
myCurrentSide (Graphic3d_CMS_POS_X),
|
||||
myEndIsReached (false),
|
||||
myIsTopDown (true),
|
||||
myZIsInverted (false)
|
||||
myZIsInverted (false),
|
||||
myHasMipmaps (theToGenerateMipmaps)
|
||||
{}
|
||||
|
||||
//! Constructor defining direct cubemap initialization from PixMap.
|
||||
Graphic3d_CubeMap (const Handle(Image_PixMap)& thePixmap = Handle(Image_PixMap)()) :
|
||||
Graphic3d_CubeMap (const Handle(Image_PixMap)& thePixmap = Handle(Image_PixMap)(),
|
||||
Standard_Boolean theToGenerateMipmaps = Standard_False) :
|
||||
Graphic3d_TextureMap (thePixmap, Graphic3d_TOT_CUBEMAP),
|
||||
myCurrentSide (Graphic3d_CMS_POS_X),
|
||||
myEndIsReached (false),
|
||||
myIsTopDown (true),
|
||||
myZIsInverted (false)
|
||||
myZIsInverted (false),
|
||||
myHasMipmaps (theToGenerateMipmaps)
|
||||
{}
|
||||
|
||||
//! Returns whether the iterator has reached the end (true if it hasn't).
|
||||
@@ -81,6 +85,12 @@ public:
|
||||
return myZIsInverted;
|
||||
}
|
||||
|
||||
//! Returns whether mipmaps of cubemap will be generated or not.
|
||||
Standard_Boolean HasMipmaps() const { return myHasMipmaps; }
|
||||
|
||||
//! Sets whether to generate mipmaps of cubemap or not.
|
||||
void SetMipmapsGeneration (Standard_Boolean theToGenerateMipmaps) { myHasMipmaps = theToGenerateMipmaps; }
|
||||
|
||||
//! Returns PixMap containing current side of cubemap.
|
||||
//! Returns null handle if current side is invalid.
|
||||
virtual Handle(Image_PixMap) Value() = 0;
|
||||
@@ -102,6 +112,7 @@ protected:
|
||||
Standard_Boolean myEndIsReached; //!< Indicates whether end of iteration has been reached or hasn't
|
||||
Standard_Boolean myIsTopDown; //!< Stores rows's memory layout
|
||||
Standard_Boolean myZIsInverted; //!< Indicates whether Z axis is inverted that allows to synchronize vertical flip of cubemap
|
||||
Standard_Boolean myHasMipmaps; //!< Indicates whether mipmaps of cubemap will be generated or not
|
||||
|
||||
};
|
||||
|
||||
|
@@ -25,6 +25,7 @@ namespace
|
||||
{
|
||||
const char* StringName;
|
||||
Graphic3d_BSDF BSDF;
|
||||
Graphic3d_PBRMaterial PBRMaterial;
|
||||
Quantity_Color Colors[Graphic3d_TypeOfReflection_NB];
|
||||
Standard_ShortReal TransparencyCoef;
|
||||
Standard_ShortReal RefractionIndex;
|
||||
@@ -99,6 +100,7 @@ RawMaterial::RawMaterial (Graphic3d_NameOfMaterial theName, const char* theStrin
|
||||
BSDF.Kd = Graphic3d_Vec3 (0.2f);
|
||||
BSDF.Ks = Graphic3d_Vec4 (0.00784314f, 0.00784314f, 0.00784314f, 0.25f);
|
||||
BSDF.Normalize();
|
||||
|
||||
break;
|
||||
case Graphic3d_NOM_SHINY_PLASTIC:
|
||||
MaterialType = Graphic3d_MATERIAL_ASPECT;
|
||||
@@ -124,6 +126,7 @@ RawMaterial::RawMaterial (Graphic3d_NameOfMaterial theName, const char* theStrin
|
||||
|
||||
BSDF.Kd = Graphic3d_Vec3 (0.2f);
|
||||
BSDF.Ks = Graphic3d_Vec4 (0.6f);
|
||||
|
||||
break;
|
||||
case Graphic3d_NOM_NEON_GNC:
|
||||
MaterialType = Graphic3d_MATERIAL_ASPECT;
|
||||
@@ -221,6 +224,7 @@ RawMaterial::RawMaterial (Graphic3d_NameOfMaterial theName, const char* theStrin
|
||||
Colors[Graphic3d_TOR_EMISSION] = Quantity_Color (Graphic3d_Vec3 (0.0f));
|
||||
|
||||
BSDF.Kd = Graphic3d_Vec3 (0.482353f, 0.482353f, 0.482353f);
|
||||
|
||||
break;
|
||||
case Graphic3d_NOM_SILVER:
|
||||
MaterialType = Graphic3d_MATERIAL_PHYSIC;
|
||||
@@ -261,6 +265,7 @@ RawMaterial::RawMaterial (Graphic3d_NameOfMaterial theName, const char* theStrin
|
||||
|
||||
BSDF.Kd = Graphic3d_Vec3 (0.243137f, 0.243137f, 0.243137f);
|
||||
BSDF.Ks = Graphic3d_Vec4 (0.00392157f, 0.00392157f, 0.00392157f, 0.5f);
|
||||
|
||||
break;
|
||||
case Graphic3d_NOM_CHROME:
|
||||
MaterialType = Graphic3d_MATERIAL_PHYSIC;
|
||||
@@ -418,6 +423,7 @@ RawMaterial::RawMaterial (Graphic3d_NameOfMaterial theName, const char* theStrin
|
||||
Colors[Graphic3d_TOR_EMISSION] = Quantity_Color (Graphic3d_Vec3 (0.0f));
|
||||
break;
|
||||
}
|
||||
PBRMaterial.SetBSDF (BSDF);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -447,8 +453,9 @@ Graphic3d_MaterialAspect::Graphic3d_MaterialAspect (const Graphic3d_NameOfMateri
|
||||
void Graphic3d_MaterialAspect::init (const Graphic3d_NameOfMaterial theName)
|
||||
{
|
||||
const RawMaterial& aMat = THE_MATERIALS[theName];
|
||||
myBSDF = aMat.BSDF;
|
||||
myStringName = aMat.StringName;
|
||||
myBSDF = aMat.BSDF;
|
||||
myPBRMaterial = aMat.PBRMaterial;
|
||||
myStringName = aMat.StringName;
|
||||
myColors[Graphic3d_TOR_AMBIENT] = aMat.Colors[Graphic3d_TOR_AMBIENT];
|
||||
myColors[Graphic3d_TOR_DIFFUSE] = aMat.Colors[Graphic3d_TOR_DIFFUSE];
|
||||
myColors[Graphic3d_TOR_SPECULAR] = aMat.Colors[Graphic3d_TOR_SPECULAR];
|
||||
@@ -499,6 +506,8 @@ void Graphic3d_MaterialAspect::SetColor (const Quantity_Color& theColor)
|
||||
return;
|
||||
}
|
||||
|
||||
myPBRMaterial.SetColor (theColor);
|
||||
|
||||
const RawMaterial& aSrcMat = THE_MATERIALS[myRequestedMaterialName];
|
||||
const Quantity_Color anAmbient((Graphic3d_Vec3 )theColor * aSrcMat.AmbientCoef);
|
||||
const Quantity_Color aDiffuse ((Graphic3d_Vec3 )theColor * aSrcMat.DiffuseCoef);
|
||||
@@ -585,6 +594,7 @@ void Graphic3d_MaterialAspect::SetTransparency (const Standard_ShortReal theValu
|
||||
}
|
||||
|
||||
myTransparencyCoef = theValue;
|
||||
myPBRMaterial.SetAlpha (1.0f - theValue);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#define _Graphic3d_MaterialAspect_HeaderFile
|
||||
|
||||
#include <Graphic3d_BSDF.hxx>
|
||||
#include <Graphic3d_PBRMaterial.hxx>
|
||||
#include <Graphic3d_NameOfMaterial.hxx>
|
||||
#include <Graphic3d_TypeOfMaterial.hxx>
|
||||
#include <Graphic3d_TypeOfReflection.hxx>
|
||||
@@ -170,6 +171,12 @@ public:
|
||||
//! Modifies the BSDF (bidirectional scattering distribution function).
|
||||
void SetBSDF (const Graphic3d_BSDF& theBSDF) { myBSDF = theBSDF; }
|
||||
|
||||
//! Returns physically based representation of material
|
||||
const Graphic3d_PBRMaterial& PBRMaterial () const { return myPBRMaterial; }
|
||||
|
||||
//! Modifies the physically based representation of material
|
||||
void SetPBRMaterial (const Graphic3d_PBRMaterial& thePBRMaterial) { myPBRMaterial = thePBRMaterial; }
|
||||
|
||||
//! Returns TRUE if the reflection mode is active, FALSE otherwise.
|
||||
Standard_Boolean ReflectionMode (const Graphic3d_TypeOfReflection theType) const
|
||||
{
|
||||
@@ -197,6 +204,7 @@ public:
|
||||
return myTransparencyCoef == theOther.myTransparencyCoef
|
||||
&& myRefractionIndex == theOther.myRefractionIndex
|
||||
&& myBSDF == theOther.myBSDF
|
||||
&& myPBRMaterial == theOther.myPBRMaterial
|
||||
&& myShininess == theOther.myShininess
|
||||
&& myColors[Graphic3d_TOR_AMBIENT] == theOther.myColors[Graphic3d_TOR_AMBIENT]
|
||||
&& myColors[Graphic3d_TOR_DIFFUSE] == theOther.myColors[Graphic3d_TOR_DIFFUSE]
|
||||
@@ -247,6 +255,7 @@ private:
|
||||
private:
|
||||
|
||||
Graphic3d_BSDF myBSDF;
|
||||
Graphic3d_PBRMaterial myPBRMaterial;
|
||||
TCollection_AsciiString myStringName;
|
||||
Quantity_Color myColors[Graphic3d_TypeOfReflection_NB];
|
||||
Standard_ShortReal myTransparencyCoef;
|
||||
|
351
src/Graphic3d/Graphic3d_PBRMaterial.cxx
Normal file
351
src/Graphic3d/Graphic3d_PBRMaterial.cxx
Normal file
@@ -0,0 +1,351 @@
|
||||
// Author: Ilya Khramov
|
||||
// Copyright (c) 2019 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.
|
||||
|
||||
#include <Graphic3d_PBRMaterial.hxx>
|
||||
|
||||
#include <Graphic3d_MaterialDefinitionError.hxx>
|
||||
|
||||
#include <limits>
|
||||
|
||||
// =======================================================================
|
||||
// function : RoughnessFromSpecular
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_ShortReal Graphic3d_PBRMaterial::RoughnessFromSpecular (const Quantity_Color& theSpecular,
|
||||
const Standard_Real theShiness)
|
||||
{
|
||||
Standard_Real aRoughnessFactor = 1.0 - theShiness;
|
||||
//Standard_Real aSpecIntens = theSpecular.Light() * theSpecular;
|
||||
const Standard_Real aSpecIntens = theSpecular.Red() * 0.2125
|
||||
+ theSpecular.Green() * 0.7154
|
||||
+ theSpecular.Blue() * 0.0721;
|
||||
if (aSpecIntens < 0.1)
|
||||
{
|
||||
// low specular intensity should produce a rough material even if shininess is high
|
||||
aRoughnessFactor *= (1.0 - aSpecIntens);
|
||||
}
|
||||
return (Standard_ShortReal )aRoughnessFactor;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Constructor
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Graphic3d_PBRMaterial::Graphic3d_PBRMaterial ()
|
||||
: myColor (0.f, 0.f, 0.f, 1.f),
|
||||
myMetallic (0.f),
|
||||
myRoughness (1.f),
|
||||
myEmission (0.f),
|
||||
myIOR (1.5f)
|
||||
{}
|
||||
|
||||
// =======================================================================
|
||||
// function : Constructor
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Graphic3d_PBRMaterial::Graphic3d_PBRMaterial (const Graphic3d_BSDF& theBSDF)
|
||||
{
|
||||
SetBSDF (theBSDF);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetMetallic
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_PBRMaterial::SetMetallic (Standard_ShortReal theMetallic)
|
||||
{
|
||||
Graphic3d_MaterialDefinitionError_Raise_if (theMetallic < 0.f || theMetallic > 1.f,
|
||||
"'metallic' parameter of PBR material must be in range [0, 1]")
|
||||
myMetallic = theMetallic;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Roughness
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_ShortReal Graphic3d_PBRMaterial::Roughness (Standard_ShortReal theNormalizedRoughness)
|
||||
{
|
||||
return theNormalizedRoughness * (1.f - MinRoughness()) + MinRoughness();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetRoughness
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_PBRMaterial::SetRoughness (Standard_ShortReal theRoughness)
|
||||
{
|
||||
Graphic3d_MaterialDefinitionError_Raise_if (theRoughness < 0.f || theRoughness > 1.f,
|
||||
"'roughness' parameter of PBR material must be in range [0, 1]")
|
||||
myRoughness = theRoughness;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetIOR
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_PBRMaterial::SetIOR (Standard_ShortReal theIOR)
|
||||
{
|
||||
Graphic3d_MaterialDefinitionError_Raise_if (theIOR < 1.f || theIOR > 3.f,
|
||||
"'IOR' parameter of PBR material must be in range [1, 3]")
|
||||
myIOR = theIOR;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetColor
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_PBRMaterial::SetColor (const Quantity_ColorRGBA& theColor)
|
||||
{
|
||||
myColor.SetRGB (theColor.GetRGB());
|
||||
SetAlpha (theColor.Alpha());
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetColor
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_PBRMaterial::SetColor (const Quantity_Color& theColor)
|
||||
{
|
||||
myColor.SetRGB (theColor);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetAlpha
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_PBRMaterial::SetAlpha (Standard_ShortReal theAlpha)
|
||||
{
|
||||
Graphic3d_MaterialDefinitionError_Raise_if (theAlpha < 0.f || theAlpha > 1.f,
|
||||
"'alpha' parameter of PBR material must be in range [0, 1]")
|
||||
myColor.SetAlpha (theAlpha);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetEmission
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_PBRMaterial::SetEmission (const Graphic3d_Vec3& theEmission)
|
||||
{
|
||||
Graphic3d_MaterialDefinitionError_Raise_if (theEmission.r() < 0.f
|
||||
|| theEmission.g() < 0.f
|
||||
|| theEmission.b() < 0.f,
|
||||
"all components of 'emission' parameter of PBR material must be greater than 0")
|
||||
myEmission = theEmission;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetBSDF
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_PBRMaterial::SetBSDF (const Graphic3d_BSDF& theBSDF)
|
||||
{
|
||||
SetEmission (theBSDF.Le);
|
||||
|
||||
if (theBSDF.Absorption != Graphic3d_Vec4(0.f))
|
||||
{
|
||||
SetMetallic (0.f);
|
||||
SetColor (Quantity_Color (theBSDF.Absorption.rgb()));
|
||||
if (theBSDF.FresnelCoat.FresnelType() == Graphic3d_FM_DIELECTRIC)
|
||||
{
|
||||
SetIOR (theBSDF.FresnelCoat.Serialize().y());
|
||||
SetRoughness (0.f);
|
||||
SetAlpha (theBSDF.Absorption.a() * 4.f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (theBSDF.FresnelBase.FresnelType() == Graphic3d_FM_CONSTANT
|
||||
&& theBSDF.Kt != Graphic3d_Vec3(0.f))
|
||||
{
|
||||
SetIOR (1.f);
|
||||
SetRoughness (1.f);
|
||||
SetMetallic (0.f);
|
||||
SetColor (Quantity_Color (theBSDF.Kt));
|
||||
SetAlpha (1.f - (theBSDF.Kt.r() + theBSDF.Kt.g() + theBSDF.Kt.b()) / 3.f);
|
||||
return;
|
||||
}
|
||||
|
||||
SetRoughness(sqrtf (theBSDF.Ks.w()));
|
||||
if (theBSDF.FresnelBase.FresnelType() == Graphic3d_FM_DIELECTRIC
|
||||
|| theBSDF.FresnelBase.FresnelType() == Graphic3d_FM_CONSTANT)
|
||||
{
|
||||
SetIOR (1.5f);
|
||||
SetColor (Quantity_Color (theBSDF.Kd));
|
||||
SetMetallic (0.f);
|
||||
}
|
||||
else if (theBSDF.FresnelBase.FresnelType() == Graphic3d_FM_SCHLICK)
|
||||
{
|
||||
SetColor (Quantity_Color (theBSDF.FresnelBase.Serialize().rgb()));
|
||||
SetMetallic (1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetColor (Quantity_Color (theBSDF.Ks.rgb()));
|
||||
SetMetallic (1.f);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GenerateEnvLUT
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_PBRMaterial::GenerateEnvLUT (const Handle(Image_PixMap)& theLUT,
|
||||
unsigned int theNbIntegralSamples)
|
||||
{
|
||||
if (theLUT->Format() != Image_Format_RGF)
|
||||
{
|
||||
throw Standard_ProgramError("LUT pix map format for PBR LUT generation must be Image_Format_RGF");
|
||||
}
|
||||
|
||||
for (unsigned int y = 0; y < theLUT->SizeY(); ++y)
|
||||
{
|
||||
Standard_ShortReal aRoughness = Roughness(y / Standard_ShortReal(theLUT->SizeY() - 1));
|
||||
|
||||
for (unsigned int x = 0; x < theLUT->SizeX(); ++x)
|
||||
{
|
||||
Standard_ShortReal aCosV = x / Standard_ShortReal(theLUT->SizeX() - 1);
|
||||
Graphic3d_Vec3 aView = lutGenView (aCosV);
|
||||
unsigned int aCount = 0;
|
||||
Graphic3d_Vec2 aResult = Graphic3d_Vec2 (0.f);
|
||||
for (unsigned int i = 0; i < theNbIntegralSamples; ++i)
|
||||
{
|
||||
Graphic3d_Vec2 aHammersleyPoint = lutGenHammersley (i, theNbIntegralSamples);
|
||||
Graphic3d_Vec3 aHalf = lutGenImportanceSample (aHammersleyPoint, aRoughness);
|
||||
Graphic3d_Vec3 aLight = lutGenReflect (aView, aHalf);
|
||||
if (aLight.z() >= 0.f)
|
||||
{
|
||||
++aCount;
|
||||
Standard_ShortReal aCosVH = aView.Dot (aHalf);
|
||||
Standard_ShortReal aGeometryFactor = lutGenGeometryFactor (aLight.z(),
|
||||
aCosV,
|
||||
aRoughness);
|
||||
Standard_ShortReal anIntermediateResult = 1.f - aCosVH;
|
||||
anIntermediateResult *= anIntermediateResult;
|
||||
anIntermediateResult *= anIntermediateResult;
|
||||
anIntermediateResult *= 1.f - aCosVH;
|
||||
|
||||
aResult.x() += aGeometryFactor * (aCosVH / aHalf.z()) * (1.f - anIntermediateResult);
|
||||
aResult.y() += aGeometryFactor * (aCosVH / aHalf.z()) * anIntermediateResult;
|
||||
}
|
||||
}
|
||||
|
||||
aResult = aResult / Standard_ShortReal(theNbIntegralSamples);
|
||||
theLUT->ChangeValue<Graphic3d_Vec2> (theLUT->SizeY() - 1 - y, x) = aResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SpecIBLMapSamplesFactor
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_ShortReal Graphic3d_PBRMaterial::SpecIBLMapSamplesFactor (Standard_ShortReal theProbability,
|
||||
Standard_ShortReal theRoughness)
|
||||
{
|
||||
return acosf (lutGenImportanceSampleCosTheta (theProbability, theRoughness)) * 2.f / Standard_ShortReal(M_PI);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : lutGenGeometryFactor
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_ShortReal Graphic3d_PBRMaterial::lutGenGeometryFactor (Standard_ShortReal theCosL,
|
||||
Standard_ShortReal theCosV,
|
||||
Standard_ShortReal theRoughness)
|
||||
{
|
||||
Standard_ShortReal aK = theRoughness * theRoughness * 0.5f;
|
||||
|
||||
Standard_ShortReal aGeometryFactor = theCosL;
|
||||
aGeometryFactor /= theCosL * (1.f - aK) + aK;
|
||||
aGeometryFactor /= theCosV * (1.f - aK) + aK;
|
||||
|
||||
return aGeometryFactor;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : lutGenHammersley
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Graphic3d_Vec2 Graphic3d_PBRMaterial::lutGenHammersley (unsigned int theNumber, unsigned int theCount)
|
||||
{
|
||||
Standard_ShortReal aPhi2 = 0.f;
|
||||
for (unsigned int i = 0; i < sizeof(unsigned int) * 8; ++i)
|
||||
{
|
||||
if ((theNumber >> i) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
aPhi2 += ((theNumber >> i) & 1) / Standard_ShortReal(1 << (i + 1));
|
||||
}
|
||||
|
||||
return Graphic3d_Vec2(theNumber / Standard_ShortReal(theCount), aPhi2);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : lutGenImportanceSampleCosTheta
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_ShortReal Graphic3d_PBRMaterial::lutGenImportanceSampleCosTheta (Standard_ShortReal theHammersleyPointComponent,
|
||||
Standard_ShortReal theRoughness)
|
||||
{
|
||||
Standard_ShortReal aQuadRoughness = theRoughness * theRoughness;
|
||||
aQuadRoughness *= aQuadRoughness;
|
||||
|
||||
Standard_ShortReal aTmp = 1.f + (aQuadRoughness - 1.f) * theHammersleyPointComponent;
|
||||
|
||||
if (aTmp != 0.f)
|
||||
{
|
||||
return sqrtf ((1.f - theHammersleyPointComponent) / aTmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : lutGenImportanceSample
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Graphic3d_Vec3 Graphic3d_PBRMaterial::lutGenImportanceSample (const Graphic3d_Vec2 &theHammerslayPoint,
|
||||
Standard_ShortReal theRoughness)
|
||||
{
|
||||
Standard_ShortReal aPhi = 2.f * Standard_ShortReal(M_PI) * theHammerslayPoint.y();
|
||||
|
||||
Standard_ShortReal aCosTheta = lutGenImportanceSampleCosTheta (theHammerslayPoint.x(), theRoughness);
|
||||
Standard_ShortReal aSinTheta = sqrtf (1.f - aCosTheta * aCosTheta);
|
||||
|
||||
return Graphic3d_Vec3(aSinTheta * cosf (aPhi),
|
||||
aSinTheta * sinf (aPhi),
|
||||
aCosTheta);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : lutGenView
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Graphic3d_Vec3 Graphic3d_PBRMaterial::lutGenView (Standard_ShortReal theCosV)
|
||||
{
|
||||
return Graphic3d_Vec3(0.f, sqrtf(1.f - theCosV * theCosV), theCosV);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : lutGenReflect
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Graphic3d_Vec3 Graphic3d_PBRMaterial::lutGenReflect (const Graphic3d_Vec3 &theVector,
|
||||
const Graphic3d_Vec3 &theAxis)
|
||||
{
|
||||
return theAxis * theAxis.Dot(theVector) * 2.f - theVector;
|
||||
}
|
198
src/Graphic3d/Graphic3d_PBRMaterial.hxx
Normal file
198
src/Graphic3d/Graphic3d_PBRMaterial.hxx
Normal file
@@ -0,0 +1,198 @@
|
||||
// Author: Ilya Khramov
|
||||
// Copyright (c) 2019 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_PBRMaterial_HeaderFile
|
||||
#define _Graphic3d_PBRMaterial_HeaderFile
|
||||
|
||||
#include <Image_PixMap.hxx>
|
||||
#include <Graphic3d_BSDF.hxx>
|
||||
#include <Graphic3d_Vec2.hxx>
|
||||
#include <Graphic3d_Vec3.hxx>
|
||||
#include <Graphic3d_Vec4.hxx>
|
||||
#include <Quantity_Color.hxx>
|
||||
|
||||
//! Class implementing Metallic-Roughness physically based material definition
|
||||
class Graphic3d_PBRMaterial
|
||||
{
|
||||
public:
|
||||
|
||||
//! Creates new physically based material in Metallic-Roughness system.
|
||||
//! 'metallic' parameter is 0 by default.
|
||||
//! 'roughness' parameter is 1 by default.
|
||||
//! 'color' parameter is (0, 0, 0) by default.
|
||||
//! 'alpha' parameter is 1 by default.
|
||||
//! 'IOR' parameter is 1.5 by default.
|
||||
//! 'emission' parameter is (0, 0, 0) by default.
|
||||
Standard_EXPORT Graphic3d_PBRMaterial();
|
||||
|
||||
//! Creates new physically based material in Metallic-Roughness system from Graphic3d_BSDF.
|
||||
Standard_EXPORT Graphic3d_PBRMaterial (const Graphic3d_BSDF& theBSDF);
|
||||
|
||||
//! Returns material's metallic coefficient in [0, 1] range.
|
||||
//! 1 for metals and 0 for dielectrics.
|
||||
//! It is preferable to be exactly 0 or 1. Average values are needed for textures mixing in shader.
|
||||
Standard_ShortReal Metallic() const { return myMetallic; }
|
||||
|
||||
//! Modifies metallic coefficient of material in [0, 1] range.
|
||||
Standard_EXPORT void SetMetallic (Standard_ShortReal theMetallic);
|
||||
|
||||
//! Maps roughness from [0, 1] to [MinRoughness, 1] for calculations.
|
||||
Standard_EXPORT static Standard_ShortReal Roughness(Standard_ShortReal theNormalizedRoughness);
|
||||
|
||||
//! Returns real value of roughness in [MinRoughness, 1] range for calculations.
|
||||
Standard_ShortReal Roughness() const { return Roughness(myRoughness); }
|
||||
|
||||
//! Returns roughness mapping parameter in [0, 1] range.
|
||||
//! Roughness is defined in [0, 1] for handful material settings
|
||||
//! and is mapped to [MinRoughness, 1] for calculations.
|
||||
Standard_ShortReal NormalizedRoughness() const { return myRoughness; }
|
||||
|
||||
//! Modifies roughness coefficient of material in [0, 1] range.
|
||||
Standard_EXPORT void SetRoughness (Standard_ShortReal theRoughness);
|
||||
|
||||
//! Returns index of refraction in [1, 3] range.
|
||||
Standard_ShortReal IOR() const { return myIOR; }
|
||||
|
||||
//! Modifies index of refraction in [1, 3] range.
|
||||
//! In practice affects only on non-metal materials reflection possibilities.
|
||||
Standard_EXPORT void SetIOR (Standard_ShortReal theIOR);
|
||||
|
||||
//! Returns albedo color with alpha component of material.
|
||||
const Quantity_ColorRGBA& Color() const { return myColor; }
|
||||
|
||||
//! Modifies albedo color with alpha component.
|
||||
Standard_EXPORT void SetColor (const Quantity_ColorRGBA& theColor);
|
||||
|
||||
//! Modifies only albedo color.
|
||||
Standard_EXPORT void SetColor (const Quantity_Color& theColor);
|
||||
|
||||
//! Returns alpha component in range [0, 1].
|
||||
Standard_ShortReal Alpha() const { return myColor.Alpha(); };
|
||||
|
||||
//! Modifies alpha component.
|
||||
Standard_EXPORT void SetAlpha (Standard_ShortReal theAlpha);
|
||||
|
||||
//! Returns light intensity emitted by material.
|
||||
//! Values are greater or equal 0.
|
||||
Graphic3d_Vec3 Emission() const { return myEmission; }
|
||||
|
||||
//! Modifies light intensity emitted by material.
|
||||
Standard_EXPORT void SetEmission (const Graphic3d_Vec3& theEmission);
|
||||
|
||||
//! Generates material in Metallic-Roughness system from Graphic3d_BSDF.
|
||||
Standard_EXPORT void SetBSDF (const Graphic3d_BSDF& theBSDF);
|
||||
|
||||
public:
|
||||
|
||||
//! PBR materials comparison operator.
|
||||
Standard_Boolean operator== (const Graphic3d_PBRMaterial& theOther) const
|
||||
{
|
||||
return (myMetallic == theOther.myMetallic)
|
||||
&& (myRoughness == theOther.myRoughness)
|
||||
&& (myIOR == theOther.myIOR)
|
||||
&& (myColor == theOther.myColor)
|
||||
&& (myEmission == theOther.myEmission);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Generates 2D look up table of scale and bias for fresnell zero coefficient.
|
||||
//! It is needed for calculation reflectance part of environment lighting.
|
||||
//! @param [out] theLUT table storage (must be Image_Format_RGF).
|
||||
//! @param [in] theIntegralSamplesCount number of importance samples in hemisphere integral calculation for every table item.
|
||||
Standard_EXPORT static void GenerateEnvLUT (const Handle(Image_PixMap)& theLUT,
|
||||
unsigned int theNbIntegralSamples = 1024);
|
||||
|
||||
//! Compute material roughness from common material (specular color + shininess).
|
||||
//! @param theSpecular [in] specular color
|
||||
//! @param theShiness [in] normalized shininess coefficient within [0..1] range
|
||||
//! @return roughness within [0..1] range
|
||||
Standard_EXPORT static Standard_ShortReal RoughnessFromSpecular (const Quantity_Color& theSpecular,
|
||||
const Standard_Real theShiness);
|
||||
|
||||
//! Compute material metallicity from common material (specular color).
|
||||
//! @param theSpecular [in] specular color
|
||||
//! @return metallicity within [0..1] range
|
||||
static Standard_ShortReal MetallicFromSpecular (const Quantity_Color& theSpecular)
|
||||
{
|
||||
return ((Graphic3d_Vec3 )theSpecular).maxComp();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Roughness cannot be 0 in real calculations, so it returns minimal achievable level of roughness in practice
|
||||
static Standard_ShortReal MinRoughness() { return 0.01f; }
|
||||
|
||||
public:
|
||||
|
||||
//! Shows how much times less samples can be used in certain roughness value specular IBL map generation
|
||||
//! in compare with samples number for map with roughness of 1.
|
||||
//! Specular IBL maps with less roughness values have higher resolution but require less samples for the same quality of baking.
|
||||
//! So that reducing samples number is good strategy to improve performance of baking.
|
||||
//! The samples number for specular IBL map with roughness of 1 (the maximum possible samples number) is expected to be defined as baking parameter.
|
||||
//! Samples number for other roughness values can be calculated by multiplication origin samples number by this factor.
|
||||
//! @param theProbability value from 0 to 1 controlling strength of samples reducing.
|
||||
//! Bigger values result in slower reduction to provide better quality but worse performance.
|
||||
//! Value of 1 doesn't affect at all so that 1 will be returned (it can be used to disable reduction strategy).
|
||||
//! @param theRoughness roughness value of current generated specular IBL map (from 0 to 1).
|
||||
//! @return factor to calculate number of samples for current specular IBL map baking.
|
||||
//! Be aware! It has no obligation to return 1 in case of roughness of 1.
|
||||
//! Be aware! It produces poor quality with small number of origin samples. In that case it is recommended to be disabled.
|
||||
Standard_EXPORT static Standard_ShortReal SpecIBLMapSamplesFactor (Standard_ShortReal theProbability,
|
||||
Standard_ShortReal theRoughness);
|
||||
|
||||
private:
|
||||
|
||||
//! Calculates geometry factor of Cook-Torrance BRDF using Smith formula.
|
||||
static Standard_ShortReal lutGenGeometryFactor (Standard_ShortReal theCosL,
|
||||
Standard_ShortReal theCosV,
|
||||
Standard_ShortReal theRoughness);
|
||||
|
||||
//! Generates quasi-random point from Hammersley set.
|
||||
//! @param theNumber number of point
|
||||
//! @param theCount size of Hammersley set
|
||||
static Graphic3d_Vec2 lutGenHammersley (unsigned int theNumber, unsigned int theCount);
|
||||
|
||||
//! Generates only cosine theta of direction in spherical coordinates system
|
||||
//! according to micro facet distribution function from Cook-Torrance BRDF.
|
||||
static Standard_ShortReal lutGenImportanceSampleCosTheta (Standard_ShortReal theHammerslayPointComponent,
|
||||
Standard_ShortReal theRoughness);
|
||||
|
||||
//! Generates direction using point from Hammersley set
|
||||
//! according to micro facet distribution function from Cook-Torrance BRDF.
|
||||
static Graphic3d_Vec3 lutGenImportanceSample (const Graphic3d_Vec2 &theHammerslayPoint,
|
||||
Standard_ShortReal theRoughness);
|
||||
|
||||
//! Generates vector using cosine of angle between up vector (normal in hemisphere)
|
||||
//! and desired vector.
|
||||
//! x component for resulting vector will be zero.
|
||||
static Graphic3d_Vec3 lutGenView (Standard_ShortReal theCosV);
|
||||
|
||||
//! Returns reflected vector according axis.
|
||||
//! @param theVector vector is needed to be reflected.
|
||||
//! @param theAxis axis of reflection.
|
||||
static Graphic3d_Vec3 lutGenReflect (const Graphic3d_Vec3 &theVector,
|
||||
const Graphic3d_Vec3 &theAxis);
|
||||
|
||||
private:
|
||||
|
||||
Quantity_ColorRGBA myColor; //!< albedo color with alpha component [0, 1]
|
||||
Standard_ShortReal myMetallic; //!< metallic coefficient of material [0, 1]
|
||||
Standard_ShortReal myRoughness; //!< roughness coefficient of material [0, 1]
|
||||
Graphic3d_Vec3 myEmission; //!< light intensity emitted by material [>= 0]
|
||||
Standard_ShortReal myIOR; //!< index of refraction [1, 3]
|
||||
|
||||
};
|
||||
|
||||
#endif // _Graphic3d_PBRMaterial_HeaderFile
|
@@ -95,6 +95,13 @@ public:
|
||||
: Method (Graphic3d_RM_RASTERIZATION),
|
||||
TransparencyMethod (Graphic3d_RTM_BLEND_UNORDERED),
|
||||
LineFeather (1.0f),
|
||||
// PBR parameters
|
||||
PbrEnvPow2Size (9),
|
||||
PbrEnvSpecMapNbLevels (6),
|
||||
PbrEnvBakingDiffNbSamples (1024),
|
||||
PbrEnvBakingSpecNbSamples (256),
|
||||
PbrEnvBakingProbability (0.99f),
|
||||
//
|
||||
OitDepthFactor (0.0f),
|
||||
NbMsaaSamples (0),
|
||||
RenderResolutionScale (1.0f),
|
||||
@@ -171,6 +178,15 @@ public:
|
||||
Graphic3d_RenderTransparentMethod TransparencyMethod; //!< specifies rendering method for transparent graphics
|
||||
Standard_ShortReal LineFeather; //!< line feater width in pixels (> 0.0), 1.0 by default;
|
||||
//! high values produce blurred results, small values produce sharp (aliased) edges
|
||||
|
||||
Standard_Integer PbrEnvPow2Size; //!< size of IBL maps side can be calculated as 2^PbrEnvPow2Size (> 0), 9 by default
|
||||
Standard_Integer PbrEnvSpecMapNbLevels; //!< number of levels used in specular IBL map (> 1), 6 by default
|
||||
Standard_Integer PbrEnvBakingDiffNbSamples; //!< number of samples used in Monte-Carlo integration during diffuse IBL map's
|
||||
//! spherical harmonics coefficients generation (> 0), 1024 by default
|
||||
Standard_Integer PbrEnvBakingSpecNbSamples; //!< number of samples used in Monte-Carlo integration during specular IBL map's generation (> 0), 256 by default
|
||||
Standard_ShortReal PbrEnvBakingProbability; //!< controls strength of samples reducing strategy during specular IBL map's generation
|
||||
//! (see 'SpecIBLMapSamplesFactor' function for detail explanation) [0.0, 1.0], 0.99 by default
|
||||
|
||||
Standard_ShortReal OitDepthFactor; //!< scalar factor [0-1] controlling influence of depth of a fragment to its final coverage
|
||||
Standard_Integer NbMsaaSamples; //!< number of MSAA samples (should be within 0..GL_MAX_SAMPLES, power-of-two number), 0 by default
|
||||
Standard_ShortReal RenderResolutionScale; //!< rendering resolution scale factor, 1 by default;
|
||||
|
@@ -82,7 +82,8 @@ Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
|
||||
myNbFragOutputs (THE_NB_FRAG_OUTPUTS),
|
||||
myHasDefSampler (true),
|
||||
myHasAlphaTest (false),
|
||||
myHasWeightOitOutput (false)
|
||||
myHasWeightOitOutput (false),
|
||||
myIsPBR (false)
|
||||
{
|
||||
myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_")
|
||||
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER));
|
||||
|
@@ -151,6 +151,13 @@ public:
|
||||
//! Note that weighted OIT also requires at least 2 Fragment Outputs (color + coverage).
|
||||
void SetWeightOitOutput (Standard_Boolean theOutput) { myHasWeightOitOutput = theOutput; }
|
||||
|
||||
//! Return TRUE if standard program header should define functions and variables used in PBR pipeline.
|
||||
//! FALSE by default
|
||||
Standard_Boolean IsPBR() const { return myIsPBR; }
|
||||
|
||||
//! Sets whether standard program header should define functions and variables used in PBR pipeline.
|
||||
void SetPBR (Standard_Boolean theIsPBR) { myIsPBR = theIsPBR; }
|
||||
|
||||
//! Pushes custom uniform variable to the program.
|
||||
//! The list of pushed variables is automatically cleared after applying to GLSL program.
|
||||
//! Thus after program recreation even unchanged uniforms should be pushed anew.
|
||||
@@ -204,6 +211,7 @@ private:
|
||||
Standard_Boolean myHasDefSampler; //!< flag indicating that program defines default texture sampler occSampler0
|
||||
Standard_Boolean myHasAlphaTest; //!< flag indicating that Fragment Shader performs alpha test
|
||||
Standard_Boolean myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
|
||||
Standard_Boolean myIsPBR; //!< flag indicating that program defines functions and variables used in PBR pipeline
|
||||
|
||||
};
|
||||
|
||||
|
@@ -29,6 +29,8 @@ Graphic3d_TextureParams::Graphic3d_TextureParams()
|
||||
myFilter (Graphic3d_TOTF_NEAREST),
|
||||
myAnisoLevel (Graphic3d_LOTA_OFF),
|
||||
myGenMode (Graphic3d_TOTM_MANUAL),
|
||||
myBaseLevel (0),
|
||||
myMaxLevel (1000),
|
||||
myRotAngle (0.0f),
|
||||
myToModulate (Standard_False),
|
||||
myToRepeat (Standard_False)
|
||||
|
@@ -106,6 +106,21 @@ public:
|
||||
//! Setup texture coordinates generation mode.
|
||||
Standard_EXPORT void SetGenMode (const Graphic3d_TypeOfTextureMode theMode, const Graphic3d_Vec4 thePlaneS, const Graphic3d_Vec4 thePlaneT);
|
||||
|
||||
//! @return base texture mipmap level; 0 by default.
|
||||
Standard_Integer BaseLevel() const { return myBaseLevel; }
|
||||
|
||||
//! @return maximum texture mipmap array level; 1000 by default.
|
||||
Standard_Integer MaxLevel() const { return myMaxLevel; }
|
||||
|
||||
//! Setups texture mipmap array levels range.
|
||||
//! The lowest value will be the base level.
|
||||
//! The remaining one will be the maximum level.
|
||||
void SetLevelsRange (Standard_Integer theFirstLevel, Standard_Integer theSecondLevel = 0)
|
||||
{
|
||||
myMaxLevel = theFirstLevel > theSecondLevel ? theFirstLevel : theSecondLevel;
|
||||
myBaseLevel = theFirstLevel > theSecondLevel ? theSecondLevel : theFirstLevel;
|
||||
}
|
||||
|
||||
//! Return modification counter of parameters related to sampler state.
|
||||
unsigned int SamplerRevision() const { return mySamplerRevision; }
|
||||
|
||||
@@ -125,6 +140,8 @@ private:
|
||||
Graphic3d_TypeOfTextureFilter myFilter; //!< texture filter, Graphic3d_TOTF_NEAREST by default
|
||||
Graphic3d_LevelOfTextureAnisotropy myAnisoLevel; //!< level of anisotropy filter, Graphic3d_LOTA_OFF by default
|
||||
Graphic3d_TypeOfTextureMode myGenMode; //!< texture coordinates generation mode, Graphic3d_TOTM_MANUAL by default
|
||||
Standard_Integer myBaseLevel; //!< base texture mipmap level (0 by default)
|
||||
Standard_Integer myMaxLevel; //!< maximum texture mipmap array level (1000 by default)
|
||||
Standard_ShortReal myRotAngle; //!< texture coordinates rotation angle in degrees, 0 by default
|
||||
Standard_Boolean myToModulate; //!< flag to modulate texture with material color, FALSE by default
|
||||
Standard_Boolean myToRepeat; //!< flag to repeat (true) or wrap (false) texture coordinates out of [0,1] range
|
||||
|
@@ -25,6 +25,7 @@ enum Graphic3d_TypeOfLimit
|
||||
Graphic3d_TypeOfLimit_MaxViewDumpSizeY, //!< maximum height for image dump
|
||||
Graphic3d_TypeOfLimit_MaxCombinedTextureUnits, //!< maximum number of combined texture units for multitexturing
|
||||
Graphic3d_TypeOfLimit_MaxMsaa, //!< maximum number of MSAA samples
|
||||
Graphic3d_TypeOfLimit_HasPBR, //!< indicates whether PBR metallic-roughness shading model is supported
|
||||
Graphic3d_TypeOfLimit_HasRayTracing, //!< indicates whether ray tracing is supported
|
||||
Graphic3d_TypeOfLimit_HasRayTracingTextures, //!< indicates whether ray tracing textures are supported
|
||||
Graphic3d_TypeOfLimit_HasRayTracingAdaptiveSampling, //!< indicates whether adaptive screen sampling is supported
|
||||
|
@@ -46,6 +46,12 @@ enum Graphic3d_TypeOfShadingModel
|
||||
//! Shading model requires normals to be defined within vertex attributes.
|
||||
Graphic3d_TOSM_FRAGMENT,
|
||||
|
||||
//! Metallic-roughness physically based (PBR) illumination system.
|
||||
Graphic3d_TOSM_PBR,
|
||||
|
||||
//! Same as Graphic3d_TOSM_PBR but using flat per-triangle normal.
|
||||
Graphic3d_TOSM_PBR_FACET,
|
||||
|
||||
// obsolete aliases
|
||||
Graphic3d_TOSM_NONE = Graphic3d_TOSM_UNLIT,
|
||||
V3d_COLOR = Graphic3d_TOSM_NONE,
|
||||
@@ -57,7 +63,7 @@ enum Graphic3d_TypeOfShadingModel
|
||||
enum
|
||||
{
|
||||
//! Auxiliary value defining the overall number of values in enumeration Graphic3d_TypeOfShadingModel
|
||||
Graphic3d_TypeOfShadingModel_NB = Graphic3d_TOSM_FRAGMENT + 1
|
||||
Graphic3d_TypeOfShadingModel_NB = Graphic3d_TOSM_PBR_FACET + 1
|
||||
};
|
||||
|
||||
#endif // _Graphic3d_TypeOfShadingModel_HeaderFile
|
||||
|
@@ -77,8 +77,9 @@ namespace IMeshData
|
||||
const size_t MEMORY_BLOCK_SIZE_HUGE = 512 * 1024;
|
||||
#endif
|
||||
|
||||
typedef IMeshData_Edge* IEdgePtr;
|
||||
typedef IMeshData_Face* IFacePtr;
|
||||
typedef IMeshData_Edge* IEdgePtr;
|
||||
typedef IMeshData_PCurve* IPCurvePtr;
|
||||
typedef IMeshData_Face* IFacePtr;
|
||||
|
||||
typedef Handle(IMeshData_Edge) IEdgeHandle;
|
||||
typedef Handle(IMeshData_Wire) IWireHandle;
|
||||
|
@@ -266,6 +266,31 @@ public:
|
||||
|
||||
};
|
||||
|
||||
//! POD structure for packed float RG color value (2 floats)
|
||||
struct Image_ColorRGF
|
||||
{
|
||||
//! Component type.
|
||||
typedef Standard_ShortReal ComponentType_t;
|
||||
|
||||
//! Returns the number of components.
|
||||
static Standard_Integer Length() { return 2; }
|
||||
|
||||
//! Alias to 1st component (red intensity).
|
||||
Standard_ShortReal r() const { return v[0]; }
|
||||
|
||||
//! Alias to 2nd component (green intensity).
|
||||
Standard_ShortReal g() const { return v[1]; }
|
||||
|
||||
//! Alias to 1st component (red intensity).
|
||||
Standard_ShortReal& r() { return v[0]; }
|
||||
|
||||
//! Alias to 2nd component (green intensity).
|
||||
Standard_ShortReal& g() { return v[1]; }
|
||||
|
||||
public:
|
||||
Standard_ShortReal v[2];
|
||||
};
|
||||
|
||||
//! POD structure for packed float RGB color value (3 floats)
|
||||
struct Image_ColorRGBF
|
||||
{
|
||||
|
@@ -28,6 +28,7 @@ enum Image_Format
|
||||
Image_Format_BGRA, //!< same as RGBA but with different components order
|
||||
Image_Format_GrayF, //!< 1 float (4-bytes) per pixel (1-component plane), intensity of the color
|
||||
Image_Format_AlphaF, //!< 1 float (4-bytes) per pixel (1-component plane), transparency
|
||||
Image_Format_RGF, //!< 2 floats (8-bytes) RG image plane
|
||||
Image_Format_RGBF, //!< 3 floats (12-bytes) RGB image plane
|
||||
Image_Format_BGRF, //!< same as RGBF but with different components order
|
||||
Image_Format_RGBAF, //!< 4 floats (16-bytes) RGBA image plane
|
||||
|
@@ -47,6 +47,8 @@ Standard_Size Image_PixMap::SizePixelBytes (const Image_Format thePixelFormat)
|
||||
case Image_Format_GrayF:
|
||||
case Image_Format_AlphaF:
|
||||
return sizeof(float);
|
||||
case Image_Format_RGF:
|
||||
return sizeof(float) * 2;
|
||||
case Image_Format_RGBAF:
|
||||
case Image_Format_BGRAF:
|
||||
return sizeof(float) * 4;
|
||||
@@ -214,6 +216,11 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
|
||||
const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
|
||||
return Quantity_ColorRGBA (NCollection_Vec4<float> (1.0f, 1.0f, 1.0f, aPixel));
|
||||
}
|
||||
case Image_Format_RGF:
|
||||
{
|
||||
const Image_ColorRGF& aPixel = Value<Image_ColorRGF> (theY, theX);
|
||||
return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), 0.0f, 1.0f));
|
||||
}
|
||||
case Image_Format_RGBAF:
|
||||
{
|
||||
const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
|
||||
@@ -339,6 +346,13 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
|
||||
ChangeValue<Standard_ShortReal> (theY, theX) = aColor.a();
|
||||
return;
|
||||
}
|
||||
case Image_Format_RGF:
|
||||
{
|
||||
Image_ColorRGF& aPixel = ChangeValue<Image_ColorRGF> (theY, theX);
|
||||
aPixel.r() = aColor.r();
|
||||
aPixel.g() = aColor.g();
|
||||
return;
|
||||
}
|
||||
case Image_Format_RGBAF:
|
||||
{
|
||||
Image_ColorRGBAF& aPixel = ChangeValue<Image_ColorRGBAF> (theY, theX);
|
||||
|
@@ -92,6 +92,7 @@ int Media_Frame::FormatOcct2FFmpeg (Image_Format theFormat)
|
||||
return AV_PIX_FMT_GRAY8;
|
||||
case Image_Format_GrayF:
|
||||
case Image_Format_AlphaF:
|
||||
case Image_Format_RGF:
|
||||
case Image_Format_RGBAF:
|
||||
case Image_Format_RGBF:
|
||||
case Image_Format_BGRAF:
|
||||
|
@@ -257,7 +257,7 @@ Standard_Boolean Message_MsgFile::LoadFile (const Standard_CString theFileName)
|
||||
{
|
||||
// Reverse the bytes throughout the buffer
|
||||
const Standard_ExtCharacter* const anEnd =
|
||||
reinterpret_cast<const Standard_ExtCharacter* const>(&anMsgBuffer[aFileSize]);
|
||||
reinterpret_cast<const Standard_ExtCharacter*>(&anMsgBuffer[aFileSize]);
|
||||
|
||||
for (Standard_ExtCharacter* aPtr = aUnicodeBuffer; aPtr < anEnd; aPtr++)
|
||||
{
|
||||
|
@@ -31,6 +31,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <Standard_WarningDisableFunctionCast.hxx>
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(_WIN32) && !defined(OCCT_UWP)
|
||||
|
@@ -189,6 +189,8 @@ void OSD_SharedLibrary::Destroy() {
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
#include <TCollection_ExtendedString.hxx>
|
||||
|
||||
#include <Standard_WarningDisableFunctionCast.hxx>
|
||||
|
||||
static DWORD lastDLLError;
|
||||
|
||||
static wchar_t errMsg[1024];
|
||||
|
@@ -699,12 +699,13 @@ retry:
|
||||
if (retVal || (!retVal && GetLastError() == ERROR_ALREADY_EXISTS))
|
||||
{
|
||||
size_t anOldDirLength;
|
||||
StringCchLengthW (oldDir, sizeof(oldDir) / sizeof(oldDir[0]), &anOldDirLength);
|
||||
StringCchLengthW (oldDir, MAX_PATH, &anOldDirLength);
|
||||
const size_t aNameLength = anOldDirLength + WILD_CARD_LEN + sizeof (L'\x00');
|
||||
if ((pFD = (WIN32_FIND_DATAW* )HeapAlloc (hHeap, 0, sizeof(WIN32_FIND_DATAW))) != NULL
|
||||
&& (pName = (wchar_t* )HeapAlloc (hHeap, 0, anOldDirLength + WILD_CARD_LEN + sizeof(L'\x00'))) != NULL)
|
||||
&& (pName = (wchar_t* )HeapAlloc (hHeap, 0, aNameLength)) != NULL)
|
||||
{
|
||||
StringCchCopyW (pName, sizeof(pName) / sizeof(pName[0]), oldDir);
|
||||
StringCchCatW (pName, sizeof(pName), WILD_CARD);
|
||||
StringCchCopyW (pName, aNameLength, oldDir);
|
||||
StringCchCatW (pName, aNameLength, WILD_CARD);
|
||||
retVal = TRUE;
|
||||
hFindFile = FindFirstFileExW (pName, FindExInfoStandard, pFD, FindExSearchNameMatch, NULL, 0);
|
||||
for (BOOL fFind = hFindFile != INVALID_HANDLE_VALUE; fFind; fFind = FindNextFileW (hFindFile, pFD))
|
||||
@@ -715,23 +716,24 @@ retry:
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t anOldDirLength2 = 0, aNewDirLength = 0, aFileNameLength = 0;
|
||||
StringCchLengthW (oldDir, sizeof(oldDir) / sizeof(oldDir[0]), &anOldDirLength2);
|
||||
StringCchLengthW (newDir, sizeof(newDir) / sizeof(newDir[0]), &aNewDirLength);
|
||||
size_t aNewDirLength = 0, aFileNameLength = 0;
|
||||
StringCchLengthW (newDir, MAX_PATH, &aNewDirLength);
|
||||
StringCchLengthW (pFD->cFileName, sizeof(pFD->cFileName) / sizeof(pFD->cFileName[0]), &aFileNameLength);
|
||||
if ((pFullNameSrc = (wchar_t* )HeapAlloc (hHeap, 0, anOldDirLength2 + aFileNameLength + sizeof(L'/') + sizeof(L'\x00'))) == NULL
|
||||
|| (pFullNameDst = (wchar_t* )HeapAlloc (hHeap, 0, aNewDirLength + aFileNameLength + sizeof(L'/') + sizeof(L'\x00'))) == NULL)
|
||||
const size_t aFullNameSrcLength = anOldDirLength + aFileNameLength + sizeof (L'/') + sizeof (L'\x00');
|
||||
const size_t aFullNameDstLength = aNewDirLength + aFileNameLength + sizeof (L'/') + sizeof (L'\x00');
|
||||
if ((pFullNameSrc = (wchar_t* )HeapAlloc (hHeap, 0, aFullNameSrcLength)) == NULL
|
||||
|| (pFullNameDst = (wchar_t* )HeapAlloc (hHeap, 0, aFullNameDstLength)) == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
StringCchCopyW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), oldDir);
|
||||
StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), L"/");
|
||||
StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), pFD->cFileName);
|
||||
StringCchCopyW (pFullNameSrc, aFullNameSrcLength, oldDir);
|
||||
StringCchCatW (pFullNameSrc, aFullNameSrcLength, L"/");
|
||||
StringCchCatW (pFullNameSrc, aFullNameSrcLength, pFD->cFileName);
|
||||
|
||||
StringCchCopyW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), newDir);
|
||||
StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), L"/");
|
||||
StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), pFD->cFileName);
|
||||
StringCchCopyW (pFullNameDst, aFullNameDstLength, newDir);
|
||||
StringCchCatW (pFullNameDst, aFullNameDstLength, L"/");
|
||||
StringCchCatW (pFullNameDst, aFullNameDstLength, pFD->cFileName);
|
||||
|
||||
if ((pFD->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
{
|
||||
@@ -853,12 +855,13 @@ BOOL CopyDirectory (const wchar_t* dirSrc, const wchar_t* dirDst)
|
||||
if (retVal || (!retVal && GetLastError() == ERROR_ALREADY_EXISTS))
|
||||
{
|
||||
size_t aDirSrcLength = 0;
|
||||
StringCchLengthW (dirSrc, sizeof(dirSrc) / sizeof(dirSrc[0]), &aDirSrcLength);
|
||||
StringCchLengthW (dirSrc, MAX_PATH, &aDirSrcLength);
|
||||
const size_t aNameLength = aDirSrcLength + WILD_CARD_LEN + sizeof (L'\x00');
|
||||
if ((pFD = (WIN32_FIND_DATAW* )HeapAlloc (hHeap, 0, sizeof(WIN32_FIND_DATAW))) != NULL
|
||||
&& (pName = (wchar_t* )HeapAlloc (hHeap, 0, aDirSrcLength + WILD_CARD_LEN + sizeof(L'\x00'))) != NULL)
|
||||
&& (pName = (wchar_t* )HeapAlloc (hHeap, 0, aNameLength)) != NULL)
|
||||
{
|
||||
StringCchCopyW(pName, sizeof(pName) / sizeof(pName[0]), dirSrc);
|
||||
StringCchCatW (pName, sizeof(pName) / sizeof(pName[0]), WILD_CARD);
|
||||
StringCchCopyW(pName, aNameLength, dirSrc);
|
||||
StringCchCatW (pName, aNameLength, WILD_CARD);
|
||||
|
||||
retVal = TRUE;
|
||||
hFindFile = FindFirstFileExW (pName, FindExInfoStandard, pFD, FindExSearchNameMatch, NULL, 0);
|
||||
@@ -870,23 +873,24 @@ BOOL CopyDirectory (const wchar_t* dirSrc, const wchar_t* dirDst)
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t aDirSrcLength2 = 0, aDirDstLength = 0, aFileNameLength = 0;
|
||||
StringCchLengthW (dirSrc, sizeof(dirSrc) / sizeof(dirSrc[0]), &aDirSrcLength2);
|
||||
StringCchLengthW (dirDst, sizeof(dirDst) / sizeof(dirDst[0]), &aDirDstLength);
|
||||
size_t aDirDstLength = 0, aFileNameLength = 0;
|
||||
StringCchLengthW (dirDst, MAX_PATH, &aDirDstLength);
|
||||
StringCchLengthW (pFD->cFileName, sizeof(pFD->cFileName) / sizeof(pFD->cFileName[0]), &aFileNameLength);
|
||||
if ((pFullNameSrc = (wchar_t* )HeapAlloc (hHeap, 0, aDirSrcLength2 + aFileNameLength + sizeof(L'/') + sizeof(L'\x00'))) == NULL
|
||||
|| (pFullNameDst = (wchar_t* )HeapAlloc (hHeap, 0, aDirDstLength + aFileNameLength + sizeof(L'/') + sizeof(L'\x00'))) == NULL)
|
||||
const size_t aFullNameSrcLength = aDirSrcLength + aFileNameLength + sizeof (L'/') + sizeof (L'\x00');
|
||||
const size_t aFullNameDstLength = aDirDstLength + aFileNameLength + sizeof (L'/') + sizeof (L'\x00');
|
||||
if ((pFullNameSrc = (wchar_t* )HeapAlloc (hHeap, 0, aFullNameSrcLength)) == NULL
|
||||
|| (pFullNameDst = (wchar_t* )HeapAlloc (hHeap, 0, aFullNameDstLength)) == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
StringCchCopyW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), dirSrc);
|
||||
StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), L"/");
|
||||
StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), pFD->cFileName);
|
||||
StringCchCopyW (pFullNameSrc, aFullNameSrcLength, dirSrc);
|
||||
StringCchCatW (pFullNameSrc, aFullNameSrcLength, L"/");
|
||||
StringCchCatW (pFullNameSrc, aFullNameSrcLength, pFD->cFileName);
|
||||
|
||||
StringCchCopyW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), dirDst);
|
||||
StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), L"/");
|
||||
StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), pFD->cFileName);
|
||||
StringCchCopyW (pFullNameDst, aFullNameDstLength, dirDst);
|
||||
StringCchCatW (pFullNameDst, aFullNameDstLength, L"/");
|
||||
StringCchCatW (pFullNameDst, aFullNameDstLength, pFD->cFileName);
|
||||
if ((pFD->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
{
|
||||
retVal = CopyDirectory (pFullNameSrc, pFullNameDst);
|
||||
|
@@ -18,6 +18,8 @@
|
||||
#include <Standard_Overflow.hxx>
|
||||
#include <Standard_Assert.hxx>
|
||||
|
||||
#include <Standard_WarningDisableFunctionCast.hxx>
|
||||
|
||||
static OSD_SignalMode OSD_WasSetSignal = OSD_SignalMode_AsIs;
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -105,6 +105,8 @@ OpenGl_GraphicDriver.hxx
|
||||
OpenGl_IndexBuffer.cxx
|
||||
OpenGl_IndexBuffer.hxx
|
||||
OpenGl_Layer.hxx
|
||||
OpenGl_PBREnvironment.cxx
|
||||
OpenGl_PBREnvironment.hxx
|
||||
OpenGl_RenderFilter.hxx
|
||||
OpenGl_Sampler.cxx
|
||||
OpenGl_Sampler.hxx
|
||||
|
@@ -144,6 +144,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
|
||||
hasUintIndex(Standard_True),
|
||||
hasTexRGBA8(Standard_True),
|
||||
#endif
|
||||
hasTexFloatLinear (Standard_False),
|
||||
hasTexSRGB (Standard_False),
|
||||
hasFboSRGB (Standard_False),
|
||||
hasSRGBControl (Standard_False),
|
||||
@@ -208,6 +209,10 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
|
||||
myHasRayTracingTextures (Standard_False),
|
||||
myHasRayTracingAdaptiveSampling (Standard_False),
|
||||
myHasRayTracingAdaptiveSamplingAtomic (Standard_False),
|
||||
myHasPBR (Standard_False),
|
||||
myPBREnvLUTTexUnit (Graphic3d_TextureUnit_0),
|
||||
myPBRDiffIBLMapSHTexUnit (Graphic3d_TextureUnit_0),
|
||||
myPBRSpecIBLMapTexUnit (Graphic3d_TextureUnit_0),
|
||||
myFrameStats (new OpenGl_FrameStats()),
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
myPointSpriteOrig (GL_UPPER_LEFT),
|
||||
@@ -1485,6 +1490,8 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
|
||||
|
||||
arbTexFloat = IsGlGreaterEqual (3, 0)
|
||||
&& FindProcShort (glTexImage3D);
|
||||
hasTexFloatLinear = arbTexFloat
|
||||
&& CheckExtension ("GL_OES_texture_float_linear");
|
||||
|
||||
const Standard_Boolean hasTexBuffer32 = IsGlGreaterEqual (3, 2) && FindProcShort (glTexBuffer);
|
||||
const Standard_Boolean hasExtTexBuffer = CheckExtension ("GL_EXT_texture_buffer") && FindProc ("glTexBufferEXT", myFuncs->glTexBuffer);
|
||||
@@ -1581,6 +1588,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
|
||||
arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
|
||||
arbTexFloat = IsGlGreaterEqual (3, 0)
|
||||
|| CheckExtension ("GL_ARB_texture_float");
|
||||
hasTexFloatLinear = arbTexFloat;
|
||||
arbSampleShading = CheckExtension ("GL_ARB_sample_shading");
|
||||
extBgra = CheckExtension ("GL_EXT_bgra");
|
||||
extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
|
||||
@@ -2933,6 +2941,23 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
|
||||
"Check OpenGL window creation parameters for optimal performance.", Message_Trace);
|
||||
}
|
||||
}
|
||||
|
||||
// check whether PBR shading model is supported
|
||||
myHasPBR = arbFBO != NULL
|
||||
&& myMaxTexCombined >= 4
|
||||
&& arbTexRG
|
||||
&& arbTexFloat
|
||||
&& (IsGlGreaterEqual (3, 0)
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
|| (IsGlGreaterEqual (2, 1) && CheckExtension ("GL_EXT_gpu_shader4"))
|
||||
#endif
|
||||
);
|
||||
if (myHasPBR)
|
||||
{
|
||||
myPBREnvLUTTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined - 3);
|
||||
myPBRDiffIBLMapSHTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined - 2);
|
||||
myPBRSpecIBLMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -3547,8 +3572,11 @@ void OpenGl_Context::SetShadingMaterial (const OpenGl_Aspects* theAspect,
|
||||
Standard_ShortReal anAlphaBack = 1.0f;
|
||||
if (CheckIsTransparent (theAspect, theHighlight, anAlphaFront, anAlphaBack))
|
||||
{
|
||||
myMatFront.Diffuse.a() = anAlphaFront;
|
||||
myMatBack .Diffuse.a() = anAlphaBack;
|
||||
myMatFront.Common.Diffuse.a() = anAlphaFront;
|
||||
myMatBack .Common.Diffuse.a() = anAlphaBack;
|
||||
|
||||
myMatFront.Pbr.BaseColor.a() = anAlphaFront;
|
||||
myMatBack .Pbr.BaseColor.a() = anAlphaBack;
|
||||
}
|
||||
|
||||
// do not update material properties in case of zero reflection mode,
|
||||
|
@@ -587,6 +587,25 @@ public:
|
||||
return Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB (theColor);
|
||||
}
|
||||
|
||||
//! Returns TRUE if PBR shading model is supported.
|
||||
//! Basically, feature requires OpenGL 3.0+ / OpenGL ES 3.0+ hardware; more precisely:
|
||||
//! - Graphics hardware with moderate capabilities for compiling long enough GLSL program.
|
||||
//! - FBO (e.g. for baking environment).
|
||||
//! - Multi-texturing with >= 4 units (LUT and IBL textures).
|
||||
//! - GL_RG32F texture format (arbTexRG + arbTexFloat)
|
||||
//! - Cubemap texture lookup textureCubeLod()/textureLod() with LOD index within Fragment Shader,
|
||||
//! which requires GLSL OpenGL 3.0+ / OpenGL ES 3.0+ or OpenGL 2.1 + GL_EXT_gpu_shader4 extension.
|
||||
Standard_Boolean HasPBR() const { return myHasPBR; }
|
||||
|
||||
//! Returns texture unit where Environment Lookup Table is expected to be bound, or 0 if PBR is unavailable.
|
||||
Graphic3d_TextureUnit PBREnvLUTTexUnit() const { return myPBREnvLUTTexUnit; }
|
||||
|
||||
//! Returns texture unit where Diffuse (irradiance) IBL map's spherical harmonics coefficients is expected to be bound, or 0 if PBR is unavailable.
|
||||
Graphic3d_TextureUnit PBRDiffIBLMapSHTexUnit() const { return myPBRDiffIBLMapSHTexUnit; }
|
||||
|
||||
//! Returns texture unit where Specular IBL map is expected to be bound, or 0 if PBR is unavailable.
|
||||
Graphic3d_TextureUnit PBRSpecIBLMapTexUnit() const { return myPBRSpecIBLMapTexUnit; }
|
||||
|
||||
//! Returns true if VBO is supported and permitted.
|
||||
inline bool ToUseVbo() const
|
||||
{
|
||||
@@ -956,6 +975,7 @@ public: //! @name extensions
|
||||
Standard_Boolean hasHighp; //!< highp in GLSL ES fragment shader is supported
|
||||
Standard_Boolean hasUintIndex; //!< GLuint for index buffer is supported (always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_element_index_uint)
|
||||
Standard_Boolean hasTexRGBA8; //!< always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_rgb8_rgba8
|
||||
Standard_Boolean hasTexFloatLinear; //!< texture-filterable state for 32-bit floating texture formats (always on desktop, GL_OES_texture_float_linear within OpenGL ES)
|
||||
Standard_Boolean hasTexSRGB; //!< sRGB texture formats (desktop OpenGL 2.0, OpenGL ES 3.0 or GL_EXT_texture_sRGB)
|
||||
Standard_Boolean hasFboSRGB; //!< sRGB FBO render targets (desktop OpenGL 2.1, OpenGL ES 3.0)
|
||||
Standard_Boolean hasSRGBControl; //!< sRGB write control (any desktop OpenGL, OpenGL ES + GL_EXT_sRGB_write_control extension)
|
||||
@@ -969,7 +989,7 @@ public: //! @name extensions
|
||||
Standard_Boolean arbDrawBuffers; //!< GL_ARB_draw_buffers
|
||||
Standard_Boolean arbNPTW; //!< GL_ARB_texture_non_power_of_two
|
||||
Standard_Boolean arbTexRG; //!< GL_ARB_texture_rg
|
||||
Standard_Boolean arbTexFloat; //!< GL_ARB_texture_float (on desktop OpenGL - since 3.0 or as extension GL_ARB_texture_float; on OpenGL ES - since 3.0)
|
||||
Standard_Boolean arbTexFloat; //!< GL_ARB_texture_float (on desktop OpenGL - since 3.0 or as extension GL_ARB_texture_float; on OpenGL ES - since 3.0); @sa hasTexFloatLinear for linear filtering support
|
||||
OpenGl_ArbSamplerObject* arbSamplerObject; //!< GL_ARB_sampler_objects (on desktop OpenGL - since 3.3 or as extension GL_ARB_sampler_objects; on OpenGL ES - since 3.0)
|
||||
OpenGl_ArbTexBindless* arbTexBindless; //!< GL_ARB_bindless_texture
|
||||
OpenGl_ArbTBO* arbTBO; //!< GL_ARB_texture_buffer_object
|
||||
@@ -1056,6 +1076,12 @@ private: // context info
|
||||
Standard_Boolean myHasRayTracingAdaptiveSampling; //! indicates whether adaptive screen sampling in ray tracing mode is supported
|
||||
Standard_Boolean myHasRayTracingAdaptiveSamplingAtomic; //! indicates whether atomic adaptive screen sampling in ray tracing mode is supported
|
||||
|
||||
Standard_Boolean myHasPBR; //!< indicates whether PBR shading model is supported
|
||||
Graphic3d_TextureUnit myPBREnvLUTTexUnit; //!< texture unit where environment lookup table is expected to be binded (0 if PBR is not supported)
|
||||
Graphic3d_TextureUnit myPBRDiffIBLMapSHTexUnit; //!< texture unit where diffuse (irradiance) IBL map's spherical harmonics coefficients is expected to be binded
|
||||
//! (0 if PBR is not supported)
|
||||
Graphic3d_TextureUnit myPBRSpecIBLMapTexUnit; //!< texture unit where specular IBL map is expected to be binded (0 if PBR is not supported)
|
||||
|
||||
Handle(OpenGl_ShaderManager) myShaderManager; //! support object for managing shader programs
|
||||
|
||||
private: //! @name fields tracking current state
|
||||
|
@@ -786,6 +786,10 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
|
||||
aFormat = GL_DEPTH_COMPONENT;
|
||||
aType = GL_FLOAT;
|
||||
break;
|
||||
case Image_Format_RGF:
|
||||
aFormat = GL_RG;
|
||||
aType = GL_FLOAT;
|
||||
break;
|
||||
case Image_Format_RGB:
|
||||
aFormat = GL_RGB;
|
||||
aType = GL_UNSIGNED_BYTE;
|
||||
@@ -812,6 +816,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
|
||||
case Image_Format_GrayF:
|
||||
case Image_Format_BGRF:
|
||||
case Image_Format_BGRAF:
|
||||
case Image_Format_RGF:
|
||||
return Standard_False;
|
||||
case Image_Format_BGRA:
|
||||
case Image_Format_BGR32:
|
||||
|
@@ -80,6 +80,9 @@
|
||||
// adds GL_FRAMEBUFFER_SRGB_EXT flag as on desktop OpenGL
|
||||
#define GL_FRAMEBUFFER_SRGB 0x8DB9
|
||||
|
||||
#define GL_TEXTURE_BASE_LEVEL 0x813C
|
||||
#define GL_TEXTURE_MAX_LEVEL 0x813D
|
||||
|
||||
// OpenGL ES 3.1+
|
||||
#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
|
||||
#define GL_MAX_SAMPLES 0x8D57
|
||||
|
@@ -400,6 +400,8 @@ Standard_Integer OpenGl_GraphicDriver::InquireLimit (const Graphic3d_TypeOfLimit
|
||||
return !aCtx.IsNull() ? aCtx->MaxDumpSizeX() : 1024;
|
||||
case Graphic3d_TypeOfLimit_MaxViewDumpSizeY:
|
||||
return !aCtx.IsNull() ? aCtx->MaxDumpSizeY() : 1024;
|
||||
case Graphic3d_TypeOfLimit_HasPBR:
|
||||
return (!aCtx.IsNull() && aCtx->HasPBR()) ? 1 : 0;
|
||||
case Graphic3d_TypeOfLimit_HasRayTracing:
|
||||
return (!aCtx.IsNull() && aCtx->HasRayTracing()) ? 1 : 0;
|
||||
case Graphic3d_TypeOfLimit_HasRayTracingTextures:
|
||||
|
@@ -594,7 +594,7 @@ void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace
|
||||
if (hasOwnLights)
|
||||
{
|
||||
aLayerSettings.Lights()->UpdateRevision();
|
||||
aManager->UpdateLightSourceStateTo (aLayerSettings.Lights());
|
||||
aManager->UpdateLightSourceStateTo (aLayerSettings.Lights(), theWorkspace->View()->SpecIBLMapLevels());
|
||||
}
|
||||
|
||||
const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera();
|
||||
@@ -665,7 +665,7 @@ void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace
|
||||
|
||||
if (hasOwnLights)
|
||||
{
|
||||
aManager->UpdateLightSourceStateTo (aLightsBack);
|
||||
aManager->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels());
|
||||
}
|
||||
if (hasLocalCS)
|
||||
{
|
||||
@@ -732,7 +732,7 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
|
||||
if (aPassIter == 0)
|
||||
{
|
||||
aCtx->SetColorMask (false);
|
||||
aCtx->ShaderManager()->UpdateLightSourceStateTo (Handle(Graphic3d_LightSet)());
|
||||
aCtx->ShaderManager()->UpdateLightSourceStateTo (Handle(Graphic3d_LightSet)(), theWorkspace->View()->SpecIBLMapLevels());
|
||||
aDefaultSettings.DepthFunc = aPrevSettings.DepthFunc;
|
||||
aDefaultSettings.DepthMask = GL_TRUE;
|
||||
}
|
||||
@@ -743,13 +743,13 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
|
||||
continue;
|
||||
}
|
||||
aCtx->SetColorMask (true);
|
||||
aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack);
|
||||
aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels());
|
||||
aDefaultSettings = aPrevSettings;
|
||||
}
|
||||
else if (aPassIter == 2)
|
||||
{
|
||||
aCtx->SetColorMask (true);
|
||||
aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack);
|
||||
aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels());
|
||||
if (toPerformDepthPrepass)
|
||||
{
|
||||
aDefaultSettings.DepthFunc = GL_EQUAL;
|
||||
|
@@ -22,7 +22,7 @@
|
||||
class OpenGl_Context;
|
||||
|
||||
//! OpenGL material definition
|
||||
struct OpenGl_Material
|
||||
struct OpenGl_MaterialCommon
|
||||
{
|
||||
|
||||
OpenGl_Vec4 Ambient; //!< ambient reflection coefficient
|
||||
@@ -37,31 +37,58 @@ struct OpenGl_Material
|
||||
float Transparency() const { return Params.y(); }
|
||||
float& ChangeTransparency() { return Params.y(); }
|
||||
|
||||
//! Empty constructor.
|
||||
OpenGl_MaterialCommon() : Ambient (1.0f), Diffuse (1.0f), Specular (1.0f), Emission (1.0f), Params (1.0f, 0.0f, 0.0f, 0.0f) {}
|
||||
|
||||
//! Returns packed (serialized) representation of material properties
|
||||
const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
|
||||
static Standard_Integer NbOfVec4() { return 5; }
|
||||
|
||||
};
|
||||
|
||||
//! OpenGL material definition
|
||||
struct OpenGl_MaterialPBR
|
||||
{
|
||||
|
||||
OpenGl_Vec4 BaseColor; //!< base color of PBR material with alpha component
|
||||
OpenGl_Vec4 EmissionIOR; //!< light intensity which is emitted by PBR material and index of refraction
|
||||
OpenGl_Vec4 Params; //!< extra packed parameters
|
||||
|
||||
float Metallic() const { return Params.b(); }
|
||||
float& ChangeMetallic() { return Params.b(); }
|
||||
|
||||
float Roughness() const { return Params.g(); }
|
||||
float& ChangeRoughness() { return Params.g(); }
|
||||
|
||||
//! Empty constructor.
|
||||
OpenGl_MaterialPBR() : BaseColor (1.0f), EmissionIOR (1.0f), Params (1.0f, 1.0f, 1.0f, 1.0f) {}
|
||||
|
||||
//! Returns packed (serialized) representation of material properties
|
||||
const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
|
||||
static Standard_Integer NbOfVec4() { return 3; }
|
||||
|
||||
};
|
||||
|
||||
//! OpenGL material definition
|
||||
struct OpenGl_Material
|
||||
{
|
||||
OpenGl_MaterialCommon Common;
|
||||
OpenGl_MaterialPBR Pbr;
|
||||
|
||||
//! Set material color.
|
||||
void SetColor (const OpenGl_Vec4& theColor)
|
||||
{
|
||||
// apply the same formula as in Graphic3d_MaterialAspect::SetColor()
|
||||
Ambient.SetValues (theColor.rgb() * 0.25f, Ambient.a());
|
||||
Diffuse.SetValues (theColor.rgb(), Diffuse.a());
|
||||
Common.Ambient.SetValues (theColor.rgb() * 0.25f, Common.Ambient.a());
|
||||
Common.Diffuse.SetValues (theColor.rgb(), Common.Diffuse.a());
|
||||
Pbr .BaseColor.SetValues (theColor.rgb(), Pbr.BaseColor.a());
|
||||
}
|
||||
|
||||
//! Empty constructor.
|
||||
OpenGl_Material()
|
||||
: Ambient (1.0f),
|
||||
Diffuse (1.0f),
|
||||
Specular(1.0f),
|
||||
Emission(1.0f),
|
||||
Params (1.0f, 0.0f, 0.0f, 0.0f) {}
|
||||
|
||||
//! Initialize material
|
||||
void Init (const OpenGl_Context& theCtx,
|
||||
const Graphic3d_MaterialAspect& theProp,
|
||||
const Quantity_Color& theInteriorColor);
|
||||
|
||||
//! Returns packed (serialized) representation of material properties
|
||||
const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
|
||||
static Standard_Integer NbOfVec4() { return 5; }
|
||||
|
||||
//! Check this material for equality with another material (without tolerance!).
|
||||
bool IsEqual (const OpenGl_Material& theOther) const
|
||||
{
|
||||
|
487
src/OpenGl/OpenGl_PBREnvironment.cxx
Normal file
487
src/OpenGl/OpenGl_PBREnvironment.cxx
Normal file
@@ -0,0 +1,487 @@
|
||||
// Author: Ilya Khramov
|
||||
// Copyright (c) 2019 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.
|
||||
|
||||
#include <OpenGl_PBREnvironment.hxx>
|
||||
|
||||
#include <Graphic3d_PBRMaterial.hxx>
|
||||
#include <OpenGl_ArbFBO.hxx>
|
||||
#include <OpenGl_FrameBuffer.hxx>
|
||||
#include <OpenGl_ShaderManager.hxx>
|
||||
#include <OSD_Timer.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_PBREnvironment, OpenGl_NamedResource)
|
||||
|
||||
//! Constructor of this class saves necessary OpenGL states components which can be changed by OpenGl_PBREnvironment.
|
||||
//! Destructor restores state back.
|
||||
class OpenGl_PBREnvironmentSentry
|
||||
{
|
||||
public:
|
||||
|
||||
OpenGl_PBREnvironmentSentry (const Handle(OpenGl_Context)& theCtx)
|
||||
: myContext (theCtx)
|
||||
{
|
||||
backup();
|
||||
prepare();
|
||||
}
|
||||
|
||||
~OpenGl_PBREnvironmentSentry()
|
||||
{
|
||||
restore();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void backup()
|
||||
{
|
||||
myContext->core11fwd->glGetIntegerv (GL_FRAMEBUFFER_BINDING, &myFBO);
|
||||
myShaderProgram = myContext->ActiveProgram();
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
{
|
||||
myViewport[i] = myContext->Viewport()[i];
|
||||
}
|
||||
myContext->core11fwd->glGetFloatv (GL_COLOR_CLEAR_VALUE, myClearColor);
|
||||
|
||||
GLboolean aStatus = GL_TRUE;
|
||||
myContext->core11fwd->glGetBooleanv (GL_DEPTH_TEST, &aStatus);
|
||||
myDepthTestWasEnabled = aStatus ? Standard_True : Standard_False;
|
||||
myContext->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aStatus);
|
||||
myDepthWrirtingWasEnablig = aStatus ? Standard_True : Standard_False;
|
||||
myContext->core11fwd->glGetBooleanv (GL_SCISSOR_TEST, &aStatus);
|
||||
myScissorTestWasEnabled = aStatus ? Standard_True : Standard_False;
|
||||
myContext->core11fwd->glGetIntegerv (GL_SCISSOR_BOX, myScissorBox);
|
||||
}
|
||||
|
||||
void prepare()
|
||||
{
|
||||
myContext->BindDefaultVao();
|
||||
myContext->core11fwd->glDisable (GL_DEPTH_TEST);
|
||||
myContext->core11fwd->glDepthMask (GL_FALSE);
|
||||
myContext->core11fwd->glDisable (GL_BLEND);
|
||||
myContext->core11fwd->glDisable (GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void restore()
|
||||
{
|
||||
myContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myFBO);
|
||||
myContext->BindProgram (myShaderProgram);
|
||||
myContext->ResizeViewport (myViewport);
|
||||
myContext->core11fwd->glClearColor (myClearColor.r(), myClearColor.g(), myClearColor.b(), myClearColor.a());
|
||||
if (myDepthTestWasEnabled)
|
||||
{
|
||||
myContext->core11fwd->glEnable (GL_DEPTH_TEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
myContext->core11fwd->glDisable (GL_DEPTH_TEST);
|
||||
}
|
||||
myContext->core11fwd->glDepthMask (myDepthWrirtingWasEnablig ? GL_TRUE : GL_FALSE);
|
||||
if (myScissorTestWasEnabled)
|
||||
{
|
||||
myContext->core11fwd->glEnable (GL_SCISSOR_TEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
myContext->core11fwd->glDisable (GL_SCISSOR_TEST);
|
||||
}
|
||||
myContext->core11fwd->glScissor (myScissorBox[0], myScissorBox[1], myScissorBox[2], myScissorBox[3]);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
OpenGl_PBREnvironmentSentry (const OpenGl_PBREnvironmentSentry& );
|
||||
OpenGl_PBREnvironmentSentry& operator= (const OpenGl_PBREnvironmentSentry& );
|
||||
|
||||
private:
|
||||
|
||||
const Handle(OpenGl_Context) myContext;
|
||||
GLint myFBO;
|
||||
Handle(OpenGl_ShaderProgram) myShaderProgram;
|
||||
Standard_Boolean myDepthTestWasEnabled;
|
||||
Standard_Boolean myDepthWrirtingWasEnablig;
|
||||
Standard_Boolean myScissorTestWasEnabled;
|
||||
Standard_Integer myScissorBox[4];
|
||||
Standard_Integer myViewport[4];
|
||||
Graphic3d_Vec4 myClearColor;
|
||||
|
||||
};
|
||||
|
||||
// =======================================================================
|
||||
// function : Create
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Handle(OpenGl_PBREnvironment) OpenGl_PBREnvironment::Create (const Handle(OpenGl_Context)& theCtx,
|
||||
unsigned int thePow2Size,
|
||||
unsigned int theLevelsNumber,
|
||||
const TCollection_AsciiString& theId)
|
||||
{
|
||||
if (theCtx->arbFBO == NULL)
|
||||
{
|
||||
return Handle(OpenGl_PBREnvironment)();
|
||||
}
|
||||
|
||||
Handle(OpenGl_PBREnvironment) anEnvironment = new OpenGl_PBREnvironment (theCtx, thePow2Size, theLevelsNumber, theId);
|
||||
if (!anEnvironment->IsComplete())
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
|
||||
"Warning: PBR environment is not created. PBR material system will be ignored.");
|
||||
anEnvironment->Release (theCtx.get());
|
||||
anEnvironment.Nullify();
|
||||
}
|
||||
|
||||
return anEnvironment;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : OpenGl_PBREnvironment
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
OpenGl_PBREnvironment::OpenGl_PBREnvironment (const Handle(OpenGl_Context)& theCtx,
|
||||
unsigned int thePowOf2Size,
|
||||
unsigned int theSpecMapLevelsNumber,
|
||||
const TCollection_AsciiString& theId)
|
||||
: OpenGl_NamedResource (theId),
|
||||
myPow2Size (std::max (1u, thePowOf2Size)),
|
||||
mySpecMapLevelsNumber (std::max (2u, std::min (theSpecMapLevelsNumber, std::max (1u, thePowOf2Size) + 1))),
|
||||
myFBO (OpenGl_FrameBuffer::NO_FRAMEBUFFER),
|
||||
myIsComplete (Standard_False),
|
||||
myIsNeededToBeBound (Standard_True)
|
||||
{
|
||||
OpenGl_PBREnvironmentSentry aSentry (theCtx);
|
||||
|
||||
myIsComplete = initVAO (theCtx)
|
||||
&& initTextures (theCtx)
|
||||
&& initFBO (theCtx);
|
||||
|
||||
if (myIsComplete)
|
||||
{
|
||||
clear (theCtx);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Bind
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_PBREnvironment::Bind (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Bind (theCtx);
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Bind (theCtx);
|
||||
myIsNeededToBeBound = Standard_False;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Unbind
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_PBREnvironment::Unbind (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Unbind (theCtx);
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Unbind (theCtx);
|
||||
myIsNeededToBeBound = Standard_True;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Clear
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_PBREnvironment::Clear (const Handle(OpenGl_Context)& theCtx,
|
||||
const Graphic3d_Vec3& theColor)
|
||||
{
|
||||
OpenGl_PBREnvironmentSentry aSentry (theCtx);
|
||||
clear (theCtx, theColor);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Bake
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_PBREnvironment::Bake (const Handle(OpenGl_Context)& theCtx,
|
||||
const Handle(OpenGl_Texture)& theEnvMap,
|
||||
Standard_Boolean theZIsInverted,
|
||||
Standard_Boolean theIsTopDown,
|
||||
Standard_Size theDiffMapNbSamples,
|
||||
Standard_Size theSpecMapNbSamples,
|
||||
Standard_ShortReal theProbability)
|
||||
{
|
||||
Standard_ProgramError_Raise_if (theEnvMap.IsNull(), "'Bake' function of 'OpenGl_PBREnvironment' can't work without source environment map")
|
||||
Standard_RangeError_Raise_if (theProbability > 1.f || theProbability < 0.f, "'probability' parameter in 'Bake' function of 'OpenGl_PBREnvironment' must be in range [0, 1]")
|
||||
Unbind (theCtx);
|
||||
OpenGl_PBREnvironmentSentry aSentry (theCtx);
|
||||
bake (theCtx, theEnvMap, theZIsInverted, theIsTopDown, theDiffMapNbSamples, theSpecMapNbSamples, theProbability);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SizesAreDifferent
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_PBREnvironment::SizesAreDifferent (unsigned int thePow2Size,
|
||||
unsigned int theSpecMapLevelsNumber) const
|
||||
{
|
||||
thePow2Size = std::max (1u, thePow2Size);
|
||||
theSpecMapLevelsNumber = std::max (2u, std::min (theSpecMapLevelsNumber, std::max (1u, thePow2Size) + 1));
|
||||
return myPow2Size != thePow2Size
|
||||
|| mySpecMapLevelsNumber != theSpecMapLevelsNumber;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Release
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_PBREnvironment::Release (OpenGl_Context* theCtx)
|
||||
{
|
||||
if (myFBO != OpenGl_FrameBuffer::NO_FRAMEBUFFER)
|
||||
{
|
||||
if (theCtx != NULL
|
||||
&& theCtx->IsValid())
|
||||
{
|
||||
theCtx->arbFBO->glDeleteFramebuffers (1, &myFBO);
|
||||
}
|
||||
myFBO = OpenGl_FrameBuffer::NO_FRAMEBUFFER;
|
||||
}
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Release(theCtx);
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Release (theCtx);
|
||||
myVBO.Release (theCtx);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ~OpenGl_PBREnvironment
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
OpenGl_PBREnvironment::~OpenGl_PBREnvironment()
|
||||
{
|
||||
Release (NULL);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : initTextures
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_PBREnvironment::initTextures (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Sampler()->Parameters()->SetTextureUnit (theCtx->PBRSpecIBLMapTexUnit());
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Sampler()->Parameters()->SetTextureUnit (theCtx->PBRDiffIBLMapSHTexUnit());
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Sampler()->Parameters()->SetFilter (Graphic3d_TOTF_TRILINEAR);
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Sampler()->Parameters()->SetFilter(Graphic3d_TOTF_NEAREST);
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Sampler()->Parameters()->SetLevelsRange (mySpecMapLevelsNumber - 1);
|
||||
|
||||
// NVIDIA's driver didn't work properly with 3 channel texture for diffuse SH coefficients so that alpha channel has been added
|
||||
return myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Init (theCtx,
|
||||
OpenGl_TextureFormat::FindFormat (theCtx, Image_Format_RGBAF, false),
|
||||
Graphic3d_Vec2i (9, 1),
|
||||
Graphic3d_TOT_2D)
|
||||
&& myIBLMaps[OpenGl_TypeOfIBLMap_Specular].InitCubeMap (theCtx, Handle(Graphic3d_CubeMap)(),
|
||||
Standard_Size(1) << myPow2Size, Image_Format_RGB, true, false);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : initVAO
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_PBREnvironment::initVAO (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
const float aVertexPos[] =
|
||||
{
|
||||
-1.f, -1.f, 0.f, 0.f,
|
||||
1.f, -1.f, 0.f, 0.f,
|
||||
-1.f, 1.f, 0.f, 0.f,
|
||||
1.f, 1.f, 0.f, 0.f
|
||||
};
|
||||
return myVBO.Init (theCtx, 4, 4, aVertexPos);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : initFBO
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_PBREnvironment::initFBO (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
theCtx->arbFBO->glGenFramebuffers (1, &myFBO);
|
||||
return checkFBOComplentess (theCtx);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : processDiffIBLMap
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_PBREnvironment::processDiffIBLMap (const Handle(OpenGl_Context)& theCtx,
|
||||
Standard_Boolean theIsDrawAction,
|
||||
Standard_Size theNbSamples)
|
||||
{
|
||||
theCtx->arbFBO->glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].TextureId(), 0);
|
||||
const Standard_Integer aViewport[4] = { 0, 0, 9, 1 };
|
||||
theCtx->ResizeViewport(aViewport);
|
||||
if (theIsDrawAction)
|
||||
{
|
||||
theCtx->ActiveProgram()->SetUniform(theCtx, "occNbSpecIBLLevels", 0);
|
||||
theCtx->ActiveProgram()->SetUniform(theCtx, "uSamplesNum", static_cast<Standard_Integer>(theNbSamples));
|
||||
|
||||
theCtx->core11fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
theCtx->core11fwd->glClear (GL_COLOR_BUFFER_BIT);
|
||||
|
||||
theCtx->core11fwd->glEnable (GL_SCISSOR_TEST);
|
||||
theCtx->core11fwd->glClearColor (0.f, 0.f, 0.f, 1.f);
|
||||
theCtx->core11fwd->glScissor (1, 0, 8, 1);
|
||||
theCtx->core11fwd->glClear (GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : processSpecIBLMap
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_PBREnvironment::processSpecIBLMap (const Handle(OpenGl_Context)& theCtx,
|
||||
Standard_Boolean theIsDrawAction,
|
||||
Standard_Integer theEnvMapSize,
|
||||
Standard_Size theNbSamples,
|
||||
Standard_ShortReal theProbability)
|
||||
{
|
||||
if (theIsDrawAction)
|
||||
{
|
||||
theCtx->ActiveProgram()->SetUniform (theCtx, "occNbSpecIBLLevels", Standard_Integer(mySpecMapLevelsNumber));
|
||||
theCtx->ActiveProgram()->SetUniform (theCtx, "uEnvMapSize", theEnvMapSize);
|
||||
}
|
||||
|
||||
for (int aLevelIter = mySpecMapLevelsNumber - 1;; --aLevelIter)
|
||||
{
|
||||
const Standard_Integer aSize = 1 << (myPow2Size - aLevelIter);
|
||||
const Standard_Integer aViewport[4] = { 0, 0, aSize, aSize };
|
||||
theCtx->ResizeViewport (aViewport);
|
||||
if (theIsDrawAction)
|
||||
{
|
||||
Standard_Integer aNbSamples = static_cast<Standard_Integer>(Graphic3d_PBRMaterial::SpecIBLMapSamplesFactor (theProbability, aLevelIter / float (mySpecMapLevelsNumber - 1)) * theNbSamples);
|
||||
theCtx->ActiveProgram()->SetUniform (theCtx, "uSamplesNum", static_cast<Standard_Integer>(aNbSamples));
|
||||
theCtx->ActiveProgram()->SetUniform (theCtx, "uCurrentLevel", aLevelIter);
|
||||
}
|
||||
|
||||
for (Standard_Integer aSideIter = 0; aSideIter < 6; ++aSideIter)
|
||||
{
|
||||
theCtx->arbFBO->glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + aSideIter,
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_Specular].TextureId(), aLevelIter);
|
||||
if (theIsDrawAction)
|
||||
{
|
||||
theCtx->ActiveProgram()->SetUniform(theCtx, "uCurrentSide", aSideIter);
|
||||
theCtx->core11fwd->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
theCtx->core11fwd->glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
if (aLevelIter == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : checkFBOCompletness
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_PBREnvironment::checkFBOComplentess (const Handle(OpenGl_Context)& theCtx) const
|
||||
{
|
||||
theCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myFBO);
|
||||
theCtx->arbFBO->glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].TextureId(), 0);
|
||||
if (theCtx->arbFBO->glCheckFramebufferStatus (GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (Standard_Integer aSideIter = 0; aSideIter < 6; ++aSideIter)
|
||||
{
|
||||
for (unsigned int aLevel = 0; aLevel < mySpecMapLevelsNumber; ++aLevel)
|
||||
{
|
||||
theCtx->arbFBO->glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + aSideIter,
|
||||
myIBLMaps[OpenGl_TypeOfIBLMap_Specular].TextureId(), aLevel);
|
||||
if (theCtx->arbFBO->glCheckFramebufferStatus (GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : bake
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_PBREnvironment::bake (const Handle(OpenGl_Context)& theCtx,
|
||||
const Handle(OpenGl_Texture)& theEnvMap,
|
||||
Standard_Boolean theZIsInverted,
|
||||
Standard_Boolean theIsTopDown,
|
||||
Standard_Size theDiffNbSamples,
|
||||
Standard_Size theSpecNbSamples,
|
||||
Standard_ShortReal theProbability)
|
||||
{
|
||||
myIsNeededToBeBound = Standard_True;
|
||||
if (!theCtx->ShaderManager()->BindPBREnvBakingProgram())
|
||||
{
|
||||
return;
|
||||
}
|
||||
theEnvMap->Bind (theCtx, theCtx->PBRSpecIBLMapTexUnit());
|
||||
theCtx->ActiveProgram()->SetSampler (theCtx, "uEnvMap", theCtx->PBRSpecIBLMapTexUnit());
|
||||
theCtx->ActiveProgram()->SetUniform (theCtx, "uZCoeff", theZIsInverted ? -1 : 1);
|
||||
theCtx->ActiveProgram()->SetUniform (theCtx, "uYCoeff", theIsTopDown ? 1 : -1);
|
||||
theCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myFBO);
|
||||
myVBO.BindAttribute (theCtx, Graphic3d_TOA_POS);
|
||||
|
||||
OSD_Timer aTimer;
|
||||
aTimer.Start();
|
||||
if (processSpecIBLMap (theCtx, true, theEnvMap->SizeX(), theSpecNbSamples, theProbability)
|
||||
&& processDiffIBLMap (theCtx, true, theDiffNbSamples))
|
||||
{
|
||||
Message::DefaultMessenger()->Send(TCollection_AsciiString()
|
||||
+ "IBL " + myIBLMaps[OpenGl_TypeOfIBLMap_Specular].SizeX() + "x" + myIBLMaps[OpenGl_TypeOfIBLMap_Specular].SizeY()
|
||||
+ " is baked in " + aTimer.ElapsedTime() + " s", Message_Trace);
|
||||
}
|
||||
else
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString("Error: baking PBR environment ") + myIBLMaps[OpenGl_TypeOfIBLMap_Specular].SizeX()
|
||||
+ "x" + myIBLMaps[OpenGl_TypeOfIBLMap_Specular].SizeY() + " takes too much time!.");
|
||||
clear (theCtx, Graphic3d_Vec3(1.0f));
|
||||
}
|
||||
|
||||
myVBO.UnbindAttribute (theCtx, Graphic3d_TOA_POS);
|
||||
theEnvMap->Unbind (theCtx, theCtx->PBREnvLUTTexUnit());
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : clear
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_PBREnvironment::clear (const Handle(OpenGl_Context)& theCtx,
|
||||
const Graphic3d_Vec3& theColor)
|
||||
{
|
||||
myIsNeededToBeBound = Standard_True;
|
||||
theCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myFBO);
|
||||
theCtx->core11fwd->glClearColor (theColor.r(), theColor.g(), theColor.b(), 1.f);
|
||||
|
||||
processSpecIBLMap (theCtx, false);
|
||||
processDiffIBLMap (theCtx, false);
|
||||
}
|
206
src/OpenGl/OpenGl_PBREnvironment.hxx
Normal file
206
src/OpenGl/OpenGl_PBREnvironment.hxx
Normal file
@@ -0,0 +1,206 @@
|
||||
// Author: Ilya Khramov
|
||||
// Copyright (c) 2019 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 _OpenGl_PBREnvironment_HeaderFile
|
||||
#define _OpenGl_PBREnvironment_HeaderFile
|
||||
|
||||
#include <OpenGl_Texture.hxx>
|
||||
#include <OpenGl_VertexBuffer.hxx>
|
||||
|
||||
//! This class contains specular and diffuse maps required for Image Base Lighting (IBL) in PBR shading model with it's generation methods.
|
||||
class OpenGl_PBREnvironment : public OpenGl_NamedResource
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(OpenGl_PBREnvironment, OpenGl_NamedResource)
|
||||
public:
|
||||
|
||||
//! Creates and initializes new PBR environment. It is the only way to create OpenGl_PBREnvironment.
|
||||
//! @param theCtx OpenGL context where environment will be created
|
||||
//! @param thePow2Size final size of texture's sides can be calculated as 2^thePow2Size;
|
||||
//! if thePow2Size less than 1 it will be set to 1
|
||||
//! @param theSpecMapLevelsNum number of mipmap levels used in specular IBL map;
|
||||
//! if theSpecMapLevelsNum less than 2 or less than Pow2Size + 1 it will be set to the corresponding values.
|
||||
//! @param theId OpenGl_Resource name
|
||||
//! @return handle to created PBR environment or NULL handle in case of fail
|
||||
Standard_EXPORT static Handle(OpenGl_PBREnvironment) Create (const Handle(OpenGl_Context)& theCtx,
|
||||
unsigned int thePow2Size = 9,
|
||||
unsigned int theSpecMapLevelsNum = 6,
|
||||
const TCollection_AsciiString& theId = "PBREnvironment");
|
||||
|
||||
public:
|
||||
|
||||
//! Binds diffuse and specular IBL maps to the corresponding texture units.
|
||||
Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx);
|
||||
|
||||
//! Unbinds diffuse and specular IBL maps.
|
||||
Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theCtx);
|
||||
|
||||
//! Fills all mipmaps of specular IBL map and diffuse IBL map with one color.
|
||||
//! So that environment illumination will be constant.
|
||||
Standard_EXPORT void Clear (const Handle(OpenGl_Context)& theCtx,
|
||||
const Graphic3d_Vec3& theColor = Graphic3d_Vec3 (1.f));
|
||||
|
||||
//! Generates specular and diffuse (irradiance) IBL maps.
|
||||
//! @param theCtx OpenGL context
|
||||
//! @param theEnvMap source environment map
|
||||
//! @param theZIsInverted flags indicates whether environment cubemap has inverted Z axis or not
|
||||
//! @param theIsTopDown flags indicates whether environment cubemap has top-down memory layout or not
|
||||
//! @param theDiffMapNbSamples number of samples in Monte-Carlo integration for diffuse IBL spherical harmonics calculation
|
||||
//! @param theSpecMapNbSamples number of samples in Monte-Carlo integration for specular IBL map generation
|
||||
//! @param theProbability controls strength of samples number reducing strategy during specular IBL map baking (see 'SpecIBLMapSamplesFactor' for details)
|
||||
//! theZIsInverted and theIsTopDown can be taken from Graphic3d_CubeMap source of environment cubemap.
|
||||
//! theDiffMapNbSamples and theSpecMapNbSamples is the main parameter directly affected to performance.
|
||||
Standard_EXPORT void Bake (const Handle(OpenGl_Context)& theCtx,
|
||||
const Handle(OpenGl_Texture)& theEnvMap,
|
||||
Standard_Boolean theZIsInverted = Standard_False,
|
||||
Standard_Boolean theIsTopDown = Standard_True,
|
||||
Standard_Size theDiffMapNbSamples = 1024,
|
||||
Standard_Size theSpecMapNbSamples = 256,
|
||||
Standard_ShortReal theProbability = 0.99f);
|
||||
|
||||
//! Returns number of mipmap levels used in specular IBL map.
|
||||
//! It can be different from value passed to creation method.
|
||||
unsigned int SpecMapLevelsNumber() const { return mySpecMapLevelsNumber; }
|
||||
|
||||
//! Returns size of IBL maps sides as power of 2.
|
||||
//! So that the real size can be calculated as 2^Pow2Size()
|
||||
unsigned int Pow2Size() const { return myPow2Size; }
|
||||
|
||||
//! Checks whether the given sizes affects to the current ones.
|
||||
//! It can be imagined as creation of new PBR environment.
|
||||
//! If creation method with this values returns the PBR environment having real sizes which are equals to current ones
|
||||
//! then this method will return false.
|
||||
//! It is handful when sizes are required to be changed.
|
||||
//! If this method returns false there is no reason to recreate PBR environment in order to change sizes.
|
||||
Standard_EXPORT bool SizesAreDifferent (unsigned int thePow2Size,
|
||||
unsigned int theSpecMapLevelsNumber) const;
|
||||
|
||||
//! Indicates whether IBL map's textures have to be bound or it is not obligate.
|
||||
bool IsNeededToBeBound() const
|
||||
{
|
||||
return myIsNeededToBeBound;
|
||||
}
|
||||
|
||||
//! Releases all OpenGL resources.
|
||||
//! It must be called before destruction.
|
||||
Standard_EXPORT virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE;
|
||||
|
||||
//! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules.
|
||||
virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE
|
||||
{
|
||||
unsigned int aDiffIBLMapSidePixelsCount = 1 << myPow2Size;
|
||||
aDiffIBLMapSidePixelsCount *= aDiffIBLMapSidePixelsCount;
|
||||
Standard_Size anEstimatedDataSize = aDiffIBLMapSidePixelsCount;
|
||||
for (unsigned int i = 0; i < mySpecMapLevelsNumber; ++i)
|
||||
{
|
||||
anEstimatedDataSize += aDiffIBLMapSidePixelsCount >> (2 * i);
|
||||
}
|
||||
anEstimatedDataSize *= 6; // cubemap sides
|
||||
anEstimatedDataSize *= 3; // channels
|
||||
return anEstimatedDataSize;
|
||||
}
|
||||
|
||||
//! Checks completeness of PBR environment.
|
||||
//! Creation method returns only completed objects or null handles otherwise.
|
||||
Standard_Boolean IsComplete() const { return myIsComplete; }
|
||||
|
||||
//! Destructor.
|
||||
//! Warning! 'Release' method must be called before destruction.
|
||||
//! Otherwise unhandled critical error will be generated.
|
||||
Standard_EXPORT virtual ~OpenGl_PBREnvironment();
|
||||
|
||||
private:
|
||||
|
||||
//! Creates new PBR environment.
|
||||
//! Parameters and logic are described in 'Create' method documentation.
|
||||
Standard_EXPORT OpenGl_PBREnvironment (const Handle(OpenGl_Context)& theCtx,
|
||||
unsigned int thePowOf2Size = 9,
|
||||
unsigned int theSpecMapLevelsNumber = 6,
|
||||
const TCollection_AsciiString& theId = "PBREnvironment");
|
||||
|
||||
private:
|
||||
|
||||
//! Enum classified the type of IBL map
|
||||
enum OpenGl_TypeOfIBLMap
|
||||
{
|
||||
OpenGl_TypeOfIBLMap_DiffuseSH,
|
||||
OpenGl_TypeOfIBLMap_Specular
|
||||
};
|
||||
|
||||
//! Initializes all textures.
|
||||
//! @return false in case of failed texture initialization
|
||||
//! Warning! Requires using of OpenGl_PBREnvironmentSentry.
|
||||
bool initTextures (const Handle(OpenGl_Context)& theCtx);
|
||||
|
||||
//! Creates frame buffer object for IBL maps generation.
|
||||
//! @return false in case of failed FBO initialization
|
||||
//! Warning! Requires using of OpenGl_PBREnvironmentSentry.
|
||||
bool initFBO (const Handle(OpenGl_Context)& theCtx);
|
||||
|
||||
//! Initializes vertex buffer object of screen rectangle.
|
||||
//! @return false in case of failed creation
|
||||
//! Warning! Requires using of OpenGl_PBREnvironmentSentry.
|
||||
bool initVAO (const Handle(OpenGl_Context)& theCtx);
|
||||
|
||||
//! Responses for diffuse (irradiance) IBL map processing.
|
||||
//! @return false in case of failed baking or clearing
|
||||
//! Warning! Requires using of OpenGl_PBREnvironmentSentry.
|
||||
bool processDiffIBLMap (const Handle(OpenGl_Context)& theCtx,
|
||||
Standard_Boolean theIsDrawAction,
|
||||
Standard_Size theNbSamples = 0);
|
||||
|
||||
//! Responses for specular IBL map processing.
|
||||
//! @return false in case of failed baking or clearing
|
||||
//! Warning! Requires using of OpenGl_PBREnvironmentSentry.
|
||||
bool processSpecIBLMap (const Handle(OpenGl_Context)& theCtx,
|
||||
Standard_Boolean theIsDrawAction,
|
||||
Standard_Integer theEnvMapSize = 1024,
|
||||
Standard_Size theNbSamples = 0,
|
||||
Standard_ShortReal theProbability = 1.f);
|
||||
|
||||
//! Checks completeness of frame buffer object for all targets
|
||||
//! (all cube map sides and levels of IBL maps).
|
||||
//! @return false in case of uncompleted frame buffer object.
|
||||
//! Warning! Requires using of OpenGl_PBREnvironmentSentry.
|
||||
bool checkFBOComplentess (const Handle(OpenGl_Context)& theCtx) const;
|
||||
|
||||
//! Version of 'Bake' without OpenGl_PBREnvironmentSetnry.
|
||||
//! Warning! Requires using of OpenGl_PBREnvironmentSentry.
|
||||
void bake (const Handle(OpenGl_Context)& theCtx,
|
||||
const Handle(OpenGl_Texture)& theEnvMap,
|
||||
Standard_Boolean theZIsInverted = Standard_False,
|
||||
Standard_Boolean theIsTopDown = Standard_True,
|
||||
Standard_Size theDiffMapNbSamples = 1024,
|
||||
Standard_Size theSpecMapNbSamples = 256,
|
||||
Standard_ShortReal theProbability = 1.f);
|
||||
|
||||
//! Version of 'Clear' without OpenGl_PBREnvironmentSetnry.
|
||||
//! Warning! Requires using of OpenGl_PBREnvironmentSentry.
|
||||
void clear (const Handle(OpenGl_Context)& theCtx,
|
||||
const Graphic3d_Vec3& theColor = Graphic3d_Vec3 (1.f));
|
||||
|
||||
private:
|
||||
|
||||
unsigned int myPow2Size; //!< size of IBL maps sides (real size can be calculated as 2^myPow2Size)
|
||||
unsigned int mySpecMapLevelsNumber; //!< number of mipmap levels used in specular IBL map
|
||||
|
||||
OpenGl_Texture myIBLMaps[2]; //!< IBL maps
|
||||
OpenGl_VertexBuffer myVBO; //!< vertex buffer object of screen rectangular
|
||||
GLuint myFBO; //!< frame buffer object to generate or clear IBL maps
|
||||
|
||||
Standard_Boolean myIsComplete; //!< completeness of PBR environment
|
||||
Standard_Boolean myIsNeededToBeBound; //!< indicates whether IBL map's textures have to be bound or it is not obligate
|
||||
|
||||
};
|
||||
|
||||
#endif // _OpenGl_PBREnvironment_HeaderFile
|
@@ -223,7 +223,8 @@ void OpenGl_Sampler::applySamplerParams (const Handle(OpenGl_Context)& theCtx,
|
||||
}
|
||||
#endif
|
||||
setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_T, aWrapMode);
|
||||
if (theTarget == GL_TEXTURE_3D)
|
||||
if (theTarget == GL_TEXTURE_3D
|
||||
|| theTarget == GL_TEXTURE_CUBE_MAP)
|
||||
{
|
||||
setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_R, aWrapMode);
|
||||
return;
|
||||
@@ -261,6 +262,13 @@ void OpenGl_Sampler::applySamplerParams (const Handle(OpenGl_Context)& theCtx,
|
||||
|
||||
setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
|
||||
}
|
||||
|
||||
if (theCtx->IsGlGreaterEqual(1, 2) &&
|
||||
(theSampler == NULL || !theSampler->isValidSampler()))
|
||||
{
|
||||
setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_BASE_LEVEL, theParams->BaseLevel());
|
||||
setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAX_LEVEL, theParams->MaxLevel());
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -19,14 +19,22 @@
|
||||
#include <OpenGl_Aspects.hxx>
|
||||
#include <OpenGl_ClippingIterator.hxx>
|
||||
#include <OpenGl_Context.hxx>
|
||||
#include <Graphic3d_CubeMapPacked.hxx>
|
||||
#include <OpenGl_ShaderManager.hxx>
|
||||
#include <OpenGl_ShaderProgram.hxx>
|
||||
#include <OpenGl_VertexBufferCompat.hxx>
|
||||
#include <OpenGl_PointSprite.hxx>
|
||||
#include <OpenGl_Workspace.hxx>
|
||||
|
||||
#include <TCollection_ExtendedString.hxx>
|
||||
|
||||
#include "../Shaders/Shaders_PBRDistribution_glsl.pxx"
|
||||
#include "../Shaders/Shaders_PBRGeometry_glsl.pxx"
|
||||
#include "../Shaders/Shaders_PBRFresnel_glsl.pxx"
|
||||
#include "../Shaders/Shaders_PBRCookTorrance_glsl.pxx"
|
||||
#include "../Shaders/Shaders_PBRIllumination_glsl.pxx"
|
||||
#include "../Shaders/Shaders_PBREnvBaking_fs.pxx"
|
||||
#include "../Shaders/Shaders_PBREnvBaking_vs.pxx"
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient)
|
||||
|
||||
namespace
|
||||
@@ -57,8 +65,8 @@ const char THE_VARY_TexCoord_Trsf[] =
|
||||
//! Auxiliary function to flip gl_PointCoord vertically
|
||||
#define THE_VEC2_glPointCoord "vec2 (gl_PointCoord.x, 1.0 - gl_PointCoord.y)"
|
||||
|
||||
//! Auxiliary function to transform normal
|
||||
const char THE_FUNC_transformNormal[] =
|
||||
//! Auxiliary function to transform normal from model to view coordinate system.
|
||||
const char THE_FUNC_transformNormal_view[] =
|
||||
EOL"vec3 transformNormal (in vec3 theNormal)"
|
||||
EOL"{"
|
||||
EOL" vec4 aResult = occWorldViewMatrixInverseTranspose"
|
||||
@@ -67,12 +75,31 @@ const char THE_FUNC_transformNormal[] =
|
||||
EOL" return normalize (aResult.xyz);"
|
||||
EOL"}";
|
||||
|
||||
//! The same function as THE_FUNC_transformNormal but is used in PBR pipeline.
|
||||
//! The normals are expected to be in world coordinate system in PBR pipeline.
|
||||
const char THE_FUNC_transformNormal_world[] =
|
||||
EOL"vec3 transformNormal (in vec3 theNormal)"
|
||||
EOL"{"
|
||||
EOL" vec4 aResult = occModelWorldMatrixInverseTranspose"
|
||||
EOL" * vec4 (theNormal, 0.0);"
|
||||
EOL" return normalize (aResult.xyz);"
|
||||
EOL"}";
|
||||
|
||||
//! Global shader variable for color definition with lighting enabled.
|
||||
const char THE_FUNC_lightDef[] =
|
||||
EOL"vec3 Ambient;" //!< Ambient contribution of light sources
|
||||
EOL"vec3 Diffuse;" //!< Diffuse contribution of light sources
|
||||
EOL"vec3 Specular;"; //!< Specular contribution of light sources
|
||||
|
||||
//! Global shader variable for color definition with lighting enabled.
|
||||
const char THE_FUNC_PBR_lightDef[] =
|
||||
EOL"vec3 DirectLighting;" //!< Accumulator of direct lighting from light sources
|
||||
EOL"vec4 BaseColor;" //!< Base color (albedo) of material for PBR
|
||||
EOL"float Metallic;" //!< Metallic coefficient of material
|
||||
EOL"float Roughness;" //!< Roughness coefficient of material
|
||||
EOL"vec3 Emission;" //!< Light intensity emitted by material
|
||||
EOL"float IOR;"; //!< Material's index of refraction
|
||||
|
||||
//! Function computes contribution of isotropic point light source
|
||||
const char THE_FUNC_pointLight[] =
|
||||
EOL"void pointLight (in int theId,"
|
||||
@@ -82,7 +109,7 @@ const char THE_FUNC_pointLight[] =
|
||||
EOL" in bool theIsFront)"
|
||||
EOL"{"
|
||||
EOL" vec3 aLight = occLight_Position (theId).xyz;"
|
||||
EOL" if (occLight_IsHeadlight (theId) == 0)"
|
||||
EOL" if (!occLight_IsHeadlight (theId))"
|
||||
EOL" {"
|
||||
EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));"
|
||||
EOL" }"
|
||||
@@ -110,6 +137,38 @@ const char THE_FUNC_pointLight[] =
|
||||
EOL" Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
|
||||
EOL"}";
|
||||
|
||||
//! Function computes contribution of isotropic point light source
|
||||
const char THE_FUNC_PBR_pointLight[] =
|
||||
EOL"void pointLight (in int theId,"
|
||||
EOL" in vec3 theNormal,"
|
||||
EOL" in vec3 theView,"
|
||||
EOL" in vec3 thePoint,"
|
||||
EOL" in bool theIsFront)"
|
||||
EOL"{"
|
||||
EOL" vec3 aLight = occLight_Position (theId).xyz;"
|
||||
EOL" if (occLight_IsHeadlight (theId))"
|
||||
EOL" {"
|
||||
EOL" aLight = vec3 (occWorldViewMatrixInverse * vec4 (aLight, 1.0));"
|
||||
EOL" }"
|
||||
EOL" aLight -= thePoint;"
|
||||
EOL
|
||||
EOL" float aDist = length (aLight);"
|
||||
EOL" aLight /= aDist;"
|
||||
EOL
|
||||
EOL" float anAtten = 1.0 / max (aDist * aDist, 0.01);"
|
||||
EOL
|
||||
EOL" theNormal = theIsFront ? theNormal : -theNormal;"
|
||||
EOL" DirectLighting += occPBRIllumination (theView,"
|
||||
EOL" aLight,"
|
||||
EOL" theNormal,"
|
||||
EOL" BaseColor,"
|
||||
EOL" Metallic,"
|
||||
EOL" Roughness,"
|
||||
EOL" IOR,"
|
||||
EOL" occLight_Specular(theId).rgb,"
|
||||
EOL" occLight_Intensity(theId) * anAtten);"
|
||||
EOL"}";
|
||||
|
||||
//! Function computes contribution of spotlight source
|
||||
const char THE_FUNC_spotLight[] =
|
||||
EOL"void spotLight (in int theId,"
|
||||
@@ -120,7 +179,7 @@ const char THE_FUNC_spotLight[] =
|
||||
EOL"{"
|
||||
EOL" vec3 aLight = occLight_Position (theId).xyz;"
|
||||
EOL" vec3 aSpotDir = occLight_SpotDirection (theId).xyz;"
|
||||
EOL" if (occLight_IsHeadlight (theId) == 0)"
|
||||
EOL" if (!occLight_IsHeadlight (theId))"
|
||||
EOL" {"
|
||||
EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));"
|
||||
EOL" aSpotDir = vec3 (occWorldViewMatrix * vec4 (aSpotDir, 0.0));"
|
||||
@@ -162,6 +221,53 @@ const char THE_FUNC_spotLight[] =
|
||||
EOL" Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
|
||||
EOL"}";
|
||||
|
||||
//! Function computes contribution of spotlight source
|
||||
const char THE_FUNC_PBR_spotLight[] =
|
||||
EOL"void spotLight (in int theId,"
|
||||
EOL" in vec3 theNormal,"
|
||||
EOL" in vec3 theView,"
|
||||
EOL" in vec3 thePoint,"
|
||||
EOL" in bool theIsFront)"
|
||||
EOL"{"
|
||||
EOL" vec3 aLight = occLight_Position (theId).xyz;"
|
||||
EOL" vec3 aSpotDir = occLight_SpotDirection (theId).xyz;"
|
||||
EOL" if (occLight_IsHeadlight (theId))"
|
||||
EOL" {"
|
||||
EOL" aLight = vec3 (occWorldViewMatrixInverse * vec4 (aLight, 1.0));"
|
||||
EOL" aSpotDir = vec3 (occWorldViewMatrixInverse * vec4 (aSpotDir, 0.0));"
|
||||
EOL" }"
|
||||
EOL" aLight -= thePoint;"
|
||||
EOL
|
||||
EOL" float aDist = length (aLight);"
|
||||
EOL" aLight /= aDist;"
|
||||
EOL
|
||||
EOL" aSpotDir = normalize (aSpotDir);"
|
||||
// light cone
|
||||
EOL" float aCosA = dot (aSpotDir, -aLight);"
|
||||
EOL" if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))"
|
||||
EOL" {"
|
||||
EOL" return;"
|
||||
EOL" }"
|
||||
EOL
|
||||
EOL" float anExponent = occLight_SpotExponent (theId);"
|
||||
EOL" float anAtten = 1.0 / max (aDist * aDist, 0.01);"
|
||||
EOL" if (anExponent > 0.0)"
|
||||
EOL" {"
|
||||
EOL" anAtten *= pow (aCosA, anExponent * 128.0);"
|
||||
EOL" }"
|
||||
EOL
|
||||
EOL" theNormal = theIsFront ? theNormal : -theNormal;"
|
||||
EOL" DirectLighting += occPBRIllumination (theView,"
|
||||
EOL" aLight,"
|
||||
EOL" theNormal,"
|
||||
EOL" BaseColor,"
|
||||
EOL" Metallic,"
|
||||
EOL" Roughness,"
|
||||
EOL" IOR,"
|
||||
EOL" occLight_Specular(theId).rgb,"
|
||||
EOL" occLight_Intensity(theId) * anAtten);"
|
||||
EOL"}";
|
||||
|
||||
//! Function computes contribution of directional light source
|
||||
const char THE_FUNC_directionalLight[] =
|
||||
EOL"void directionalLight (in int theId,"
|
||||
@@ -170,7 +276,7 @@ const char THE_FUNC_directionalLight[] =
|
||||
EOL" in bool theIsFront)"
|
||||
EOL"{"
|
||||
EOL" vec3 aLight = normalize (occLight_Position (theId).xyz);"
|
||||
EOL" if (occLight_IsHeadlight (theId) == 0)"
|
||||
EOL" if (!occLight_IsHeadlight (theId))"
|
||||
EOL" {"
|
||||
EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
|
||||
EOL" }"
|
||||
@@ -191,6 +297,31 @@ const char THE_FUNC_directionalLight[] =
|
||||
EOL" Specular += occLight_Specular (theId).rgb * aSpecl;"
|
||||
EOL"}";
|
||||
|
||||
//! Function computes contribution of directional light source
|
||||
const char THE_FUNC_PBR_directionalLight[] =
|
||||
EOL"void directionalLight (in int theId,"
|
||||
EOL" in vec3 theNormal,"
|
||||
EOL" in vec3 theView,"
|
||||
EOL" in bool theIsFront)"
|
||||
EOL"{"
|
||||
EOL" vec3 aLight = normalize (occLight_Position (theId).xyz);"
|
||||
EOL" if (occLight_IsHeadlight (theId))"
|
||||
EOL" {"
|
||||
EOL" aLight = vec3 (occWorldViewMatrixInverse * vec4 (aLight, 0.0));"
|
||||
EOL" }"
|
||||
EOL
|
||||
EOL" theNormal = theIsFront ? theNormal : -theNormal;"
|
||||
EOL" DirectLighting += occPBRIllumination (theView,"
|
||||
EOL" aLight,"
|
||||
EOL" theNormal,"
|
||||
EOL" BaseColor,"
|
||||
EOL" Metallic,"
|
||||
EOL" Roughness,"
|
||||
EOL" IOR,"
|
||||
EOL" occLight_Specular(theId).rgb,"
|
||||
EOL" occLight_Intensity(theId));"
|
||||
EOL"}";
|
||||
|
||||
//! The same as THE_FUNC_directionalLight but for the light with zero index
|
||||
//! (avoids limitations on some mobile devices).
|
||||
const char THE_FUNC_directionalLightFirst[] =
|
||||
@@ -199,7 +330,7 @@ const char THE_FUNC_directionalLightFirst[] =
|
||||
EOL" in bool theIsFront)"
|
||||
EOL"{"
|
||||
EOL" vec3 aLight = normalize (occLightSources[1].xyz);"
|
||||
EOL" if (occLight_IsHeadlight (0) == 0)"
|
||||
EOL" if (!occLight_IsHeadlight (0))"
|
||||
EOL" {"
|
||||
EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
|
||||
EOL" }"
|
||||
@@ -220,6 +351,18 @@ const char THE_FUNC_directionalLightFirst[] =
|
||||
EOL" Specular += occLightSources[0].rgb * aSpecl;"
|
||||
EOL"}";
|
||||
|
||||
//! Returns the real cubemap fetching direction considering sides orientation, memory layout and vertical flip.
|
||||
const char THE_FUNC_cubemap_vector_transform[] =
|
||||
EOL"vec3 cubemapVectorTransform (in vec3 theVector,"
|
||||
EOL" in int theYCoeff,"
|
||||
EOL" in int theZCoeff)"
|
||||
EOL"{"
|
||||
EOL" theVector = theVector.yzx;"
|
||||
EOL" theVector.y *= float(theYCoeff);"
|
||||
EOL" theVector.z *= float(theZCoeff);"
|
||||
EOL" return theVector;"
|
||||
EOL"}";
|
||||
|
||||
//! Process clipping planes in Fragment Shader.
|
||||
//! Should be added at the beginning of the main() function.
|
||||
const char THE_FRAG_CLIP_PLANES_N[] =
|
||||
@@ -422,6 +565,10 @@ OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
|
||||
OpenGl_ShaderManager::~OpenGl_ShaderManager()
|
||||
{
|
||||
myProgramList.Clear();
|
||||
if (!myPBREnvironment.IsNull())
|
||||
{
|
||||
myPBREnvironment->Release (myContext);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -585,9 +732,11 @@ void OpenGl_ShaderManager::UpdateSRgbState()
|
||||
// function : UpdateLightSourceStateTo
|
||||
// purpose : Updates state of OCCT light sources
|
||||
// =======================================================================
|
||||
void OpenGl_ShaderManager::UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights)
|
||||
void OpenGl_ShaderManager::UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights,
|
||||
Standard_Integer theSpecIBLMapLevels)
|
||||
{
|
||||
myLightSourceState.Set (theLights);
|
||||
myLightSourceState.SetSpecIBLMapLevels (theSpecIBLMapLevels);
|
||||
myLightSourceState.Update();
|
||||
switchLightPrograms();
|
||||
}
|
||||
@@ -768,6 +917,7 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
|
||||
aLightType.Type = aLight.Type();
|
||||
aLightType.IsHeadlight = aLight.IsHeadlight();
|
||||
aLightParams.Color = aLight.PackedColor();
|
||||
aLightParams.Color.a() = aLight.Intensity(); // used by PBR and ignored by old shading model
|
||||
if (aLight.Type() == Graphic3d_TOLS_DIRECTIONAL)
|
||||
{
|
||||
aLightParams.Position = -aLight.PackedDirection();
|
||||
@@ -813,6 +963,11 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
|
||||
aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
|
||||
myLightParamsArray.First().Packed());
|
||||
}
|
||||
|
||||
if (const OpenGl_ShaderUniformLocation aLocation = theProgram->GetStateLocation (OpenGl_OCCT_NB_SPEC_IBL_LEVELS))
|
||||
{
|
||||
theProgram->SetUniform (myContext, aLocation, myLightSourceState.SpecIBLMapLevels());
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -1164,18 +1319,18 @@ void OpenGl_ShaderManager::pushMaterialState (const Handle(OpenGl_ShaderProgram)
|
||||
}
|
||||
|
||||
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());
|
||||
myContext->core11->glMaterialfv(aFrontFace, GL_SPECULAR, aFrontMat.Specular.GetData());
|
||||
myContext->core11->glMaterialfv(aFrontFace, GL_EMISSION, aFrontMat.Emission.GetData());
|
||||
myContext->core11->glMaterialf (aFrontFace, GL_SHININESS, aFrontMat.Shine());
|
||||
myContext->core11->glMaterialfv(aFrontFace, GL_AMBIENT, aFrontMat.Common.Ambient.GetData());
|
||||
myContext->core11->glMaterialfv(aFrontFace, GL_DIFFUSE, aFrontMat.Common.Diffuse.GetData());
|
||||
myContext->core11->glMaterialfv(aFrontFace, GL_SPECULAR, aFrontMat.Common.Specular.GetData());
|
||||
myContext->core11->glMaterialfv(aFrontFace, GL_EMISSION, aFrontMat.Common.Emission.GetData());
|
||||
myContext->core11->glMaterialf (aFrontFace, GL_SHININESS, aFrontMat.Common.Shine());
|
||||
if (myMaterialState.ToDistinguish())
|
||||
{
|
||||
myContext->core11->glMaterialfv(GL_BACK, GL_AMBIENT, aBackMat.Ambient.GetData());
|
||||
myContext->core11->glMaterialfv(GL_BACK, GL_DIFFUSE, aBackMat.Diffuse.GetData());
|
||||
myContext->core11->glMaterialfv(GL_BACK, GL_SPECULAR, aBackMat.Specular.GetData());
|
||||
myContext->core11->glMaterialfv(GL_BACK, GL_EMISSION, aBackMat.Emission.GetData());
|
||||
myContext->core11->glMaterialf (GL_BACK, GL_SHININESS, aBackMat.Shine());
|
||||
myContext->core11->glMaterialfv(GL_BACK, GL_AMBIENT, aBackMat.Common.Ambient.GetData());
|
||||
myContext->core11->glMaterialfv(GL_BACK, GL_DIFFUSE, aBackMat.Common.Diffuse.GetData());
|
||||
myContext->core11->glMaterialfv(GL_BACK, GL_SPECULAR, aBackMat.Common.Specular.GetData());
|
||||
myContext->core11->glMaterialfv(GL_BACK, GL_EMISSION, aBackMat.Common.Emission.GetData());
|
||||
myContext->core11->glMaterialf (GL_BACK, GL_SHININESS, aBackMat.Common.Shine());
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
@@ -1191,15 +1346,25 @@ void OpenGl_ShaderManager::pushMaterialState (const Handle(OpenGl_ShaderProgram)
|
||||
theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
|
||||
myMaterialState.ToDistinguish() ? 1 : 0);
|
||||
|
||||
if (const OpenGl_ShaderUniformLocation aLocFront = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL))
|
||||
if (const OpenGl_ShaderUniformLocation& aLocPbrFront = theProgram->GetStateLocation (OpenGl_OCCT_PBR_FRONT_MATERIAL))
|
||||
{
|
||||
theProgram->SetUniform (myContext, aLocFront, OpenGl_Material::NbOfVec4(),
|
||||
aFrontMat.Packed());
|
||||
theProgram->SetUniform (myContext, aLocPbrFront, OpenGl_MaterialPBR::NbOfVec4(),
|
||||
aFrontMat.Pbr.Packed());
|
||||
}
|
||||
if (const OpenGl_ShaderUniformLocation aLocBack = theProgram->GetStateLocation (OpenGl_OCCT_BACK_MATERIAL))
|
||||
if (const OpenGl_ShaderUniformLocation aLocPbrBack = theProgram->GetStateLocation (OpenGl_OCCT_PBR_BACK_MATERIAL))
|
||||
{
|
||||
theProgram->SetUniform (myContext, aLocBack, OpenGl_Material::NbOfVec4(),
|
||||
aBackMat.Packed());
|
||||
theProgram->SetUniform (myContext, aLocPbrBack, OpenGl_MaterialPBR::NbOfVec4(),
|
||||
aBackMat.Pbr.Packed());
|
||||
}
|
||||
if (const OpenGl_ShaderUniformLocation aLocFront = theProgram->GetStateLocation (OpenGl_OCCT_COMMON_FRONT_MATERIAL))
|
||||
{
|
||||
theProgram->SetUniform (myContext, aLocFront, OpenGl_MaterialCommon::NbOfVec4(),
|
||||
aFrontMat.Common.Packed());
|
||||
}
|
||||
if (const OpenGl_ShaderUniformLocation aLocBack = theProgram->GetStateLocation (OpenGl_OCCT_COMMON_BACK_MATERIAL))
|
||||
{
|
||||
theProgram->SetUniform (myContext, aLocBack, OpenGl_MaterialCommon::NbOfVec4(),
|
||||
aBackMat.Common.Packed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1614,7 +1779,8 @@ int OpenGl_ShaderManager::defaultGlslVersion (const Handle(Graphic3d_ShaderProgr
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((theBits & OpenGl_PO_StippleLine) != 0)
|
||||
if ((theBits & OpenGl_PO_StippleLine) != 0
|
||||
|| theProgram->IsPBR())
|
||||
{
|
||||
if (myContext->IsGlGreaterEqual (3, 0))
|
||||
{
|
||||
@@ -1654,6 +1820,11 @@ int OpenGl_ShaderManager::defaultGlslVersion (const Handle(Graphic3d_ShaderProgr
|
||||
}
|
||||
else
|
||||
{
|
||||
if (theProgram->IsPBR()
|
||||
&& myContext->IsGlGreaterEqual (3, 0))
|
||||
{
|
||||
theProgram->SetHeader ("#version 300 es");
|
||||
}
|
||||
if ((theBits & OpenGl_PO_WriteOit) != 0
|
||||
|| (theBits & OpenGl_PO_StippleLine) != 0)
|
||||
{
|
||||
@@ -1863,7 +2034,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
|
||||
}
|
||||
else if ((theBits & OpenGl_PO_TextureEnv) != 0)
|
||||
{
|
||||
aSrcVertExtraFunc = THE_FUNC_transformNormal;
|
||||
aSrcVertExtraFunc = THE_FUNC_transformNormal_view;
|
||||
|
||||
aSrcVertExtraMain +=
|
||||
EOL" vec4 aPosition = occWorldViewMatrix * occModelWorldMatrix * occVertex;"
|
||||
@@ -2046,7 +2217,8 @@ TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TColl
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights,
|
||||
Standard_Boolean theHasVertColor)
|
||||
Standard_Boolean theHasVertColor,
|
||||
Standard_Boolean theIsPBR)
|
||||
{
|
||||
TCollection_AsciiString aLightsFunc, aLightsLoop;
|
||||
theNbLights = 0;
|
||||
@@ -2122,8 +2294,19 @@ TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integ
|
||||
}
|
||||
aLightsLoop += EOL" }";
|
||||
}
|
||||
|
||||
if (theIsPBR)
|
||||
{
|
||||
aLightsFunc += Shaders_PBRDistribution_glsl;
|
||||
aLightsFunc += Shaders_PBRGeometry_glsl;
|
||||
aLightsFunc += Shaders_PBRFresnel_glsl;
|
||||
aLightsFunc += Shaders_PBRCookTorrance_glsl;
|
||||
aLightsFunc += Shaders_PBRIllumination_glsl;
|
||||
}
|
||||
|
||||
if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) == 1
|
||||
&& theNbLights == 1)
|
||||
&& theNbLights == 1
|
||||
&& !theIsPBR)
|
||||
{
|
||||
// use the version with hard-coded first index
|
||||
aLightsLoop = EOL" directionalLightFirst(theNormal, theView, theIsFront);";
|
||||
@@ -2131,15 +2314,15 @@ TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integ
|
||||
}
|
||||
else if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) > 0)
|
||||
{
|
||||
aLightsFunc += THE_FUNC_directionalLight;
|
||||
aLightsFunc += theIsPBR ? THE_FUNC_PBR_directionalLight : THE_FUNC_directionalLight;
|
||||
}
|
||||
if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_POSITIONAL) > 0)
|
||||
{
|
||||
aLightsFunc += THE_FUNC_pointLight;
|
||||
aLightsFunc += theIsPBR ? THE_FUNC_PBR_pointLight : THE_FUNC_pointLight;
|
||||
}
|
||||
if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_SPOT) > 0)
|
||||
{
|
||||
aLightsFunc += THE_FUNC_spotLight;
|
||||
aLightsFunc += theIsPBR ? THE_FUNC_PBR_spotLight : THE_FUNC_spotLight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2151,7 +2334,9 @@ TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integ
|
||||
aGetMatDiffuse = "getVertColor();";
|
||||
}
|
||||
|
||||
return TCollection_AsciiString()
|
||||
if (!theIsPBR)
|
||||
{
|
||||
return TCollection_AsciiString()
|
||||
+ THE_FUNC_lightDef
|
||||
+ aLightsFunc
|
||||
+ EOL
|
||||
@@ -2175,6 +2360,42 @@ TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integ
|
||||
EOL" + aMatEmission.rgb;"
|
||||
EOL" return vec4 (aColor, aMatDiffuse.a);"
|
||||
EOL"}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return TCollection_AsciiString()
|
||||
+ THE_FUNC_PBR_lightDef
|
||||
+ aLightsFunc
|
||||
+ EOL
|
||||
EOL"vec4 computeLighting (in vec3 theNormal,"
|
||||
EOL" in vec3 theView,"
|
||||
EOL" in vec4 thePoint,"
|
||||
EOL" in bool theIsFront)"
|
||||
EOL"{"
|
||||
EOL" DirectLighting = vec3(0.0);"
|
||||
EOL" BaseColor = " + (theHasVertColor ? "getVertColor();" : "getBaseColor (theIsFront);")
|
||||
+ EOL" Metallic = theIsFront ? occPBRFrontMaterial_Metallic() : occPBRBackMaterial_Metallic();"
|
||||
EOL" Roughness = theIsFront ? occPBRFrontMaterial_Roughness() : occPBRBackMaterial_Roughness();"
|
||||
EOL" IOR = theIsFront ? occPBRFrontMaterial_IOR() : occPBRBackMaterial_IOR();"
|
||||
EOL" Emission = theIsFront ? occPBRFrontMaterial_Emission() : occPBRBackMaterial_Emission();"
|
||||
EOL" vec3 aPoint = thePoint.xyz / thePoint.w;"
|
||||
+ aLightsLoop
|
||||
+ EOL" vec3 aColor = DirectLighting;"
|
||||
EOL" vec3 anIndirectLightingSpec = occPBRFresnel (BaseColor.rgb, Metallic, IOR);"
|
||||
EOL" Roughness = theIsFront ? occPBRFrontMaterial_NormalizedRoughness() : occPBRBackMaterial_NormalizedRoughness();"
|
||||
EOL" vec2 aCoeff = occTexture2D (occEnvLUT, vec2(abs(dot(theView, theNormal)), Roughness)).xy;"
|
||||
EOL" anIndirectLightingSpec *= aCoeff.x;"
|
||||
EOL" anIndirectLightingSpec += aCoeff.y;"
|
||||
EOL" anIndirectLightingSpec *= occTextureCubeLod (occSpecIBLMap, -reflect (theView, theNormal), Roughness * float (occNbSpecIBLLevels - 1)).rgb;"
|
||||
EOL" vec3 aRefractionCoeff = 1.0 - occPBRFresnel (BaseColor.rgb, Metallic, Roughness, IOR, abs(dot(theView, theNormal)));"
|
||||
EOL" aRefractionCoeff *= (1.0 - Metallic);"
|
||||
EOL" vec3 anIndirectLightingDiff = aRefractionCoeff * BaseColor.rgb * BaseColor.a;"
|
||||
EOL" anIndirectLightingDiff *= occDiffIBLMap (theNormal).rgb;"
|
||||
EOL" aColor += occLightAmbient.rgb * (anIndirectLightingDiff + anIndirectLightingSpec);"
|
||||
EOL" aColor += Emission;"
|
||||
EOL" return vec4 (aColor, mix(1.0, BaseColor.a, aRefractionCoeff.x));"
|
||||
EOL"}";
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -2278,9 +2499,9 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 BackColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
|
||||
|
||||
Standard_Integer aNbLights = 0;
|
||||
const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcVertColor.IsEmpty());
|
||||
const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcVertColor.IsEmpty(), false);
|
||||
aSrcVert = TCollection_AsciiString()
|
||||
+ THE_FUNC_transformNormal
|
||||
+ THE_FUNC_transformNormal_view
|
||||
+ EOL
|
||||
+ aSrcVertColor
|
||||
+ aLights
|
||||
@@ -2334,9 +2555,12 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
// =======================================================================
|
||||
Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
|
||||
const Standard_Integer theBits,
|
||||
const Standard_Boolean theIsFlatNormal)
|
||||
const Standard_Boolean theIsFlatNormal,
|
||||
const Standard_Boolean theIsPBR)
|
||||
{
|
||||
#define thePhongCompLight "computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing)"
|
||||
TCollection_AsciiString aPosition = theIsPBR ? "PositionWorld" : "Position";
|
||||
TCollection_AsciiString aPhongCompLight = TCollection_AsciiString() +
|
||||
"computeLighting (normalize (Normal), normalize (View), " + aPosition + ", gl_FrontFacing)";
|
||||
const bool isFlatNormal = theIsFlatNormal
|
||||
&& myContext->hasFlatShading != OpenGl_FeatureNotAvailable;
|
||||
const char* aDFdxSignReversion = "";
|
||||
@@ -2357,9 +2581,16 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
}
|
||||
#endif
|
||||
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
|
||||
aProgramSrc->SetPBR (theIsPBR);
|
||||
|
||||
TCollection_AsciiString aSrcVert, aSrcVertExtraFunc, aSrcVertExtraMain;
|
||||
TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
|
||||
TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return " thePhongCompLight "; }";
|
||||
TCollection_AsciiString aSrcFragGetColor = TCollection_AsciiString() + EOL"vec4 getColor(void) { return " + aPhongCompLight + "; }";
|
||||
TCollection_AsciiString aSrcFragPBRGetBaseColor = TCollection_AsciiString() +
|
||||
EOL"vec4 getBaseColor(in bool theIsFront)"
|
||||
EOL"{"
|
||||
EOL" return theIsFront ? occPBRFrontMaterial_Color() : occPBRBackMaterial_Color();"
|
||||
EOL"}";
|
||||
OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
|
||||
if ((theBits & OpenGl_PO_IsPoint) != 0)
|
||||
{
|
||||
@@ -2378,7 +2609,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
#endif
|
||||
|
||||
aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerPointSprite", Graphic3d_TOS_FRAGMENT));
|
||||
aSrcFragGetColor = pointSpriteShadingSrc (thePhongCompLight, theBits);
|
||||
aSrcFragGetColor = pointSpriteShadingSrc (aPhongCompLight, theBits);
|
||||
}
|
||||
|
||||
if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
|
||||
@@ -2399,12 +2630,24 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
|
||||
aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
|
||||
|
||||
aSrcFragGetColor =
|
||||
EOL"vec4 getColor(void)"
|
||||
EOL"{"
|
||||
EOL" vec4 aColor = " thePhongCompLight ";"
|
||||
EOL" return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) * aColor;"
|
||||
EOL"}";
|
||||
if (!theIsPBR)
|
||||
{
|
||||
aSrcFragGetColor = TCollection_AsciiString() +
|
||||
EOL"vec4 getColor(void)"
|
||||
EOL"{"
|
||||
EOL" vec4 aColor = " + aPhongCompLight + ";"
|
||||
EOL" return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) * aColor;"
|
||||
EOL"}";
|
||||
}
|
||||
else
|
||||
{
|
||||
aSrcFragPBRGetBaseColor = TCollection_AsciiString() +
|
||||
EOL"vec4 getBaseColor (in bool theIsFront)"
|
||||
EOL"{"
|
||||
EOL" return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) *"
|
||||
EOL" (theIsFront ? occPBRFrontMaterial_Color() : occPBRBackMaterial_Color());"
|
||||
EOL"}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2448,13 +2691,13 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
{
|
||||
aSrcFragExtraOut += EOL"vec3 Normal;";
|
||||
aSrcFragExtraMain += TCollection_AsciiString()
|
||||
+ EOL" Normal = " + aDFdxSignReversion + "normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));"
|
||||
+ EOL" Normal = " + aDFdxSignReversion + "normalize (cross (dFdx (" + aPosition + ".xyz / " + aPosition + ".w), dFdy (" + aPosition + ".xyz / " + aPosition + ".w)));"
|
||||
EOL" if (!gl_FrontFacing) { Normal = -Normal; }";
|
||||
}
|
||||
else
|
||||
{
|
||||
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec3 Normal", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
|
||||
aSrcVertExtraFunc += THE_FUNC_transformNormal;
|
||||
aSrcVertExtraFunc += theIsPBR ? THE_FUNC_transformNormal_world : THE_FUNC_transformNormal_view;
|
||||
aSrcVertExtraMain += EOL" Normal = transformNormal (occNormal);";
|
||||
}
|
||||
|
||||
@@ -2468,7 +2711,15 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
EOL"{"
|
||||
EOL" PositionWorld = occModelWorldMatrix * occVertex;"
|
||||
EOL" Position = occWorldViewMatrix * PositionWorld;"
|
||||
+ EOL" View = vec3 (0.0, 0.0, 1.0);"
|
||||
EOL" if (occProjectionMatrix[3][3] == 1.0)"
|
||||
EOL" {"
|
||||
EOL" View = vec3(0.0, 0.0, 1.0);"
|
||||
EOL" }"
|
||||
EOL" else"
|
||||
EOL" {"
|
||||
EOL" View = -Position.xyz;"
|
||||
EOL" }"
|
||||
+ (theIsPBR ? EOL" View = (occWorldViewMatrixInverse * vec4(View, 0.0)).xyz;" : "")
|
||||
+ aSrcVertExtraMain
|
||||
+ THE_VERT_gl_Position
|
||||
+ EOL"}";
|
||||
@@ -2479,11 +2730,12 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
: EOL"#define getFinalColor getColor";
|
||||
|
||||
Standard_Integer aNbLights = 0;
|
||||
const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcFragGetVertColor.IsEmpty());
|
||||
const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcFragGetVertColor.IsEmpty(), theIsPBR);
|
||||
aSrcFrag = TCollection_AsciiString()
|
||||
+ EOL
|
||||
+ aSrcFragExtraOut
|
||||
+ aSrcFragGetVertColor
|
||||
+ (theIsPBR ? aSrcFragPBRGetBaseColor : "")
|
||||
+ aLights
|
||||
+ aSrcFragGetColor
|
||||
+ EOL
|
||||
@@ -2493,12 +2745,13 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
+ EOL" occSetFragColor (getFinalColor());"
|
||||
+ EOL"}";
|
||||
|
||||
const TCollection_AsciiString aProgId = TCollection_AsciiString (theIsFlatNormal ? "flat-" : "phong-") + genLightKey (myLightSourceState.LightSources()) + "-";
|
||||
const TCollection_AsciiString aProgId = TCollection_AsciiString (theIsFlatNormal ? "flat-" : "phong-") + (theIsPBR ? "pbr-" : "") + genLightKey (myLightSourceState.LightSources()) + "-";
|
||||
defaultGlslVersion (aProgramSrc, aProgId, theBits, isFlatNormal);
|
||||
aProgramSrc->SetDefaultSampler (false);
|
||||
aProgramSrc->SetNbLightsMax (aNbLights);
|
||||
aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
|
||||
aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
|
||||
|
||||
const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
|
||||
aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts, "", "", aNbGeomInputVerts));
|
||||
aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcGeom, Graphic3d_TOS_GEOMETRY, aUniforms, aStageInOuts, "geomIn", "geomOut", aNbGeomInputVerts));
|
||||
@@ -2787,6 +3040,48 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramBoundBox()
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : preparePBREnvBakingProgram
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean OpenGl_ShaderManager::preparePBREnvBakingProgram()
|
||||
{
|
||||
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
|
||||
OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
|
||||
|
||||
TCollection_AsciiString aSrcVert = TCollection_AsciiString()
|
||||
+ THE_FUNC_cubemap_vector_transform
|
||||
+ Shaders_PBREnvBaking_vs;
|
||||
|
||||
TCollection_AsciiString aSrcFrag = TCollection_AsciiString()
|
||||
+ THE_FUNC_cubemap_vector_transform
|
||||
+ Shaders_PBRDistribution_glsl
|
||||
+ Shaders_PBREnvBaking_fs;
|
||||
|
||||
// constant array definition requires OpenGL 2.1+ or OpenGL ES 3.0+
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
#else
|
||||
aProgramSrc->SetHeader ("#version 120");
|
||||
#endif
|
||||
|
||||
defaultGlslVersion (aProgramSrc, "pbr_env_baking", 0);
|
||||
aProgramSrc->SetDefaultSampler (false);
|
||||
aProgramSrc->SetNbLightsMax (0);
|
||||
aProgramSrc->SetNbClipPlanesMax (0);
|
||||
aProgramSrc->SetPBR (true);
|
||||
aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
|
||||
aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
|
||||
TCollection_AsciiString aKey;
|
||||
if (!Create (aProgramSrc, aKey, myPBREnvBakingProgram))
|
||||
{
|
||||
myPBREnvBakingProgram = new OpenGl_ShaderProgram(); // just mark as invalid
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetBgCubeMapProgram
|
||||
// purpose :
|
||||
@@ -2795,24 +3090,23 @@ const Handle(Graphic3d_ShaderProgram)& OpenGl_ShaderManager::GetBgCubeMapProgram
|
||||
{
|
||||
if (myBgCubeMapProgram.IsNull())
|
||||
{
|
||||
myBgCubeMapProgram = new Graphic3d_ShaderProgram;
|
||||
myBgCubeMapProgram = new Graphic3d_ShaderProgram();
|
||||
|
||||
OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
|
||||
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable("vec3 ViewDirection", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
|
||||
aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uZCoeff", Graphic3d_TOS_VERTEX)); // defines orientation of Z axis to make horizontal flip
|
||||
aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uYCoeff", Graphic3d_TOS_VERTEX)); // defines orientation of Y axis to make vertical flip
|
||||
aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("samplerCube occSampler0", Graphic3d_TOS_FRAGMENT));
|
||||
aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uYCoeff", Graphic3d_TOS_VERTEX));
|
||||
aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uZCoeff", Graphic3d_TOS_VERTEX));
|
||||
|
||||
TCollection_AsciiString aSrcVert =
|
||||
EOL"void main()"
|
||||
TCollection_AsciiString aSrcVert = TCollection_AsciiString()
|
||||
+ THE_FUNC_cubemap_vector_transform
|
||||
+ EOL"void main()"
|
||||
EOL"{"
|
||||
EOL" vec4 aViewDirection = occProjectionMatrixInverse * vec4(occVertex.xy, 0.0, 1.0);"
|
||||
EOL" aViewDirection /= aViewDirection.w;"
|
||||
EOL" aViewDirection.w = 0.0;"
|
||||
EOL" ViewDirection = normalize((occWorldViewMatrixInverse * aViewDirection).xyz);"
|
||||
EOL" ViewDirection = ViewDirection.yzx;" // is needed to sync horizon and frontal camera position
|
||||
EOL" ViewDirection.y *= uYCoeff;"
|
||||
EOL" ViewDirection.z *= uZCoeff;"
|
||||
EOL" ViewDirection = cubemapVectorTransform (ViewDirection, uYCoeff, uZCoeff);"
|
||||
EOL" gl_Position = vec4(occVertex.xy, 0.0, 1.0);"
|
||||
EOL"}";
|
||||
|
||||
@@ -2820,15 +3114,15 @@ const Handle(Graphic3d_ShaderProgram)& OpenGl_ShaderManager::GetBgCubeMapProgram
|
||||
EOL"#define occEnvCubemap occSampler0"
|
||||
EOL"void main()"
|
||||
EOL"{"
|
||||
EOL" occSetFragColor (vec4(texture(occEnvCubemap, ViewDirection).rgb, 1.0));"
|
||||
EOL" occSetFragColor (vec4(occTextureCube (occEnvCubemap, ViewDirection).rgb, 1.0));"
|
||||
EOL"}";
|
||||
|
||||
defaultGlslVersion(myBgCubeMapProgram, "background_cubemap", 0);
|
||||
myBgCubeMapProgram->SetDefaultSampler(false);
|
||||
myBgCubeMapProgram->SetNbLightsMax(0);
|
||||
myBgCubeMapProgram->SetNbClipPlanesMax(0);
|
||||
myBgCubeMapProgram->AttachShader(OpenGl_ShaderObject::CreateFromSource(aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
|
||||
myBgCubeMapProgram->AttachShader(OpenGl_ShaderObject::CreateFromSource(aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
|
||||
defaultGlslVersion (myBgCubeMapProgram, "background_cubemap", 0);
|
||||
myBgCubeMapProgram->SetDefaultSampler (false);
|
||||
myBgCubeMapProgram->SetNbLightsMax (0);
|
||||
myBgCubeMapProgram->SetNbClipPlanesMax (0);
|
||||
myBgCubeMapProgram->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
|
||||
myBgCubeMapProgram->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
|
||||
}
|
||||
|
||||
return myBgCubeMapProgram;
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
|
||||
#include <OpenGl_PBREnvironment.hxx>
|
||||
#include <OpenGl_SetOfShaderPrograms.hxx>
|
||||
#include <OpenGl_ShaderStates.hxx>
|
||||
#include <OpenGl_Aspects.hxx>
|
||||
@@ -249,16 +250,44 @@ public:
|
||||
//! Returns bounding box vertex buffer.
|
||||
const Handle(OpenGl_VertexBuffer)& BoundBoxVertBuffer() const { return myBoundBoxVertBuffer; }
|
||||
|
||||
//! Bind program for IBL maps generation in PBR pipeline.
|
||||
Standard_Boolean BindPBREnvBakingProgram()
|
||||
{
|
||||
if (myPBREnvBakingProgram.IsNull())
|
||||
{
|
||||
preparePBREnvBakingProgram();
|
||||
}
|
||||
return myContext->BindProgram (myPBREnvBakingProgram);
|
||||
}
|
||||
|
||||
//! Generates shader program to render environment cubemap as background.
|
||||
Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgCubeMapProgram ();
|
||||
|
||||
//! Resets PBR shading models to corresponding non-PBR ones if PBR is not allowed.
|
||||
static Graphic3d_TypeOfShadingModel PBRShadingModelFallback (Graphic3d_TypeOfShadingModel theShadingModel,
|
||||
Standard_Boolean theIsPbrAllowed = Standard_False)
|
||||
{
|
||||
if (theIsPbrAllowed)
|
||||
{
|
||||
return theShadingModel;
|
||||
}
|
||||
|
||||
switch (theShadingModel)
|
||||
{
|
||||
case Graphic3d_TOSM_PBR: return Graphic3d_TOSM_FRAGMENT;
|
||||
case Graphic3d_TOSM_PBR_FACET: return Graphic3d_TOSM_FACET;
|
||||
default: return theShadingModel;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Returns current state of OCCT light sources.
|
||||
const OpenGl_LightSourceState& LightSourceState() const { return myLightSourceState; }
|
||||
|
||||
//! Updates state of OCCT light sources.
|
||||
Standard_EXPORT void UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights);
|
||||
Standard_EXPORT void UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights,
|
||||
Standard_Integer theSpecIBLMapLevels = 0);
|
||||
|
||||
//! Invalidate state of OCCT light sources.
|
||||
Standard_EXPORT void UpdateLightSourceState();
|
||||
@@ -443,6 +472,7 @@ public:
|
||||
|
||||
//! Choose Shading Model for filled primitives.
|
||||
//! Fallbacks to FACET model if there are no normal attributes.
|
||||
//! Fallbacks to corresponding non-PBR models if PBR is unavailable.
|
||||
Graphic3d_TypeOfShadingModel ChooseFaceShadingModel (Graphic3d_TypeOfShadingModel theCustomModel,
|
||||
bool theHasNodalNormals) const
|
||||
{
|
||||
@@ -460,12 +490,17 @@ public:
|
||||
case Graphic3d_TOSM_VERTEX:
|
||||
case Graphic3d_TOSM_FRAGMENT:
|
||||
return theHasNodalNormals ? aModel : Graphic3d_TOSM_FACET;
|
||||
case Graphic3d_TOSM_PBR:
|
||||
return PBRShadingModelFallback (theHasNodalNormals ? aModel : Graphic3d_TOSM_PBR_FACET, IsPbrAllowed());
|
||||
case Graphic3d_TOSM_PBR_FACET:
|
||||
return PBRShadingModelFallback (aModel, IsPbrAllowed());
|
||||
}
|
||||
return Graphic3d_TOSM_UNLIT;
|
||||
}
|
||||
|
||||
//! Choose Shading Model for line primitives.
|
||||
//! Fallbacks to UNLIT model if there are no normal attributes.
|
||||
//! Fallbacks to corresponding non-PBR models if PBR is unavailable.
|
||||
Graphic3d_TypeOfShadingModel ChooseLineShadingModel (Graphic3d_TypeOfShadingModel theCustomModel,
|
||||
bool theHasNodalNormals) const
|
||||
{
|
||||
@@ -483,6 +518,10 @@ public:
|
||||
case Graphic3d_TOSM_VERTEX:
|
||||
case Graphic3d_TOSM_FRAGMENT:
|
||||
return theHasNodalNormals ? aModel : Graphic3d_TOSM_UNLIT;
|
||||
case Graphic3d_TOSM_PBR:
|
||||
return PBRShadingModelFallback (theHasNodalNormals ? aModel : Graphic3d_TOSM_UNLIT, IsPbrAllowed());
|
||||
case Graphic3d_TOSM_PBR_FACET:
|
||||
return Graphic3d_TOSM_UNLIT;
|
||||
}
|
||||
return Graphic3d_TOSM_UNLIT;
|
||||
}
|
||||
@@ -648,11 +687,13 @@ protected:
|
||||
{
|
||||
switch (theShadingModel)
|
||||
{
|
||||
case Graphic3d_TOSM_UNLIT: return prepareStdProgramUnlit (theProgram, theBits, false);
|
||||
case Graphic3d_TOSM_FACET: return prepareStdProgramPhong (theProgram, theBits, true);
|
||||
case Graphic3d_TOSM_VERTEX: return prepareStdProgramGouraud(theProgram, theBits);
|
||||
case Graphic3d_TOSM_UNLIT: return prepareStdProgramUnlit (theProgram, theBits, false);
|
||||
case Graphic3d_TOSM_FACET: return prepareStdProgramPhong (theProgram, theBits, true);
|
||||
case Graphic3d_TOSM_VERTEX: return prepareStdProgramGouraud(theProgram, theBits);
|
||||
case Graphic3d_TOSM_DEFAULT:
|
||||
case Graphic3d_TOSM_FRAGMENT: return prepareStdProgramPhong (theProgram, theBits, false);
|
||||
case Graphic3d_TOSM_FRAGMENT: return prepareStdProgramPhong (theProgram, theBits, false);
|
||||
case Graphic3d_TOSM_PBR: return prepareStdProgramPhong (theProgram, theBits, false, true);
|
||||
case Graphic3d_TOSM_PBR_FACET: return prepareStdProgramPhong (theProgram, theBits, true, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -663,15 +704,19 @@ protected:
|
||||
|
||||
//! Prepare standard GLSL program with per-pixel lighting.
|
||||
//! @param theIsFlatNormal when TRUE, the Vertex normals will be ignored and Face normal will be computed instead
|
||||
//! @param theIsPBR when TRUE, the PBR pipeline will be activated
|
||||
Standard_EXPORT Standard_Boolean prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
|
||||
const Standard_Integer theBits,
|
||||
const Standard_Boolean theIsFlatNormal = false);
|
||||
const Standard_Boolean theIsFlatNormal = false,
|
||||
const Standard_Boolean theIsPBR = false);
|
||||
|
||||
//! Define computeLighting GLSL function depending on current lights configuration
|
||||
//! @param theNbLights [out] number of defined light sources
|
||||
//! @param theHasVertColor [in] flag to use getVertColor() instead of Ambient and Diffuse components of active material
|
||||
//! @param theIsPBR [in] flag to activate PBR pipeline
|
||||
Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights,
|
||||
Standard_Boolean theHasVertColor);
|
||||
Standard_Boolean theHasVertColor,
|
||||
Standard_Boolean theIsPBR);
|
||||
|
||||
//! Bind specified program to current context and apply state.
|
||||
Standard_EXPORT Standard_Boolean bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram);
|
||||
@@ -697,6 +742,13 @@ protected:
|
||||
OpenGl_ShaderObject::ShaderVariableList& theStageInOuts,
|
||||
Standard_Integer theBits);
|
||||
|
||||
//! Prepare GLSL source for IBL generation used in PBR pipeline.
|
||||
Standard_EXPORT Standard_Boolean preparePBREnvBakingProgram();
|
||||
|
||||
//! Checks whether one of PBR shading models is set as default model.
|
||||
Standard_Boolean IsPbrAllowed() const { return myShadingModel == Graphic3d_TOSM_PBR
|
||||
|| myShadingModel == Graphic3d_TOSM_PBR_FACET; }
|
||||
|
||||
protected:
|
||||
|
||||
//! Packed properties of light source
|
||||
@@ -769,12 +821,15 @@ protected:
|
||||
Handle(OpenGl_ShaderProgram) myOitCompositingProgram[2]; //!< standard program for OIT compositing (default and MSAA).
|
||||
OpenGl_MapOfShaderPrograms myMapOfLightPrograms; //!< map of lighting programs depending on lights configuration
|
||||
|
||||
Handle(OpenGl_ShaderProgram) myPBREnvBakingProgram;//!< program for IBL maps generation used in PBR pipeline
|
||||
Handle(Graphic3d_ShaderProgram) myBgCubeMapProgram; //!< program for background cubemap rendering
|
||||
|
||||
Handle(OpenGl_ShaderProgram) myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs
|
||||
|
||||
Handle(OpenGl_VertexBuffer) myBoundBoxVertBuffer; //!< bounding box vertex buffer
|
||||
|
||||
mutable Handle(OpenGl_PBREnvironment) myPBREnvironment; //!< manager of IBL maps used in PBR pipeline
|
||||
|
||||
OpenGl_Context* myContext; //!< OpenGL context
|
||||
Standard_Boolean mySRgbState; //!< track sRGB state
|
||||
|
||||
|
@@ -56,38 +56,42 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
|
||||
"occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
|
||||
"occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
|
||||
|
||||
"occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
|
||||
"occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS
|
||||
"occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
|
||||
"occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
|
||||
"occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS
|
||||
"occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
|
||||
|
||||
"occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
|
||||
"occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
|
||||
"occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
|
||||
"occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
|
||||
"occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
|
||||
"occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
|
||||
"occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
|
||||
"occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
|
||||
|
||||
"occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
|
||||
"occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
|
||||
"occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
|
||||
"occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
|
||||
"occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF
|
||||
"occColor", // OpenGl_OCCT_COLOR
|
||||
"occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
|
||||
"occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
|
||||
"occPbrFrontMaterial", // OpenGl_OCCT_PBR_FRONT_MATERIAL
|
||||
"occPbrBackMaterial", // OpenGl_OCCT_PBR_BACK_MATERIAL
|
||||
"occFrontMaterial", // OpenGl_OCCT_COMMON_FRONT_MATERIAL
|
||||
"occBackMaterial", // OpenGl_OCCT_COMMON_BACK_MATERIAL
|
||||
"occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF
|
||||
"occColor", // OpenGl_OCCT_COLOR
|
||||
|
||||
"occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
|
||||
"occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
|
||||
"occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
|
||||
"occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
|
||||
|
||||
"occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
|
||||
"occPointSize", // OpenGl_OCCT_POINT_SIZE
|
||||
"occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
|
||||
"occPointSize", // OpenGl_OCCT_POINT_SIZE
|
||||
|
||||
"occViewport", // OpenGl_OCCT_VIEWPORT
|
||||
"occLineWidth", // OpenGl_OCCT_LINE_WIDTH
|
||||
"occLineFeather", // OpenGl_OCCT_LINE_FEATHER
|
||||
"occStipplePattern", // OpenGl_OCCT_LINE_STIPPLE_PATTERN
|
||||
"occStippleFactor", // OpenGl_OCCT_LINE_STIPPLE_FACTOR
|
||||
"occWireframeColor", // OpenGl_OCCT_WIREFRAME_COLOR
|
||||
"occIsQuadMode", // OpenGl_OCCT_QUAD_MODE_STATE
|
||||
"occViewport", // OpenGl_OCCT_VIEWPORT
|
||||
"occLineWidth", // OpenGl_OCCT_LINE_WIDTH
|
||||
"occLineFeather", // OpenGl_OCCT_LINE_FEATHER
|
||||
"occStipplePattern", // OpenGl_OCCT_LINE_STIPPLE_PATTERN
|
||||
"occStippleFactor", // OpenGl_OCCT_LINE_STIPPLE_FACTOR
|
||||
"occWireframeColor", // OpenGl_OCCT_WIREFRAME_COLOR
|
||||
"occIsQuadMode", // OpenGl_OCCT_QUAD_MODE_STATE
|
||||
|
||||
"occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE
|
||||
"occSilhouetteThickness" // OpenGl_OCCT_SILHOUETTE_THICKNESS
|
||||
"occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE
|
||||
"occSilhouetteThickness", // OpenGl_OCCT_SILHOUETTE_THICKNESS
|
||||
|
||||
"occNbSpecIBLLevels" // OpenGl_OCCT_NB_SPEC_IBL_LEVELS
|
||||
};
|
||||
|
||||
namespace
|
||||
@@ -409,6 +413,11 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
||||
{
|
||||
aHeaderConstants += "#define THE_HAS_DEFAULT_SAMPLER\n";
|
||||
}
|
||||
if (!myProxy.IsNull()
|
||||
&& myProxy->IsPBR())
|
||||
{
|
||||
aHeaderConstants += "#define THE_IS_PBR\n";
|
||||
}
|
||||
|
||||
const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
|
||||
+ (!aHeaderVer.IsEmpty() ? "\n" : "")
|
||||
@@ -488,6 +497,18 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
||||
{
|
||||
SetUniform (theCtx, aLocSampler, GLint(theCtx->SpriteTextureUnit()));
|
||||
}
|
||||
if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occDiffIBLMapSHCoeffs"))
|
||||
{
|
||||
SetUniform (theCtx, aLocSampler, GLint(theCtx->PBRDiffIBLMapSHTexUnit()));
|
||||
}
|
||||
if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSpecIBLMap"))
|
||||
{
|
||||
SetUniform (theCtx, aLocSampler, GLint(theCtx->PBRSpecIBLMapTexUnit()));
|
||||
}
|
||||
if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occEnvLUT"))
|
||||
{
|
||||
SetUniform (theCtx, aLocSampler, GLint(theCtx->PBREnvLUTTexUnit()));
|
||||
}
|
||||
|
||||
const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
|
||||
const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
|
||||
|
@@ -62,8 +62,10 @@ enum OpenGl_StateVariable
|
||||
// Material state
|
||||
OpenGl_OCCT_TEXTURE_ENABLE,
|
||||
OpenGl_OCCT_DISTINGUISH_MODE,
|
||||
OpenGl_OCCT_FRONT_MATERIAL,
|
||||
OpenGl_OCCT_BACK_MATERIAL,
|
||||
OpenGl_OCCT_PBR_FRONT_MATERIAL,
|
||||
OpenGl_OCCT_PBR_BACK_MATERIAL,
|
||||
OpenGl_OCCT_COMMON_FRONT_MATERIAL,
|
||||
OpenGl_OCCT_COMMON_BACK_MATERIAL,
|
||||
OpenGl_OCCT_ALPHA_CUTOFF,
|
||||
OpenGl_OCCT_COLOR,
|
||||
|
||||
@@ -88,6 +90,9 @@ enum OpenGl_StateVariable
|
||||
OpenGl_OCCT_ORTHO_SCALE,
|
||||
OpenGl_OCCT_SILHOUETTE_THICKNESS,
|
||||
|
||||
// PBR state
|
||||
OpenGl_OCCT_NB_SPEC_IBL_LEVELS,
|
||||
|
||||
// DON'T MODIFY THIS ITEM (insert new items before it)
|
||||
OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES
|
||||
};
|
||||
|
@@ -122,7 +122,7 @@ class OpenGl_LightSourceState : public OpenGl_StateInterface
|
||||
public:
|
||||
|
||||
//! Creates uninitialized state of light sources.
|
||||
OpenGl_LightSourceState() {}
|
||||
OpenGl_LightSourceState() : mySpecIBLMapLevels (0) {}
|
||||
|
||||
//! Sets new light sources.
|
||||
void Set (const Handle(Graphic3d_LightSet)& theLightSources) { myLightSources = theLightSources; }
|
||||
@@ -130,9 +130,17 @@ public:
|
||||
//! Returns current list of light sources.
|
||||
const Handle(Graphic3d_LightSet)& LightSources() const { return myLightSources; }
|
||||
|
||||
//! Returns number of mipmap levels used in specular IBL map.
|
||||
//! 0 by default or in case of using non-PBR shading model.
|
||||
Standard_Integer SpecIBLMapLevels() const { return mySpecIBLMapLevels; }
|
||||
|
||||
//! Sets number of mipmap levels used in specular IBL map.
|
||||
void SetSpecIBLMapLevels(Standard_Integer theSpecIBLMapLevels) { mySpecIBLMapLevels = theSpecIBLMapLevels; }
|
||||
|
||||
private:
|
||||
|
||||
Handle(Graphic3d_LightSet) myLightSources; //!< List of OCCT light sources
|
||||
Handle(Graphic3d_LightSet) myLightSources; //!< List of OCCT light sources
|
||||
Standard_Integer mySpecIBLMapLevels; //!< Number of mipmap levels used in specular IBL map (0 by default or in case of using non-PBR shading model)
|
||||
|
||||
};
|
||||
|
||||
|
@@ -563,7 +563,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
{
|
||||
case Graphic3d_TOT_CUBEMAP:
|
||||
{
|
||||
return initCubeMap (theCtx, Handle(Graphic3d_CubeMap)::DownCast(theTextureMap),
|
||||
return InitCubeMap (theCtx, Handle(Graphic3d_CubeMap)::DownCast(theTextureMap),
|
||||
0, Image_Format_RGB, false, theTextureMap->IsColorMap());
|
||||
}
|
||||
default:
|
||||
@@ -793,10 +793,10 @@ bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx,
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : initCubeMap
|
||||
// function : InitCubeMap
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Texture::initCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
const Handle(Graphic3d_CubeMap)& theCubeMap,
|
||||
Standard_Size theSize,
|
||||
Image_Format theFormat,
|
||||
@@ -811,6 +811,7 @@ bool OpenGl_Texture::initCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
|
||||
if (!theCubeMap.IsNull())
|
||||
{
|
||||
theToGenMipmap = theCubeMap->HasMipmaps();
|
||||
if (Handle(Image_PixMap) anImage = theCubeMap->Reset().Value())
|
||||
{
|
||||
theSize = anImage->SizeX();
|
||||
@@ -836,6 +837,8 @@ bool OpenGl_Texture::initCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
myTarget = GL_TEXTURE_CUBE_MAP;
|
||||
myHasMipmaps = theToGenMipmap;
|
||||
myNbSamples = 1;
|
||||
mySizeX = (GLsizei )theSize;
|
||||
mySizeY = (GLsizei )theSize;
|
||||
Bind (theCtx);
|
||||
applyDefaultSamplerParams (theCtx);
|
||||
|
||||
@@ -991,6 +994,10 @@ Standard_Size OpenGl_Texture::EstimatedDataSize() const
|
||||
{
|
||||
aSize *= Standard_Size(mySizeZ);
|
||||
}
|
||||
if (myTarget == GL_TEXTURE_CUBE_MAP)
|
||||
{
|
||||
aSize *= 6; // cube sides
|
||||
}
|
||||
if (myHasMipmaps)
|
||||
{
|
||||
aSize = aSize + aSize / 3;
|
||||
|
@@ -245,11 +245,6 @@ public:
|
||||
return Init3D (theCtx, aFormat, Graphic3d_Vec3i (theSizeX, theSizeY, theSizeZ), thePixels);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! Apply default sampler parameters after texture creation.
|
||||
Standard_EXPORT void applyDefaultSamplerParams (const Handle(OpenGl_Context)& theCtx);
|
||||
|
||||
//! Initializes 6 sides of cubemap.
|
||||
//! If theCubeMap is not NULL then size and format will be taken from it and corresponding arguments will be ignored.
|
||||
//! Otherwise this parametres will be taken from arguments.
|
||||
@@ -259,13 +254,18 @@ protected:
|
||||
//! @param theFormat [in] image format
|
||||
//! @param theToGenMipmap [in] flag to generate mipmaped cubemap
|
||||
//! @param theIsColorMap [in] flag indicating cubemap storing color values
|
||||
Standard_EXPORT bool initCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
Standard_EXPORT bool InitCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
const Handle(Graphic3d_CubeMap)& theCubeMap,
|
||||
Standard_Size theSize,
|
||||
Image_Format theFormat,
|
||||
Standard_Boolean theToGenMipmap,
|
||||
Standard_Boolean theIsColorMap);
|
||||
|
||||
protected:
|
||||
|
||||
//! Apply default sampler parameters after texture creation.
|
||||
Standard_EXPORT void applyDefaultSamplerParams (const Handle(OpenGl_Context)& theCtx);
|
||||
|
||||
protected:
|
||||
|
||||
Handle(OpenGl_Sampler) mySampler; //!< texture sampler
|
||||
|
@@ -31,7 +31,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
|
||||
aFormat.SetNbComponents (1);
|
||||
if (theCtx->core11 == NULL)
|
||||
{
|
||||
aFormat.SetInternalFormat (GL_R8); // GL_R32F
|
||||
aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_R32F : GL_R8);
|
||||
aFormat.SetPixelFormat (GL_RED);
|
||||
}
|
||||
else
|
||||
@@ -51,7 +51,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
|
||||
aFormat.SetNbComponents (1);
|
||||
if (theCtx->core11 == NULL)
|
||||
{
|
||||
aFormat.SetInternalFormat (GL_R8); // GL_R32F
|
||||
aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_R32F : GL_R8);
|
||||
aFormat.SetPixelFormat (GL_RED);
|
||||
}
|
||||
else
|
||||
@@ -66,10 +66,22 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
|
||||
aFormat.SetDataType (GL_FLOAT);
|
||||
return aFormat;
|
||||
}
|
||||
case Image_Format_RGF:
|
||||
{
|
||||
if (!theCtx->arbTexRG)
|
||||
{
|
||||
return OpenGl_TextureFormat();
|
||||
}
|
||||
aFormat.SetNbComponents (2);
|
||||
aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RG32F : GL_RG8);
|
||||
aFormat.SetPixelFormat (GL_RG);
|
||||
aFormat.SetDataType (GL_FLOAT);
|
||||
return aFormat;
|
||||
}
|
||||
case Image_Format_RGBAF:
|
||||
{
|
||||
aFormat.SetNbComponents (4);
|
||||
aFormat.SetInternalFormat (GL_RGBA8); // GL_RGBA32F
|
||||
aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGBA32F : GL_RGBA8);
|
||||
aFormat.SetPixelFormat (GL_RGBA);
|
||||
aFormat.SetDataType (GL_FLOAT);
|
||||
return aFormat;
|
||||
@@ -81,7 +93,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
|
||||
return OpenGl_TextureFormat();
|
||||
}
|
||||
aFormat.SetNbComponents (4);
|
||||
aFormat.SetInternalFormat (GL_RGBA8); // GL_RGBA32F
|
||||
aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGBA32F : GL_RGBA8);
|
||||
aFormat.SetPixelFormat (GL_BGRA_EXT); // equals to GL_BGRA
|
||||
aFormat.SetDataType (GL_FLOAT);
|
||||
return aFormat;
|
||||
@@ -89,7 +101,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
|
||||
case Image_Format_RGBF:
|
||||
{
|
||||
aFormat.SetNbComponents (3);
|
||||
aFormat.SetInternalFormat (GL_RGB8); // GL_RGB32F
|
||||
aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGB32F : GL_RGB8);
|
||||
aFormat.SetPixelFormat (GL_RGB);
|
||||
aFormat.SetDataType (GL_FLOAT);
|
||||
return aFormat;
|
||||
@@ -98,7 +110,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
aFormat.SetNbComponents (3);
|
||||
aFormat.SetInternalFormat (GL_RGB8); // GL_RGB32F
|
||||
aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGB32F : GL_RGB8);
|
||||
aFormat.SetPixelFormat (GL_BGR); // equals to GL_BGR_EXT
|
||||
aFormat.SetDataType (GL_FLOAT);
|
||||
return aFormat;
|
||||
|
@@ -72,6 +72,8 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
|
||||
myTextureParams (new OpenGl_Aspects()),
|
||||
myCubeMapParams (new OpenGl_Aspects()),
|
||||
myBackgroundType (Graphic3d_TOB_NONE),
|
||||
myPBREnvState (OpenGl_PBREnvState_NONEXISTENT),
|
||||
myPBREnvRequest (OpenGl_PBREnvRequest_NONE),
|
||||
// ray-tracing fields initialization
|
||||
myRaytraceInitStatus (OpenGl_RT_NONE),
|
||||
myIsRaytraceDataValid (Standard_False),
|
||||
@@ -202,6 +204,11 @@ void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
|
||||
releaseSrgbResources (theCtx);
|
||||
|
||||
releaseRaytraceResources (theCtx);
|
||||
|
||||
if (!myPBREnvironment.IsNull())
|
||||
{
|
||||
myPBREnvironment->Release (theCtx.get());
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -530,37 +537,56 @@ Handle(Graphic3d_CubeMap) OpenGl_View::BackgroundCubeMap() const
|
||||
{
|
||||
return myBackgroundCubeMap;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SpecIBLMapLevels
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
unsigned int OpenGl_View::SpecIBLMapLevels() const
|
||||
{
|
||||
return myPBREnvironment.IsNull() ? 0 : myPBREnvironment->SpecMapLevelsNumber();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetBackgroundCubeMap
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap)
|
||||
void OpenGl_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
|
||||
Standard_Boolean theToUpdatePBREnv)
|
||||
{
|
||||
myBackgroundCubeMap = theCubeMap;
|
||||
Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d;
|
||||
Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (myBackgroundCubeMap);
|
||||
if (theCubeMap.IsNull())
|
||||
{
|
||||
if (theToUpdatePBREnv)
|
||||
{
|
||||
myPBREnvRequest = OpenGl_PBREnvRequest_CLEAR;
|
||||
}
|
||||
if (myBackgroundType == Graphic3d_TOB_CUBEMAP)
|
||||
{
|
||||
myBackgroundType = Graphic3d_TOB_NONE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
anAspect->SetInteriorStyle(Aspect_IS_SOLID);
|
||||
anAspect->SetSuppressBackFaces(false);
|
||||
anAspect->SetTextureSet(aTextureSet);
|
||||
theCubeMap ->SetMipmapsGeneration (Standard_True);
|
||||
Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
|
||||
Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (myBackgroundCubeMap);
|
||||
anAspect->SetInteriorStyle (Aspect_IS_SOLID);
|
||||
anAspect->SetSuppressBackFaces (false);
|
||||
anAspect->SetTextureSet (aTextureSet);
|
||||
|
||||
const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
|
||||
if (!aCtx.IsNull())
|
||||
{
|
||||
anAspect->SetShaderProgram (aCtx->ShaderManager()->GetBgCubeMapProgram());
|
||||
}
|
||||
anAspect->SetTextureMapOn (theCubeMap->IsDone());
|
||||
myCubeMapParams->SetAspect (anAspect);
|
||||
|
||||
if (theCubeMap->IsDone())
|
||||
if (theToUpdatePBREnv)
|
||||
{
|
||||
anAspect->SetTextureMapOn();
|
||||
myPBREnvRequest = OpenGl_PBREnvRequest_BAKE;
|
||||
}
|
||||
else
|
||||
{
|
||||
anAspect->SetTextureMapOff();
|
||||
}
|
||||
|
||||
myCubeMapParams->SetAspect(anAspect);
|
||||
const OpenGl_Aspects* anAspectsBackup = myWorkspace->SetAspects (myCubeMapParams);
|
||||
myWorkspace->ApplyAspects();
|
||||
myWorkspace->SetAspects (anAspectsBackup);
|
||||
|
@@ -57,6 +57,7 @@ struct OpenGl_Matrix;
|
||||
|
||||
class Graphic3d_StructureManager;
|
||||
class OpenGl_GraphicDriver;
|
||||
class OpenGl_PBREnvironment;
|
||||
class OpenGl_StateCounter;
|
||||
class OpenGl_TriangleSet;
|
||||
class OpenGl_Workspace;
|
||||
@@ -226,7 +227,27 @@ public:
|
||||
Standard_EXPORT Handle(Graphic3d_CubeMap) BackgroundCubeMap() const Standard_OVERRIDE;
|
||||
|
||||
//! Sets environment cubemap as background.
|
||||
Standard_EXPORT virtual void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap) Standard_OVERRIDE;
|
||||
//! @param theCubeMap cubemap source to be set as background
|
||||
//! @param theToUpdatePBREnv defines whether IBL maps will be generated or not (see 'GeneratePBREnvironment')
|
||||
Standard_EXPORT virtual void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
|
||||
Standard_Boolean theToUpdatePBREnv = Standard_True) Standard_OVERRIDE;
|
||||
|
||||
//! Generates PBR specular probe and irradiance map
|
||||
//! in order to provide environment indirect illumination in PBR shading model (Image Based Lighting).
|
||||
//! The source of environment data is background cubemap.
|
||||
//! If PBR is unavailable it does nothing.
|
||||
//! If PBR is available but there is no cubemap being set to background it clears all IBL maps (see 'ClearPBREnvironment').
|
||||
virtual void GeneratePBREnvironment() Standard_OVERRIDE { myPBREnvRequest = OpenGl_PBREnvRequest_BAKE; }
|
||||
|
||||
//! Fills PBR specular probe and irradiance map with white color.
|
||||
//! So that environment indirect illumination will be constant
|
||||
//! and will be fully controlled by ambient light sources.
|
||||
//! If PBR is unavailable it does nothing.
|
||||
virtual void ClearPBREnvironment() Standard_OVERRIDE { myPBREnvRequest = OpenGl_PBREnvRequest_CLEAR; }
|
||||
|
||||
//! Returns number of mipmap levels used in specular IBL map.
|
||||
//! 0 if PBR environment is not created.
|
||||
Standard_EXPORT unsigned int SpecIBLMapLevels() const;
|
||||
|
||||
//! Returns environment texture set for the view.
|
||||
virtual Handle(Graphic3d_TextureEnv) TextureEnv() const Standard_OVERRIDE { return myTextureEnvData; }
|
||||
@@ -518,10 +539,48 @@ protected: //! @name Background parameters
|
||||
|
||||
OpenGl_Aspects* myTextureParams; //!< Stores texture and its parameters for textured background
|
||||
OpenGl_Aspects* myCubeMapParams; //!< Stores cubemap and its parameters for cubemap background
|
||||
Handle(Graphic3d_CubeMap) myBackgroundCubeMap; //!< Cubemap has been setted as background
|
||||
Graphic3d_TypeOfBackground myBackgroundType; //!< Current typy of background
|
||||
Handle(Graphic3d_CubeMap) myBackgroundCubeMap; //!< Cubemap has been set as background
|
||||
Graphic3d_TypeOfBackground myBackgroundType; //!< Current type of background
|
||||
OpenGl_BackgroundArray* myBackgrounds[Graphic3d_TypeOfBackground_NB]; //!< Array of primitive arrays of different background types
|
||||
|
||||
protected: //! @name methods related to PBR
|
||||
|
||||
//! Checks whether PBR is available.
|
||||
Standard_EXPORT Standard_Boolean checkPBRAvailability() const;
|
||||
|
||||
//! Generates IBL maps used in PBR pipeline.
|
||||
//! If background cubemap is not set clears all IBL maps.
|
||||
Standard_EXPORT void bakePBREnvironment (const Handle(OpenGl_Context)& theCtx);
|
||||
|
||||
//! Fills all IBL maps with white color.
|
||||
//! So that environment lighting is considered to be constant and is completely controls by ambient light sources.
|
||||
Standard_EXPORT void clearPBREnvironment (const Handle(OpenGl_Context)& theCtx);
|
||||
|
||||
//! Process requests to generate or to clear PBR environment.
|
||||
Standard_EXPORT void processPBREnvRequest (const Handle(OpenGl_Context)& theCtx);
|
||||
|
||||
protected: //! @name fields and types related to PBR
|
||||
|
||||
//! State of PBR environment.
|
||||
enum PBREnvironmentState
|
||||
{
|
||||
OpenGl_PBREnvState_NONEXISTENT,
|
||||
OpenGl_PBREnvState_UNAVAILABLE, // indicates failed try to create PBR environment
|
||||
OpenGl_PBREnvState_CREATED
|
||||
};
|
||||
|
||||
//! Type of action which can be done with PBR environment.
|
||||
enum PBREnvironmentRequest
|
||||
{
|
||||
OpenGl_PBREnvRequest_NONE,
|
||||
OpenGl_PBREnvRequest_BAKE,
|
||||
OpenGl_PBREnvRequest_CLEAR
|
||||
};
|
||||
|
||||
Handle(OpenGl_PBREnvironment) myPBREnvironment; //!< manager of IBL maps used in PBR pipeline
|
||||
PBREnvironmentState myPBREnvState; //!< state of PBR environment
|
||||
PBREnvironmentRequest myPBREnvRequest; //!< type of action is requested to be done with PBR environment
|
||||
|
||||
protected: //! @name data types related to ray-tracing
|
||||
|
||||
//! Result of OpenGL shaders initialization.
|
||||
|
@@ -39,6 +39,8 @@
|
||||
#include <OpenGl_Structure.hxx>
|
||||
#include <OpenGl_ArbFBO.hxx>
|
||||
|
||||
#include "../Textures/Textures_EnvLUT.pxx"
|
||||
|
||||
namespace
|
||||
{
|
||||
//! Format Frame Buffer format for logging messages.
|
||||
@@ -344,6 +346,65 @@ void OpenGl_View::Redraw()
|
||||
}
|
||||
}
|
||||
|
||||
// process PBR environment
|
||||
if (myShadingModel == Graphic3d_TOSM_PBR
|
||||
|| myShadingModel == Graphic3d_TOSM_PBR_FACET)
|
||||
{
|
||||
if (!myPBREnvironment.IsNull()
|
||||
&& myPBREnvironment->SizesAreDifferent (myRenderParams.PbrEnvPow2Size,
|
||||
myRenderParams.PbrEnvSpecMapNbLevels))
|
||||
{
|
||||
myPBREnvironment->Release (aCtx.get());
|
||||
myPBREnvironment.Nullify();
|
||||
myPBREnvState = OpenGl_PBREnvState_NONEXISTENT;
|
||||
myPBREnvRequest = OpenGl_PBREnvRequest_BAKE;
|
||||
++myLightsRevision;
|
||||
}
|
||||
|
||||
if (myPBREnvState == OpenGl_PBREnvState_NONEXISTENT
|
||||
&& aCtx->HasPBR())
|
||||
{
|
||||
myPBREnvironment = OpenGl_PBREnvironment::Create (aCtx, myRenderParams.PbrEnvPow2Size, myRenderParams.PbrEnvSpecMapNbLevels);
|
||||
myPBREnvState = myPBREnvironment.IsNull() ? OpenGl_PBREnvState_UNAVAILABLE : OpenGl_PBREnvState_CREATED;
|
||||
if (myPBREnvState == OpenGl_PBREnvState_CREATED)
|
||||
{
|
||||
Handle(OpenGl_Texture) anEnvLUT;
|
||||
static const TCollection_AsciiString THE_SHARED_ENV_LUT_KEY("EnvLUT");
|
||||
if (!aCtx->GetResource (THE_SHARED_ENV_LUT_KEY, anEnvLUT))
|
||||
{
|
||||
Handle(Graphic3d_TextureParams) aParams = new Graphic3d_TextureParams();
|
||||
aParams->SetFilter (Graphic3d_TOTF_BILINEAR);
|
||||
aParams->SetRepeat (Standard_False);
|
||||
aParams->SetTextureUnit (aCtx->PBREnvLUTTexUnit());
|
||||
anEnvLUT = new OpenGl_Texture(THE_SHARED_ENV_LUT_KEY, aParams);
|
||||
Handle(Image_PixMap) aPixMap = new Image_PixMap();
|
||||
aPixMap->InitWrapper (Image_Format_RGF, (Standard_Byte*)Textures_EnvLUT, Textures_EnvLUTSize, Textures_EnvLUTSize);
|
||||
OpenGl_TextureFormat aTexFormat = OpenGl_TextureFormat::FindFormat (aCtx, aPixMap->Format(), false);
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
// GL_RG32F is not texture-filterable format on OpenGL ES without OES_texture_float_linear extension.
|
||||
// GL_RG16F is texture-filterable since OpenGL ES 3.0 and can be initialized from 32-bit floats.
|
||||
// Note that it is expected that GL_RG16F has enough precision for this table, so that it can be used also on desktop OpenGL.
|
||||
//if (!aCtx->hasTexFloatLinear)
|
||||
aTexFormat.SetInternalFormat (GL_RG16F);
|
||||
#endif
|
||||
if (!aTexFormat.IsValid()
|
||||
|| !anEnvLUT->Init (aCtx, aTexFormat, Graphic3d_Vec2i((Standard_Integer)Textures_EnvLUTSize), Graphic3d_TOT_2D, aPixMap.get()))
|
||||
{
|
||||
aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Failed allocation of LUT for PBR");
|
||||
anEnvLUT.Nullify();
|
||||
}
|
||||
aCtx->ShareResource (THE_SHARED_ENV_LUT_KEY, anEnvLUT);
|
||||
}
|
||||
if (!anEnvLUT.IsNull())
|
||||
{
|
||||
anEnvLUT->Bind (aCtx);
|
||||
}
|
||||
myWorkspace->ApplyAspects();
|
||||
}
|
||||
}
|
||||
processPBREnvRequest (aCtx);
|
||||
}
|
||||
|
||||
// create color and coverage accumulation buffers required for OIT algorithm
|
||||
if (toUseOit)
|
||||
{
|
||||
@@ -938,7 +999,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
|
||||
|| aLightsRevision != myLightsRevision)
|
||||
{
|
||||
myLightsRevision = aLightsRevision;
|
||||
aManager->UpdateLightSourceStateTo (aLights);
|
||||
aManager->UpdateLightSourceStateTo (aLights, SpecIBLMapLevels());
|
||||
myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
|
||||
}
|
||||
|
||||
@@ -1020,7 +1081,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
|
||||
}
|
||||
#endif
|
||||
|
||||
aManager->SetShadingModel (myShadingModel);
|
||||
aManager->SetShadingModel (OpenGl_ShaderManager::PBRShadingModelFallback (myShadingModel, checkPBRAvailability()));
|
||||
|
||||
// Redraw 3d scene
|
||||
if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye)
|
||||
@@ -1848,3 +1909,64 @@ bool OpenGl_View::chooseOitColorConfiguration (const Handle(OpenGl_Context)& the
|
||||
}
|
||||
return false; // color combination does not exist
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : checkPBRAvailability
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean OpenGl_View::checkPBRAvailability() const
|
||||
{
|
||||
return myWorkspace->GetGlContext()->HasPBR()
|
||||
&& !myPBREnvironment.IsNull();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : bakePBREnvironment
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_View::bakePBREnvironment (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
const Handle(OpenGl_TextureSet)& aTextureSet = myCubeMapParams->TextureSet (theCtx);
|
||||
if (!aTextureSet.IsNull()
|
||||
&& !aTextureSet->IsEmpty())
|
||||
{
|
||||
myPBREnvironment->Bake (theCtx,
|
||||
aTextureSet->First(),
|
||||
myBackgroundCubeMap->ZIsInverted(),
|
||||
myBackgroundCubeMap->IsTopDown(),
|
||||
myRenderParams.PbrEnvBakingDiffNbSamples,
|
||||
myRenderParams.PbrEnvBakingSpecNbSamples,
|
||||
myRenderParams.PbrEnvBakingProbability);
|
||||
}
|
||||
else
|
||||
{
|
||||
myPBREnvironment->Clear (theCtx);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : clearPBREnvironment
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_View::clearPBREnvironment (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
myPBREnvironment->Clear (theCtx);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : clearPBREnvironment
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_View::processPBREnvRequest (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
if (myPBREnvState == OpenGl_PBREnvState_CREATED)
|
||||
{
|
||||
switch (myPBREnvRequest)
|
||||
{
|
||||
case OpenGl_PBREnvRequest_NONE: return;
|
||||
case OpenGl_PBREnvRequest_BAKE: bakePBREnvironment (theCtx); break;
|
||||
case OpenGl_PBREnvRequest_CLEAR: clearPBREnvironment (theCtx); break;
|
||||
}
|
||||
}
|
||||
myPBREnvRequest = OpenGl_PBREnvRequest_NONE;
|
||||
}
|
||||
|
@@ -28,6 +28,8 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <Standard_WarningDisableFunctionCast.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Window,Standard_Transient)
|
||||
|
||||
#if defined(HAVE_EGL)
|
||||
|
@@ -58,36 +58,42 @@ void OpenGl_Material::Init (const OpenGl_Context& theCtx,
|
||||
const Graphic3d_MaterialAspect& theMat,
|
||||
const Quantity_Color& theInteriorColor)
|
||||
{
|
||||
ChangeShine() = 128.0f * theMat.Shininess();
|
||||
ChangeTransparency() = theMat.Alpha();
|
||||
Common.ChangeShine() = 128.0f * theMat.Shininess();
|
||||
Common.ChangeTransparency() = theMat.Alpha();
|
||||
|
||||
Pbr.ChangeMetallic() = theMat.PBRMaterial().Metallic();
|
||||
Pbr.ChangeRoughness() = theMat.PBRMaterial().NormalizedRoughness();
|
||||
Pbr.EmissionIOR = Graphic3d_Vec4 (theMat.PBRMaterial().Emission(), theMat.PBRMaterial().IOR());
|
||||
|
||||
const OpenGl_Vec3& aSrcAmb = theMat.AmbientColor();
|
||||
const OpenGl_Vec3& aSrcDif = theMat.DiffuseColor();
|
||||
const OpenGl_Vec3& aSrcSpe = theMat.SpecularColor();
|
||||
const OpenGl_Vec3& aSrcEms = theMat.EmissiveColor();
|
||||
Specular.SetValues (aSrcSpe, 1.0f); // interior color is ignored for Specular
|
||||
Common.Specular.SetValues (aSrcSpe, 1.0f); // interior color is ignored for Specular
|
||||
switch (theMat.MaterialType())
|
||||
{
|
||||
case Graphic3d_MATERIAL_ASPECT:
|
||||
{
|
||||
Ambient .SetValues (aSrcAmb * theInteriorColor, 1.0f);
|
||||
Diffuse .SetValues (aSrcDif * theInteriorColor, 1.0f);
|
||||
Emission.SetValues (aSrcEms * theInteriorColor, 1.0f);
|
||||
Common.Ambient .SetValues (aSrcAmb * theInteriorColor, 1.0f);
|
||||
Common.Diffuse .SetValues (aSrcDif * theInteriorColor, 1.0f);
|
||||
Common.Emission.SetValues (aSrcEms * theInteriorColor, 1.0f);
|
||||
Pbr .BaseColor.SetValues (theInteriorColor, theMat.Alpha());
|
||||
break;
|
||||
}
|
||||
case Graphic3d_MATERIAL_PHYSIC:
|
||||
{
|
||||
Ambient .SetValues (aSrcAmb, 1.0f);
|
||||
Diffuse .SetValues (aSrcDif, 1.0f);
|
||||
Emission.SetValues (aSrcEms, 1.0f);
|
||||
Common.Ambient .SetValues (aSrcAmb, 1.0f);
|
||||
Common.Diffuse .SetValues (aSrcDif, 1.0f);
|
||||
Common.Emission.SetValues (aSrcEms, 1.0f);
|
||||
Pbr.BaseColor = theMat.PBRMaterial().Color();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ambient = theCtx.Vec4FromQuantityColor (Ambient);
|
||||
Diffuse = theCtx.Vec4FromQuantityColor (Diffuse);
|
||||
Specular = theCtx.Vec4FromQuantityColor (Specular);
|
||||
Emission = theCtx.Vec4FromQuantityColor (Emission);
|
||||
Common.Ambient = theCtx.Vec4FromQuantityColor (Common.Ambient);
|
||||
Common.Diffuse = theCtx.Vec4FromQuantityColor (Common.Diffuse);
|
||||
Common.Specular = theCtx.Vec4FromQuantityColor (Common.Specular);
|
||||
Common.Emission = theCtx.Vec4FromQuantityColor (Common.Emission);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -310,6 +316,14 @@ const OpenGl_Aspects* OpenGl_Workspace::ApplyAspects()
|
||||
myGlContext->BindTextures (myEnvironmentTexture);
|
||||
}
|
||||
|
||||
if ((myView->myShadingModel == Graphic3d_TOSM_PBR
|
||||
|| myView->myShadingModel == Graphic3d_TOSM_PBR_FACET)
|
||||
&& !myView->myPBREnvironment.IsNull()
|
||||
&& myView->myPBREnvironment->IsNeededToBeBound())
|
||||
{
|
||||
myView->myPBREnvironment->Bind (myGlContext);
|
||||
}
|
||||
|
||||
myAspectsApplied = myAspectsSet->Aspect();
|
||||
return myAspectsSet;
|
||||
}
|
||||
|
@@ -24,6 +24,8 @@
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
#include <Standard_WarningDisableFunctionCast.hxx>
|
||||
|
||||
static Standard_Character tc[1000];
|
||||
static Standard_PCharacter thePluginId = tc;
|
||||
|
||||
|
@@ -4748,6 +4748,7 @@ Standard_Integer OCC28478 (Draw_Interpretor& di, Standard_Integer argc, const ch
|
||||
{
|
||||
Standard_Integer nbOuter = (argc > 1 ? Draw::Atoi(argv[1]) : 3);
|
||||
Standard_Integer nbInner = (argc > 2 ? Draw::Atoi(argv[2]) : 2);
|
||||
Standard_Boolean isInf = (argc > 3 && ! strcmp (argv[3], "-inf"));
|
||||
|
||||
// test behavior of progress indicator when using nested scopes with names set by Sentry objects
|
||||
Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
|
||||
@@ -4758,7 +4759,7 @@ Standard_Integer OCC28478 (Draw_Interpretor& di, Standard_Integer argc, const ch
|
||||
for (int i = 0; i < nbOuter && anOuter.More(); i++, anOuter.Next())
|
||||
{
|
||||
// Inner cycle
|
||||
Message_ProgressSentry anInner (aProgress, "Inner", 0, nbInner, 1);
|
||||
Message_ProgressSentry anInner (aProgress, "Inner", 0, nbInner, 1, isInf);
|
||||
for (int j = 0; j < nbInner && anInner.More(); j++, anInner.Next())
|
||||
{
|
||||
// Cycle body
|
||||
@@ -4870,6 +4871,6 @@ void QABugs::Commands_11(Draw_Interpretor& theCommands) {
|
||||
theCommands.Add("OCC22558", "OCC22558 x_vec y_vec z_vec x_dir y_dir z_dit x_pnt y_pnt z_pnt", __FILE__, OCC22558, group);
|
||||
theCommands.Add("CR23403", "CR23403 string", __FILE__, CR23403, group);
|
||||
theCommands.Add("OCC23429", "OCC23429 res shape tool [appr]", __FILE__, OCC23429, group);
|
||||
theCommands.Add("OCC28478", "OCC28478 [nb_outer=3 [nb_inner=2]: test progress indicator on nested cycles", __FILE__, OCC28478, group);
|
||||
theCommands.Add("OCC28478", "OCC28478 [nb_outer=3 [nb_inner=2] [-inf]: test progress indicator on nested cycles", __FILE__, OCC28478, group);
|
||||
return;
|
||||
}
|
||||
|
@@ -3152,7 +3152,7 @@ static Standard_Integer OCC25547(
|
||||
|
||||
aIntFlag = BRepMesh_GeomTool::IntSegSeg(
|
||||
aRefPnts[0], aRefPnts[1], aRefPnts[2], aRefPnts[3],
|
||||
Standard_False, Standard_False, aIntPnt);
|
||||
Standard_False, Standard_False, aIntPnt, aParams);
|
||||
|
||||
aDiff = aIntPnt.Distance(gp::Origin2d());
|
||||
if (aIntFlag != BRepMesh_GeomTool::Cross || aDiff > Precision::PConfusion())
|
||||
|
@@ -3154,7 +3154,7 @@ static Standard_Integer OCC30708_1 (Draw_Interpretor& di, Standard_Integer, cons
|
||||
it.Initialize (empty);
|
||||
|
||||
}
|
||||
catch (Standard_Failure)
|
||||
catch (const Standard_Failure&)
|
||||
{
|
||||
di << "Cannot initialize TopoDS_Iterator with null shape\n";
|
||||
return 0;
|
||||
@@ -3179,7 +3179,7 @@ static Standard_Integer OCC30708_2 (Draw_Interpretor& di, Standard_Integer, cons
|
||||
TopoDS_Wire empty;
|
||||
BRepLib_MakeWire aWBuilder (empty);
|
||||
}
|
||||
catch (Standard_Failure)
|
||||
catch (const Standard_Failure&)
|
||||
{
|
||||
di << "Cannot initialize BRepLib_MakeWire with null wire\n";
|
||||
}
|
||||
|
@@ -830,66 +830,6 @@ static Standard_Integer closefreebounds (Draw_Interpretor& di,
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : MyVISEDG
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Integer MyVISEDG (Draw_Interpretor& /*di*/,
|
||||
Standard_Integer n, const char** a)
|
||||
{
|
||||
if (n >4) return 1;
|
||||
TopoDS_Shape MaListe = DBRep::Get(a[1]);
|
||||
if (MaListe.IsNull()) return 1;
|
||||
TopoDS_Compound TheList = TopoDS::Compound(MaListe);
|
||||
if (TheList.IsNull()) return 1;
|
||||
Standard_Real toler = 0.001;
|
||||
int create = 0;
|
||||
if ( n >= 3) toler = Draw::Atof(a[2]);
|
||||
if (n == 4 && !strcmp(a[3],"C")) create = 1;
|
||||
ShapeAnalysis_FreeBounds F(TheList,toler);
|
||||
//
|
||||
//
|
||||
//
|
||||
char name[100];
|
||||
char num[5];
|
||||
if (!create)
|
||||
{
|
||||
TopoDS_Compound Wires = F.GetClosedWires();
|
||||
TopoDS_Iterator S(Wires);
|
||||
Standard_Integer iwire = 0;
|
||||
while (S.More())
|
||||
{
|
||||
Sprintf (num,"%d",iwire);
|
||||
name[0] = 'w';
|
||||
name[1] = '\0';
|
||||
strncat(name,num,strlen(num));
|
||||
name[strlen(name)] = '\0';
|
||||
DBRep::Set(name,S.Value());
|
||||
S.Next();
|
||||
iwire++;
|
||||
}
|
||||
iwire = 0;
|
||||
TopoDS_Compound Edges = F.GetOpenWires();
|
||||
S.Initialize(Edges);
|
||||
iwire = 0;
|
||||
while (S.More())
|
||||
{
|
||||
Sprintf (num,"%d",iwire);
|
||||
name[0] = 'E';
|
||||
name[1] = '\0';
|
||||
strncat(name,num,strlen(num));
|
||||
name[strlen(name)] = '\0';
|
||||
DBRep::Set(name,S.Value());
|
||||
S.Next();
|
||||
iwire++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Standard_Integer getareacontour (Draw_Interpretor& di,
|
||||
Standard_Integer n, const char** a)
|
||||
{
|
||||
@@ -1076,9 +1016,6 @@ static Standard_Integer checkedge(Draw_Interpretor& di, Standard_Integer argc, c
|
||||
theCommands.Add("fbclose",
|
||||
"shp sewtoler closetoler [splitclosed [splitopen]] - closes free bounds; use sewtoler <= 0 for shells (no sewing call)",
|
||||
__FILE__, closefreebounds, groupold);
|
||||
theCommands.Add("K_VISEDG",
|
||||
"K_VISEDG Visu of free edge of a compound of faces.",
|
||||
__FILE__, MyVISEDG, groupold);
|
||||
|
||||
theCommands.Add("getareacontour","wire ",__FILE__, getareacontour, groupold);
|
||||
theCommands.Add ("checkselfintersection","wire [face]", __FILE__,checkselfintersection,g);
|
||||
|
@@ -49,7 +49,6 @@ namespace
|
||||
SelectMgr_SelectableObject::SelectMgr_SelectableObject (const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d)
|
||||
: PrsMgr_PresentableObject (aTypeOfPresentation3d),
|
||||
myGlobalSelMode (0),
|
||||
mycurrent (0),
|
||||
myAutoHilight (Standard_True)
|
||||
{
|
||||
//
|
||||
|
@@ -172,24 +172,6 @@ public:
|
||||
//! Dumps the content of me into the stream
|
||||
Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, const Standard_Integer theDepth = -1) const Standard_OVERRIDE;
|
||||
|
||||
public:
|
||||
|
||||
//! Begins the iteration scanning for sensitive primitives.
|
||||
Standard_DEPRECATED("Deprecated method, Selections() should be used instead")
|
||||
void Init() { mycurrent = 1; }
|
||||
|
||||
//! Continues the iteration scanning for sensitive primitives.
|
||||
Standard_DEPRECATED("Deprecated method, Selections() should be used instead")
|
||||
Standard_Boolean More() const { return mycurrent <= myselections.Length(); }
|
||||
|
||||
//! Continues the iteration scanning for sensitive primitives.
|
||||
Standard_DEPRECATED("Deprecated method, Selections() should be used instead")
|
||||
void Next() { ++mycurrent; }
|
||||
|
||||
//! Returns the current selection in this framework.
|
||||
Standard_DEPRECATED("Deprecated method, Selections() should be used instead")
|
||||
const Handle(SelectMgr_Selection)& CurrentSelection() const { return myselections (mycurrent); }
|
||||
|
||||
protected:
|
||||
|
||||
//! Protected empty constructor.
|
||||
@@ -214,7 +196,6 @@ protected:
|
||||
Handle(Prs3d_Presentation) mySelectionPrs; //!< optional presentation for highlighting selected object
|
||||
Handle(Prs3d_Presentation) myHilightPrs; //!< optional presentation for highlighting detected object
|
||||
Standard_Integer myGlobalSelMode; //!< global selection mode
|
||||
Standard_Integer mycurrent; //!< [deprecated] iterator value
|
||||
Standard_Boolean myAutoHilight; //!< auto-highlighting flag defining
|
||||
|
||||
};
|
||||
|
@@ -26,8 +26,7 @@ IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_Selection,Standard_Transient)
|
||||
// Purpose :
|
||||
//==================================================
|
||||
SelectMgr_Selection::SelectMgr_Selection (const Standard_Integer theModeIdx)
|
||||
: myEntityIter (0),
|
||||
myMode (theModeIdx),
|
||||
: myMode (theModeIdx),
|
||||
mySelectionState (SelectMgr_SOS_Unknown),
|
||||
myBVHUpdateStatus (SelectMgr_TBU_None),
|
||||
mySensFactor (2),
|
||||
|
@@ -92,25 +92,6 @@ public:
|
||||
//! Return entities.
|
||||
NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>& ChangeEntities() { return myEntities; }
|
||||
|
||||
//! Begins an iteration scanning for sensitive primitives.
|
||||
Standard_DEPRECATED("Deprecated method, Entities() should be used instead")
|
||||
void Init() { myEntityIter = myEntities.Lower(); }
|
||||
|
||||
//! Continues the iteration scanning for sensitive
|
||||
//! primitives with the mode defined in this framework.
|
||||
Standard_DEPRECATED("Deprecated method, Entities() should be used instead")
|
||||
Standard_Boolean More() const { return myEntityIter <= myEntities.Upper(); }
|
||||
|
||||
//! Returns the next sensitive primitive found in the
|
||||
//! iteration. This is a scan for entities with the mode
|
||||
//! defined in this framework.
|
||||
Standard_DEPRECATED("Deprecated method, Entities() should be used instead")
|
||||
void Next() { ++myEntityIter; }
|
||||
|
||||
//! Returns any sensitive primitive in this framework.
|
||||
Standard_DEPRECATED("Deprecated method, Entities() should be used instead")
|
||||
const Handle(SelectMgr_SensitiveEntity)& Sensitive() const { return myEntities.Value (myEntityIter); }
|
||||
|
||||
//! Returns the flag UpdateFlag.
|
||||
//! This flage gives the update status of this framework
|
||||
//! in a ViewerSelector object:
|
||||
@@ -142,7 +123,6 @@ public:
|
||||
private:
|
||||
|
||||
NCollection_Vector<Handle(SelectMgr_SensitiveEntity)> myEntities;
|
||||
Standard_Integer myEntityIter;
|
||||
Standard_Integer myMode;
|
||||
SelectMgr_TypeOfUpdate myUpdateStatus;
|
||||
mutable SelectMgr_StateOfSelection mySelectionState;
|
||||
|
@@ -21,6 +21,8 @@
|
||||
#define occTexture1D texture
|
||||
#define occTexture2D texture
|
||||
#define occTexture3D texture
|
||||
#define occTextureCube texture
|
||||
#define occTextureCubeLod textureLod
|
||||
#else
|
||||
#define THE_ATTRIBUTE attribute
|
||||
#define THE_SHADER_IN varying
|
||||
@@ -29,10 +31,16 @@
|
||||
#define occTexture1D texture1D
|
||||
#define occTexture2D texture2D
|
||||
#define occTexture3D texture3D
|
||||
#define occTextureCube textureCube
|
||||
#define occTextureCubeLod textureCubeLod
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define THE_PREC_ENUM lowp // enumerations should fit into lowp range
|
||||
#if (__VERSION__ >= 300)
|
||||
#define THE_PREC_ENUM highp // lowp should be enough for enums but triggers driver bugs
|
||||
#else
|
||||
#define THE_PREC_ENUM lowp
|
||||
#endif
|
||||
#else
|
||||
#define THE_PREC_ENUM
|
||||
#endif
|
||||
@@ -85,6 +93,15 @@
|
||||
void occSetFragColor (in vec4 theColor);
|
||||
#endif
|
||||
|
||||
// Pi number definitions
|
||||
#define PI 3.141592654
|
||||
#define PI_2 6.283185307
|
||||
#define PI_DIV_2 1.570796327
|
||||
#define PI_DIV_3 1.047197551
|
||||
#define PI_DIV_4 0.785398163
|
||||
#define INV_PI 0.318309886
|
||||
#define INV_PI_2 0.159154943
|
||||
|
||||
// Matrix state
|
||||
uniform mat4 occWorldViewMatrix; //!< World-view matrix
|
||||
uniform mat4 occProjectionMatrix; //!< Projection matrix
|
||||
@@ -102,6 +119,15 @@ uniform mat4 occWorldViewMatrixInverseTranspose; //!< Transpose of the inverse
|
||||
uniform mat4 occProjectionMatrixInverseTranspose; //!< Transpose of the inverse of the projection matrix
|
||||
uniform mat4 occModelWorldMatrixInverseTranspose; //!< Transpose of the inverse of the model-world matrix
|
||||
|
||||
#if defined(THE_IS_PBR)
|
||||
uniform sampler2D occEnvLUT; //!< Environment Lookup Table
|
||||
uniform sampler2D occDiffIBLMapSHCoeffs; //!< Packed diffuse (irradiance) IBL map's spherical harmonics coefficients
|
||||
uniform samplerCube occSpecIBLMap; //!< Specular IBL map
|
||||
uniform int occNbSpecIBLLevels; //!< Number of mipmap levels used in occSpecIBLMap to store different roughness values maps
|
||||
|
||||
vec3 occDiffIBLMap (in vec3 theNormal); //!< Unpacks spherical harmonics coefficients to diffuse IBL map's values
|
||||
#endif
|
||||
|
||||
// light type enumeration (same as Graphic3d_TypeOfLightSource)
|
||||
const int OccLightType_Direct = 1; //!< directional light source
|
||||
const int OccLightType_Point = 2; //!< isotropic point light source
|
||||
@@ -116,7 +142,7 @@ uniform THE_PREC_ENUM int occLightSourcesCount; //!< Total number of light sour
|
||||
#define occLight_Type(theId) occLightSourcesTypes[theId].x
|
||||
|
||||
//! Is light a headlight, int?
|
||||
#define occLight_IsHeadlight(theId) occLightSourcesTypes[theId].y
|
||||
#define occLight_IsHeadlight(theId) (occLightSourcesTypes[theId].y != 0)
|
||||
|
||||
//! Specular intensity (equals to diffuse), vec4.
|
||||
#define occLight_Specular(theId) occLightSources[theId * 4 + 0]
|
||||
@@ -133,6 +159,11 @@ uniform THE_PREC_ENUM int occLightSourcesCount; //!< Total number of light sour
|
||||
//! Attenuation of the spot light intensity (from 0 to 1), float.
|
||||
#define occLight_SpotExponent(theId) occLightSources[theId * 4 + 3].w
|
||||
|
||||
#if defined(THE_IS_PBR)
|
||||
//! Intensity of light source (>= 0), float.
|
||||
#define occLight_Intensity(theId) occLightSources[theId * 4 + 0].a
|
||||
#else
|
||||
|
||||
//! Diffuse intensity (equals to Specular), vec4.
|
||||
#define occLight_Diffuse(theId) occLightSources[theId * 4 + 0]
|
||||
|
||||
@@ -142,22 +173,44 @@ uniform THE_PREC_ENUM int occLightSourcesCount; //!< Total number of light sour
|
||||
//! Linear attenuation factor of positional light source, float.
|
||||
#define occLight_LinearAttenuation(theId) occLightSources[theId * 4 + 3].y
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Converts roughness value from range [0, 1] to real value for calculations
|
||||
float occRoughness (in float theNormalizedRoughness);
|
||||
|
||||
// Front material properties accessors
|
||||
vec4 occFrontMaterial_Emission(void); //!< Emission color
|
||||
vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection
|
||||
vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection
|
||||
vec4 occFrontMaterial_Specular(void); //!< Specular reflection
|
||||
float occFrontMaterial_Shininess(void); //!< Specular exponent
|
||||
float occFrontMaterial_Transparency(void); //!< Transparency coefficient
|
||||
#if !defined(THE_IS_PBR)
|
||||
vec4 occFrontMaterial_Emission(void); //!< Emission color
|
||||
vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection
|
||||
vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection
|
||||
vec4 occFrontMaterial_Specular(void); //!< Specular reflection
|
||||
float occFrontMaterial_Shininess(void); //!< Specular exponent
|
||||
float occFrontMaterial_Transparency(void); //!< Transparency coefficient
|
||||
#else
|
||||
vec4 occPBRFrontMaterial_Color(void); //!< Base color of PBR material
|
||||
float occPBRFrontMaterial_Metallic(void); //!< Metallic coefficient
|
||||
float occPBRFrontMaterial_Roughness(void); //!< Roughness coefficient
|
||||
float occPBRFrontMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient
|
||||
vec3 occPBRFrontMaterial_Emission(void); //!< Light intensity emitted by material
|
||||
float occPBRFrontMaterial_IOR(void); //!< Index of refraction
|
||||
#endif
|
||||
|
||||
// Back material properties accessors
|
||||
vec4 occBackMaterial_Emission(void); //!< Emission color
|
||||
vec4 occBackMaterial_Ambient(void); //!< Ambient reflection
|
||||
vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection
|
||||
vec4 occBackMaterial_Specular(void); //!< Specular reflection
|
||||
float occBackMaterial_Shininess(void); //!< Specular exponent
|
||||
float occBackMaterial_Transparency(void); //!< Transparency coefficient
|
||||
#if !defined(THE_IS_PBR)
|
||||
vec4 occBackMaterial_Emission(void); //!< Emission color
|
||||
vec4 occBackMaterial_Ambient(void); //!< Ambient reflection
|
||||
vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection
|
||||
vec4 occBackMaterial_Specular(void); //!< Specular reflection
|
||||
float occBackMaterial_Shininess(void); //!< Specular exponent
|
||||
float occBackMaterial_Transparency(void); //!< Transparency coefficient
|
||||
#else
|
||||
vec4 occPBRBackMaterial_Color(void); //!< Base color of PBR material
|
||||
float occPBRBackMaterial_Metallic(void); //!< Metallic coefficient
|
||||
float occPBRBackMaterial_Roughness(void); //!< Roughness coefficient
|
||||
float occPBRBackMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient
|
||||
vec3 occPBRBackMaterial_Emission(void); //!< Light intensity emitted by material
|
||||
float occPBRBackMaterial_IOR(void); //!< Index of refraction
|
||||
#endif
|
||||
|
||||
#ifdef THE_HAS_DEFAULT_SAMPLER
|
||||
#define occActiveSampler occSampler0 //!< alias for backward compatibility
|
||||
|
@@ -19,15 +19,59 @@ void occSetFragColor (in vec4 theColor)
|
||||
|
||||
#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)
|
||||
// arrays of light sources
|
||||
uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types
|
||||
uniform vec4 occLightSources[THE_MAX_LIGHTS * 4]; //!< packed light sources parameters
|
||||
uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types
|
||||
#endif
|
||||
|
||||
// material state
|
||||
#if defined(THE_IS_PBR)
|
||||
vec3 occDiffIBLMap (in vec3 theNormal)
|
||||
{
|
||||
vec3 aSHCoeffs[9];
|
||||
for (int i = 0; i < 9; ++i)
|
||||
{
|
||||
aSHCoeffs[i] = occTexture2D (occDiffIBLMapSHCoeffs, vec2 ((float(i) + 0.5) / 9.0, 0.0)).rgb;
|
||||
}
|
||||
return aSHCoeffs[0]
|
||||
|
||||
+ aSHCoeffs[1] * theNormal.x
|
||||
+ aSHCoeffs[2] * theNormal.y
|
||||
+ aSHCoeffs[3] * theNormal.z
|
||||
|
||||
+ aSHCoeffs[4] * theNormal.x * theNormal.z
|
||||
+ aSHCoeffs[5] * theNormal.y * theNormal.z
|
||||
+ aSHCoeffs[6] * theNormal.x * theNormal.y
|
||||
|
||||
+ aSHCoeffs[7] * (3.0 * theNormal.z * theNormal.z - 1.0)
|
||||
+ aSHCoeffs[8] * (theNormal.x * theNormal.x - theNormal.y * theNormal.y);
|
||||
}
|
||||
#endif
|
||||
|
||||
// front and back material properties accessors
|
||||
#if defined(THE_IS_PBR)
|
||||
uniform vec4 occPbrFrontMaterial[3];
|
||||
uniform vec4 occPbrBackMaterial[3];
|
||||
|
||||
#define MIN_ROUGHNESS 0.01
|
||||
// Converts roughness value from range [0, 1] to real value for calculations
|
||||
float occRoughness (in float theNormalizedRoughness) { return theNormalizedRoughness * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS; }
|
||||
|
||||
vec4 occPBRFrontMaterial_Color(void) { return occPbrFrontMaterial[0]; }
|
||||
vec3 occPBRFrontMaterial_Emission(void) { return occPbrFrontMaterial[1].rgb; }
|
||||
float occPBRFrontMaterial_IOR(void) { return occPbrFrontMaterial[1].w; }
|
||||
float occPBRFrontMaterial_Metallic(void) { return occPbrFrontMaterial[2].b; }
|
||||
float occPBRFrontMaterial_Roughness(void) { return occRoughness (occPbrFrontMaterial[2].g); }
|
||||
float occPBRFrontMaterial_NormalizedRoughness(void) { return occPbrFrontMaterial[2].g; }
|
||||
|
||||
vec4 occPBRBackMaterial_Color(void) { return occPbrBackMaterial[0]; }
|
||||
vec3 occPBRBackMaterial_Emission(void) { return occPbrBackMaterial[1].rgb; }
|
||||
float occPBRBackMaterial_IOR(void) { return occPbrBackMaterial[1].w; }
|
||||
float occPBRBackMaterial_Metallic(void) { return occPbrBackMaterial[2].b; }
|
||||
float occPBRBackMaterial_Roughness(void) { return occRoughness (occPbrBackMaterial[2].g); }
|
||||
float occPBRBackMaterial_NormalizedRoughness(void) { return occPbrBackMaterial[2].g; }
|
||||
#else
|
||||
uniform vec4 occFrontMaterial[5];
|
||||
uniform vec4 occBackMaterial[5];
|
||||
|
||||
// front material properties accessors
|
||||
vec4 occFrontMaterial_Ambient(void) { return occFrontMaterial[0]; }
|
||||
vec4 occFrontMaterial_Diffuse(void) { return occFrontMaterial[1]; }
|
||||
vec4 occFrontMaterial_Specular(void) { return occFrontMaterial[2]; }
|
||||
@@ -35,13 +79,13 @@ vec4 occFrontMaterial_Emission(void) { return occFrontMaterial[3]; }
|
||||
float occFrontMaterial_Shininess(void) { return occFrontMaterial[4].x; }
|
||||
float occFrontMaterial_Transparency(void) { return occFrontMaterial[4].y; }
|
||||
|
||||
// back material properties accessors
|
||||
vec4 occBackMaterial_Ambient(void) { return occBackMaterial[0]; }
|
||||
vec4 occBackMaterial_Diffuse(void) { return occBackMaterial[1]; }
|
||||
vec4 occBackMaterial_Specular(void) { return occBackMaterial[2]; }
|
||||
vec4 occBackMaterial_Emission(void) { return occBackMaterial[3]; }
|
||||
float occBackMaterial_Shininess(void) { return occBackMaterial[4].x; }
|
||||
float occBackMaterial_Transparency(void) { return occBackMaterial[4].y; }
|
||||
#endif
|
||||
|
||||
// 2D texture coordinates transformation
|
||||
vec2 occTextureTrsf_Translation(void) { return occTexTrsf2d[0].xy; }
|
||||
|
@@ -1,5 +1,12 @@
|
||||
srcinc:::Declarations.glsl
|
||||
srcinc:::DeclarationsImpl.glsl
|
||||
srcinc:::PBRCookTorrance.glsl
|
||||
srcinc:::PBRDistribution.glsl
|
||||
srcinc:::PBREnvBaking.fs
|
||||
srcinc:::PBREnvBaking.vs
|
||||
srcinc:::PBRFresnel.glsl
|
||||
srcinc:::PBRGeometry.glsl
|
||||
srcinc:::PBRIllumination.glsl
|
||||
srcinc:::PhongShading.fs
|
||||
srcinc:::PhongShading.vs
|
||||
srcinc:::Display.fs
|
||||
@@ -11,6 +18,13 @@ srcinc:::RaytraceSmooth.fs
|
||||
Shaders_Declarations_glsl.pxx
|
||||
Shaders_DeclarationsImpl_glsl.pxx
|
||||
Shaders_Display_fs.pxx
|
||||
Shaders_PBRCookTorrance_glsl.pxx
|
||||
Shaders_PBRDistribution_glsl.pxx
|
||||
Shaders_PBREnvBaking_fs.pxx
|
||||
Shaders_PBREnvBaking_vs.pxx
|
||||
Shaders_PBRFresnel_glsl.pxx
|
||||
Shaders_PBRGeometry_glsl.pxx
|
||||
Shaders_PBRIllumination_glsl.pxx
|
||||
Shaders_RaytraceBase_fs.pxx
|
||||
Shaders_RaytraceRender_fs.pxx
|
||||
Shaders_PathtraceBase_fs.pxx
|
||||
|
20
src/Shaders/PBRCookTorrance.glsl
Normal file
20
src/Shaders/PBRCookTorrance.glsl
Normal file
@@ -0,0 +1,20 @@
|
||||
//! Calculates Cook-Torrance BRDF.
|
||||
vec3 occPBRCookTorrance (in vec3 theView,
|
||||
in vec3 theLight,
|
||||
in vec3 theNormal,
|
||||
in vec3 theBaseColor,
|
||||
in float theMetallic,
|
||||
in float theRoughness,
|
||||
in float theIOR)
|
||||
{
|
||||
vec3 aHalf = normalize (theView + theLight);
|
||||
float aCosV = max(dot(theView, theNormal), 0.0);
|
||||
float aCosL = max(dot(theLight, theNormal), 0.0);
|
||||
float aCosH = max(dot(aHalf, theNormal), 0.0);
|
||||
float aCosVH = max(dot(aHalf, theView), 0.0);
|
||||
vec3 aCookTorrance = occPBRDistribution (aCosH, theRoughness)
|
||||
* occPBRGeometry (aCosV, aCosL, theRoughness)
|
||||
* occPBRFresnel (theBaseColor, theMetallic, theIOR, aCosVH);
|
||||
aCookTorrance /= 4.0;
|
||||
return aCookTorrance;
|
||||
}
|
9
src/Shaders/PBRDistribution.glsl
Normal file
9
src/Shaders/PBRDistribution.glsl
Normal file
@@ -0,0 +1,9 @@
|
||||
//! Calculates micro facet normals distribution.
|
||||
float occPBRDistribution (in float theCosH,
|
||||
in float theRoughness)
|
||||
{
|
||||
float aDistribution = theRoughness * theRoughness;
|
||||
aDistribution = aDistribution / (theCosH * theCosH * (aDistribution * aDistribution - 1.0) + 1.0);
|
||||
aDistribution = INV_PI * aDistribution * aDistribution;
|
||||
return aDistribution;
|
||||
}
|
162
src/Shaders/PBREnvBaking.fs
Normal file
162
src/Shaders/PBREnvBaking.fs
Normal file
@@ -0,0 +1,162 @@
|
||||
THE_SHADER_IN vec3 ViewDirection; //!< direction of fetching from environment cubemap
|
||||
|
||||
uniform int uSamplesNum; //!< number of samples in Monte-Carlo integration
|
||||
uniform int uCurrentLevel; //!< current level of specular IBL map (ignored in case of diffuse map's processing)
|
||||
uniform int uEnvMapSize; //!< one edge's size of source environtment map's zero mipmap level
|
||||
uniform int uYCoeff; //!< coefficient of Y controlling horizontal flip of cubemap
|
||||
uniform int uZCoeff; //!< coefficient of Z controlling vertical flip of cubemap
|
||||
uniform samplerCube uEnvMap; //!< source of baking (environment cubemap)
|
||||
|
||||
//! Returns coordinates of point theNumber from Hammersley point set having size theSize.
|
||||
vec2 hammersley (in int theNumber,
|
||||
in int theSize)
|
||||
{
|
||||
int aDenominator = 2;
|
||||
int aNumber = theNumber;
|
||||
float aVanDerCorput = 0.0;
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
if (aNumber > 0)
|
||||
{
|
||||
aVanDerCorput += float(aNumber % 2) / float(aDenominator);
|
||||
aNumber /= 2;
|
||||
aDenominator *= 2;
|
||||
}
|
||||
}
|
||||
return vec2(float(theNumber) / float(theSize), aVanDerCorput);
|
||||
}
|
||||
|
||||
//! This function does importance sampling on hemisphere surface using GGX normal distribution function
|
||||
//! in tangent space (positive z axis is surface normal direction).
|
||||
vec3 importanceSample (in vec2 theHammersleyPoint,
|
||||
in float theRoughness)
|
||||
{
|
||||
float aPhi = PI_2 * theHammersleyPoint.x;
|
||||
theRoughness *= theRoughness;
|
||||
theRoughness *= theRoughness;
|
||||
float aCosTheta = sqrt((1.0 - theHammersleyPoint.y) / (1.0 + (theRoughness - 1.0) * theHammersleyPoint.y));
|
||||
float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);
|
||||
return vec3(aSinTheta * cos(aPhi),
|
||||
aSinTheta * sin(aPhi),
|
||||
aCosTheta);
|
||||
}
|
||||
|
||||
//! This function uniformly generates samples on whole sphere.
|
||||
vec3 sphereUniformSample (in vec2 theHammersleyPoint)
|
||||
{
|
||||
float aPhi = PI_2 * theHammersleyPoint.x;
|
||||
float aCosTheta = 2.0 * theHammersleyPoint.y - 1.0;
|
||||
float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);
|
||||
return vec3(aSinTheta * cos(aPhi),
|
||||
aSinTheta * sin(aPhi),
|
||||
aCosTheta);
|
||||
}
|
||||
|
||||
//! Transforms resulted sampled direction from tangent space to world space considering the surface normal.
|
||||
vec3 fromTangentSpace (in vec3 theVector,
|
||||
in vec3 theNormal)
|
||||
{
|
||||
vec3 anUp = (abs(theNormal.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 anX = normalize(cross(anUp, theNormal));
|
||||
vec3 anY = cross(theNormal, anX);
|
||||
return anX * theVector.x + anY * theVector.y + theNormal * theVector.z;
|
||||
}
|
||||
|
||||
const float aSHBasisFuncCoeffs[9] = float[9]
|
||||
(
|
||||
0.282095 * 0.282095,
|
||||
0.488603 * 0.488603,
|
||||
0.488603 * 0.488603,
|
||||
0.488603 * 0.488603,
|
||||
1.092548 * 1.092548,
|
||||
1.092548 * 1.092548,
|
||||
1.092548 * 1.092548,
|
||||
0.315392 * 0.315392,
|
||||
0.546274 * 0.546274
|
||||
);
|
||||
|
||||
const float aSHCosCoeffs[9] = float[9]
|
||||
(
|
||||
3.141593,
|
||||
2.094395,
|
||||
2.094395,
|
||||
2.094395,
|
||||
0.785398,
|
||||
0.785398,
|
||||
0.785398,
|
||||
0.785398,
|
||||
0.785398
|
||||
);
|
||||
|
||||
//! Bakes diffuse IBL map's spherical harmonics coefficients.
|
||||
vec3 bakeDiffuseSH()
|
||||
{
|
||||
int anIndex = int(gl_FragCoord.x);
|
||||
vec3 aResult = vec3 (0.0);
|
||||
for (int aSampleIter = 0; aSampleIter < uSamplesNum; ++aSampleIter)
|
||||
{
|
||||
vec2 aHammersleyPoint = hammersley (aSampleIter, uSamplesNum);
|
||||
vec3 aDirection = sphereUniformSample (aHammersleyPoint);
|
||||
|
||||
vec3 aValue = occTextureCube (uEnvMap, cubemapVectorTransform (aDirection, uYCoeff, uZCoeff)).rgb;
|
||||
|
||||
float aBasisFunc[9];
|
||||
aBasisFunc[0] = 1.0;
|
||||
|
||||
aBasisFunc[1] = aDirection.x;
|
||||
aBasisFunc[2] = aDirection.y;
|
||||
aBasisFunc[3] = aDirection.z;
|
||||
|
||||
aBasisFunc[4] = aDirection.x * aDirection.z;
|
||||
aBasisFunc[5] = aDirection.y * aDirection.z;
|
||||
aBasisFunc[6] = aDirection.x * aDirection.y;
|
||||
|
||||
aBasisFunc[7] = 3.0 * aDirection.z * aDirection.z - 1.0;
|
||||
aBasisFunc[8] = aDirection.x * aDirection.x - aDirection.y * aDirection.y;
|
||||
|
||||
aResult += aValue * aBasisFunc[anIndex];
|
||||
}
|
||||
|
||||
aResult *= 4.0 * aSHCosCoeffs[anIndex] * aSHBasisFuncCoeffs[anIndex] / float(uSamplesNum);
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//! Bakes specular IBL map.
|
||||
vec3 bakeSpecularMap (in vec3 theNormal,
|
||||
in float theRoughness)
|
||||
{
|
||||
vec3 aResult = vec3(0.0);
|
||||
float aWeightSum = 0.0;
|
||||
int aSamplesNum = (theRoughness == 0.0) ? 1 : uSamplesNum;
|
||||
float aSolidAngleSource = 4.0 * PI / (6.0 * float(uEnvMapSize * uEnvMapSize));
|
||||
for (int aSampleIter = 0; aSampleIter < aSamplesNum; ++aSampleIter)
|
||||
{
|
||||
vec2 aHammersleyPoint = hammersley (aSampleIter, aSamplesNum);
|
||||
vec3 aHalf = importanceSample (aHammersleyPoint, occRoughness (theRoughness));
|
||||
float aHdotV = aHalf.z;
|
||||
aHalf = fromTangentSpace (aHalf, theNormal);
|
||||
vec3 aLight = -reflect (theNormal, aHalf);
|
||||
float aNdotL = dot (aLight, theNormal);
|
||||
if (aNdotL > 0.0)
|
||||
{
|
||||
float aSolidAngleSample = 1.0 / (float(aSamplesNum) * (occPBRDistribution (aHdotV, theRoughness) * 0.25 + 0.0001) + 0.0001);
|
||||
float aLod = (theRoughness == 0.0) ? 0.0 : 0.5 * log2 (aSolidAngleSample / aSolidAngleSource);
|
||||
aResult += occTextureCubeLod (uEnvMap, aLight, aLod).rgb * aNdotL;
|
||||
aWeightSum += aNdotL;
|
||||
}
|
||||
}
|
||||
return aResult / aWeightSum;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 aViewDirection = normalize (ViewDirection);
|
||||
if (occNbSpecIBLLevels == 0)
|
||||
{
|
||||
occSetFragColor (vec4 (bakeDiffuseSH (), 1.0));
|
||||
}
|
||||
else
|
||||
{
|
||||
occSetFragColor (vec4 (bakeSpecularMap (aViewDirection, float(uCurrentLevel) / float(occNbSpecIBLLevels - 1)), 1.0));
|
||||
}
|
||||
}
|
35
src/Shaders/PBREnvBaking.vs
Normal file
35
src/Shaders/PBREnvBaking.vs
Normal file
@@ -0,0 +1,35 @@
|
||||
THE_SHADER_OUT vec3 ViewDirection; //!< direction of fetching from environment cubemap
|
||||
|
||||
uniform int uCurrentSide; //!< current side of cubemap
|
||||
uniform int uYCoeff; //!< coefficient of Y controlling horizontal flip of cubemap
|
||||
uniform int uZCoeff; //!< coefficient of Z controlling vertical flip of cubemap
|
||||
|
||||
const mat2 cubemapDirectionMatrices[6] = mat2[]
|
||||
(
|
||||
mat2 ( 0, -1, -1, 0),
|
||||
mat2 ( 0, 1, -1, 0),
|
||||
mat2 ( 0, 1, 1, 0),
|
||||
mat2 ( 0, 1, -1, 0),
|
||||
mat2 ( 1, 0, 0, -1),
|
||||
mat2 (-1, 0, 0, -1)
|
||||
);
|
||||
|
||||
//! Generates environment map fetching direction considering current index of side.
|
||||
vec3 cubemapBakingViewDirection (in int theSide,
|
||||
in vec2 theScreenCoord)
|
||||
{
|
||||
int anAxis = theSide / 2;
|
||||
vec3 aDirection = vec3(0.0);
|
||||
aDirection[anAxis] = float(-(int(theSide) % 2) * 2 + 1);
|
||||
theScreenCoord = cubemapDirectionMatrices[theSide] * theScreenCoord;
|
||||
aDirection[(anAxis + 1) % 3] = theScreenCoord.x;
|
||||
aDirection[(anAxis + 2) % 3] = theScreenCoord.y;
|
||||
return aDirection;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ViewDirection = cubemapBakingViewDirection (uCurrentSide, occVertex.xy);
|
||||
ViewDirection = cubemapVectorTransform (ViewDirection, uYCoeff, uZCoeff);
|
||||
gl_Position = vec4 (occVertex.xy, 0.0, 1.0);
|
||||
}
|
36
src/Shaders/PBRFresnel.glsl
Normal file
36
src/Shaders/PBRFresnel.glsl
Normal file
@@ -0,0 +1,36 @@
|
||||
//! Functions to calculate fresnel coefficient and approximate zero fresnel value.
|
||||
vec3 occPBRFresnel (in vec3 theBaseColor,
|
||||
in float theMetallic,
|
||||
in float theIOR)
|
||||
{
|
||||
theIOR = (1.0 - theIOR) / (1.0 + theIOR);
|
||||
theIOR *= theIOR;
|
||||
vec3 f0 = vec3(theIOR);
|
||||
f0 = mix (f0, theBaseColor.rgb, theMetallic);
|
||||
return f0;
|
||||
}
|
||||
|
||||
vec3 occPBRFresnel (in vec3 theBaseColor,
|
||||
in float theMetallic,
|
||||
in float theIOR,
|
||||
in float theCosVH)
|
||||
{
|
||||
vec3 f0 = occPBRFresnel (theBaseColor, theMetallic, theIOR);
|
||||
theCosVH = 1.0 - theCosVH;
|
||||
theCosVH *= theCosVH;
|
||||
theCosVH *= theCosVH * theCosVH * theCosVH * theCosVH;
|
||||
return f0 + (vec3 (1.0) - f0) * theCosVH;
|
||||
}
|
||||
|
||||
vec3 occPBRFresnel (in vec3 theBaseColor,
|
||||
in float theMetallic,
|
||||
in float theRoughness,
|
||||
in float theIOR,
|
||||
in float theCosV)
|
||||
{
|
||||
vec3 f0 = occPBRFresnel (theBaseColor, theMetallic, theIOR);
|
||||
theCosV = 1.0 - theCosV;
|
||||
theCosV *= theCosV;
|
||||
theCosV *= theCosV * theCosV * theCosV * theCosV;
|
||||
return f0 + (max(vec3(1.0 - theRoughness), f0) - f0) * theCosV;
|
||||
}
|
13
src/Shaders/PBRGeometry.glsl
Normal file
13
src/Shaders/PBRGeometry.glsl
Normal file
@@ -0,0 +1,13 @@
|
||||
//! Calculates geometry factor for Cook-Torrance BRDF.
|
||||
float occPBRGeometry (in float theCosV,
|
||||
in float theCosL,
|
||||
in float theRoughness)
|
||||
{
|
||||
float k = theRoughness + 1.0;
|
||||
k *= 0.125 * k;
|
||||
float g1 = 1.0;
|
||||
g1 /= theCosV * (1.0 - k) + k;
|
||||
float g2 = 1.0;
|
||||
g2 /= theCosL * (1.0 - k) + k;
|
||||
return g1 * g2;
|
||||
}
|
28
src/Shaders/PBRIllumination.glsl
Normal file
28
src/Shaders/PBRIllumination.glsl
Normal file
@@ -0,0 +1,28 @@
|
||||
//! Calculates direct illumination using Cook-Torrance BRDF.
|
||||
vec3 occPBRIllumination (in vec3 theView,
|
||||
in vec3 theLight,
|
||||
in vec3 theNormal,
|
||||
in vec4 theBaseColor,
|
||||
in float theMetallic,
|
||||
in float theRoughness,
|
||||
in float theIOR,
|
||||
in vec3 theLightColor,
|
||||
in float theLightIntensity)
|
||||
{
|
||||
vec3 aHalf = normalize (theView + theLight);
|
||||
float aCosVH = max(dot(theView, aHalf), 0.0);
|
||||
vec3 aFresnel = occPBRFresnel (theBaseColor.rgb, theMetallic, theIOR, aCosVH);
|
||||
vec3 aSpecular = occPBRCookTorrance (theView,
|
||||
theLight,
|
||||
theNormal,
|
||||
theBaseColor.rgb,
|
||||
theMetallic,
|
||||
theRoughness,
|
||||
theIOR);
|
||||
vec3 aDiffuse = vec3(1.0) - aFresnel;
|
||||
aDiffuse *= 1.0 - theMetallic;
|
||||
aDiffuse *= INV_PI;
|
||||
aDiffuse *= theBaseColor.rgb;
|
||||
aDiffuse = mix (vec3(0.0), aDiffuse, theBaseColor.a);
|
||||
return (aDiffuse + aSpecular) * theLightColor * theLightIntensity * max(0.0, dot(theLight, theNormal));
|
||||
}
|
@@ -29,7 +29,7 @@ void pointLight (in int theId,
|
||||
in vec3 thePoint)
|
||||
{
|
||||
vec3 aLight = occLight_Position (theId).xyz;
|
||||
if (occLight_IsHeadlight (theId) == 0)
|
||||
if (!occLight_IsHeadlight (theId))
|
||||
{
|
||||
aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));
|
||||
}
|
||||
|
@@ -22,15 +22,59 @@ static const char Shaders_DeclarationsImpl_glsl[] =
|
||||
"\n"
|
||||
"#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)\n"
|
||||
"// arrays of light sources\n"
|
||||
"uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types\n"
|
||||
"uniform vec4 occLightSources[THE_MAX_LIGHTS * 4]; //!< packed light sources parameters\n"
|
||||
"uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"// material state\n"
|
||||
"#if defined(THE_IS_PBR)\n"
|
||||
"vec3 occDiffIBLMap (in vec3 theNormal)\n"
|
||||
"{\n"
|
||||
" vec3 aSHCoeffs[9];\n"
|
||||
" for (int i = 0; i < 9; ++i)\n"
|
||||
" {\n"
|
||||
" aSHCoeffs[i] = occTexture2D (occDiffIBLMapSHCoeffs, vec2 ((float(i) + 0.5) / 9.0, 0.0)).rgb;\n"
|
||||
" }\n"
|
||||
" return aSHCoeffs[0]\n"
|
||||
"\n"
|
||||
" + aSHCoeffs[1] * theNormal.x\n"
|
||||
" + aSHCoeffs[2] * theNormal.y\n"
|
||||
" + aSHCoeffs[3] * theNormal.z\n"
|
||||
"\n"
|
||||
" + aSHCoeffs[4] * theNormal.x * theNormal.z\n"
|
||||
" + aSHCoeffs[5] * theNormal.y * theNormal.z\n"
|
||||
" + aSHCoeffs[6] * theNormal.x * theNormal.y\n"
|
||||
"\n"
|
||||
" + aSHCoeffs[7] * (3.0 * theNormal.z * theNormal.z - 1.0)\n"
|
||||
" + aSHCoeffs[8] * (theNormal.x * theNormal.x - theNormal.y * theNormal.y);\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"// front and back material properties accessors\n"
|
||||
"#if defined(THE_IS_PBR)\n"
|
||||
"uniform vec4 occPbrFrontMaterial[3];\n"
|
||||
"uniform vec4 occPbrBackMaterial[3];\n"
|
||||
"\n"
|
||||
"#define MIN_ROUGHNESS 0.01\n"
|
||||
"// Converts roughness value from range [0, 1] to real value for calculations\n"
|
||||
"float occRoughness (in float theNormalizedRoughness) { return theNormalizedRoughness * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS; }\n"
|
||||
"\n"
|
||||
"vec4 occPBRFrontMaterial_Color(void) { return occPbrFrontMaterial[0]; }\n"
|
||||
"vec3 occPBRFrontMaterial_Emission(void) { return occPbrFrontMaterial[1].rgb; }\n"
|
||||
"float occPBRFrontMaterial_IOR(void) { return occPbrFrontMaterial[1].w; }\n"
|
||||
"float occPBRFrontMaterial_Metallic(void) { return occPbrFrontMaterial[2].b; }\n"
|
||||
"float occPBRFrontMaterial_Roughness(void) { return occRoughness (occPbrFrontMaterial[2].g); }\n"
|
||||
"float occPBRFrontMaterial_NormalizedRoughness(void) { return occPbrFrontMaterial[2].g; }\n"
|
||||
"\n"
|
||||
"vec4 occPBRBackMaterial_Color(void) { return occPbrBackMaterial[0]; }\n"
|
||||
"vec3 occPBRBackMaterial_Emission(void) { return occPbrBackMaterial[1].rgb; }\n"
|
||||
"float occPBRBackMaterial_IOR(void) { return occPbrBackMaterial[1].w; }\n"
|
||||
"float occPBRBackMaterial_Metallic(void) { return occPbrBackMaterial[2].b; }\n"
|
||||
"float occPBRBackMaterial_Roughness(void) { return occRoughness (occPbrBackMaterial[2].g); }\n"
|
||||
"float occPBRBackMaterial_NormalizedRoughness(void) { return occPbrBackMaterial[2].g; }\n"
|
||||
"#else\n"
|
||||
"uniform vec4 occFrontMaterial[5];\n"
|
||||
"uniform vec4 occBackMaterial[5];\n"
|
||||
"\n"
|
||||
"// front material properties accessors\n"
|
||||
"vec4 occFrontMaterial_Ambient(void) { return occFrontMaterial[0]; }\n"
|
||||
"vec4 occFrontMaterial_Diffuse(void) { return occFrontMaterial[1]; }\n"
|
||||
"vec4 occFrontMaterial_Specular(void) { return occFrontMaterial[2]; }\n"
|
||||
@@ -38,13 +82,13 @@ static const char Shaders_DeclarationsImpl_glsl[] =
|
||||
"float occFrontMaterial_Shininess(void) { return occFrontMaterial[4].x; }\n"
|
||||
"float occFrontMaterial_Transparency(void) { return occFrontMaterial[4].y; }\n"
|
||||
"\n"
|
||||
"// back material properties accessors\n"
|
||||
"vec4 occBackMaterial_Ambient(void) { return occBackMaterial[0]; }\n"
|
||||
"vec4 occBackMaterial_Diffuse(void) { return occBackMaterial[1]; }\n"
|
||||
"vec4 occBackMaterial_Specular(void) { return occBackMaterial[2]; }\n"
|
||||
"vec4 occBackMaterial_Emission(void) { return occBackMaterial[3]; }\n"
|
||||
"float occBackMaterial_Shininess(void) { return occBackMaterial[4].x; }\n"
|
||||
"float occBackMaterial_Transparency(void) { return occBackMaterial[4].y; }\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"// 2D texture coordinates transformation\n"
|
||||
"vec2 occTextureTrsf_Translation(void) { return occTexTrsf2d[0].xy; }\n"
|
||||
|
@@ -24,6 +24,8 @@ static const char Shaders_Declarations_glsl[] =
|
||||
" #define occTexture1D texture\n"
|
||||
" #define occTexture2D texture\n"
|
||||
" #define occTexture3D texture\n"
|
||||
" #define occTextureCube texture\n"
|
||||
" #define occTextureCubeLod textureLod\n"
|
||||
"#else\n"
|
||||
" #define THE_ATTRIBUTE attribute\n"
|
||||
" #define THE_SHADER_IN varying\n"
|
||||
@@ -32,10 +34,16 @@ static const char Shaders_Declarations_glsl[] =
|
||||
" #define occTexture1D texture1D\n"
|
||||
" #define occTexture2D texture2D\n"
|
||||
" #define occTexture3D texture3D\n"
|
||||
" #define occTextureCube textureCube\n"
|
||||
" #define occTextureCubeLod textureCubeLod\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#ifdef GL_ES\n"
|
||||
" #define THE_PREC_ENUM lowp // enumerations should fit into lowp range\n"
|
||||
"#if (__VERSION__ >= 300)\n"
|
||||
" #define THE_PREC_ENUM highp // lowp should be enough for enums but triggers driver bugs\n"
|
||||
"#else\n"
|
||||
" #define THE_PREC_ENUM lowp\n"
|
||||
"#endif\n"
|
||||
"#else\n"
|
||||
" #define THE_PREC_ENUM\n"
|
||||
"#endif\n"
|
||||
@@ -88,6 +96,15 @@ static const char Shaders_Declarations_glsl[] =
|
||||
" void occSetFragColor (in vec4 theColor);\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"// Pi number definitions\n"
|
||||
"#define PI 3.141592654\n"
|
||||
"#define PI_2 6.283185307\n"
|
||||
"#define PI_DIV_2 1.570796327\n"
|
||||
"#define PI_DIV_3 1.047197551\n"
|
||||
"#define PI_DIV_4 0.785398163\n"
|
||||
"#define INV_PI 0.318309886\n"
|
||||
"#define INV_PI_2 0.159154943\n"
|
||||
"\n"
|
||||
"// Matrix state\n"
|
||||
"uniform mat4 occWorldViewMatrix; //!< World-view matrix\n"
|
||||
"uniform mat4 occProjectionMatrix; //!< Projection matrix\n"
|
||||
@@ -105,6 +122,15 @@ static const char Shaders_Declarations_glsl[] =
|
||||
"uniform mat4 occProjectionMatrixInverseTranspose; //!< Transpose of the inverse of the projection matrix\n"
|
||||
"uniform mat4 occModelWorldMatrixInverseTranspose; //!< Transpose of the inverse of the model-world matrix\n"
|
||||
"\n"
|
||||
"#if defined(THE_IS_PBR)\n"
|
||||
"uniform sampler2D occEnvLUT; //!< Environment Lookup Table\n"
|
||||
"uniform sampler2D occDiffIBLMapSHCoeffs; //!< Packed diffuse (irradiance) IBL map's spherical harmonics coefficients\n"
|
||||
"uniform samplerCube occSpecIBLMap; //!< Specular IBL map\n"
|
||||
"uniform int occNbSpecIBLLevels; //!< Number of mipmap levels used in occSpecIBLMap to store different roughness values maps\n"
|
||||
"\n"
|
||||
"vec3 occDiffIBLMap (in vec3 theNormal); //!< Unpacks spherical harmonics coefficients to diffuse IBL map's values\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"// light type enumeration (same as Graphic3d_TypeOfLightSource)\n"
|
||||
"const int OccLightType_Direct = 1; //!< directional light source\n"
|
||||
"const int OccLightType_Point = 2; //!< isotropic point light source\n"
|
||||
@@ -119,7 +145,7 @@ static const char Shaders_Declarations_glsl[] =
|
||||
"#define occLight_Type(theId) occLightSourcesTypes[theId].x\n"
|
||||
"\n"
|
||||
"//! Is light a headlight, int?\n"
|
||||
"#define occLight_IsHeadlight(theId) occLightSourcesTypes[theId].y\n"
|
||||
"#define occLight_IsHeadlight(theId) (occLightSourcesTypes[theId].y != 0)\n"
|
||||
"\n"
|
||||
"//! Specular intensity (equals to diffuse), vec4.\n"
|
||||
"#define occLight_Specular(theId) occLightSources[theId * 4 + 0]\n"
|
||||
@@ -136,6 +162,11 @@ static const char Shaders_Declarations_glsl[] =
|
||||
"//! Attenuation of the spot light intensity (from 0 to 1), float.\n"
|
||||
"#define occLight_SpotExponent(theId) occLightSources[theId * 4 + 3].w\n"
|
||||
"\n"
|
||||
"#if defined(THE_IS_PBR)\n"
|
||||
"//! Intensity of light source (>= 0), float.\n"
|
||||
"#define occLight_Intensity(theId) occLightSources[theId * 4 + 0].a\n"
|
||||
"#else\n"
|
||||
"\n"
|
||||
"//! Diffuse intensity (equals to Specular), vec4.\n"
|
||||
"#define occLight_Diffuse(theId) occLightSources[theId * 4 + 0]\n"
|
||||
"\n"
|
||||
@@ -145,22 +176,44 @@ static const char Shaders_Declarations_glsl[] =
|
||||
"//! Linear attenuation factor of positional light source, float.\n"
|
||||
"#define occLight_LinearAttenuation(theId) occLightSources[theId * 4 + 3].y\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"// Converts roughness value from range [0, 1] to real value for calculations\n"
|
||||
"float occRoughness (in float theNormalizedRoughness);\n"
|
||||
"\n"
|
||||
"// Front material properties accessors\n"
|
||||
"vec4 occFrontMaterial_Emission(void); //!< Emission color\n"
|
||||
"vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection\n"
|
||||
"vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection\n"
|
||||
"vec4 occFrontMaterial_Specular(void); //!< Specular reflection\n"
|
||||
"float occFrontMaterial_Shininess(void); //!< Specular exponent\n"
|
||||
"float occFrontMaterial_Transparency(void); //!< Transparency coefficient\n"
|
||||
"#if !defined(THE_IS_PBR)\n"
|
||||
"vec4 occFrontMaterial_Emission(void); //!< Emission color\n"
|
||||
"vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection\n"
|
||||
"vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection\n"
|
||||
"vec4 occFrontMaterial_Specular(void); //!< Specular reflection\n"
|
||||
"float occFrontMaterial_Shininess(void); //!< Specular exponent\n"
|
||||
"float occFrontMaterial_Transparency(void); //!< Transparency coefficient\n"
|
||||
"#else\n"
|
||||
"vec4 occPBRFrontMaterial_Color(void); //!< Base color of PBR material\n"
|
||||
"float occPBRFrontMaterial_Metallic(void); //!< Metallic coefficient\n"
|
||||
"float occPBRFrontMaterial_Roughness(void); //!< Roughness coefficient\n"
|
||||
"float occPBRFrontMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient\n"
|
||||
"vec3 occPBRFrontMaterial_Emission(void); //!< Light intensity emitted by material\n"
|
||||
"float occPBRFrontMaterial_IOR(void); //!< Index of refraction\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"// Back material properties accessors\n"
|
||||
"vec4 occBackMaterial_Emission(void); //!< Emission color\n"
|
||||
"vec4 occBackMaterial_Ambient(void); //!< Ambient reflection\n"
|
||||
"vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection\n"
|
||||
"vec4 occBackMaterial_Specular(void); //!< Specular reflection\n"
|
||||
"float occBackMaterial_Shininess(void); //!< Specular exponent\n"
|
||||
"float occBackMaterial_Transparency(void); //!< Transparency coefficient\n"
|
||||
"#if !defined(THE_IS_PBR)\n"
|
||||
"vec4 occBackMaterial_Emission(void); //!< Emission color\n"
|
||||
"vec4 occBackMaterial_Ambient(void); //!< Ambient reflection\n"
|
||||
"vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection\n"
|
||||
"vec4 occBackMaterial_Specular(void); //!< Specular reflection\n"
|
||||
"float occBackMaterial_Shininess(void); //!< Specular exponent\n"
|
||||
"float occBackMaterial_Transparency(void); //!< Transparency coefficient\n"
|
||||
"#else\n"
|
||||
"vec4 occPBRBackMaterial_Color(void); //!< Base color of PBR material\n"
|
||||
"float occPBRBackMaterial_Metallic(void); //!< Metallic coefficient\n"
|
||||
"float occPBRBackMaterial_Roughness(void); //!< Roughness coefficient\n"
|
||||
"float occPBRBackMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient\n"
|
||||
"vec3 occPBRBackMaterial_Emission(void); //!< Light intensity emitted by material\n"
|
||||
"float occPBRBackMaterial_IOR(void); //!< Index of refraction\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#ifdef THE_HAS_DEFAULT_SAMPLER\n"
|
||||
"#define occActiveSampler occSampler0 //!< alias for backward compatibility\n"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user