Skip to content

Commit 17dc4ae

Browse files
committed
support different shader param language
Signed-off-by: Ian Chen <[email protected]>
1 parent 5c87434 commit 17dc4ae

File tree

2 files changed

+74
-12
lines changed

2 files changed

+74
-12
lines changed

src/systems/shader_param/ShaderParam.cc

+68-10
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,21 @@ class ignition::gazebo::systems::ShaderParamPrivate
6565
public: std::vector<std::string> args;
6666
};
6767

68-
/// \brief Path to vertex shader
69-
public: std::string vertexShaderUri;
68+
/// \brief Data structure for storing shader files uri
69+
public: class ShaderUri
70+
{
71+
/// \brief Shader language: glsl or metal
72+
public: std::string language;
73+
74+
/// \brief Path to vertex shader
75+
public: std::string vertexShaderUri;
7076

71-
/// \brief Path to fragment shader
72-
public: std::string fragmentShaderUri;
77+
/// \brief Path to fragment shader
78+
public: std::string fragmentShaderUri;
79+
};
80+
81+
/// \brief A map of shader language to shader program files
82+
public: std::map<std::string, ShaderUri> shaders;
7383

7484
/// \brief Mutex to protect sim time updates.
7585
public: std::mutex mutex;
@@ -179,9 +189,16 @@ void ShaderParam::Configure(const Entity &_entity,
179189
}
180190

181191
// parse path to shaders
182-
if (sdf->HasElement("shader"))
192+
if (!sdf->HasElement("shader"))
193+
{
194+
ignerr << "Unable to load shader param system. "
195+
<< "Missing <shader> SDF element." << std::endl;
196+
return;
197+
}
198+
// allow mulitple shader SDF element for different shader languages
199+
sdf::ElementPtr shaderElem = sdf->GetElement("shader");
200+
while (shaderElem)
183201
{
184-
sdf::ElementPtr shaderElem = sdf->GetElement("shader");
185202
if (!shaderElem->HasElement("vertex") ||
186203
!shaderElem->HasElement("fragment"))
187204
{
@@ -190,16 +207,35 @@ void ShaderParam::Configure(const Entity &_entity,
190207
}
191208
else
192209
{
210+
// default to glsl
211+
std::string api = "glsl";
212+
if (shaderElem->HasAttribute("language"))
213+
api = shaderElem->GetAttribute("language")->GetAsString();
214+
215+
ShaderParamPrivate::ShaderUri shader;
216+
shader.language = api;
217+
193218
sdf::ElementPtr vertexElem = shaderElem->GetElement("vertex");
194-
this->dataPtr->vertexShaderUri = common::findFile(
219+
shader.vertexShaderUri = common::findFile(
195220
asFullPath(vertexElem->Get<std::string>(),
196221
this->dataPtr->modelPath));
197222
sdf::ElementPtr fragmentElem = shaderElem->GetElement("fragment");
198-
this->dataPtr->fragmentShaderUri = common::findFile(
223+
shader.fragmentShaderUri = common::findFile(
199224
asFullPath(fragmentElem->Get<std::string>(),
200225
this->dataPtr->modelPath));
226+
this->dataPtr->shaders[api] = shader;
227+
228+
std::cerr << "api: " << api << ", " << shader.vertexShaderUri << std::endl;
229+
230+
shaderElem = shaderElem->GetNextElement("shader");
201231
}
202232
}
233+
if (this->dataPtr->shaders.empty())
234+
{
235+
ignerr << "Unable to load shader param system. "
236+
<< "No valid shaders." << std::endl;
237+
return;
238+
}
203239

204240
this->dataPtr->entity = _entity;
205241
auto nameComp = _ecm.Component<components::Name>(_entity);
@@ -272,8 +308,30 @@ void ShaderParamPrivate::OnUpdate()
272308
if (!this->material)
273309
{
274310
auto mat = scene->CreateMaterial();
275-
mat->SetVertexShader(this->vertexShaderUri);
276-
mat->SetFragmentShader(this->fragmentShaderUri);
311+
312+
// default to glsl
313+
auto it = this->shaders.find("glsl");
314+
if (it != this->shaders.end())
315+
{
316+
mat->SetVertexShader(it->second.vertexShaderUri);
317+
mat->SetFragmentShader(it->second.fragmentShaderUri);
318+
}
319+
// prefer metal over glsl on macOS
320+
// \todo(anyone) instead of using ifdef to check for macOS,
321+
// expose add an accessor function to get the GraphicsApi
322+
// from rendering::RenderEngine
323+
#ifdef __APPLE__
324+
auto metalIt = this->shaders.find("metal");
325+
if (metalIt != this->shaders.end())
326+
{
327+
mat->SetVertexShader(metalIt->second.vertexShaderUri);
328+
mat->SetFragmentShader(metalIt->second.fragmentShaderUri);
329+
// if both glsl and metal are specified, print a msg to inform that
330+
// metal is used instead of glsl
331+
if (it != this->shaders.end())
332+
ignmsg << "Using metal shaders. " << std::endl
333+
}
334+
#endif
277335
this->visual->SetMaterial(mat);
278336
scene->DestroyMaterial(mat);
279337
this->material = this->visual->Material();

src/systems/shader_param/ShaderParam.hh

+6-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ namespace systems
3737
///
3838
/// Plugin parameters:
3939
///
40-
/// <shader>
40+
/// <shader> Shader to use - can be repeated to specify shader programs
41+
/// written in different languages.
42+
/// Attributes:
43+
/// language - Shader language. Possible values: glsl, metal
44+
/// Default to glsl if not specified
4145
/// <vertex> Path to vertex program
4246
/// <fragment> Path to fragment program
4347
/// <param> Shader parameter - can be repeated within plugin SDF element
@@ -54,7 +58,7 @@ namespace systems
5458
/// \verbatim
5559
/// <plugin filename="ignition-gazebo-shader-param-system"
5660
/// name="ignition::gazebo::systems::ShaderParam">
57-
/// <shader>
61+
/// <shader language='glsl'>
5862
/// <vertex>materials/my_vs.glsl</vertex>
5963
/// <fragment>materials/my_fs.glsl</fragment>
6064
/// </shader>

0 commit comments

Comments
 (0)