36 if (
type == GLSLImageFilter)
37 filename =
"GLSLImageFilter.fs";
38 else if (
type == GLSLImageGenerator)
39 filename =
"GLSLImageGenerator.fs";
40 else if (
type == GLSLImageTransition)
41 filename =
"GLSLImageTransition.fs";
42 else if (
type == GLSLObjectRenderer)
43 filename =
"GLSLObjectRenderer.fs";
45 filename =
"GLSLObjectFilter.vs";
57 else if (stage == Geometry)
59 else if (stage == Fragment)
77 init(file, overriddenFragmentSource);
88 splitMetadataAndSource(! overriddenFragmentSource.empty() ? overriddenFragmentSource : readStage(file.
fileWithDifferentExtension(
"fs")), &isfMetadata, _fragmentSource);
90 parseMetadata(isfMetadata);
100 VUserLog(
" isfVersion: %s", isfVersion.c_str());
101 VUserLog(
" shaderVersion: %s", shaderVersion.c_str());
102 VUserLog(
" copyright: %s",copyright.c_str());
103 VUserLog(
" license: %s",license.c_str());
104 VUserLog(
" description: %s",description.c_str());
105 VUserLog(
" homepageLink: %s", homepageLink.c_str());
106 VUserLog(
" documentationLink: %s", documentationLink.c_str());
108 for (vector<string>::iterator i = categories.begin(); i != categories.end(); ++i)
111 for (vector<string>::iterator i = keywords.begin(); i != keywords.end(); ++i)
114 for (vector<Port>::iterator i = _inputPorts.begin(); i != _inputPorts.end(); ++i)
115 VUserLog(
" %s %s %s", i->vuoTypeName.c_str(), i->key.c_str(), json_object_to_json_string(i->vuoPortDetails));
116 VUserLog(
" showsTime : %d", _showsTime);
117 VUserLog(
" outputKey : %s", outputKey.c_str());
118 VUserLog(
" outputName: %s", outputName.c_str());
119 VUserLog(
"VS [%s]",_vertexSource.c_str());
120 VUserLog(
"GS [%s]",_geometrySource.c_str());
121 VUserLog(
"FS [%s]",_fragmentSource.c_str());
146 if (_type == VuoShaderFile::GLSLImageFilter)
147 return "Image Filter";
148 else if (_type == VuoShaderFile::GLSLImageGenerator)
149 return "Image Generator";
150 else if (_type == VuoShaderFile::GLSLImageTransition)
151 return "Image Transition";
152 else if (_type == VuoShaderFile::GLSLObjectRenderer)
153 return "3D Object Renderer";
155 return "3D Object Filter";
163 if (_type == VuoShaderFile::GLSLImageFilter
164 || _type == VuoShaderFile::GLSLImageGenerator
165 || _type == VuoShaderFile::GLSLImageTransition)
167 else if (_type == VuoShaderFile::GLSLObjectRenderer)
168 return "OBJECT_RENDER";
170 return "OBJECT_FILTER";
178 return _type == VuoShaderFile::GLSLObjectRenderer
179 || _type == VuoShaderFile::GLSLObjectFilter;
187 return _type == VuoShaderFile::GLSLImageFilter
188 || _type == VuoShaderFile::GLSLImageGenerator
189 || _type == VuoShaderFile::GLSLImageTransition
190 || _type == VuoShaderFile::GLSLObjectRenderer;
218 if (! customizedName.empty())
219 _name = customizedName;
236 return _vuoModuleMetadata;
277 json_object *vuoPortDetails = json_object_new_object();
278 json_object_object_add(vuoPortDetails,
"name", json_object_new_string(outputName.c_str()));
279 return (
Port){outputKey,
"", vuoPortDetails};
288 return _vertexSource;
296 _vertexSource = source;
299 void VuoShaderFile::insertPreamble(ostringstream &oss,
bool isFragment)
301 oss <<
"#version 120\n"
307 "// Standard ISF variables\n"
309 "varying vec2 isf_FragNormCoord;\n"
313 "uniform int PASSINDEX;\n"
316 "uniform vec2 viewportSize;\n"
317 "#define RENDERSIZE viewportSize\n"
319 "uniform float TIME;\n"
320 "uniform float TIMEDELTA;\n"
321 "uniform vec4 DATE;\n"
322 "uniform int FRAMEINDEX;\n"
325 "#define vv_FragNormCoord isf_FragNormCoord\n"
326 "#define vv_vertShaderInit isf_vertShaderInit\n";
330 for (vector<Port>::iterator it = _inputPorts.begin(); it != _inputPorts.end(); ++it)
331 oss << glslDeclarationForPort(*it);
335 "#include \"ISFGLMacro2D.txt\"\n"
337 "#include \"ISFGLMacro2DRect.txt\"\n"
351 insertPreamble(oss,
false);
353 oss <<
"#include \"ISFGLSceneVertShaderIncludeVarDec.txt\"\n"
354 <<
"void isf_vertShaderInit(void)\n"
356 <<
"\t#include \"ISFGLSceneVertShaderIncludeInitFunc.txt\"\n"
360 if (_vertexSource.empty())
361 oss <<
"#include \"ISFGLScenePassthru.vs\"";
375 return _geometrySource;
383 _geometrySource = source;
393 if (_geometrySource.empty())
398 insertPreamble(oss,
false);
412 return _fragmentSource;
420 _fragmentSource = source;
430 if (_type == GLSLObjectFilter)
435 insertPreamble(oss,
true);
452 string basename = filePath.substr(0, filePath.find_last_of(
'.'));
454 string vertexFile = basename +
".vs";
455 string geometryFile = basename +
".gs";
456 string fragmentFile = basename +
".fs";
458 if (_type == GLSLImageFilter
459 || _type == GLSLImageGenerator
460 || _type == GLSLImageTransition
461 || _type == GLSLObjectRenderer)
463 saveStage(vertexFile, _vertexSource);
464 saveStage(geometryFile, _geometrySource);
465 saveStage(fragmentFile, _fragmentSource, _vuoModuleMetadata);
469 saveStage(vertexFile, _vertexSource, _vuoModuleMetadata);
470 saveStage(geometryFile, _geometrySource);
472 saveStage(fragmentFile, empty);
481 return stageFileContents(_fragmentSource, _vuoModuleMetadata);
492 void VuoShaderFile::splitMetadataAndSource(
string inputString,
json_object **outputMetadata,
string &outputSourceString)
494 regex_t metadataRegex;
495 regcomp(&metadataRegex,
"/\\*[\\s\r\n]*{.*}[\\s\r\n]*\\*/", REG_EXTENDED);
497 regmatch_t pmatch[nmatch];
498 bool metadataFound = !regexec(&metadataRegex, inputString.c_str(), nmatch, pmatch, 0);
499 regfree(&metadataRegex);
502 string metadataString = inputString.substr(pmatch[0].rm_so + 2, (pmatch[0].rm_eo - 1) - pmatch[0].rm_so - 3);
503 outputSourceString = inputString.substr(0, pmatch[0].rm_so) + inputString.substr(pmatch[0].rm_eo);
505 json_tokener_error error;
506 *outputMetadata = json_tokener_parse_verbose(metadataString.c_str(), &error);
507 if (!*outputMetadata)
509 VUserLog(
"Error: The metadata header isn't valid JSON: %s", json_tokener_error_desc(error));
514 outputSourceString = inputString;
521 string::size_type len = outputSourceString.length();
522 string::size_type pos = 0;
523 while ( (pos = outputSourceString.find(
"TIME", pos)) != string::npos )
524 if ( (pos > 1) && !isalnum(outputSourceString[pos - 1])
525 && (pos + 4 < len) && !isalnum(outputSourceString[pos + 4]) )
535 void VuoShaderFile::parseMetadata(
json_object *metadata)
537 string normalizedBasename = basename;
539 normalizedBasename = normalizedBasename.substr(0, normalizedBasename.length() - extension.length() - 1);
555 if (json_object_object_get_ex(
metadata,
"PASSES", &passes)
556 && ((json_object_is_type(passes, json_type_array ) && json_object_array_length(passes))
557 || (json_object_is_type(passes, json_type_object) && json_object_object_length(passes))))
558 throw VuoException(
"This shader uses ISF's multipass feature, which Vuo doesn't support yet.");
561 if (json_object_object_get_ex(
metadata,
"IMPORTED", &imported)
562 && ((json_object_is_type(imported, json_type_array ) && json_object_array_length(imported))
563 || (json_object_is_type(imported, json_type_object) && json_object_object_length(imported))))
564 throw VuoException(
"This shader uses ISF's image-importing feature, which Vuo doesn't support yet.");
566 bool hasInputImage =
false;
567 bool hasStartImage =
false;
568 bool hasEndImage =
false;
569 bool hasProgress =
false;
571 if (json_object_object_get_ex(
metadata,
"INPUTS", &inputsArray))
573 int inputCount = json_object_array_length(inputsArray);
574 for (
int i = 0; i < inputCount; ++i)
576 json_object *inputObject = json_object_array_get_idx(inputsArray, i);
581 if (key ==
"inputImage")
582 hasInputImage =
true;
583 else if (key ==
"startImage")
584 hasStartImage =
true;
585 else if (key ==
"endImage")
587 else if (key ==
"progress")
590 string vuoType = vuoTypeForIsfType(
type);
593 VUserLog(
"Warning: Input port '%s' has unknown type '%s'.", key.c_str(),
type.c_str());
597 json_object *vuoPortDetails = json_object_new_object();
599 if (
name.empty() && key ==
"inputImage")
603 json_object_object_add(vuoPortDetails,
"name", json_object_new_string(
name.c_str()));
606 if (json_object_object_get_ex(inputObject,
"DEFAULT", &defaultValue))
607 json_object_object_add(vuoPortDetails,
"default", defaultValue);
610 if (json_object_object_get_ex(inputObject,
"MIN", &minValue))
611 json_object_object_add(vuoPortDetails,
"suggestedMin", minValue);
614 if (vuoType ==
"VuoReal")
615 json_object_object_add(vuoPortDetails,
"suggestedMin", json_object_new_double(0));
616 else if (vuoType ==
"VuoPoint2d")
618 json_object_object_add(vuoPortDetails,
"scaleToSamplerRect", json_object_new_boolean(
true));
619 json_object_object_add(vuoPortDetails,
"suggestedMin", json_object_new_string(
"0,0"));
624 if (json_object_object_get_ex(inputObject,
"MAX", &maxValue))
625 json_object_object_add(vuoPortDetails,
"suggestedMax", maxValue);
628 if (vuoType ==
"VuoReal")
629 json_object_object_add(vuoPortDetails,
"suggestedMax", json_object_new_double(1));
630 else if (vuoType ==
"VuoPoint2d")
632 json_object_object_add(vuoPortDetails,
"scaleToSamplerRect", json_object_new_boolean(
true));
633 json_object_object_add(vuoPortDetails,
"suggestedMax", json_object_new_string(
"1,1"));
638 if (json_object_object_get_ex(inputObject,
"STEP", &stepValue))
639 json_object_object_add(vuoPortDetails,
"suggestedStep", stepValue);
644 if (json_object_object_get_ex(inputObject,
"MAX_ITEMS", &maxItemsValue))
645 json_object_object_add(vuoPortDetails,
"maxItems", maxItemsValue);
650 if (json_object_object_get_ex(inputObject,
"VALUES", &values)
651 && json_object_object_get_ex(inputObject,
"LABELS", &labels))
654 int valueCount = json_object_array_length(values);
655 for (
int i = 0; i < valueCount; ++i)
656 json_object_object_add(menuItems, json_object_get_string(json_object_array_get_idx(values, i)), json_object_array_get_idx(labels, i));
657 json_object_object_add(vuoPortDetails,
"menuItems", menuItems);
660 _inputPorts.push_back((Port){ key, vuoType, vuoPortDetails });
665 if (json_object_object_get_ex(
metadata,
"OUTPUTS", &outputsArray))
667 int outputCount = json_object_array_length(outputsArray);
668 for (
int i = 0; i < outputCount; ++i)
670 json_object *outputObject = json_object_array_get_idx(outputsArray, i);
676 if (typeString ==
"IMAGE")
679 _type = GLSLImageFilter;
680 else if (hasStartImage && hasEndImage && hasProgress)
681 _type = GLSLImageTransition;
683 _type = GLSLImageGenerator;
685 if (outputKey.empty())
686 outputKey =
"outputImage";
687 if (outputName.empty())
690 else if (typeString ==
"OBJECT_RENDER")
692 _type = GLSLObjectRenderer;
694 if (outputKey.empty())
695 outputKey =
"shader";
696 if (outputName.empty())
699 else if (typeString ==
"OBJECT_FILTER")
701 _type = GLSLObjectFilter;
703 if (outputKey.empty())
704 outputKey =
"outputObject";
705 if (outputName.empty())
709 _vuoModuleMetadata = json_object_new_object();
711 string title = (! _name.empty() ? _name : normalizedBasename);
712 json_object_object_add(_vuoModuleMetadata,
"title", json_object_new_string(title.c_str()));
714 string metadataDescription = description;
715 if (!copyright.empty())
716 metadataDescription +=
"\n\n" + copyright;
717 if (!metadataDescription.empty())
718 json_object_object_add(_vuoModuleMetadata,
"description", json_object_new_string(metadataDescription.c_str()));
720 if (!shaderVersion.empty())
721 json_object_object_add(_vuoModuleMetadata,
"version", json_object_new_string(shaderVersion.c_str()));
722 if (!keywords.empty())
725 if (!examples.empty())
727 json_object *nodeMetadataJson = json_object_new_object();
729 json_object_object_add(_vuoModuleMetadata,
"node", nodeMetadataJson);
732 if (_type == VuoShaderFile::GLSLImageFilter
733 || _type == VuoShaderFile::GLSLImageGenerator
734 || _type == VuoShaderFile::GLSLImageTransition
735 || _type == VuoShaderFile::GLSLObjectFilter)
737 json_object *dependenciesJson = json_object_new_array();
739 if (_type == VuoShaderFile::GLSLImageFilter
740 || _type == VuoShaderFile::GLSLImageGenerator
741 || _type == VuoShaderFile::GLSLImageTransition)
742 json_object_array_add(dependenciesJson, json_object_new_string(
"VuoImageRenderer"));
743 else if (_type == VuoShaderFile::GLSLObjectFilter)
744 json_object_array_add(dependenciesJson, json_object_new_string(
"VuoSceneObjectRenderer"));
746 json_object_object_add(_vuoModuleMetadata,
"dependencies", dependenciesJson);
750 string VuoShaderFile::vuoTypeForIsfType(
string isfType)
752 if (isfType ==
"event")
755 else if (isfType ==
"bool")
757 else if (isfType ==
"long")
759 else if (isfType ==
"float")
761 else if (isfType ==
"point2D")
763 else if (isfType ==
"point3D")
765 else if (isfType ==
"point4D")
767 else if (isfType ==
"color")
770 else if (isfType ==
"bool[]")
771 return "VuoList_VuoBoolean";
772 else if (isfType ==
"long[]")
773 return "VuoList_VuoInteger";
774 else if (isfType ==
"float[]")
775 return "VuoList_VuoReal";
776 else if (isfType ==
"point2D[]")
777 return "VuoList_VuoPoint2d";
778 else if (isfType ==
"point3D[]")
779 return "VuoList_VuoPoint3d";
780 else if (isfType ==
"point4D[]")
781 return "VuoList_VuoPoint4d";
782 else if (isfType ==
"color[]")
783 return "VuoList_VuoColor";
785 else if (isfType ==
"image")
788 else if (isfType ==
"size")
790 else if (isfType ==
"colorDepth")
791 return "VuoImageColorDepth";
796 string VuoShaderFile::isfTypeForVuoType(
string vuoType)
798 if (vuoType ==
"event")
800 else if (vuoType ==
"VuoBoolean")
802 else if (vuoType ==
"VuoInteger")
804 else if (vuoType ==
"VuoReal")
806 else if (vuoType ==
"VuoPoint2d")
808 else if (vuoType ==
"VuoPoint3d")
810 else if (vuoType ==
"VuoPoint4d")
812 else if (vuoType ==
"VuoColor")
815 else if (vuoType ==
"VuoList_VuoBoolean")
817 else if (vuoType ==
"VuoList_VuoInteger")
819 else if (vuoType ==
"VuoList_VuoReal")
821 else if (vuoType ==
"VuoList_VuoPoint2d")
823 else if (vuoType ==
"VuoList_VuoPoint3d")
825 else if (vuoType ==
"VuoList_VuoPoint4d")
827 else if (vuoType ==
"VuoList_VuoColor")
830 else if (vuoType ==
"VuoImage")
833 else if (vuoType ==
"VuoSize")
835 else if (vuoType ==
"VuoImageColorDepth")
848 types.insert(
"VuoBoolean");
849 types.insert(
"VuoInteger");
850 types.insert(
"VuoReal");
851 types.insert(
"VuoPoint2d");
852 types.insert(
"VuoPoint3d");
853 types.insert(
"VuoPoint4d");
854 types.insert(
"VuoColor");
856 types.insert(
"VuoList_VuoBoolean");
857 types.insert(
"VuoList_VuoInteger");
858 types.insert(
"VuoList_VuoReal");
859 types.insert(
"VuoList_VuoPoint2d");
860 types.insert(
"VuoList_VuoPoint3d");
861 types.insert(
"VuoList_VuoPoint4d");
862 types.insert(
"VuoList_VuoColor");
864 types.insert(
"VuoImage");
865 types.insert(
"VuoSize");
866 types.insert(
"VuoImageColorDepth");
871 string VuoShaderFile::glslDeclarationForPort(Port port)
875 if (port.vuoTypeName ==
"event"
876 || port.vuoTypeName ==
"VuoBoolean")
877 return "uniform bool " + port.key +
";\n";
878 else if (port.vuoTypeName ==
"VuoInteger")
879 return "uniform int " + port.key +
";\n";
880 else if (port.vuoTypeName ==
"VuoReal")
881 return "uniform float " + port.key +
";\n";
882 else if (port.vuoTypeName ==
"VuoPoint2d")
883 return "uniform vec2 " + port.key +
";\n";
884 else if (port.vuoTypeName ==
"VuoPoint3d")
885 return "uniform vec3 " + port.key +
";\n";
886 else if (port.vuoTypeName ==
"VuoPoint4d")
887 return "uniform vec4 " + port.key +
";\n";
888 else if (port.vuoTypeName ==
"VuoColor")
889 return "uniform vec4 " + port.key +
";\n";
891 else if (port.vuoTypeName ==
"VuoList_VuoBoolean")
892 return "uniform bool " + port.key +
"[" + maxItems +
"];\n"
893 "uniform int _" + port.key +
"_length;\n";
894 else if (port.vuoTypeName ==
"VuoList_VuoInteger")
895 return "uniform int " + port.key +
"[" + maxItems +
"];\n"
896 "uniform int _" + port.key +
"_length;\n";
897 else if (port.vuoTypeName ==
"VuoList_VuoReal")
898 return "uniform float " + port.key +
"[" + maxItems +
"];\n"
899 "uniform int _" + port.key +
"_length;\n";
900 else if (port.vuoTypeName ==
"VuoList_VuoPoint2d")
901 return "uniform vec2 " + port.key +
"[" + maxItems +
"];\n"
902 "uniform int _" + port.key +
"_length;\n";
903 else if (port.vuoTypeName ==
"VuoList_VuoPoint3d")
904 return "uniform vec3 " + port.key +
"[" + maxItems +
"];\n"
905 "uniform int _" + port.key +
"_length;\n";
906 else if (port.vuoTypeName ==
"VuoList_VuoPoint4d")
907 return "uniform vec4 " + port.key +
"[" + maxItems +
"];\n"
908 "uniform int _" + port.key +
"_length;\n";
909 else if (port.vuoTypeName ==
"VuoList_VuoColor")
910 return "uniform vec4 " + port.key +
"[" + maxItems +
"];\n"
911 "uniform int _" + port.key +
"_length;\n";
913 else if (port.vuoTypeName ==
"VuoImage")
914 return "//uniform VuoImage " + port.key +
";\n"
915 "uniform vec4 _" + port.key +
"_imgRect;\n"
916 "uniform vec2 _" + port.key +
"_imgSize;\n"
917 "uniform bool _" + port.key +
"_flip;\n";
922 void VuoShaderFile::saveStage(
string filePath,
string &source,
json_object *vuoModuleMetadata)
938 string VuoShaderFile::stageFileContents(
string &source,
json_object *vuoModuleMetadata)
945 json_object *isfMetadata = json_object_new_object();
947 if (isfVersion.empty())
948 json_object_object_add(isfMetadata,
"ISFVSN", json_object_new_string(
"2.0"));
950 json_object_object_add(isfMetadata,
"ISFVSN", json_object_new_string(isfVersion.c_str()));
952 json_object_object_add(isfMetadata,
"TYPE", json_object_new_string(
typeNameISF().c_str()));
955 json_object_object_add(isfMetadata,
"LABEL", json_object_new_string(_name.c_str()));
957 if (!shaderVersion.empty())
958 json_object_object_add(isfMetadata,
"VSN", json_object_new_string(shaderVersion.c_str()));
960 if (!copyright.empty())
961 json_object_object_add(isfMetadata,
"CREDIT", json_object_new_string(copyright.c_str()));
963 if (!license.empty())
964 json_object_object_add(isfMetadata,
"LICENSE", json_object_new_string(license.c_str()));
966 if (!description.empty())
967 json_object_object_add(isfMetadata,
"DESCRIPTION", json_object_new_string(description.c_str()));
969 if (!homepageLink.empty() || !documentationLink.empty())
972 if (!homepageLink.empty())
973 json_object_object_add(links,
"HOMEPAGE", json_object_new_string(homepageLink.c_str()));
974 if (!documentationLink.empty())
975 json_object_object_add(links,
"DOCUMENTATION", json_object_new_string(documentationLink.c_str()));
976 json_object_object_add(isfMetadata,
"LINKS", links);
979 if (!categories.empty())
982 if (!keywords.empty())
985 if (!examples.empty())
989 if (!_inputPorts.empty())
992 for (vector<Port>::iterator i = _inputPorts.begin(); i != _inputPorts.end(); ++i)
997 json_object_object_add(input,
"NAME", json_object_new_string(i->key.c_str()));
999 json_object_object_add(input,
"TYPE", json_object_new_string(isfTypeForVuoType(i->vuoTypeName).c_str()));
1002 if (json_object_object_get_ex(i->vuoPortDetails,
"name", &nameValue))
1003 json_object_object_add(input,
"LABEL", nameValue);
1006 if (json_object_object_get_ex(i->vuoPortDetails,
"default", &defaultValue))
1010 && json_object_get_type(defaultValue) == json_type_object)
1016 json_object_object_get_ex(defaultValue,
"x", &x);
1017 json_object_object_get_ex(defaultValue,
"y", &y);
1018 json_object_object_get_ex(defaultValue,
"z", &z);
1019 json_object_object_get_ex(defaultValue,
"w", &w);
1021 defaultValue = json_object_new_array();
1022 json_object_array_add(defaultValue, x);
1023 json_object_array_add(defaultValue, y);
1024 if (i->vuoTypeName ==
"VuoPoint3d" || i->vuoTypeName ==
"VuoPoint4d")
1025 json_object_array_add(defaultValue, z);
1026 if (i->vuoTypeName ==
"VuoPoint4d")
1027 json_object_array_add(defaultValue, w);
1030 json_object_object_add(input,
"DEFAULT", defaultValue);
1034 if (!(json_object_object_get_ex(i->vuoPortDetails,
"scaleToSamplerRect", &scaleToSamplerRectValue)
1035 && json_object_get_boolean(scaleToSamplerRectValue)))
1038 if (json_object_object_get_ex(i->vuoPortDetails,
"suggestedMin", &minValue))
1039 json_object_object_add(input,
"MIN", minValue);
1042 if (json_object_object_get_ex(i->vuoPortDetails,
"suggestedMax", &maxValue))
1043 json_object_object_add(input,
"MAX", maxValue);
1047 if (json_object_object_get_ex(i->vuoPortDetails,
"suggestedStep", &stepValue))
1048 json_object_object_add(input,
"STEP", stepValue);
1051 if (json_object_object_get_ex(i->vuoPortDetails,
"maxItems", &maxItemsValue))
1052 json_object_object_add(input,
"MAX_ITEMS", maxItemsValue);
1055 if (json_object_object_get_ex(i->vuoPortDetails,
"menuItems", &menuItemsValue))
1057 json_object *valueItems = json_object_new_array();
1058 json_object *labelItems = json_object_new_array();
1059 json_object_object_foreach(menuItemsValue, key, val)
1061 json_object_array_add(valueItems, json_object_new_string(key));
1062 json_object_array_add(labelItems, val);
1064 json_object_object_add(input,
"VALUES", valueItems);
1065 json_object_object_add(input,
"LABELS", labelItems);
1068 json_object_array_add(inputs, input);
1070 json_object_object_add(isfMetadata,
"INPUTS", inputs);
1077 if (_type == VuoShaderFile::GLSLImageFilter
1078 || _type == VuoShaderFile::GLSLImageGenerator
1079 || _type == VuoShaderFile::GLSLImageTransition)
1081 if (outputKey !=
"outputImage")
1082 json_object_object_add(output,
"NAME", json_object_new_string(outputKey.c_str()));
1083 if (outputName !=
"Output Image")
1084 json_object_object_add(output,
"LABEL", json_object_new_string(outputName.c_str()));
1086 else if (_type == VuoShaderFile::GLSLObjectRenderer)
1088 if (outputKey !=
"shader")
1089 json_object_object_add(output,
"NAME", json_object_new_string(outputKey.c_str()));
1090 if (outputName !=
"Shader")
1091 json_object_object_add(output,
"LABEL", json_object_new_string(outputName.c_str()));
1095 if (outputKey !=
"outputObject")
1096 json_object_object_add(output,
"NAME", json_object_new_string(outputKey.c_str()));
1097 if (outputName !=
"Output Object")
1098 json_object_object_add(output,
"LABEL", json_object_new_string(outputName.c_str()));
1101 if (json_object_object_length(output))
1104 json_object_array_add(outputs, output);
1105 json_object_object_add(isfMetadata,
"OUTPUTS", outputs);
1109 string json = json_object_to_json_string_ext(isfMetadata, JSON_C_TO_STRING_PRETTY);
1110 ss << spacesToTabs(json);
1116 if (source[source.length() - 1] !=
'\n')
1125 string VuoShaderFile::spacesToTabs(
string &str)
1127 stringstream strStream(str);
1130 while (getline(strStream, ln))
1132 size_t spaces = ln.find_first_not_of(
' ');
1133 out << string(spaces / 2,
'\t');
1134 out << ln.substr(spaces);
1135 if (!strStream.eof())