diff --git a/src/osltoy/osltoyapp.cpp b/src/osltoy/osltoyapp.cpp index 3e6a59d08..597768c07 100644 --- a/src/osltoy/osltoyapp.cpp +++ b/src/osltoy/osltoyapp.cpp @@ -711,6 +711,22 @@ OSLToyMainWindow::open_file(const std::string& filename) } +void +OSLToyMainWindow::add_include_search_path(const std::string& path) +{ + auto begin = m_include_search_paths.begin(); + auto end = m_include_search_paths.end(); + if (std::find(begin, end, path) == end) { + m_include_search_paths.push_back(path); + m_should_regenerate_compile_options = true; + + // Open question: Do we want to force a recompile whenever the list is updated? + // For now this doesn't matter cause the list is only modified + // via command line arguments, but if we want to have a GUI component, + // this is worth considering. + } +} + void OSLToyMainWindow::action_saveas() @@ -836,6 +852,24 @@ class MyOSLCErrorHandler final : public OIIO::ErrorHandler { }; +void +OSLToyMainWindow::regenerate_compile_options() +{ + // Right now, the only option we consider is include search path (-I) + + // Annoyingly, oslcomp only supports -I flags without any seperator between + // the -I and the path itself, but OIIO::ArgParse does not support parsing + // arguments in this manner. Oy vey. + + m_compile_options.clear(); + + for (auto&& path : m_include_search_paths) + m_compile_options.push_back(std::string("-I").append(path)); + + + m_should_regenerate_compile_options = false; +} + void OSLToyMainWindow::recompile_shaders() @@ -863,11 +897,20 @@ OSLToyMainWindow::recompile_shaders() MyOSLCErrorHandler errhandler(this); OSLCompiler oslcomp(&errhandler); std::string osooutput; - std::vector options; - ok = oslcomp.compile_buffer(source, osooutput, options, "", + + if (m_should_regenerate_compile_options) + regenerate_compile_options(); + + ok = oslcomp.compile_buffer(source, osooutput, m_compile_options, "", briefname); - set_error_message(tab, - OIIO::Strutil::join(errhandler.errors, "\n")); + + auto error_message = OIIO::Strutil::fmt::format( + "{}\n\nCompiled {} with options: {}", + OIIO::Strutil::join(errhandler.errors, "\n"), + briefname, + OIIO::Strutil::join(m_compile_options, " ")); + set_error_message(tab, error_message); + if (ok) { // std::cout << osooutput << "\n"; ok = shadingsys()->LoadMemoryCompiledShader(briefname, diff --git a/src/osltoy/osltoyapp.h b/src/osltoy/osltoyapp.h index 3d4055ee8..aea7f8fe1 100644 --- a/src/osltoy/osltoyapp.h +++ b/src/osltoy/osltoyapp.h @@ -91,6 +91,8 @@ class OSLToyMainWindow final : public QMainWindow { bool open_file(const std::string& filename); + void add_include_search_path(const std::string& path); + void rerender_needed() { m_rerender_needed = 1; } private slots: @@ -183,6 +185,8 @@ private slots: void make_param_adjustment_row(ParamRec* param, QGridLayout* layout, int row); + void regenerate_compile_options(); + void rebuild_param_area(); void inventory_params(); OIIO::ImageBuf& framebuffer(); @@ -197,6 +201,13 @@ private slots: std::string m_groupname; bool m_shader_uses_time = false; + std::vector m_include_search_paths; + + + bool m_should_regenerate_compile_options = true; + std::vector m_compile_options; + + // Access control mutex for handing things off between the GUI thread // and the shading thread. OIIO::spin_mutex m_job_mutex; diff --git a/src/osltoy/osltoymain.cpp b/src/osltoy/osltoymain.cpp index 9b926e356..99b67f200 100644 --- a/src/osltoy/osltoymain.cpp +++ b/src/osltoy/osltoymain.cpp @@ -39,6 +39,7 @@ static bool foreground_mode = true; static int threads = 0; static int xres = 512, yres = 512; static std::vector filenames; +static std::vector include_paths; static void @@ -58,6 +59,9 @@ getargs(int argc, char* argv[]) .help("Set thread count (0=cores)"); ap.arg("--res %d:XRES %d:YRES", &xres, &yres) .help("Set resolution"); + ap.arg("-I DIRPATH") + .action([&](cspan argv){ include_paths.emplace_back(argv[1]); }) + .help("Add DIRPATH to the list of header search paths."); // clang-format on if (ap.parse(argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; @@ -94,6 +98,10 @@ main(int argc, char* argv[]) QApplication app(argc, argv); OSLToyMainWindow mainwin(rend, xres, yres); mainwin.show(); + + for (auto&& path : include_paths) + mainwin.add_include_search_path(path); + for (auto&& filename : filenames) mainwin.open_file(filename);