1
$\begingroup$

I have some SSBOs that are used in several shaders. So I want to save their definition and their call functions in a separate text file and include them into the shaders. This is really necessary because if I change them, I have to copy the changes to all shaders. This was a mistake more than once that could have been prevented.

The shaders are compiled with glslc.exe before runtime.

How to include them?

askedJan 16 at 11:23
Thomas's user avatar
$\endgroup$
1
  • $\begingroup$I have already found similar questions here, but not with compiled shaders before runtime$\endgroup$CommentedJan 16 at 11:29

1 Answer1

1
$\begingroup$

Unfortunately, I haven't found an answer to this question, but I have developed an alternative.

I wrote a program in C++ that reads the shader code as std::string and searches it for “#include”. When it occurs, I recursively loaded this file and replaced the content accordingly. Since this happens recursively, “#include” can also be in included files. The finished string is written to a temporary file at the end and compiled to Spir-V using a batch file.

static std::vector<std::string> split(const std::string& text, const std::string& delimiter){    std::vector<std::string> result;    std::string s = text;    std::string d = delimiter;    size_t pos = 0;    std::string token;    while ((pos = s.find(d)) != std::string::npos) {        token = s.substr(0, pos);        result.push_back(token);        s.erase(0, pos + d.length());    }    result.push_back(s);    return result;}static std::string getIncludeFileName(std::string includeCode){    std::string result = "";    bool recording = false;    for (unsigned int i = 0; i < includeCode.length(); ++i) {        if (includeCode.at(i) == 34) // find '"'            recording = !recording;        else            if (recording)                result += includeCode.at(i);    }    return result;}static std::string loadShaderCode(const std::string& shaderCodeFile) //can handle "#include" within the shader code{    std::string result = "";    std::ifstream file(shaderCodeFile);    std::string directory = "";    std::vector<std::string> splittedPath = split(shaderCodeFile, "/");    for (unsigned int i = 0; i < splittedPath.size() - 1; ++i)        directory += splittedPath[i] + "/";    std::string line;    while (std::getline(file, line)) {        if (line.length() > 8 && line.substr(0, 8).compare("#include") == 0) {            //#include found            std::string includeFile = getIncludeFileName(line);            result += loadShaderCode(directory + "/" + includeFile);        }        else            result += line + "\n";    }    return result;}
answeredAug 27 at 9:09
Thomas's user avatar
$\endgroup$

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.