Skip to content

Commit

Permalink
Add #include directive support in glsl
Browse files Browse the repository at this point in the history
  • Loading branch information
mogemimi committed Oct 3, 2016
1 parent 56200f6 commit cc6a1f8
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions src/Content/AssetBuilders/ShaderBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@
#include "Pomdog/Graphics/Shader.hpp"
#include "Pomdog/Graphics/ShaderLanguage.hpp"
#include "Pomdog/Graphics/ShaderPipelineStage.hpp"
#include "Pomdog/Logging/Log.hpp"
#include "Pomdog/Utility/Assert.hpp"
#include "Pomdog/Utility/Exception.hpp"
#include "Pomdog/Utility/FileSystem.hpp"
#include "Pomdog/Utility/Optional.hpp"
#include "Pomdog/Utility/PathHelper.hpp"
#include "Pomdog/Utility/StringHelper.hpp"
#include <fstream>
#include <vector>
#include <utility>
#include <set>
#include <regex>

using Pomdog::Detail::BinaryReader;
using Pomdog::Detail::ShaderBytecode;
Expand All @@ -28,7 +32,56 @@ using Pomdog::ShaderCompilers::MetalCompiler;

namespace Pomdog {
namespace AssetBuilders {
namespace {

Optional<std::string> IncludeGLSLFilesRecursive(
const std::string& path, std::set<std::string> & includes)
{
if (FileSystem::IsDirectory(path)) {
Log::Warning("Pomdog", "error: " + path + "is directory, not text file.");
return NullOpt;
}

std::ifstream input(path);
if (!input) {
return NullOpt;
}
std::istreambuf_iterator<char> start(input);
std::istreambuf_iterator<char> end;
std::string text(start, end);
input.close();

auto currentDirectory = PathHelper::GetDirectoryName(PathHelper::Normalize(path));

auto lines = StringHelper::Split(text, '\n');
text.clear();
for (const auto& line : lines) {
std::regex includeRegex(R"(\s*#\s*include\s+\"([\w\.\/\\]+)\")");
std::smatch match;

bool matched = std::regex_match(line, match, includeRegex);
if (!matched || match.size() != 2) {
text += line;
text += '\n';
continue;
}

auto includePath = PathHelper::Join(currentDirectory, match[1]);
if (includes.find(includePath) == includes.end()) {
includes.insert(includePath);
auto result = IncludeGLSLFilesRecursive(includePath, includes);
if (!result) {
return NullOpt;
}
text += *result;
}
text += '\n';
}

return text;
}

} // unnamed namespace

// explicit instantiations
template class Builder<Shader>;
Expand Down Expand Up @@ -115,6 +168,22 @@ Builder<Shader> & Builder<Shader>::SetGLSLFromFile(const std::string& assetName)
POMDOG_THROW_EXCEPTION(std::runtime_error, "The file is too small");
}

{
// NOTE: Using the #include in GLSL support
std::set<std::string> includes;
auto includeResult = IncludeGLSLFilesRecursive(
PathHelper::Join(impl->loaderContext.get().RootDirectory, assetName),
includes);

if (includeResult) {
auto & shaderCode = *includeResult;
impl->shaderBlob.clear();
impl->shaderBlob.resize(shaderCode.size() + 1);
impl->shaderBlob[shaderCode.size()] = 0;
std::memcpy(impl->shaderBlob.data(), shaderCode.data(), shaderCode.size());
}
}

impl->shaderBytecode.Code = impl->shaderBlob.data();
impl->shaderBytecode.ByteLength = impl->shaderBlob.size();
impl->shaderFilePath = assetName;
Expand Down

0 comments on commit cc6a1f8

Please sign in to comment.