(WIP) implement preprocessor for GLSL

This commit is contained in:
falsycat 2022-10-27 21:27:44 +09:00
parent 1b424e299c
commit cd3525b3b5
2 changed files with 78 additions and 2 deletions

View File

@ -0,0 +1,62 @@
#pragma once
#include <fstream>
#include <memory>
#include <sstream>
#include <string_view>
#include "nf7.hh"
namespace nf7::gl {
inline nf7::Future<std::monostate> ExecPreprocessShader(
const std::shared_ptr<nf7::Context>& ctx,
const std::shared_ptr<std::ostream>& ost,
const std::shared_ptr<std::istream>& ist) noexcept;
inline void PreprocessShader(
nf7::Future<std::monostate>::Promise& pro,
const std::shared_ptr<nf7::Context>& ctx,
const std::shared_ptr<std::ostream>& ost,
const std::shared_ptr<std::istream>& ist) noexcept
try {
std::string line;
while (std::getline(*ist, line)) {
if (line.starts_with('#')) {
std::string_view tok {line.begin() + 1, line.end()};
while (!tok.empty() && !std::isalpha(tok.front())) {
tok.remove_prefix(1);
}
if (tok.starts_with("include ")) {
tok.remove_prefix(sizeof("include")-1);
auto begin = std::find(tok.begin(), tok.end(), '"');
auto end = std::find(begin, tok.end(), '"');
auto f = std::make_shared<std::ifstream>(std::string {begin, end}, std::ios::binary);
ExecPreprocessShader(ctx, ost, f).ThenIf([=](auto&) mutable {
ExecPreprocessShader(ctx, ost, ist).Chain(pro);
});
return;
}
}
*ost << line;
}
pro.Return({});
} catch (...) {
pro.Throw<nf7::Exception>("failed to preprocess GLSL");
}
inline nf7::Future<std::monostate> ExecPreprocessShader(
const std::shared_ptr<nf7::Context>& ctx,
const std::shared_ptr<std::ostream>& ost,
const std::shared_ptr<std::istream>& ist) noexcept {
nf7::Future<std::monostate>::Promise pro {ctx};
ctx->env().ExecAsync(ctx, [=]() mutable {
PreprocessShader(pro, ctx, ost, ist);
});
return pro.future();
}
} // namespace nf7::gl

View File

@ -35,6 +35,7 @@
#include "common/gl_enum.hh"
#include "common/gl_fence.hh"
#include "common/gl_obj.hh"
#include "common/gl_shader_preproc.hh"
#include "common/gui_config.hh"
#include "common/life.hh"
#include "common/logger_ref.hh"
@ -667,8 +668,21 @@ struct Shader {
}
nf7::Future<std::shared_ptr<Product>> Create(const CreateParam& p) noexcept {
// TODO: preprocessing GLSL source
return Product::Create(p.ctx, type_, src_);
nf7::Future<std::shared_ptr<Product>>::Promise pro {p.ctx};
// TODO test
auto ost = std::make_shared<std::ostringstream>(src_);
auto ist = std::make_shared<std::istringstream>();
gl::ExecPreprocessShader(p.ctx, ost, ist).
Then([p, ist, pro, type = type_](auto) mutable {
try {
Product::Create(p.ctx, type, ist->str()).Chain(pro);
} catch (nf7::Exception&) {
pro.Throw(std::current_exception());
}
});
return pro.future();
}
bool Handle(const HandleParam<Product>&) {