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)
658 json_object_object_add(menuItem,
"value", json_object_array_get_idx(values, i));
659 json_object_object_add(menuItem,
"name", json_object_array_get_idx(labels, i));
660 json_object_array_add(menuItems, menuItem);
662 json_object_object_add(vuoPortDetails,
"menuItems", menuItems);
665 _inputPorts.push_back((Port){ key, vuoType, vuoPortDetails });
670 if (json_object_object_get_ex(
metadata,
"OUTPUTS", &outputsArray))
672 int outputCount = json_object_array_length(outputsArray);
673 for (
int i = 0; i < outputCount; ++i)
675 json_object *outputObject = json_object_array_get_idx(outputsArray, i);
681 if (typeString ==
"IMAGE")
684 _type = GLSLImageFilter;
685 else if (hasStartImage && hasEndImage && hasProgress)
686 _type = GLSLImageTransition;
688 _type = GLSLImageGenerator;
690 if (outputKey.empty())
691 outputKey =
"outputImage";
692 if (outputName.empty())
695 else if (typeString ==
"OBJECT_RENDER")
697 _type = GLSLObjectRenderer;
699 if (outputKey.empty())
700 outputKey =
"shader";
701 if (outputName.empty())
704 else if (typeString ==
"OBJECT_FILTER")
706 _type = GLSLObjectFilter;
708 if (outputKey.empty())
709 outputKey =
"outputObject";
710 if (outputName.empty())
714 _vuoModuleMetadata = json_object_new_object();
716 string title = (! _name.empty() ? _name : normalizedBasename);
717 json_object_object_add(_vuoModuleMetadata,
"title", json_object_new_string(title.c_str()));
719 string metadataDescription = description;
720 if (!copyright.empty())
721 metadataDescription +=
"\n\n" + copyright;
722 if (!metadataDescription.empty())
723 json_object_object_add(_vuoModuleMetadata,
"description", json_object_new_string(metadataDescription.c_str()));
725 if (!shaderVersion.empty())
726 json_object_object_add(_vuoModuleMetadata,
"version", json_object_new_string(shaderVersion.c_str()));
727 if (!keywords.empty())
730 if (!examples.empty())
732 json_object *nodeMetadataJson = json_object_new_object();
734 json_object_object_add(_vuoModuleMetadata,
"node", nodeMetadataJson);
737 if (_type == VuoShaderFile::GLSLImageFilter
738 || _type == VuoShaderFile::GLSLImageGenerator
739 || _type == VuoShaderFile::GLSLImageTransition
740 || _type == VuoShaderFile::GLSLObjectFilter)
742 json_object *dependenciesJson = json_object_new_array();
744 if (_type == VuoShaderFile::GLSLImageFilter
745 || _type == VuoShaderFile::GLSLImageGenerator
746 || _type == VuoShaderFile::GLSLImageTransition)
747 json_object_array_add(dependenciesJson, json_object_new_string(
"VuoImageRenderer"));
748 else if (_type == VuoShaderFile::GLSLObjectFilter)
749 json_object_array_add(dependenciesJson, json_object_new_string(
"VuoSceneObjectRenderer"));
751 json_object_object_add(_vuoModuleMetadata,
"dependencies", dependenciesJson);
755 string VuoShaderFile::vuoTypeForIsfType(
string isfType)
757 if (isfType ==
"event")
760 else if (isfType ==
"bool")
762 else if (isfType ==
"long")
764 else if (isfType ==
"float")
766 else if (isfType ==
"point2D")
768 else if (isfType ==
"point3D")
770 else if (isfType ==
"point4D")
772 else if (isfType ==
"color")
775 else if (isfType ==
"bool[]")
776 return "VuoList_VuoBoolean";
777 else if (isfType ==
"long[]")
778 return "VuoList_VuoInteger";
779 else if (isfType ==
"float[]")
780 return "VuoList_VuoReal";
781 else if (isfType ==
"point2D[]")
782 return "VuoList_VuoPoint2d";
783 else if (isfType ==
"point3D[]")
784 return "VuoList_VuoPoint3d";
785 else if (isfType ==
"point4D[]")
786 return "VuoList_VuoPoint4d";
787 else if (isfType ==
"color[]")
788 return "VuoList_VuoColor";
790 else if (isfType ==
"image")
793 else if (isfType ==
"size")
795 else if (isfType ==
"colorDepth")
796 return "VuoImageColorDepth";
801 string VuoShaderFile::isfTypeForVuoType(
string vuoType)
803 if (vuoType ==
"event")
805 else if (vuoType ==
"VuoBoolean")
807 else if (vuoType ==
"VuoInteger")
809 else if (vuoType ==
"VuoReal")
811 else if (vuoType ==
"VuoPoint2d")
813 else if (vuoType ==
"VuoPoint3d")
815 else if (vuoType ==
"VuoPoint4d")
817 else if (vuoType ==
"VuoColor")
820 else if (vuoType ==
"VuoList_VuoBoolean")
822 else if (vuoType ==
"VuoList_VuoInteger")
824 else if (vuoType ==
"VuoList_VuoReal")
826 else if (vuoType ==
"VuoList_VuoPoint2d")
828 else if (vuoType ==
"VuoList_VuoPoint3d")
830 else if (vuoType ==
"VuoList_VuoPoint4d")
832 else if (vuoType ==
"VuoList_VuoColor")
835 else if (vuoType ==
"VuoImage")
838 else if (vuoType ==
"VuoSize")
840 else if (vuoType ==
"VuoImageColorDepth")
853 types.insert(
"VuoBoolean");
854 types.insert(
"VuoInteger");
855 types.insert(
"VuoReal");
856 types.insert(
"VuoPoint2d");
857 types.insert(
"VuoPoint3d");
858 types.insert(
"VuoPoint4d");
859 types.insert(
"VuoColor");
861 types.insert(
"VuoList_VuoBoolean");
862 types.insert(
"VuoList_VuoInteger");
863 types.insert(
"VuoList_VuoReal");
864 types.insert(
"VuoList_VuoPoint2d");
865 types.insert(
"VuoList_VuoPoint3d");
866 types.insert(
"VuoList_VuoPoint4d");
867 types.insert(
"VuoList_VuoColor");
869 types.insert(
"VuoImage");
870 types.insert(
"VuoSize");
871 types.insert(
"VuoImageColorDepth");
876 string VuoShaderFile::glslDeclarationForPort(Port port)
880 if (port.vuoTypeName ==
"event"
881 || port.vuoTypeName ==
"VuoBoolean")
882 return "uniform bool " + port.key +
";\n";
883 else if (port.vuoTypeName ==
"VuoInteger")
884 return "uniform int " + port.key +
";\n";
885 else if (port.vuoTypeName ==
"VuoReal")
886 return "uniform float " + port.key +
";\n";
887 else if (port.vuoTypeName ==
"VuoPoint2d")
888 return "uniform vec2 " + port.key +
";\n";
889 else if (port.vuoTypeName ==
"VuoPoint3d")
890 return "uniform vec3 " + port.key +
";\n";
891 else if (port.vuoTypeName ==
"VuoPoint4d")
892 return "uniform vec4 " + port.key +
";\n";
893 else if (port.vuoTypeName ==
"VuoColor")
894 return "uniform vec4 " + port.key +
";\n";
896 else if (port.vuoTypeName ==
"VuoList_VuoBoolean")
897 return "uniform bool " + port.key +
"[" + maxItems +
"];\n"
898 "uniform int _" + port.key +
"_length;\n";
899 else if (port.vuoTypeName ==
"VuoList_VuoInteger")
900 return "uniform int " + port.key +
"[" + maxItems +
"];\n"
901 "uniform int _" + port.key +
"_length;\n";
902 else if (port.vuoTypeName ==
"VuoList_VuoReal")
903 return "uniform float " + port.key +
"[" + maxItems +
"];\n"
904 "uniform int _" + port.key +
"_length;\n";
905 else if (port.vuoTypeName ==
"VuoList_VuoPoint2d")
906 return "uniform vec2 " + port.key +
"[" + maxItems +
"];\n"
907 "uniform int _" + port.key +
"_length;\n";
908 else if (port.vuoTypeName ==
"VuoList_VuoPoint3d")
909 return "uniform vec3 " + port.key +
"[" + maxItems +
"];\n"
910 "uniform int _" + port.key +
"_length;\n";
911 else if (port.vuoTypeName ==
"VuoList_VuoPoint4d")
912 return "uniform vec4 " + port.key +
"[" + maxItems +
"];\n"
913 "uniform int _" + port.key +
"_length;\n";
914 else if (port.vuoTypeName ==
"VuoList_VuoColor")
915 return "uniform vec4 " + port.key +
"[" + maxItems +
"];\n"
916 "uniform int _" + port.key +
"_length;\n";
918 else if (port.vuoTypeName ==
"VuoImage")
919 return "//uniform VuoImage " + port.key +
";\n"
920 "uniform vec4 _" + port.key +
"_imgRect;\n"
921 "uniform vec2 _" + port.key +
"_imgSize;\n"
922 "uniform bool _" + port.key +
"_flip;\n";
927 void VuoShaderFile::saveStage(
string filePath,
string &source,
json_object *vuoModuleMetadata)
943 string VuoShaderFile::stageFileContents(
string &source,
json_object *vuoModuleMetadata)
950 json_object *isfMetadata = json_object_new_object();
952 if (isfVersion.empty())
953 json_object_object_add(isfMetadata,
"ISFVSN", json_object_new_string(
"2.0"));
955 json_object_object_add(isfMetadata,
"ISFVSN", json_object_new_string(isfVersion.c_str()));
957 json_object_object_add(isfMetadata,
"TYPE", json_object_new_string(
typeNameISF().c_str()));
960 json_object_object_add(isfMetadata,
"LABEL", json_object_new_string(_name.c_str()));
962 if (!shaderVersion.empty())
963 json_object_object_add(isfMetadata,
"VSN", json_object_new_string(shaderVersion.c_str()));
965 if (!copyright.empty())
966 json_object_object_add(isfMetadata,
"CREDIT", json_object_new_string(copyright.c_str()));
968 if (!license.empty())
969 json_object_object_add(isfMetadata,
"LICENSE", json_object_new_string(license.c_str()));
971 if (!description.empty())
972 json_object_object_add(isfMetadata,
"DESCRIPTION", json_object_new_string(description.c_str()));
974 if (!homepageLink.empty() || !documentationLink.empty())
977 if (!homepageLink.empty())
978 json_object_object_add(links,
"HOMEPAGE", json_object_new_string(homepageLink.c_str()));
979 if (!documentationLink.empty())
980 json_object_object_add(links,
"DOCUMENTATION", json_object_new_string(documentationLink.c_str()));
981 json_object_object_add(isfMetadata,
"LINKS", links);
984 if (!categories.empty())
987 if (!keywords.empty())
990 if (!examples.empty())
994 if (!_inputPorts.empty())
997 for (vector<Port>::iterator i = _inputPorts.begin(); i != _inputPorts.end(); ++i)
1001 if (!i->key.empty())
1002 json_object_object_add(input,
"NAME", json_object_new_string(i->key.c_str()));
1004 json_object_object_add(input,
"TYPE", json_object_new_string(isfTypeForVuoType(i->vuoTypeName).c_str()));
1007 if (json_object_object_get_ex(i->vuoPortDetails,
"name", &nameValue))
1008 json_object_object_add(input,
"LABEL", nameValue);
1011 if (json_object_object_get_ex(i->vuoPortDetails,
"default", &defaultValue))
1015 && json_object_get_type(defaultValue) == json_type_object)
1021 json_object_object_get_ex(defaultValue,
"x", &x);
1022 json_object_object_get_ex(defaultValue,
"y", &y);
1023 json_object_object_get_ex(defaultValue,
"z", &z);
1024 json_object_object_get_ex(defaultValue,
"w", &w);
1026 defaultValue = json_object_new_array();
1027 json_object_array_add(defaultValue, x);
1028 json_object_array_add(defaultValue, y);
1029 if (i->vuoTypeName ==
"VuoPoint3d" || i->vuoTypeName ==
"VuoPoint4d")
1030 json_object_array_add(defaultValue, z);
1031 if (i->vuoTypeName ==
"VuoPoint4d")
1032 json_object_array_add(defaultValue, w);
1035 json_object_object_add(input,
"DEFAULT", defaultValue);
1039 if (!(json_object_object_get_ex(i->vuoPortDetails,
"scaleToSamplerRect", &scaleToSamplerRectValue)
1040 && json_object_get_boolean(scaleToSamplerRectValue)))
1043 if (json_object_object_get_ex(i->vuoPortDetails,
"suggestedMin", &minValue))
1044 json_object_object_add(input,
"MIN", minValue);
1047 if (json_object_object_get_ex(i->vuoPortDetails,
"suggestedMax", &maxValue))
1048 json_object_object_add(input,
"MAX", maxValue);
1052 if (json_object_object_get_ex(i->vuoPortDetails,
"suggestedStep", &stepValue))
1053 json_object_object_add(input,
"STEP", stepValue);
1056 if (json_object_object_get_ex(i->vuoPortDetails,
"maxItems", &maxItemsValue))
1057 json_object_object_add(input,
"MAX_ITEMS", maxItemsValue);
1060 if (json_object_object_get_ex(i->vuoPortDetails,
"menuItems", &menuItemsValue))
1062 json_object *valueItems = json_object_new_array();
1063 json_object *labelItems = json_object_new_array();
1064 int len = json_object_array_length(menuItemsValue);
1065 for (
int mi = 0; mi < len; ++mi)
1067 json_object *menuItem = json_object_array_get_idx(menuItemsValue, mi);
1070 json_object_object_get_ex(menuItem,
"value", &valueItem);
1071 json_object_array_add(valueItems, valueItem);
1074 json_object_object_get_ex(menuItem,
"name", &nameItem);
1075 json_object_array_add(labelItems, nameItem);
1077 json_object_object_add(input,
"VALUES", valueItems);
1078 json_object_object_add(input,
"LABELS", labelItems);
1081 json_object_array_add(inputs, input);
1083 json_object_object_add(isfMetadata,
"INPUTS", inputs);
1090 if (_type == VuoShaderFile::GLSLImageFilter
1091 || _type == VuoShaderFile::GLSLImageGenerator
1092 || _type == VuoShaderFile::GLSLImageTransition)
1094 if (outputKey !=
"outputImage")
1095 json_object_object_add(output,
"NAME", json_object_new_string(outputKey.c_str()));
1096 if (outputName !=
"Output Image")
1097 json_object_object_add(output,
"LABEL", json_object_new_string(outputName.c_str()));
1099 else if (_type == VuoShaderFile::GLSLObjectRenderer)
1101 if (outputKey !=
"shader")
1102 json_object_object_add(output,
"NAME", json_object_new_string(outputKey.c_str()));
1103 if (outputName !=
"Shader")
1104 json_object_object_add(output,
"LABEL", json_object_new_string(outputName.c_str()));
1108 if (outputKey !=
"outputObject")
1109 json_object_object_add(output,
"NAME", json_object_new_string(outputKey.c_str()));
1110 if (outputName !=
"Output Object")
1111 json_object_object_add(output,
"LABEL", json_object_new_string(outputName.c_str()));
1114 if (json_object_object_length(output))
1117 json_object_array_add(outputs, output);
1118 json_object_object_add(isfMetadata,
"OUTPUTS", outputs);
1122 string json = json_object_to_json_string_ext(isfMetadata, JSON_C_TO_STRING_PRETTY);
1123 ss << spacesToTabs(json);
1129 if (source[source.length() - 1] !=
'\n')
1138 string VuoShaderFile::spacesToTabs(
string &str)
1140 stringstream strStream(str);
1143 while (getline(strStream, ln))
1145 size_t spaces = ln.find_first_not_of(
' ');
1146 out << string(spaces / 2,
'\t');
1147 out << ln.substr(spaces);
1148 if (!strStream.eof())