1 // Created on: 2012-04-09
2 // Created by: Sergey ANIKIN
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <ViewerTest.hxx>
18 #include <AIS_InteractiveContext.hxx>
19 #include <AIS_InteractiveObject.hxx>
21 #include <Draw_Interpretor.hxx>
22 #include <Graphic3d_Group.hxx>
23 #include <Graphic3d_ShaderObject.hxx>
24 #include <Graphic3d_ShaderProgram.hxx>
25 #include <Image_AlienPixMap.hxx>
26 #include <OpenGl_Aspects.hxx>
27 #include <OpenGl_Context.hxx>
28 #include <OpenGl_Element.hxx>
29 #include <OpenGl_GlCore20.hxx>
30 #include <OpenGl_GraphicDriver.hxx>
31 #include <OpenGl_ShaderManager.hxx>
32 #include <OpenGl_Workspace.hxx>
33 #include <OSD_Environment.hxx>
34 #include <OSD_File.hxx>
35 #include <OSD_OpenFile.hxx>
36 #include <Prs3d_Drawer.hxx>
37 #include <Prs3d_Presentation.hxx>
38 #include <Prs3d_Root.hxx>
39 #include <Prs3d_LineAspect.hxx>
40 #include <Prs3d_ShadingAspect.hxx>
41 #include <Select3D_SensitiveCurve.hxx>
42 #include <SelectMgr_EntityOwner.hxx>
43 #include <SelectMgr_Selection.hxx>
44 #include <TCollection_AsciiString.hxx>
45 #include <V3d_View.hxx>
46 #include <V3d_Viewer.hxx>
47 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
48 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
49 #include <OpenGl_Group.hxx>
50 #include <OSD_OpenFile.hxx>
52 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
53 const Handle(AIS_InteractiveObject)& theAISObj,
54 Standard_Boolean theReplaceIfExists = Standard_True);
55 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
59 //=======================================================================
60 //function : VUserDraw
61 //purpose : Checks availability and operation of UserDraw feature
62 //=======================================================================
64 class VUserDrawObj : public AIS_InteractiveObject
68 DEFINE_STANDARD_RTTI_INLINE(VUserDrawObj,AIS_InteractiveObject);
81 class Element : public OpenGl_Element
84 Handle(VUserDrawObj) myIObj;
87 Element (const Handle(VUserDrawObj)& theIObj) : myIObj (theIObj) {}
91 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
94 myIObj->Render(theWorkspace);
97 virtual void Release (OpenGl_Context*)
103 DEFINE_STANDARD_ALLOC
107 // Virtual methods implementation
108 void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
109 const Handle(Prs3d_Presentation)& thePresentation,
110 const Standard_Integer theMode) Standard_OVERRIDE;
112 void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
113 const Standard_Integer theMode) Standard_OVERRIDE;
115 // Called by VUserDrawElement
116 void Render(const Handle(OpenGl_Workspace)& theWorkspace) const;
120 friend class Element;
123 void VUserDrawObj::Compute(const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
124 const Handle(Prs3d_Presentation)& thePrs,
125 const Standard_Integer /*theMode*/)
129 Graphic3d_Vec4 aBndMin (myCoords[0], myCoords[1], myCoords[2], 1.0f);
130 Graphic3d_Vec4 aBndMax (myCoords[3], myCoords[4], myCoords[5], 1.0f);
131 Handle(OpenGl_Group) aGroup = Handle(OpenGl_Group)::DownCast (thePrs->NewGroup());
132 aGroup->SetMinMaxValues (aBndMin.x(), aBndMin.y(), aBndMin.z(),
133 aBndMax.x(), aBndMax.y(), aBndMax.z());
134 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
135 VUserDrawObj::Element* anElem = new VUserDrawObj::Element (this);
136 aGroup->AddElement(anElem);
138 // invalidate bounding box of the scene
139 thePrsMgr->StructureManager()->Update();
142 void VUserDrawObj::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
143 const Standard_Integer /*theMode*/)
145 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
146 Handle(TColgp_HArray1OfPnt) aPnts = new TColgp_HArray1OfPnt(1, 5);
147 aPnts->SetValue(1, gp_Pnt(myCoords[0], myCoords[1], myCoords[2]));
148 aPnts->SetValue(2, gp_Pnt(myCoords[3], myCoords[4], myCoords[2]));
149 aPnts->SetValue(3, gp_Pnt(myCoords[3], myCoords[4], myCoords[5]));
150 aPnts->SetValue(4, gp_Pnt(myCoords[0], myCoords[1], myCoords[5]));
151 aPnts->SetValue(5, gp_Pnt(myCoords[0], myCoords[1], myCoords[2]));
152 Handle(Select3D_SensitiveCurve) aSensitive = new Select3D_SensitiveCurve(anEntityOwner, aPnts);
153 theSelection->Add(aSensitive);
156 void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
158 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
160 // To test linking against OpenGl_Workspace and all aspect classes
161 const OpenGl_Aspects* aMA = theWorkspace->Aspects();
162 aMA->Aspect()->MarkerType();
163 OpenGl_Vec4 aColor = theWorkspace->InteriorColor();
165 aCtx->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), Aspect_TOL_SOLID,
166 Graphic3d_TOSM_UNLIT, Graphic3d_AlphaMode_Opaque, false,
167 Handle(OpenGl_ShaderProgram)());
168 aCtx->SetColor4fv (aColor);
170 const OpenGl_Vec3 aVertArray[4] =
172 OpenGl_Vec3(myCoords[0], myCoords[1], myCoords[2]),
173 OpenGl_Vec3(myCoords[3], myCoords[4], myCoords[2]),
174 OpenGl_Vec3(myCoords[3], myCoords[4], myCoords[5]),
175 OpenGl_Vec3(myCoords[0], myCoords[1], myCoords[5]),
177 Handle(OpenGl_VertexBuffer) aVertBuffer = new OpenGl_VertexBuffer();
178 aVertBuffer->Init (aCtx, 3, 4, aVertArray[0].GetData());
180 // Finally draw something to make sure UserDraw really works
181 aVertBuffer->BindAttribute (aCtx, Graphic3d_TOA_POS);
182 glDrawArrays(GL_LINE_LOOP, 0, aVertBuffer->GetElemsNb());
183 aVertBuffer->UnbindAttribute(aCtx, Graphic3d_TOA_POS);
184 aVertBuffer->Release (aCtx.get());
187 } // end of anonymous namespace
189 static Standard_Integer VUserDraw (Draw_Interpretor& di,
190 Standard_Integer argc,
193 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
194 if (aContext.IsNull())
196 di << argv[0] << "Call 'vinit' before!\n";
200 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
201 if (aDriver.IsNull())
203 std::cerr << "Graphic driver not available.\n";
209 di << argv[0] << "Wrong number of arguments, only the object name expected\n";
213 TCollection_AsciiString aName (argv[1]);
214 VDisplayAISObject(aName, Handle(AIS_InteractiveObject)());
216 Handle(VUserDrawObj) anIObj = new VUserDrawObj();
217 VDisplayAISObject(aName, anIObj);
222 //==============================================================================
223 //function : VFeedback
225 //==============================================================================
227 static int VFeedback (Draw_Interpretor& theDI,
228 Standard_Integer /*theArgNb*/,
229 const char** /*theArgVec*/)
231 #if !defined(GL_ES_VERSION_2_0)
232 // get the active view
233 Handle(V3d_View) aView = ViewerTest::CurrentView();
236 std::cerr << "No active view. Please call vinit.\n";
240 unsigned int aBufferSize = 1024 * 1024;
243 size_t aBytes = (size_t )aBufferSize * sizeof(GLfloat);
244 if (aBytes / sizeof(GLfloat) != (size_t )aBufferSize)
246 // finito la commedia
247 std::cerr << "Can not allocate buffer - requested size ("
248 << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
249 << " MiB) is out of address space\n";
253 GLfloat* aBuffer = (GLfloat* )Standard::Allocate (aBytes);
256 // finito la commedia
257 std::cerr << "Can not allocate buffer with size ("
258 << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
263 glFeedbackBuffer ((GLsizei )aBufferSize, GL_2D, aBuffer);
264 glRenderMode (GL_FEEDBACK);
268 GLint aResult = glRenderMode (GL_RENDER);
273 void* aPtr = aBuffer;
274 Standard::Free (aPtr);
279 std::cout << "FeedBack result= " << aResult << "\n";
286 GLint aBitmapsNb = 0;
287 GLint aPassThrNb = 0;
288 GLint aUnknownNb = 0;
289 const GLint NODE_VALUES = 2; // GL_2D
290 for (GLint anIter = 0; anIter < aResult;)
292 const GLfloat aPos = aBuffer[anIter];
293 switch ((GLint )aPos)
299 anIter += 1 + NODE_VALUES;
302 case GL_LINE_RESET_TOKEN:
307 anIter += 1 + 2 * NODE_VALUES;
310 case GL_POLYGON_TOKEN:
312 const GLint aCount = (GLint )aBuffer[++anIter];
314 anIter += aCount * NODE_VALUES + 1;
319 else if (aCount == 4)
329 case GL_BITMAP_TOKEN:
330 case GL_DRAW_PIXEL_TOKEN:
331 case GL_COPY_PIXEL_TOKEN:
334 anIter += 1 + NODE_VALUES;
337 case GL_PASS_THROUGH_TOKEN:
340 anIter += 2; // header + value
351 void* aPtr = aBuffer;
352 Standard::Free (aPtr);
355 theDI << "Total nodes: " << aNodesNb << "\n"
356 << "Points: " << aPntNb << "\n"
357 << "Line segments: " << aLinesNb << "\n"
358 << "Triangles: " << aTriNb << "\n"
359 << "Quads: " << aQuadsNb << "\n"
360 << "Polygons: " << aPolyNb << "\n"
361 << "Bitmap tokens: " << aBitmapsNb << "\n"
362 << "Pass through: " << aPassThrNb << "\n"
363 << "UNKNOWN: " << aUnknownNb << "\n";
365 double aLen2D = double(aNodesNb * 2 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
366 double aLen3D = double(aNodesNb * 3 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
367 double aLen3D_rgba = double(aNodesNb * 7 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
368 theDI << "Buffer size GL_2D: " << aLen2D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
369 << "Buffer size GL_3D: " << aLen3D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
370 << "Buffer size GL_3D_COLOR: " << aLen3D_rgba * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n";
375 std::cout << "Command is unsupported on current platform.\n";
380 //==============================================================================
381 //function : VImmediateFront
383 //==============================================================================
385 static int VImmediateFront (Draw_Interpretor& /*theDI*/,
386 Standard_Integer theArgNb,
387 const char** theArgVec)
390 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
391 if (aContextAIS.IsNull())
393 std::cerr << "No active view. Please call vinit.\n";
397 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
399 if (aDriver.IsNull())
401 std::cerr << "Graphic driver not available.\n";
407 std::cerr << "Wrong number of arguments.\n";
411 ViewerTest::CurrentView()->View()->SetImmediateModeDrawToFront (atoi(theArgVec[1]) != 0);
416 //! Search the info from the key.
417 inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
418 const TCollection_AsciiString& theKey)
420 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
422 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
424 return anIter.Value();
427 return TCollection_AsciiString();
430 //==============================================================================
433 //==============================================================================
435 static int VGlInfo (Draw_Interpretor& theDI,
436 Standard_Integer theArgNb,
437 const char** theArgVec)
439 // get the active view
440 Handle(V3d_View) aView = ViewerTest::CurrentView();
443 std::cerr << "No active view. Please call vinit.\n";
447 Standard_Integer anArgIter = 1;
448 Graphic3d_DiagnosticInfo anInfoLevel = Graphic3d_DiagnosticInfo_Basic;
451 TCollection_AsciiString aName (theArgVec[1]);
453 if (aName == "-short")
456 anInfoLevel = Graphic3d_DiagnosticInfo_Short;
458 else if (aName == "-basic")
461 anInfoLevel = Graphic3d_DiagnosticInfo_Basic;
463 else if (aName == "-complete"
467 anInfoLevel = Graphic3d_DiagnosticInfo_Complete;
471 TColStd_IndexedDataMapOfStringString aDict;
472 if (anArgIter >= theArgNb)
474 aView->DiagnosticInformation (aDict, anInfoLevel);
475 TCollection_AsciiString aText;
476 for (TColStd_IndexedDataMapOfStringString::Iterator aValueIter (aDict); aValueIter.More(); aValueIter.Next())
478 if (!aText.IsEmpty())
482 aText += TCollection_AsciiString(" ") + aValueIter.Key() + ": " + aValueIter.Value();
485 theDI << "OpenGL info:\n"
490 const Standard_Boolean isList = theArgNb >= 3;
491 aView->DiagnosticInformation (aDict, Graphic3d_DiagnosticInfo_Complete);
492 for (; anArgIter < theArgNb; ++anArgIter)
494 TCollection_AsciiString aName (theArgVec[anArgIter]);
496 TCollection_AsciiString aValue;
497 if (aName.Search ("VENDOR") != -1)
499 aValue = searchInfo (aDict, "GLvendor");
501 else if (aName.Search ("RENDERER") != -1)
503 aValue = searchInfo (aDict, "GLdevice");
505 else if (aName.Search ("SHADING_LANGUAGE_VERSION") != -1
506 || aName.Search ("GLSL") != -1)
508 aValue = searchInfo (aDict, "GLSLversion");
510 else if (aName.Search ("VERSION") != -1)
512 aValue = searchInfo (aDict, "GLversion");
514 else if (aName.Search ("EXTENSIONS") != -1)
516 aValue = searchInfo (aDict, "GLextensions");
520 std::cerr << "Unknown key '" << aName.ToCString() << "'\n";
526 theDI << "{" << aValue << "} ";
537 //! Parse shader type argument.
538 static bool parseShaderTypeArg (Graphic3d_TypeOfShaderObject& theType,
539 const TCollection_AsciiString& theArg)
541 if (theArg == "-vertex"
542 || theArg == "-vert")
544 theType = Graphic3d_TOS_VERTEX;
546 else if (theArg == "-tessevaluation"
547 || theArg == "-tesseval"
548 || theArg == "-evaluation"
549 || theArg == "-eval")
551 theType = Graphic3d_TOS_TESS_EVALUATION;
553 else if (theArg == "-tesscontrol"
554 || theArg == "-tessctrl"
555 || theArg == "-control"
556 || theArg == "-ctrl")
558 theType = Graphic3d_TOS_TESS_CONTROL;
560 else if (theArg == "-geometry"
561 || theArg == "-geom")
563 theType = Graphic3d_TOS_GEOMETRY;
565 else if (theArg == "-fragment"
566 || theArg == "-frag")
568 theType = Graphic3d_TOS_FRAGMENT;
570 else if (theArg == "-compute"
571 || theArg == "-comp")
573 theType = Graphic3d_TOS_COMPUTE;
582 //==============================================================================
583 //function : VShaderProg
584 //purpose : Sets the pair of vertex and fragment shaders for the object
585 //==============================================================================
586 static Standard_Integer VShaderProg (Draw_Interpretor& theDI,
587 Standard_Integer theArgNb,
588 const char** theArgVec)
590 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
593 std::cout << "Error: no active view.\n";
596 else if (theArgNb < 2)
598 std::cout << "Syntax error: lack of arguments\n";
602 bool isExplicitShaderType = false;
603 Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram();
604 NCollection_Sequence<Handle(AIS_InteractiveObject)> aPrsList;
605 Graphic3d_GroupAspect aGroupAspect = Graphic3d_ASPECT_FILL_AREA;
606 bool isSetGroupAspect = false;
607 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
609 TCollection_AsciiString anArg (theArgVec[anArgIter]);
611 Graphic3d_TypeOfShaderObject aShaderTypeArg = Graphic3d_TypeOfShaderObject(-1);
612 if (!aProgram.IsNull()
613 && anArg == "-uniform"
614 && anArgIter + 2 < theArgNb)
616 TCollection_AsciiString aName = theArgVec[++anArgIter];
617 aProgram->PushVariableFloat (aName, float (Draw::Atof (theArgVec[++anArgIter])));
619 else if (anArg == "-list"
620 || ((anArg == "-update"
623 || anArg == "-reload"
625 && anArgIter + 1 < theArgNb))
627 Handle(OpenGl_Context) aGlCtx;
628 if (Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aCtx->CurrentViewer()->Driver()))
630 aGlCtx = aDriver->GetSharedContext();
634 std::cout << "Error: no OpenGl_Context\n";
638 if (anArg == "-list")
640 for (OpenGl_Context::OpenGl_ResourcesMap::Iterator aResIter (aGlCtx->SharedResources()); aResIter.More(); aResIter.Next())
642 if (Handle(OpenGl_ShaderProgram) aResProg = Handle(OpenGl_ShaderProgram)::DownCast (aResIter.Value()))
644 theDI << aResProg->ResourceId() << " ";
650 TCollection_AsciiString aShaderName = theArgVec[++anArgIter];
651 Handle(OpenGl_ShaderProgram) aResProg;
652 if (!aGlCtx->GetResource (aShaderName, aResProg))
654 std::cout << "Syntax error: shader resource '" << aShaderName << "' is not found\n";
657 if (aResProg->UpdateDebugDump (aGlCtx, "", false, anArg == "-dump"))
659 aCtx->UpdateCurrentViewer();
662 if (anArgIter + 1 < theArgNb)
664 std::cout << "Syntax error: wrong number of arguments\n";
669 else if (!aProgram.IsNull()
670 && aProgram->ShaderObjects().IsEmpty()
676 else if (!aProgram.IsNull()
677 && aProgram->ShaderObjects().IsEmpty()
678 && (anArg == "-phong"
679 || anArg == "phong"))
681 const TCollection_AsciiString& aShadersRoot = Graphic3d_ShaderProgram::ShadersFolder();
682 if (aShadersRoot.IsEmpty())
684 std::cout << "Error: both environment variables CSF_ShadersDirectory and CASROOT are undefined!\n"
685 "At least one should be defined to load Phong program.\n";
689 const TCollection_AsciiString aSrcVert = aShadersRoot + "/PhongShading.vs";
690 const TCollection_AsciiString aSrcFrag = aShadersRoot + "/PhongShading.fs";
691 if (!aSrcVert.IsEmpty()
692 && !OSD_File (aSrcVert).Exists())
694 std::cout << "Error: PhongShading.vs is not found\n";
697 if (!aSrcFrag.IsEmpty()
698 && !OSD_File (aSrcFrag).Exists())
700 std::cout << "Error: PhongShading.fs is not found\n";
704 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert));
705 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag));
707 else if (aPrsList.IsEmpty()
712 else if (!isSetGroupAspect
713 && anArgIter + 1 < theArgNb
714 && (anArg == "-primtype"
715 || anArg == "-primitivetype"
716 || anArg == "-groupaspect"
717 || anArg == "-aspecttype"
718 || anArg == "-aspect"))
720 isSetGroupAspect = true;
721 TCollection_AsciiString aPrimTypeStr (theArgVec[++anArgIter]);
722 aPrimTypeStr.LowerCase();
723 if (aPrimTypeStr == "line")
725 aGroupAspect = Graphic3d_ASPECT_LINE;
727 else if (aPrimTypeStr == "tris"
728 || aPrimTypeStr == "triangles"
729 || aPrimTypeStr == "fill"
730 || aPrimTypeStr == "fillarea"
731 || aPrimTypeStr == "shading"
732 || aPrimTypeStr == "shade")
734 aGroupAspect = Graphic3d_ASPECT_FILL_AREA;
736 else if (aPrimTypeStr == "text")
738 aGroupAspect = Graphic3d_ASPECT_TEXT;
740 else if (aPrimTypeStr == "marker"
741 || aPrimTypeStr == "point"
742 || aPrimTypeStr == "pnt")
744 aGroupAspect = Graphic3d_ASPECT_MARKER;
748 std::cerr << "Syntax error at '" << aPrimTypeStr << "'\n";
752 else if (anArgIter + 1 < theArgNb
753 && !aProgram.IsNull()
754 && aProgram->Header().IsEmpty()
755 && (anArg == "-version"
756 || anArg == "-glslversion"
757 || anArg == "-header"
758 || anArg == "-glslheader"))
760 TCollection_AsciiString aHeader (theArgVec[++anArgIter]);
761 if (aHeader.IsIntegerValue())
763 aHeader = TCollection_AsciiString ("#version ") + aHeader;
765 aProgram->SetHeader (aHeader);
767 else if (!anArg.StartsWith ("-")
768 && GetMapOfAIS().IsBound2 (theArgVec[anArgIter]))
770 Handle(AIS_InteractiveObject) anIO = GetMapOfAIS().Find2 (theArgVec[anArgIter]);
773 std::cerr << "Syntax error: " << theArgVec[anArgIter] << " is not an AIS object\n";
776 aPrsList.Append (anIO);
778 else if (!aProgram.IsNull()
779 && ((anArgIter + 1 < theArgNb && parseShaderTypeArg (aShaderTypeArg, anArg))
780 || (!isExplicitShaderType && aProgram->ShaderObjects().Size() < 2)))
782 TCollection_AsciiString aShaderPath (theArgVec[anArgIter]);
783 if (aShaderTypeArg != Graphic3d_TypeOfShaderObject(-1))
785 aShaderPath = (theArgVec[++anArgIter]);
786 isExplicitShaderType = true;
789 const bool isSrcFile = OSD_File (aShaderPath).Exists();
790 Handle(Graphic3d_ShaderObject) aShader = isSrcFile
791 ? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aShaderPath)
792 : Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_VERTEX, aShaderPath);
793 const TCollection_AsciiString& aShaderSrc = aShader->Source();
795 const bool hasVertPos = aShaderSrc.Search ("gl_Position") != -1;
796 const bool hasFragColor = aShaderSrc.Search ("occSetFragColor") != -1
797 || aShaderSrc.Search ("occFragColor") != -1
798 || aShaderSrc.Search ("gl_FragColor") != -1
799 || aShaderSrc.Search ("gl_FragData") != -1;
800 Graphic3d_TypeOfShaderObject aShaderType = aShaderTypeArg;
801 if (aShaderType == Graphic3d_TypeOfShaderObject(-1))
806 aShaderType = Graphic3d_TOS_VERTEX;
811 aShaderType = Graphic3d_TOS_FRAGMENT;
814 if (aShaderType == Graphic3d_TypeOfShaderObject(-1))
816 std::cerr << "Error: non-existing or invalid shader source\n";
820 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aShaderType, aShaderSrc));
824 std::cerr << "Syntax error at '" << anArg << "'\n";
829 if (!aProgram.IsNull()
830 && ViewerTest::CurrentView()->RenderingParams().TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
832 aProgram->SetNbFragmentOutputs (2);
833 aProgram->SetWeightOitOutput (true);
836 ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aGlobalPrsIter (GetMapOfAIS());
837 NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator aPrsIter (aPrsList);
838 const bool isGlobalList = aPrsList.IsEmpty();
841 Handle(AIS_InteractiveObject) anIO;
844 if (!aGlobalPrsIter.More())
848 anIO = aGlobalPrsIter.Key1();
849 aGlobalPrsIter.Next();
857 if (!aPrsIter.More())
861 anIO = aPrsIter.Value();
865 if (anIO->Attributes()->SetShaderProgram (aProgram, aGroupAspect, true))
867 aCtx->Redisplay (anIO, Standard_False);
871 anIO->SynchronizeAspects();
875 aCtx->UpdateCurrentViewer();
879 //! Print triplet of values.
880 template<class S, class T> static S& operator<< (S& theStream, const NCollection_Vec3<T>& theVec)
882 theStream << theVec[0] << " " << theVec[1] << " " << theVec[2];
887 template<class S, class T> static S& operator<< (S& theStream, const NCollection_Vec4<T>& theVec)
889 theStream << theVec[0] << " " << theVec[1] << " " << theVec[2] << " " << theVec[3];
893 //! Print fresnel model.
894 static const char* fresnelModelString (const Graphic3d_FresnelModel theModel)
898 case Graphic3d_FM_SCHLICK: return "SCHLICK";
899 case Graphic3d_FM_CONSTANT: return "CONSTANT";
900 case Graphic3d_FM_CONDUCTOR: return "CONDUCTOR";
901 case Graphic3d_FM_DIELECTRIC: return "DIELECTRIC";
906 //! Create a colored rectangle SVG element.
907 static TCollection_AsciiString formatSvgColoredRect (const Quantity_Color& theColor)
909 return TCollection_AsciiString()
910 + "<svg width='20px' height='20px'><rect width='20px' height='20px' fill='" + Quantity_Color::ColorToHex (theColor) + "' /></svg>";
913 //==============================================================================
914 //function : VListMaterials
916 //==============================================================================
917 static Standard_Integer VListMaterials (Draw_Interpretor& theDI,
918 Standard_Integer theArgNb,
919 const char** theArgVec)
921 TCollection_AsciiString aDumpFile;
922 NCollection_Sequence<Graphic3d_NameOfMaterial> aMatList;
923 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
925 TCollection_AsciiString anArg (theArgVec[anArgIter]);
927 Graphic3d_NameOfMaterial aMat = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter]);
928 if (aMat != Graphic3d_NOM_DEFAULT)
930 aMatList.Append (aMat);
932 else if (anArg == "*")
934 for (Standard_Integer aMatIter = 0; aMatIter < (Standard_Integer )Graphic3d_NOM_DEFAULT; ++aMatIter)
936 aMatList.Append ((Graphic3d_NameOfMaterial )aMatIter);
939 else if (aDumpFile.IsEmpty()
940 && (anArg.EndsWith (".obj")
941 || anArg.EndsWith (".mtl")
942 || anArg.EndsWith (".htm")
943 || anArg.EndsWith (".html")))
945 aDumpFile = theArgVec[anArgIter];
949 std::cout << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'\n";
953 if (aMatList.IsEmpty())
955 if (aDumpFile.IsEmpty())
957 for (Standard_Integer aMatIter = 1; aMatIter <= Graphic3d_MaterialAspect::NumberOfMaterials(); ++aMatIter)
959 theDI << Graphic3d_MaterialAspect::MaterialName (aMatIter) << " ";
964 for (Standard_Integer aMatIter = 0; aMatIter < (Standard_Integer )Graphic3d_NOM_DEFAULT; ++aMatIter)
966 aMatList.Append ((Graphic3d_NameOfMaterial )aMatIter);
970 // geometry for dumping
971 const Graphic3d_Vec3 aBoxVerts[8] =
973 Graphic3d_Vec3( 1, -1, -1),
974 Graphic3d_Vec3( 1, -1, 1),
975 Graphic3d_Vec3(-1, -1, 1),
976 Graphic3d_Vec3(-1, -1, -1),
977 Graphic3d_Vec3( 1, 1, -1),
978 Graphic3d_Vec3( 1, 1, 1),
979 Graphic3d_Vec3(-1, 1, 1),
980 Graphic3d_Vec3(-1, 1, -1)
983 const Graphic3d_Vec4i aBoxQuads[6] =
985 Graphic3d_Vec4i (1, 2, 3, 4),
986 Graphic3d_Vec4i (5, 8, 7, 6),
987 Graphic3d_Vec4i (1, 5, 6, 2),
988 Graphic3d_Vec4i (2, 6, 7, 3),
989 Graphic3d_Vec4i (3, 7, 8, 4),
990 Graphic3d_Vec4i (5, 1, 4, 8)
993 std::ofstream aMatFile, anObjFile, anHtmlFile;
994 if (aDumpFile.EndsWith (".obj")
995 || aDumpFile.EndsWith (".mtl"))
997 const TCollection_AsciiString aMatFilePath = aDumpFile.SubString (1, aDumpFile.Length() - 3) + "mtl";
998 const TCollection_AsciiString anObjFilePath = aDumpFile.SubString (1, aDumpFile.Length() - 3) + "obj";
1000 OSD_OpenStream (aMatFile, aMatFilePath.ToCString(), std::ios::out | std::ios::binary);
1001 if (!aMatFile.is_open())
1003 std::cout << "Error: unable creating material file\n";
1006 if (!aDumpFile.EndsWith (".mtl"))
1008 OSD_OpenStream (anObjFile, anObjFilePath.ToCString(), std::ios::out | std::ios::binary);
1009 if (!anObjFile.is_open())
1011 std::cout << "Error: unable creating OBJ file\n";
1015 TCollection_AsciiString anMtlName, aFolder;
1016 OSD_Path::FolderAndFileFromPath (aMatFilePath, aFolder, anMtlName);
1017 anObjFile << "mtllib " << anMtlName << "\n";
1020 else if (aDumpFile.EndsWith (".htm")
1021 || aDumpFile.EndsWith (".html"))
1023 OSD_OpenStream (anHtmlFile, aDumpFile.ToCString(), std::ios::out | std::ios::binary);
1024 if (!anHtmlFile.is_open())
1026 std::cout << "Error: unable creating HTML file\n";
1029 anHtmlFile << "<html>\n"
1030 "<head><title>OCCT Material table</title></head>\n"
1032 "<table border='1'><tbody>\n"
1034 "<th rowspan='2'><div title='Material name.\n"
1035 "See also Graphic3d_NameOfMaterial enumeration'>"
1037 "<th rowspan='2'><div title='Material type: PHYSIC or ASPECT.\n"
1038 "ASPECT material does not define final colors, it is taken from Internal Color instead.\n"
1039 "See also Graphic3d_TypeOfMaterial enumeration'>"
1041 "<th rowspan='2'>Transparency</th>\n"
1042 "<th colspan='5'><div title='PBR Metallic-Roughness'>"
1043 "PBR Metallic-Roughness</div></th>\n"
1044 "<th colspan='5'><div title='Common material definition for Phong shading model'>"
1045 "Common (Blinn-Phong)</div></th>\n"
1046 "<th colspan='10'><div title='BSDF (Bidirectional Scattering Distribution Function).\n"
1047 "Used for physically-based rendering (in path tracing engine).\n"
1048 "BSDF is represented as weighted mixture of basic BRDFs/BTDFs (Bidirectional Reflectance (Transmittance) Distribution Functions).\n"
1049 "See also Graphic3d_BSDF structure.'>"
1050 "BSDF (Bidirectional Scattering Distribution Function)</div></th>\n"
1054 "<th>Metallic</th>\n"
1055 "<th>Roughness</th>\n"
1056 "<th>Emission</th>\n"
1057 "<th><div title='Index of refraction'>"
1059 "<th>Ambient</th>\n"
1060 "<th>Diffuse</th>\n"
1061 "<th>Specular</th>\n"
1062 "<th>Emissive</th>\n"
1063 "<th>Shiness</th>\n"
1064 "<th><div title='Weight of coat specular/glossy BRDF'>"
1066 "<th><div title='Weight of base diffuse BRDF'>"
1068 "<th><div title='Weight of base specular/glossy BRDF'>"
1070 "<th><div title='Weight of base specular/glossy BTDF'>"
1072 "<th><div title='Radiance emitted by the surface'>"
1074 "<th><div title='Volume scattering color/density'>"
1075 "Absorption</div></th>\n"
1076 "<th><div title='Parameters of Fresnel reflectance of coat layer'>"
1077 "FresnelCoat</div></th>\n"
1078 "<th><div title='Parameters of Fresnel reflectance of base layer'>"
1079 "FresnelBase</div></th>\n"
1080 "<th>Refraction Index</th>\n"
1083 else if (!aDumpFile.IsEmpty())
1085 std::cout << "Syntax error: unknown output file format\n";
1089 Standard_Integer aMatIndex = 0, anX = 0, anY = 0;
1090 for (NCollection_Sequence<Graphic3d_NameOfMaterial>::Iterator aMatIter (aMatList); aMatIter.More(); aMatIter.Next(), ++aMatIndex)
1092 Graphic3d_MaterialAspect aMat (aMatIter.Value());
1093 const TCollection_AsciiString aMatName = aMat.StringName();
1094 const Graphic3d_Vec3 anAmbient = (Graphic3d_Vec3 )aMat.AmbientColor();
1095 const Graphic3d_Vec3 aDiffuse = (Graphic3d_Vec3 )aMat.DiffuseColor();
1096 const Graphic3d_Vec3 aSpecular = (Graphic3d_Vec3 )aMat.SpecularColor();
1097 const Graphic3d_Vec3 anEmission = (Graphic3d_Vec3 )aMat.EmissiveColor();
1098 const Standard_Real aShiness = aMat.Shininess() * 1000.0;
1099 if (aMatFile.is_open())
1101 aMatFile << "newmtl " << aMatName << "\n";
1102 aMatFile << "Ka " << Quantity_Color::Convert_LinearRGB_To_sRGB (anAmbient) << "\n";
1103 aMatFile << "Kd " << Quantity_Color::Convert_LinearRGB_To_sRGB (aDiffuse) << "\n";
1104 aMatFile << "Ks " << Quantity_Color::Convert_LinearRGB_To_sRGB (aSpecular) << "\n";
1105 aMatFile << "Ns " << aShiness << "\n";
1106 if (aMat.Transparency() >= 0.0001)
1108 aMatFile << "Tr " << aMat.Transparency() << "\n";
1112 else if (anHtmlFile.is_open())
1114 anHtmlFile << "<tr>\n";
1115 anHtmlFile << "<td>" << aMat.StringName() << "</td>\n";
1116 anHtmlFile << "<td>" << (aMat.MaterialType() == Graphic3d_MATERIAL_PHYSIC ? "PHYSIC" : "ASPECT") << "</td>\n";
1117 anHtmlFile << "<td>" << aMat.Transparency() << "</td>\n";
1118 anHtmlFile << "<td>" << formatSvgColoredRect (aMat.PBRMaterial().Color().GetRGB()) << (Graphic3d_Vec3 )aMat.PBRMaterial().Color().GetRGB() << "</td>\n";
1119 anHtmlFile << "<td>" << aMat.PBRMaterial().Metallic() << "</td>\n";
1120 anHtmlFile << "<td>" << aMat.PBRMaterial().NormalizedRoughness() << "</td>\n";
1121 anHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (aMat.PBRMaterial().Emission())) << aMat.PBRMaterial().Emission() << "</td>\n";
1122 anHtmlFile << "<td>" << aMat.PBRMaterial().IOR() << "</td>\n";
1123 anHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (anAmbient)) << anAmbient << "</td>\n";
1124 anHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (aDiffuse)) << aDiffuse << "</td>\n";
1125 anHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (aSpecular)) << aSpecular << "</td>\n";
1126 anHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (anEmission)) << anEmission << "</td>\n";
1127 anHtmlFile << "<td>" << aMat.Shininess() << "</td>\n";
1128 anHtmlFile << "<td>" << aMat.BSDF().Kc << "</td>\n";
1129 anHtmlFile << "<td>" << aMat.BSDF().Kd << "</td>\n";
1130 anHtmlFile << "<td>" << aMat.BSDF().Ks << "</td>\n";
1131 anHtmlFile << "<td>" << aMat.BSDF().Kt << "</td>\n";
1132 anHtmlFile << "<td>" << aMat.BSDF().Le << "</td>\n";
1133 anHtmlFile << "<td>" << aMat.BSDF().Absorption << "</td>\n";
1134 anHtmlFile << "<td>" << fresnelModelString (aMat.BSDF().FresnelCoat.FresnelType()) << "</td>\n";
1135 anHtmlFile << "<td>" << fresnelModelString (aMat.BSDF().FresnelBase.FresnelType()) << "</td>\n";
1136 anHtmlFile << "<td>" << aMat.RefractionIndex() << "</td>\n";
1137 anHtmlFile << "</tr>\n";
1141 theDI << aMat.StringName() << "\n";
1142 theDI << " Transparency: " << aMat.Transparency() << "\n";
1143 theDI << " PBR.BaseColor: " << (Graphic3d_Vec3 )aMat.PBRMaterial().Color().GetRGB() << "\n";
1144 theDI << " PBR.Metallic: " << aMat.PBRMaterial().Metallic() << "\n";
1145 theDI << " PBR.Roughness: " << aMat.PBRMaterial().NormalizedRoughness() << "\n";
1146 theDI << " PBR.Emission: " << aMat.PBRMaterial().Emission() << "\n";
1147 theDI << " PBR.IOR: " << aMat.PBRMaterial().IOR() << "\n";
1148 theDI << " Common.Ambient: " << anAmbient << "\n";
1149 theDI << " Common.Diffuse: " << aDiffuse << "\n";
1150 theDI << " Common.Specular: " << aSpecular << "\n";
1151 theDI << " Common.Emissive: " << anEmission << "\n";
1152 theDI << " Common.Shiness: " << aMat.Shininess() << "\n";
1153 theDI << " BSDF.Kc: " << aMat.BSDF().Kc << "\n";
1154 theDI << " BSDF.Kd: " << aMat.BSDF().Kd << "\n";
1155 theDI << " BSDF.Ks: " << aMat.BSDF().Ks << "\n";
1156 theDI << " BSDF.Kt: " << aMat.BSDF().Kt << "\n";
1157 theDI << " BSDF.Le: " << aMat.BSDF().Le << "\n";
1158 theDI << " BSDF.Absorption: " << aMat.BSDF().Absorption << "\n";
1159 theDI << " BSDF.FresnelCoat: " << fresnelModelString (aMat.BSDF().FresnelCoat.FresnelType()) << "\n";
1160 theDI << " BSDF.FresnelBase: " << fresnelModelString (aMat.BSDF().FresnelBase.FresnelType()) << "\n";
1161 theDI << " RefractionIndex: " << aMat.RefractionIndex() << "\n";
1164 if (anObjFile.is_open())
1166 anObjFile << "g " << aMatName << "\n";
1167 anObjFile << "usemtl " << aMatName << "\n";
1168 for (Standard_Integer aVertIter = 0; aVertIter < 8; ++aVertIter)
1170 anObjFile << "v " << (aBoxVerts[aVertIter] + Graphic3d_Vec3 (3.0f * anX, -3.0f * anY, 0.0f)) << "\n";
1172 anObjFile << "s off\n";
1173 for (Standard_Integer aFaceIter = 0; aFaceIter < 6; ++aFaceIter)
1175 anObjFile << "f " << (aBoxQuads[aFaceIter] + Graphic3d_Vec4i (8 * aMatIndex)) << "\n";
1186 if (anHtmlFile.is_open())
1188 anHtmlFile << "</tbody></table>\n</body>\n</html>\n";
1193 //==============================================================================
1194 //function : VListColors
1196 //==============================================================================
1197 static Standard_Integer VListColors (Draw_Interpretor& theDI,
1198 Standard_Integer theArgNb,
1199 const char** theArgVec)
1201 TCollection_AsciiString aDumpFile;
1202 NCollection_Sequence<Quantity_NameOfColor> aColList;
1203 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
1205 TCollection_AsciiString anArg (theArgVec[anArgIter]);
1207 Quantity_NameOfColor aName;
1208 if (Quantity_Color::ColorFromName (theArgVec[anArgIter], aName))
1210 aColList.Append (aName);
1212 else if (anArg == "*")
1214 for (Standard_Integer aColIter = 0; aColIter <= (Standard_Integer )Quantity_NOC_WHITE; ++aColIter)
1216 aColList.Append ((Quantity_NameOfColor )aColIter);
1219 else if (aDumpFile.IsEmpty()
1220 && (anArg.EndsWith (".htm")
1221 || anArg.EndsWith (".html")))
1223 aDumpFile = theArgVec[anArgIter];
1227 std::cout << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'\n";
1231 if (aColList.IsEmpty())
1233 if (aDumpFile.IsEmpty())
1235 for (Standard_Integer aColIter = 0; aColIter <= (Standard_Integer )Quantity_NOC_WHITE; ++aColIter)
1237 theDI << Quantity_Color::StringName (Quantity_NameOfColor (aColIter)) << " ";
1242 for (Standard_Integer aColIter = 0; aColIter <= (Standard_Integer )Quantity_NOC_WHITE; ++aColIter)
1244 aColList.Append ((Quantity_NameOfColor )aColIter);
1248 std::ofstream anHtmlFile;
1249 TCollection_AsciiString aFileNameBase, aFolder;
1250 if (aDumpFile.EndsWith (".htm")
1251 || aDumpFile.EndsWith (".html"))
1253 OSD_Path::FolderAndFileFromPath (aDumpFile, aFolder, aFileNameBase);
1254 aFileNameBase = aFileNameBase.SubString (1, aFileNameBase.Length() - (aDumpFile.EndsWith (".htm") ? 4 : 5));
1256 else if (!aDumpFile.IsEmpty())
1258 std::cout << "Syntax error: unknown output file format\n";
1262 Standard_Integer aMaxNameLen = 1;
1263 for (NCollection_Sequence<Quantity_NameOfColor>::Iterator aColIter (aColList); aColIter.More(); aColIter.Next())
1265 aMaxNameLen = Max (aMaxNameLen, TCollection_AsciiString (Quantity_Color::StringName (aColIter.Value())).Length());
1268 V3d_ImageDumpOptions anImgParams;
1269 anImgParams.Width = 60;
1270 anImgParams.Height = 30;
1271 anImgParams.BufferType = Graphic3d_BT_RGB;
1272 anImgParams.StereoOptions = V3d_SDO_MONO;
1273 anImgParams.ToAdjustAspect = Standard_True;
1274 Handle(V3d_View) aView;
1275 if (!aDumpFile.IsEmpty())
1277 ViewerTest::ViewerInit (0, 0, anImgParams.Width, anImgParams.Height, "TmpDriver/TmpViewer/TmpView");
1278 aView = ViewerTest::CurrentView();
1279 aView->SetImmediateUpdate (false);
1280 aView->SetBgGradientStyle (Aspect_GFM_NONE, false);
1283 if (!aDumpFile.IsEmpty())
1285 OSD_OpenStream (anHtmlFile, aDumpFile.ToCString(), std::ios::out | std::ios::binary);
1286 if (!anHtmlFile.is_open())
1288 std::cout << "Error: unable creating HTML file\n";
1291 anHtmlFile << "<html>\n"
1292 << "<head><title>OCCT Color table</title></head>\n"
1294 << "<table border='1'><tbody>\n"
1296 << "<th>HTML</th>\n"
1297 << "<th>OCCT</th>\n"
1298 << "<th>Color name</th>\n"
1299 << "<th>sRGB hex</th>\n"
1300 << "<th>sRGB dec</th>\n"
1301 << "<th>RGB linear</th>\n"
1305 Image_AlienPixMap anImg;
1306 Standard_Integer aColIndex = 0;
1307 for (NCollection_Sequence<Quantity_NameOfColor>::Iterator aColIter (aColList); aColIter.More(); aColIter.Next(), ++aColIndex)
1309 Quantity_Color aCol (aColIter.Value());
1310 const TCollection_AsciiString aColName = Quantity_Color::StringName (aColIter.Value());
1311 const TCollection_AsciiString anSRgbHex = Quantity_Color::ColorToHex (aCol);
1312 const Graphic3d_Vec3i anSRgbInt ((Graphic3d_Vec3 )aCol * 255.0f);
1313 if (anHtmlFile.is_open())
1315 const TCollection_AsciiString anImgPath = aFileNameBase + "_" + aColName + ".png";
1316 if (!aView.IsNull())
1318 aView->SetImmediateUpdate (false);
1319 aView->SetBackgroundColor (aCol);
1320 if (!aView->ToPixMap (anImg, anImgParams)
1321 || !anImg.Save (aFolder + anImgPath))
1323 theDI << "Error: image dump failed\n";
1328 anHtmlFile << "<tr>\n";
1329 anHtmlFile << "<td style='background-color:" << anSRgbHex << "'><pre> </pre></td>\n";
1330 anHtmlFile << "<td><img src='" << (!aView.IsNull() ? anImgPath : "") << "'></img></td>\n";
1331 anHtmlFile << "<td style='text-align:left'>" << aColName << "</td>\n";
1332 anHtmlFile << "<td style='text-align:left'><pre>" << anSRgbHex << "</pre></td>\n";
1333 anHtmlFile << "<td style='text-align:left'>(" << anSRgbInt.r() << " " << anSRgbInt.g() << " " << anSRgbInt.b() << ")</td>\n";
1334 anHtmlFile << "<td style='text-align:left'>(" << aCol.Red() << " " << aCol.Green() << " " << aCol.Blue() << ")</td>\n";
1335 anHtmlFile << "</tr>\n";
1339 TCollection_AsciiString aColNameLong (aColName);
1340 aColNameLong.RightJustify (aMaxNameLen, ' ');
1341 theDI << aColNameLong << " [" << anSRgbHex << "]: " << aCol.Red() << " " << aCol.Green() << " " << aCol.Blue() << "\n";
1345 if (!aView.IsNull())
1347 ViewerTest::RemoveView (aView);
1350 if (anHtmlFile.is_open())
1352 anHtmlFile << "</tbody></table>\n</body>\n</html>\n";
1357 //==============================================================================
1358 //function : envlutWriteToFile
1360 //==============================================================================
1361 static std::string envLutWriteToFile (Standard_ShortReal theValue)
1363 std::stringstream aStream;
1364 aStream << theValue;
1365 if (aStream.str().length() == 1)
1370 return aStream.str();
1373 //==============================================================================
1374 //function : VGenEnvLUT
1376 //==============================================================================
1377 static Standard_Integer VGenEnvLUT (Draw_Interpretor&,
1378 Standard_Integer theArgNb,
1379 const char** theArgVec)
1381 Standard_Integer aTableSize = -1;
1382 Standard_Integer aNbSamples = -1;
1383 TCollection_AsciiString aFilePath = Graphic3d_TextureRoot::TexturesFolder() + "/Textures_EnvLUT.pxx";
1385 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
1387 TCollection_AsciiString anArg(theArgVec[anArgIter]);
1390 if (anArg == "-size"
1393 if (anArgIter + 1 >= theArgNb)
1395 std::cerr << "Syntax error: size of PBR environment look up table is undefined" << "\n";
1399 aTableSize = Draw::Atoi(theArgVec[++anArgIter]);
1401 if (aTableSize < 16)
1403 std::cerr << "Error: size of PBR environment look up table must be greater or equal 16\n";
1407 else if (anArg == "-nbsamples"
1408 || anArg == "-samples")
1410 if (anArgIter + 1 >= theArgNb)
1412 std::cerr << "Syntax error: number of samples to generate PBR environment look up table is undefined" << "\n";
1416 aNbSamples = Draw::Atoi(theArgVec[++anArgIter]);
1420 std::cerr << "Syntax error: number of samples to generate PBR environment look up table must be greater than 1\n" << "\n";
1426 std::cerr << "Syntax error: unknown argument " << anArg << ";\n";
1441 std::ofstream aFile;
1443 OSD_OpenStream (aFile, aFilePath, std::ios::out | std::ios::binary);
1447 std::cerr << "Error: unable to write to " << aFilePath << "\n";
1451 aFile << "//this file has been generated by vgenenvlut draw command\n";
1452 aFile << "static unsigned int Textures_EnvLUTSize = " << aTableSize << ";\n\n";
1453 aFile << "static float Textures_EnvLUT[] =\n";
1456 Handle(Image_PixMap) aPixMap = new Image_PixMap();
1457 aPixMap->InitZero (Image_Format_RGF, aTableSize, aTableSize);
1458 Graphic3d_PBRMaterial::GenerateEnvLUT (aPixMap, aNbSamples);
1460 const Standard_Integer aNumbersInRow = 5;
1461 Standard_Integer aCounter = 0;
1463 for (int y = 0; y < aTableSize - 1; ++y)
1466 for (int x = 0; x < aTableSize; ++x)
1468 aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(aTableSize - 1 - y, x).x()) << ",";
1469 aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(aTableSize - 1 - y, x).y()) << ",";
1470 if (++aCounter % aNumbersInRow == 0)
1474 else if (x != aTableSize - 1)
1480 if (aTableSize % aNumbersInRow != 0)
1487 for (int x = 0; x < aTableSize - 1; ++x)
1489 aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(0, x).x()) << ",";
1490 aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(0, x).y()) << ",";
1491 if (++aCounter % aNumbersInRow == 0)
1501 aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(0, aTableSize - 1).x()) << ",";
1502 aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(0, aTableSize - 1).y()) << "\n";
1510 //=======================================================================
1511 //function : OpenGlCommands
1513 //=======================================================================
1515 void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands)
1517 const char* aGroup ="Commands for low-level TKOpenGl features";
1519 theCommands.Add("vuserdraw",
1520 "vuserdraw : name - simulates drawing with help of UserDraw",
1521 __FILE__, VUserDraw, aGroup);
1522 theCommands.Add("vfeedback",
1523 "vfeedback : perform test GL feedback rendering",
1524 __FILE__, VFeedback, aGroup);
1525 theCommands.Add("vimmediatefront",
1526 "vimmediatefront : render immediate mode to front buffer or to back buffer",
1527 __FILE__, VImmediateFront, aGroup);
1528 theCommands.Add("vglinfo",
1529 "vglinfo [-short|-basic|-complete]"
1530 "\n\t\t: [GL_VENDOR] [GL_RENDERER] [GL_VERSION]"
1531 "\n\t\t: [GL_SHADING_LANGUAGE_VERSION] [GL_EXTENSIONS]"
1532 "\n\t\t: print OpenGL info",
1533 __FILE__, VGlInfo, aGroup);
1534 theCommands.Add("vshader",
1535 "vshader name -vert VertexShader -frag FragmentShader [-geom GeometryShader]"
1536 "\n\t\t: [-off] [-phong] [-aspect {shading|line|point|text}=shading]"
1537 "\n\t\t: [-header VersionHeader]"
1538 "\n\t\t: [-tessControl TessControlShader -tesseval TessEvaluationShader]"
1539 "\n\t\t: [-uniform Name FloatValue]"
1540 "\n\t\t: Assign custom GLSL program to presentation aspects."
1541 "\nvshader [-list] [-dump] [-reload] ShaderId"
1542 "\n\t\t: -list prints the list of registered GLSL programs"
1543 "\n\t\t: -dump dumps specified GLSL program (for debugging)"
1544 "\n\t\t: -reload restores dump of specified GLSL program",
1545 __FILE__, VShaderProg, aGroup);
1546 theCommands.Add("vshaderprog", "Alias for vshader", __FILE__, VShaderProg, aGroup);
1547 theCommands.Add("vlistmaterials",
1548 "vlistmaterials [*] [MaterialName1 [MaterialName2 [...]]] [dump.obj|dump.html]"
1549 "\n\t\t: Without arguments, command prints the list of standard materials."
1550 "\n\t\t: Otherwise, properties of specified materials will be printed"
1551 "\n\t\t: or dumped into specified file."
1552 "\n\t\t: * can be used to refer to complete list of standard materials.",
1553 __FILE__, VListMaterials, aGroup);
1554 theCommands.Add("vlistcolors",
1555 "vlistcolors [*] [ColorName1 [ColorName2 [...]]] [dump.html]"
1556 "\n\t\t: Without arguments, command prints the list of standard colors."
1557 "\n\t\t: Otherwise, properties of specified colors will be printed"
1558 "\n\t\t: or dumped into specified file."
1559 "\n\t\t: * can be used to refer to complete list of standard colors.",
1560 __FILE__, VListColors, aGroup);
1561 theCommands.Add("vgenenvlut",
1562 "vgenenvlut [-size size = 128] [-nbsamples nbsamples = 1024]"
1563 "\n\t\t: Generates PBR environment look up table."
1564 "\n\t\t: Saves it as C++ source file which is expected to be included in code."
1565 "\n\t\t: The path where result will be located is 'Graphic3d_TextureRoot::TexturesFolder()'."
1566 "\n\t\t: -size size of one side of resulted square table"
1567 "\n\t\t: -nbsamples number of samples used in Monte-Carlo integration",
1568 __FILE__, VGenEnvLUT, aGroup);