22
33#include " sajson.h"
44
5+ #include < boost/algorithm/string.hpp>
6+
57#include < array>
68#include < iostream>
79#include < regex>
@@ -72,6 +74,27 @@ layout(std140, binding = 1) uniform process_t {
7274 vec4 DATE;
7375} isf_process_uniforms;
7476
77+ float TIME = isf_process_uniforms.TIME;
78+ float TIMEDELTA = isf_process_uniforms.TIMEDELTA;
79+ float PROGRESS = isf_process_uniforms.PROGRESS;
80+ int PASSINDEX = isf_process_uniforms.PASSINDEX;
81+ int FRAMEINDEX = isf_process_uniforms.FRAMEINDEX;
82+ vec4 DATE = isf_process_uniforms.DATE;
83+ )_" ;
84+
85+ static constexpr auto defaultGeometryUniforms = R"_(
86+ // Time-dependent uniforms, only relevant during execution
87+ layout(std140, binding = 1) uniform process_t {
88+ float TIME;
89+ float TIMEDELTA;
90+ float PROGRESS;
91+
92+ int PASSINDEX;
93+ int FRAMEINDEX;
94+
95+ vec4 DATE;
96+ } isf_process_uniforms;
97+
7598float TIME = isf_process_uniforms.TIME;
7699float TIMEDELTA = isf_process_uniforms.TIMEDELTA;
77100float PROGRESS = isf_process_uniforms.PROGRESS;
@@ -147,6 +170,12 @@ uniform int PASSINDEX;
147170} GLSL3;
148171}
149172
173+ parser::parser (std::string geom)
174+ : m_source_geometry_filter{std::move (geom)}
175+ {
176+ parse_geometry_filter ();
177+ }
178+
150179parser::parser (std::string vert, std::string frag, int glslVersion, ShaderType t)
151180 : m_sourceVertex{std::move (vert)}
152181 , m_sourceFragment{std::move (frag)}
@@ -198,6 +227,8 @@ parser::parser(std::string vert, std::string frag, int glslVersion, ShaderType t
198227 parse_glsl_sandbox ();
199228 break ;
200229 }
230+ default :
231+ break ;
201232 }
202233}
203234
@@ -216,6 +247,11 @@ std::string parser::fragment() const
216247 return m_fragment;
217248}
218249
250+ std::string parser::geometry_filter () const
251+ {
252+ return m_geometry_filter;
253+ }
254+
219255static bool is_number (sajson::value& v)
220256{
221257 auto t = v.get_type ();
@@ -612,24 +648,24 @@ struct create_val_visitor_450
612648 return_type operator ()(const audioFFT_input&) { return {" uniform sampler2D" , true }; }
613649};
614650
615- void parser::parse_isf ( )
651+ std::string parser::parse_isf_header (std::string_view source )
616652{
617653 using namespace std ::literals;
618654
619- auto start = m_sourceFragment .find (" /*" );
655+ auto start = source .find (" /*" );
620656 if (start == std::string::npos)
621657 throw invalid_file{" Missing start comment" };
622- auto end = m_sourceFragment .find (" */" , start);
658+ auto end = source .find (" */" , start);
623659 if (end == std::string::npos)
624660 throw invalid_file{" Unfinished comment" };
625- auto fragWithoutISF = m_sourceFragment ;
661+ std::string fragWithoutISF = std::string (source) ;
626662 fragWithoutISF.erase (0 , end + 2 );
627663
628664 // First comes the json part
629665 auto doc = sajson::parse (
630666 sajson::dynamic_allocation (),
631667 sajson::mutable_string_view (
632- (end - start - 2 ), const_cast <char *>(m_sourceFragment .data ()) + start + 2 ));
668+ (end - start - 2 ), const_cast <char *>(source .data ()) + start + 2 ));
633669 if (!doc.is_valid ())
634670 {
635671 std::stringstream err;
@@ -658,12 +694,73 @@ void parser::parse_isf()
658694 }
659695 m_desc = d;
660696
697+ return fragWithoutISF;
698+ }
699+
700+ void parser::parse_geometry_filter ()
701+ {
702+ using namespace std ::literals;
703+
704+ auto geomWithoutISF = parse_isf_header (m_source_geometry_filter);
705+
661706 // There is always one pass at least
662707 if (m_desc.passes .empty ())
663708 {
664709 m_desc.passes .push_back (isf::pass{});
665710 }
666711
712+ boost::algorithm::trim (geomWithoutISF);
713+ boost::algorithm::replace_all (geomWithoutISF, " this_filter" , " filter_%node%" );
714+
715+ std::string filter_ubo;
716+ if (!m_desc.inputs .empty ())
717+ {
718+ std::string globalvars;
719+ filter_ubo += " layout(std140, binding = %next%) uniform filter_%node%_t {\n " ;
720+ for (const isf::input& val : m_desc.inputs )
721+ {
722+ auto [type, isSampler] = ossia::visit (create_val_visitor_450{}, val.data );
723+
724+ {
725+ filter_ubo += " " ;
726+ filter_ubo += type;
727+ filter_ubo += ' ' ;
728+ filter_ubo += val.name ;
729+ filter_ubo += " ;\n " ;
730+
731+ // // See comment above regarding little dance to make spirv-cross happy
732+ // globalvars += type;
733+ // globalvars += ' ';
734+ // globalvars += val.name;
735+ // globalvars += " = filter_%node%.";
736+ // globalvars += val.name;
737+ // globalvars += ";\n";
738+ }
739+ }
740+
741+ filter_ubo += " } filter_%node%;\n " ;
742+ filter_ubo += " \n " ;
743+ // filter_ubo += globalvars;
744+ // filter_ubo += "\n";
745+ }
746+ m_geometry_filter
747+ = glsl45_t ::defaultGeometryUniforms + filter_ubo + geomWithoutISF + " \n " ;
748+ }
749+
750+ void parser::parse_isf ()
751+ {
752+ using namespace std ::literals;
753+
754+ auto fragWithoutISF = parse_isf_header (m_sourceFragment);
755+
756+ // There is always one pass at least
757+ if (m_desc.passes .empty ())
758+ {
759+ m_desc.passes .push_back (isf::pass{});
760+ }
761+
762+ auto & d = m_desc;
763+
667764 // We start from empty strings.
668765
669766 bool simpleVS = false ;
0 commit comments