(WIP) implement preprocessor for GLSL
This commit is contained in:
parent
1b424e299c
commit
cd3525b3b5
62
common/gl_shader_preproc.hh
Normal file
62
common/gl_shader_preproc.hh
Normal 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
|
@ -35,6 +35,7 @@
|
|||||||
#include "common/gl_enum.hh"
|
#include "common/gl_enum.hh"
|
||||||
#include "common/gl_fence.hh"
|
#include "common/gl_fence.hh"
|
||||||
#include "common/gl_obj.hh"
|
#include "common/gl_obj.hh"
|
||||||
|
#include "common/gl_shader_preproc.hh"
|
||||||
#include "common/gui_config.hh"
|
#include "common/gui_config.hh"
|
||||||
#include "common/life.hh"
|
#include "common/life.hh"
|
||||||
#include "common/logger_ref.hh"
|
#include "common/logger_ref.hh"
|
||||||
@ -667,8 +668,21 @@ struct Shader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nf7::Future<std::shared_ptr<Product>> Create(const CreateParam& p) noexcept {
|
nf7::Future<std::shared_ptr<Product>> Create(const CreateParam& p) noexcept {
|
||||||
// TODO: preprocessing GLSL source
|
nf7::Future<std::shared_ptr<Product>>::Promise pro {p.ctx};
|
||||||
return Product::Create(p.ctx, type_, src_);
|
|
||||||
|
// 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>&) {
|
bool Handle(const HandleParam<Product>&) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user