return 0;
}
+//! Parse shader type argument.
+static bool parseShaderTypeArg (Graphic3d_TypeOfShaderObject& theType,
+ const TCollection_AsciiString& theArg)
+{
+ if (theArg == "-vertex"
+ || theArg == "-vert")
+ {
+ theType = Graphic3d_TOS_VERTEX;
+ }
+ else if (theArg == "-tessevaluation"
+ || theArg == "-tesseval"
+ || theArg == "-evaluation"
+ || theArg == "-eval")
+ {
+ theType = Graphic3d_TOS_TESS_EVALUATION;
+ }
+ else if (theArg == "-tesscontrol"
+ || theArg == "-tessctrl"
+ || theArg == "-control"
+ || theArg == "-ctrl")
+ {
+ theType = Graphic3d_TOS_TESS_CONTROL;
+ }
+ else if (theArg == "-geometry"
+ || theArg == "-geom")
+ {
+ theType = Graphic3d_TOS_GEOMETRY;
+ }
+ else if (theArg == "-fragment"
+ || theArg == "-frag")
+ {
+ theType = Graphic3d_TOS_FRAGMENT;
+ }
+ else if (theArg == "-compute"
+ || theArg == "-comp")
+ {
+ theType = Graphic3d_TOS_COMPUTE;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+}
//==============================================================================
//function : VShaderProg
Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
if (aCtx.IsNull())
{
- std::cerr << "Use 'vinit' command before " << theArgVec[0] << "\n";
+ std::cout << "Error: no active view.\n";
return 1;
}
else if (theArgNb < 2)
{
- std::cerr << theArgVec[0] << " syntax error: lack of arguments\n";
+ std::cout << "Syntax error: lack of arguments\n";
return 1;
}
- TCollection_AsciiString aLastArg (theArgVec[theArgNb - 1]);
- aLastArg.LowerCase();
- const Standard_Boolean toTurnOff = aLastArg == "off";
- Standard_Integer anArgsNb = theArgNb - 1;
- Handle(Graphic3d_ShaderProgram) aProgram;
- if (!toTurnOff
- && aLastArg == "phong")
+ bool isExplicitShaderType = false;
+ Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram();
+ NCollection_Sequence<Handle(AIS_InteractiveObject)> aPrsList;
+ Graphic3d_GroupAspect aGroupAspect = Graphic3d_ASPECT_FILL_AREA;
+ bool isSetGroupAspect = false;
+ for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
- const TCollection_AsciiString& aShadersRoot = Graphic3d_ShaderProgram::ShadersFolder();
- if (aShadersRoot.IsEmpty())
- {
- std::cerr << "Both environment variables CSF_ShadersDirectory and CASROOT are undefined!\n"
- << "At least one should be defined to load Phong program.\n";
- return 1;
- }
+ TCollection_AsciiString anArg (theArgVec[anArgIter]);
+ anArg.LowerCase();
+ Graphic3d_TypeOfShaderObject aShaderTypeArg = Graphic3d_TypeOfShaderObject(-1);
+ if (!aProgram.IsNull()
+ && aProgram->ShaderObjects().IsEmpty()
+ && (anArg == "-off"
+ || anArg == "off"))
+ {
+ aProgram.Nullify();
+ }
+ else if (!aProgram.IsNull()
+ && aProgram->ShaderObjects().IsEmpty()
+ && (anArg == "-phong"
+ || anArg == "phong"))
+ {
+ const TCollection_AsciiString& aShadersRoot = Graphic3d_ShaderProgram::ShadersFolder();
+ if (aShadersRoot.IsEmpty())
+ {
+ std::cout << "Error: both environment variables CSF_ShadersDirectory and CASROOT are undefined!\n"
+ "At least one should be defined to load Phong program.\n";
+ return 1;
+ }
- const TCollection_AsciiString aSrcVert = aShadersRoot + "/PhongShading.vs";
- const TCollection_AsciiString aSrcFrag = aShadersRoot + "/PhongShading.fs";
+ const TCollection_AsciiString aSrcVert = aShadersRoot + "/PhongShading.vs";
+ const TCollection_AsciiString aSrcFrag = aShadersRoot + "/PhongShading.fs";
+ if (!aSrcVert.IsEmpty()
+ && !OSD_File (aSrcVert).Exists())
+ {
+ std::cout << "Error: PhongShading.vs is not found\n";
+ return 1;
+ }
+ if (!aSrcFrag.IsEmpty()
+ && !OSD_File (aSrcFrag).Exists())
+ {
+ std::cout << "Error: PhongShading.fs is not found\n";
+ return 1;
+ }
- if (!aSrcVert.IsEmpty()
- && !OSD_File (aSrcVert).Exists())
- {
- std::cerr << "Error: PhongShading.vs is not found\n";
- return 1;
+ aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert));
+ aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag));
}
- if (!aSrcFrag.IsEmpty()
- && !OSD_File (aSrcFrag).Exists())
+ else if (aPrsList.IsEmpty()
+ && anArg == "*")
{
- std::cerr << "Error: PhongShading.fs is not found\n";
- return 1;
- }
-
- aProgram = new Graphic3d_ShaderProgram();
- aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert));
- aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag));
- }
- if (!toTurnOff
- && aProgram.IsNull())
- {
- if (theArgNb < 3)
- {
- std::cout << "Syntax error: lack of arguments\n";
- return 1;
+ //
}
-
- const TCollection_AsciiString aSrcVert = theArgVec[theArgNb - 2];
- const TCollection_AsciiString aSrcFrag = theArgVec[theArgNb - 1];
- if (aSrcVert.IsEmpty() || aSrcFrag.IsEmpty())
- {
- std::cout << "Syntax error: lack of arguments\n";
- return 1;
+ else if (!isSetGroupAspect
+ && anArgIter + 1 < theArgNb
+ && (anArg == "-primtype"
+ || anArg == "-primitivetype"
+ || anArg == "-groupaspect"
+ || anArg == "-aspecttype"
+ || anArg == "-aspect"))
+ {
+ isSetGroupAspect = true;
+ TCollection_AsciiString aPrimTypeStr (theArgVec[++anArgIter]);
+ aPrimTypeStr.LowerCase();
+ if (aPrimTypeStr == "line")
+ {
+ aGroupAspect = Graphic3d_ASPECT_LINE;
+ }
+ else if (aPrimTypeStr == "tris"
+ || aPrimTypeStr == "triangles"
+ || aPrimTypeStr == "fill"
+ || aPrimTypeStr == "fillarea"
+ || aPrimTypeStr == "shading"
+ || aPrimTypeStr == "shade")
+ {
+ aGroupAspect = Graphic3d_ASPECT_FILL_AREA;
+ }
+ else if (aPrimTypeStr == "text")
+ {
+ aGroupAspect = Graphic3d_ASPECT_TEXT;
+ }
+ else if (aPrimTypeStr == "marker"
+ || aPrimTypeStr == "point"
+ || aPrimTypeStr == "pnt")
+ {
+ aGroupAspect = Graphic3d_ASPECT_MARKER;
+ }
+ else
+ {
+ std::cerr << "Syntax error at '" << aPrimTypeStr << "'\n";
+ return 1;
+ }
}
-
- const bool isVertFile = OSD_File (aSrcVert).Exists();
- const bool isFragFile = OSD_File (aSrcFrag).Exists();
- if (!isVertFile
- && aSrcVert.Search ("gl_Position") == -1)
+ else if (anArgIter + 1 < theArgNb
+ && !aProgram.IsNull()
+ && aProgram->Header().IsEmpty()
+ && (anArg == "-version"
+ || anArg == "-glslversion"
+ || anArg == "-header"
+ || anArg == "-glslheader"))
{
- std::cerr << "Error: non-existing or invalid vertex shader source\n";
- return 1;
+ TCollection_AsciiString aHeader (theArgVec[++anArgIter]);
+ if (aHeader.IsIntegerValue())
+ {
+ aHeader = TCollection_AsciiString ("#version ") + aHeader;
+ }
+ aProgram->SetHeader (aHeader);
}
- if (!isFragFile
- && aSrcFrag.Search ("occFragColor") == -1)
+ else if (!anArg.StartsWith ("-")
+ && GetMapOfAIS().IsBound2 (theArgVec[anArgIter]))
{
- std::cerr << "Error: non-existing or invalid fragment shader source\n";
- return 1;
+ Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (theArgVec[anArgIter]));
+ if (anIO.IsNull())
+ {
+ std::cerr << "Syntax error: " << theArgVec[anArgIter] << " is not an AIS object\n";
+ return 1;
+ }
+ aPrsList.Append (anIO);
}
-
- aProgram = new Graphic3d_ShaderProgram();
- aProgram->AttachShader (isVertFile
- ? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert)
- : Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_VERTEX, aSrcVert));
- aProgram->AttachShader (isFragFile
- ? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag)
- : Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_FRAGMENT, aSrcFrag));
- anArgsNb = theArgNb - 2;
- }
-
- Handle(AIS_InteractiveObject) anIO;
- if (anArgsNb <= 1
- || *theArgVec[1] == '*')
- {
- for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
- anIter.More(); anIter.Next())
+ else if (!aProgram.IsNull()
+ && ((anArgIter + 1 < theArgNb && parseShaderTypeArg (aShaderTypeArg, anArg))
+ || (!isExplicitShaderType && aProgram->ShaderObjects().Size() < 2)))
{
- anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
- if (anIO.IsNull())
+ TCollection_AsciiString aShaderPath (theArgVec[anArgIter]);
+ if (aShaderTypeArg != Graphic3d_TypeOfShaderObject(-1))
{
- continue;
+ aShaderPath = (theArgVec[++anArgIter]);
+ isExplicitShaderType = true;
}
- if (!anIO->Attributes()->HasOwnShadingAspect())
+ const bool isSrcFile = OSD_File (aShaderPath).Exists();
+ Handle(Graphic3d_ShaderObject) aShader = isSrcFile
+ ? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aShaderPath)
+ : Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_VERTEX, aShaderPath);
+ const TCollection_AsciiString& aShaderSrc = aShader->Source();
+
+ const bool hasVertPos = aShaderSrc.Search ("gl_Position") != -1;
+ const bool hasFragColor = aShaderSrc.Search ("occFragColor") != -1
+ || aShaderSrc.Search ("gl_FragColor") != -1
+ || aShaderSrc.Search ("gl_FragData") != -1;
+ Graphic3d_TypeOfShaderObject aShaderType = aShaderTypeArg;
+ if (aShaderType == Graphic3d_TypeOfShaderObject(-1))
{
- Handle(Prs3d_ShadingAspect) aNewAspect = new Prs3d_ShadingAspect();
- *aNewAspect->Aspect() = *anIO->Attributes()->ShadingAspect()->Aspect();
- aNewAspect->Aspect()->SetShaderProgram (aProgram);
- anIO->Attributes()->SetShadingAspect (aNewAspect);
- aCtx->Redisplay (anIO, Standard_False);
+ if (hasVertPos
+ && !hasFragColor)
+ {
+ aShaderType = Graphic3d_TOS_VERTEX;
+ }
+ if (hasFragColor
+ && !hasVertPos)
+ {
+ aShaderType = Graphic3d_TOS_FRAGMENT;
+ }
}
- else
+ if (aShaderType == Graphic3d_TypeOfShaderObject(-1))
{
- anIO->Attributes()->SetShaderProgram (aProgram, Graphic3d_ASPECT_FILL_AREA);
- anIO->SynchronizeAspects();
+ std::cerr << "Error: non-existing or invalid shader source\n";
+ return 1;
}
+
+ aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aShaderType, aShaderSrc));
+ }
+ else
+ {
+ std::cerr << "Syntax error at '" << anArg << "'\n";
+ return 1;
}
- aCtx->UpdateCurrentViewer();
- return 0;
}
- for (Standard_Integer anArgIter = 1; anArgIter < anArgsNb; ++anArgIter)
+ ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aGlobalPrsIter (GetMapOfAIS());
+ NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator aPrsIter (aPrsList);
+ const bool isGlobalList = aPrsList.IsEmpty();
+ for (;;)
{
- const TCollection_AsciiString aName (theArgVec[anArgIter]);
- if (!GetMapOfAIS().IsBound2 (aName))
+ Handle(AIS_InteractiveObject) anIO;
+ if (isGlobalList)
{
- std::cerr << "Warning: " << aName.ToCString() << " is not displayed\n";
- continue;
+ if (!aGlobalPrsIter.More())
+ {
+ break;
+ }
+ anIO = Handle(AIS_InteractiveObject)::DownCast (aGlobalPrsIter.Key1());
+ aGlobalPrsIter.Next();
+ if (anIO.IsNull())
+ {
+ continue;
+ }
}
- anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
- if (anIO.IsNull())
+ else
{
- std::cerr << "Warning: " << aName.ToCString() << " is not an AIS object\n";
- continue;
+ if (!aPrsIter.More())
+ {
+ break;
+ }
+ anIO = aPrsIter.Value();
+ aPrsIter.Next();
}
- if (!anIO->Attributes()->HasOwnShadingAspect())
+ if (anIO->Attributes()->SetShaderProgram (aProgram, aGroupAspect, true))
{
- Handle(Prs3d_ShadingAspect) aNewAspect = new Prs3d_ShadingAspect();
- *aNewAspect->Aspect() = *anIO->Attributes()->ShadingAspect()->Aspect();
- aNewAspect->Aspect()->SetShaderProgram (aProgram);
- anIO->Attributes()->SetShadingAspect (aNewAspect);
aCtx->Redisplay (anIO, Standard_False);
}
else
{
- anIO->Attributes()->SetShaderProgram (aProgram, Graphic3d_ASPECT_FILL_AREA);
anIO->SynchronizeAspects();
}
}
"\n\t\t: [GL_SHADING_LANGUAGE_VERSION] [GL_EXTENSIONS]"
"\n\t\t: print OpenGL info",
__FILE__, VGlInfo, aGroup);
- theCommands.Add("vshaderprog",
- " 'vshaderprog [name] pathToVertexShader pathToFragmentShader'"
- "\n\t\t: or 'vshaderprog [name] off' to disable GLSL program"
- "\n\t\t: or 'vshaderprog [name] phong' to enable per-pixel lighting calculations"
- "\n\t\t: * might be used to specify all displayed objects",
+ theCommands.Add("vshader",
+ "vshader name -vert VertexShader -frag FragmentShader [-geom GeometryShader]"
+ "\n\t\t: [-off] [-phong] [-aspect {shading|line|point|text}=shading]"
+ "\n\t\t: [-header VersionHeader]"
+ "\n\t\t: [-tessControl TessControlShader -tesseval TessEvaluationShader]"
+ "\n\t\t: Assign custom GLSL program to presentation aspects.",
__FILE__, VShaderProg, aGroup);
+ theCommands.Add("vshaderprog", "Alias for vshader", __FILE__, VShaderProg, aGroup);
}