GLSLではHLSLのように#include
ができないので、テキストファイル化したシェーダーに、インクルードしたいファイルを挿入する形で実装する必要があります。
Shader.cpp
Shader::Shader(const char* vertexFile, const char* fragmentFile)
{
//シェーダーをロードする。
std::string vertexCode = get_file_contents(vertexFile);
std::string fragmentCode = get_file_contents(fragmentFile);
//インクルードファイルを追加する。
vertexCode = AddIncludeShaderFile(vertexCode, "test.h");
fragmentCode = AddIncludeShaderFile(fragmentCode, "test.h");
}
Shader.cpp
/// <summary>
/// シェーダーにインクルードファイルを挿入する。
/// </summary>
/// <param name="mainShader">元になるシェーダー</param>
/// <param name="includeFile">インクルードしたいファイル</param>
/// <returns></returns>
std::string Shader::AddIncludeShaderFile(
std::string mainShader,
const char* includeFile
) {
//ロードするシェーダーはAssets/shader/内にあるので、文字列を追加して読み込む。
std::string fileName = "Assets/shader/";
fileName = fileName + includeFile;
std::string includedShaderCode = get_file_contents(const_cast<char*>(fileName.c_str()));
//シェーダー内の#include test.hを置き換えたいので、文字列を追加して検索する。
std::string includeFileStr = includeFile;
includeFileStr = "#include " + includeFileStr;
// includeする位置にファイルの内容を挿入する
size_t includePos = mainShader.find(includeFileStr);
if (includePos != std::string::npos) {
mainShader.replace(
includePos,
strlen(const_cast<char*>(includeFileStr.c_str())),
includedShaderCode
);
}
return mainShader;
}
mainShader.find()
でシェーダー内にある#include test.h
を検索し、
mainShader.replace()
で検索した位置にインクルードファイルを置き換えています。