1#include "Shading/ShaderNodes/CustomShaderNode.h"
7static std::string ReplaceString(std::string subject,
const std::string &search,
8 const std::string &replace)
12 while((pos = subject.find(search, pos)) != std::string::npos)
14 subject.replace(pos, search.length(), replace);
15 pos += replace.length();
24 std::string cline = code;
26 cline = ReplaceString(cline,
"{ID}", STR(
id));
27 cline = ReplaceString(cline,
"{OFFSET}", STR(dataBlobOffset));
29 for(
auto it : sharedDataTemplate)
31 cline = ReplaceString(cline, it.alias, SDATA(did));
35 handler->AddFunction(ft);
41 for(
auto ¶m : params)
43 function->AddLine(
GLSLLine(param.first +
" " + VAR(param.second + STR(i)) +
" = " + param.first +
"(0.0f);"));
45 if(inputPins[i]->IsLinked())
48 inputPins[i]->other->Evaluate(GetParams(function, &tmp));
49 function->AddLine(
GLSLLine(VAR(param.second + STR(i)) +
" = " + tmp.line +
";"));
58 for(
auto ¶m: params)
60 function->AddLine(
GLSLLine(param.first +
" " + VAR(param.second + STR(i)) +
"[" + STR(paramCount) +
"];"));
61 for(
int k = 0 ; k < paramCount ; k++)
63 if (inputPins[k * params.size() + i]->IsLinked())
66 inputPins[k * params.size() + i]->other->Evaluate(GetParams(function, &tmp));
67 function->AddLine(
GLSLLine(VAR(param.second + STR(i)) +
"[" + STR(k) +
"]" +
" = " + tmp.line +
";"));
71 function->AddLine(
GLSLLine(VAR(param.second + STR(i)) +
"[" + STR(k) +
"]" +
" = " + param.first +
"(0.0f);"));
78 line->line = func->name +
"(";
80 int n = params.size();
82 for(
auto ¶m : params)
84 line->line += VAR(param.second + STR(i));
94 for(
int i = 0;i<outputPins.size();i++)
96 if(outputPins[i]->
id == callerPinId)
102 line->line += (params.size() == 0 ?
"" :
", ") + STR(callerPin) +
")";
109 for(
auto &it : sharedDataTemplate)
111 if(it.type ==
"float")
113 fData[i] = data[it.alias].
get<
float>();
116 else if(it.type ==
"bool")
118 bData[i] = data[it.alias].
get<
bool>();
128 data[
"type"] =
"CustomShader";
131 for(
auto &it : sharedDataTemplate)
133 if(it.type ==
"float")
135 data[it.alias] = fData[i];
138 else if(it.type ==
"bool")
140 data[it.alias] = bData[i];
146 data[
"shader"] = shader;
150void CustomShaderNode::UpdateShaders()
154 for(
auto &it : sharedDataTemplate)
161 if(it.type ==
"float")
163 SetSharedMemoryItem(sharedData, i, fData[i]);
166 else if(it.type ==
"bool")
168 SetSharedMemoryItem(sharedData, i, bData[i] ? 1.0f : 0.0f);
175void CustomShaderNode::OnRender()
179 if(!useMultipleOpins)
181 ImGui::Text(
"Output");
182 outputPins[0]->Render();
187 for(
int i = 0 ; i < oPinStrs.size() ; i++)
189 ImGui::Text(oPinStrs[i].data());
190 outputPins[i]->Render();
199 for(
auto ¶ms: params)
201 inputPins[j]->Render();
202 ImGui::Text(params.second.c_str());
208 for(
int k = 0 ; k < paramCount ; k++)
211 for(
auto ¶m: params)
213 inputPins[k + j]->Render();
214 ImGui::Text((param.second +
" #" + STR(k)).c_str());
220 ImGui::PushItemWidth(100);
223 for(
auto &it : sharedDataTemplate)
232 if(it.type ==
"float")
234 if(ImGui::DragFloat(it.text.data(), &fData[i], 0.01f))
236 SetSharedMemoryItem(sharedData, i, fData[i]);
240 else if(it.type ==
"bool")
242 if(ImGui::Checkbox(it.text.data(), &bData[i]))
244 SetSharedMemoryItem(sharedData, i, bData[i] ? 1.0f : 0.0f);
252 ImGui::PopItemWidth();
255CustomShaderNode::CustomShaderNode(
GLSLHandler *handler, std::string s)
258 name =
"Custom Shader";
259 headerColor = ImColor(SHADER_VALUE_NODE_COLOR);
262 std::stringstream ss(shader);
264 std::string codeStr =
"";
265 std::string metaStr =
"";
266 bool isCodeActive =
false;
267 bool isMetaActive =
false;
269 while(std::getline(ss, line))
276 else if(line ==
"[META]")
281 else if(line ==
"[CODE]")
286 else if(line ==
"[/META]")
288 isMetaActive =
false;
291 else if(line ==
"[/CODE]")
293 isCodeActive =
false;
296 else if(isMetaActive)
298 metaStr += line +
"\n";
301 else if(isCodeActive)
303 codeStr += line +
"\n";
308 if(metaStr.size() > 0)
315 throw std::runtime_error(
"No meta data found in shader");
319 if(codeStr.size() > 0)
326 throw std::runtime_error(
"No code found in shader");
331 std::cout <<
"Loading Node : " << name <<
"\n";
332 std::string paramsStr =
"";
335 if(meta.find(
"param_count") != meta.end())
337 paramCount = meta[
"param_count"];
338 useArrayParams =
true;
343 useArrayParams =
false;
345 int pss = meta[
"params"].size();
347 for(std::string param : meta[
"params"])
349 std::string pType = param.substr(0, param.find(
":"));
350 std::string pName = param.substr(param.find(
":") + 1);
351 params.push_back(std::make_pair(pType, pName));
353 paramsStr += pType +
" " + pName +
"[" + STR(paramCount) +
"]" + (j < pss - 1 ?
", " :
"");
355 paramsStr += pType +
" " + pName + (j < pss - 1 ?
", " :
"");
359 paramsStr += (params.size() == 0 ?
"" :
", ") + std::string(
"int callerPin");
361 func =
new GLSLFunction(meta[
"fname"], paramsStr, meta[
"returns"]);
362 func->name += STR(
id);
363 sharedDataTemplate.clear();
366 for(
auto it = meta[
"sharedData"].begin() ; it != meta[
"sharedData"].end() ; it++)
368 std::string alias = ReplaceString(it.key(),
" ",
"");
369 if(it.value().find(
"alias") != it.value().end())
370 alias = it.value()[
"alias"];
371 sharedDataTemplate.push_back(
SharedDataRep(it.key(), it.value()[
"type"], alias));
373 if(it.value()[
"type"] ==
"float")
375 fData[i] = it.value()[
"default"].get<
float>();
378 else if(it.value()[
"type"] ==
"bool")
380 bData[i] = it.value()[
"default"].get<
bool>();
386 if(meta.find(
"output_pins") != meta.end())
388 std::string returns = meta[
"returns"];
389 useMultipleOpins =
true;
390 for(std::string oPin : meta[
"output_pins"])
392 oPinStrs.push_back(oPin);
393 if(meta[
"returns"] ==
"float")
395 outputPins.push_back(
new SNEPin(NodeEditorPinType::Output, SNEPinType::SNEPinType_Float));
397 else if(meta[
"returns"] ==
"vec3")
399 outputPins.push_back(
new SNEPin(NodeEditorPinType::Output, SNEPinType::SNEPinType_Float3));
405 if(meta[
"returns"] ==
"float")
407 outputPins.push_back(
new SNEPin(NodeEditorPinType::Output, SNEPinType::SNEPinType_Float));
409 else if(meta[
"returns"] ==
"vec3")
411 outputPins.push_back(
new SNEPin(NodeEditorPinType::Output, SNEPinType::SNEPinType_Float3));
415 std::string t = meta[
"returns"];
416 throw std::runtime_error(
"Custom shader node does not support return type " + t);
421 for(
int k = 0 ; k < paramCount ; k++)
423 for(
auto &it : params)
425 if(it.first ==
"float")
427 inputPins.push_back(
new SNEPin(NodeEditorPinType::Input, SNEPinType::SNEPinType_Float));
430 else if(it.first ==
"vec3")
432 inputPins.push_back(
new SNEPin(NodeEditorPinType::Input, SNEPinType::SNEPinType_Float3));
437 throw std::runtime_error(
"Custom shader node does not support parameter type " + it.first);
441 headerColor = ImColor(meta[
"color"][
"r"].get<int>(), meta[
"color"][
"r"].get<int>(), meta[
"color"][
"b"].get<int>());
445CustomShaderNode::~CustomShaderNode()
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
a class to store JSON values