diff --git a/common/gl_enum.hh b/common/gl_enum.hh index d528f72..9b4d3b5 100644 --- a/common/gl_enum.hh +++ b/common/gl_enum.hh @@ -182,6 +182,31 @@ inline bool HasStencil(InternalFormat fmt) noexcept { } +enum class TestFunc { + Never, + Always, + Equal, + NotEqual, + Less, + LessOrEqual, + Greater, + GreaterOrEqual, +}; +template <> +struct EnumMeta { + static inline const std::unordered_map glmap = { + {TestFunc::Never, GL_NEVER}, + {TestFunc::Always, GL_ALWAYS}, + {TestFunc::Equal, GL_EQUAL}, + {TestFunc::NotEqual, GL_NOTEQUAL}, + {TestFunc::Less, GL_LESS}, + {TestFunc::LessOrEqual, GL_LEQUAL}, + {TestFunc::Greater, GL_GREATER}, + {TestFunc::GreaterOrEqual, GL_GEQUAL}, + }; +}; + + enum class BufferTarget { Array, ElementArray, @@ -280,31 +305,6 @@ struct EnumMeta { }; }; - -enum class FramebufferSlot { - Color0, - Color1, - Color2, - Color3, - Color4, - Color5, - Color6, - Color7, -}; -template <> -struct EnumMeta { - static inline const std::unordered_map glmap = { - {FramebufferSlot::Color0, GL_COLOR_ATTACHMENT0}, - {FramebufferSlot::Color1, GL_COLOR_ATTACHMENT0+1}, - {FramebufferSlot::Color2, GL_COLOR_ATTACHMENT0+2}, - {FramebufferSlot::Color3, GL_COLOR_ATTACHMENT0+3}, - {FramebufferSlot::Color4, GL_COLOR_ATTACHMENT0+4}, - {FramebufferSlot::Color5, GL_COLOR_ATTACHMENT0+5}, - {FramebufferSlot::Color6, GL_COLOR_ATTACHMENT0+6}, - {FramebufferSlot::Color7, GL_COLOR_ATTACHMENT0+7}, - }; -}; - } // namespace nf7::gl @@ -312,6 +312,8 @@ namespace yas::detail { NF7_YAS_DEFINE_ENUM_SERIALIZER(nf7::gl::NumericType); NF7_YAS_DEFINE_ENUM_SERIALIZER(nf7::gl::ColorComp); +NF7_YAS_DEFINE_ENUM_SERIALIZER(nf7::gl::InternalFormat); +NF7_YAS_DEFINE_ENUM_SERIALIZER(nf7::gl::TestFunc); NF7_YAS_DEFINE_ENUM_SERIALIZER(nf7::gl::BufferTarget); NF7_YAS_DEFINE_ENUM_SERIALIZER(nf7::gl::BufferUsage); @@ -322,6 +324,4 @@ NF7_YAS_DEFINE_ENUM_SERIALIZER(nf7::gl::ShaderType); NF7_YAS_DEFINE_ENUM_SERIALIZER(nf7::gl::DrawMode); -NF7_YAS_DEFINE_ENUM_SERIALIZER(nf7::gl::FramebufferSlot); - } // namespace yas::detail diff --git a/common/gl_obj.cc b/common/gl_obj.cc index d040da2..4c237ed 100644 --- a/common/gl_obj.cc +++ b/common/gl_obj.cc @@ -186,6 +186,19 @@ nf7::Future>> Obj_ProgramMeta::Create( return pro.future(); } +void Obj_ProgramMeta::ApplyState() const noexcept { + if (depth) { + glEnable(GL_DEPTH_TEST); + glDepthRange(depth->near, depth->far); + glDepthFunc(gl::ToEnum(depth->func)); + } +} +void Obj_ProgramMeta::RevertState() const noexcept { + if (depth) { + glDisable(GL_DEPTH_TEST); + } +} + nf7::Future>> Obj_VertexArrayMeta::Create( const std::shared_ptr& ctx) const noexcept diff --git a/common/gl_obj.hh b/common/gl_obj.hh index 097f226..681f311 100644 --- a/common/gl_obj.hh +++ b/common/gl_obj.hh @@ -113,6 +113,13 @@ struct Obj_ProgramMeta final { public: struct Param { }; + struct Depth { + float near = 0, far = 1; + gl::TestFunc func = gl::TestFunc::Less; + + void serialize(auto& ar) { ar(near, far, func); } + }; + static void Delete(GLuint id) noexcept { glDeleteProgram(id); } @@ -121,6 +128,11 @@ struct Obj_ProgramMeta final { nf7::Future>> Create( const std::shared_ptr& ctx, const std::vector& shaders) noexcept; + + void ApplyState() const noexcept; + void RevertState() const noexcept; + + std::optional depth; }; using Program = Obj; using ProgramFactory = AsyncFactory>>; diff --git a/file/gl_obj.cc b/file/gl_obj.cc index c4cd618..8ae2ab9 100644 --- a/file/gl_obj.cc +++ b/file/gl_obj.cc @@ -730,7 +730,7 @@ struct Program { Program& operator=(Program&&) = default; void serialize(auto& ar) { - ar(shaders_); + ar(shaders_, depth_); } std::string Stringify() noexcept { @@ -742,6 +742,18 @@ struct Program { st << shader.Stringify(); } st << YAML::EndSeq; + + if (depth_) { + st << YAML::Key << "depth"; + st << YAML::BeginMap; + st << YAML::Key << "near"; + st << YAML::Value << depth_->near; + st << YAML::Key << "far"; + st << YAML::Value << depth_->far; + st << YAML::Key << "func"; + st << YAML::Value << std::string {magic_enum::enum_name(depth_->func)}; + st << YAML::EndMap; + } st << YAML::EndMap; return std::string {st.c_str(), st.size()}; } @@ -749,16 +761,25 @@ struct Program { try { const auto yaml = YAML::Load(v); - std::vector shaders; + Program ret; for (const auto& shader : yaml["shaders"]) { - shaders.push_back( + ret.shaders_.push_back( nf7::File::Path::Parse(shader.as())); } - if (shaders.size() == 0) { + if (ret.shaders_.size() == 0) { throw nf7::Exception {"no shader is attached"}; } - shaders_ = std::move(shaders); + if (const auto& yaml_depth = yaml["depth"]) { + depth_.emplace(Product::Meta::Depth { + .near = yaml_depth["near"].as(), + .far = yaml_depth["far"].as(), + .func = magic_enum::enum_cast( + yaml_depth["func"].as()).value(), + }); + } + + *this = std::move(ret); } catch (YAML::Exception& e) { throw nf7::Exception {std::string {"YAML error: "}+e.what()}; } @@ -802,6 +823,9 @@ struct Program { throw nf7::Exception {"negative size viewport"}; } + gl::Program::Meta config = (**p.obj).meta(); + // TODO: override configurations + // this will be triggered when all preparation done nf7::AggregatePromise apro {p.la}; @@ -903,12 +927,14 @@ struct Program { } // draw + config.ApplyState(); if (vao->meta().index) { const auto numtype = gl::ToEnum(vao->meta().index->numtype); glDrawElementsInstanced(mode, count, numtype, nullptr, inst); } else { glDrawArraysInstanced(mode, 0, count, inst); } + config.RevertState(); const auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER); // unbind all @@ -934,7 +960,8 @@ struct Program { } private: - std::vector shaders_; + std::vector shaders_; + std::optional depth_ = {{}}; static void SetUniform(GLuint prog, const char* name, const nf7::Value& v) {