support drawing with depth test in GL/Program
This commit is contained in:
parent
fa1a29c325
commit
0cb8468a58
@ -182,6 +182,31 @@ inline bool HasStencil(InternalFormat fmt) noexcept {
|
||||
}
|
||||
|
||||
|
||||
enum class TestFunc {
|
||||
Never,
|
||||
Always,
|
||||
Equal,
|
||||
NotEqual,
|
||||
Less,
|
||||
LessOrEqual,
|
||||
Greater,
|
||||
GreaterOrEqual,
|
||||
};
|
||||
template <>
|
||||
struct EnumMeta<TestFunc> {
|
||||
static inline const std::unordered_map<TestFunc, GLenum> 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<DrawMode> {
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
enum class FramebufferSlot {
|
||||
Color0,
|
||||
Color1,
|
||||
Color2,
|
||||
Color3,
|
||||
Color4,
|
||||
Color5,
|
||||
Color6,
|
||||
Color7,
|
||||
};
|
||||
template <>
|
||||
struct EnumMeta<FramebufferSlot> {
|
||||
static inline const std::unordered_map<FramebufferSlot, GLenum> 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
|
||||
|
@ -186,6 +186,19 @@ nf7::Future<std::shared_ptr<Obj<Obj_ProgramMeta>>> 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<std::shared_ptr<Obj<Obj_VertexArrayMeta>>> Obj_VertexArrayMeta::Create(
|
||||
const std::shared_ptr<nf7::Context>& ctx) const noexcept
|
||||
|
@ -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<std::shared_ptr<Obj<Obj_ProgramMeta>>> Create(
|
||||
const std::shared_ptr<nf7::Context>& ctx,
|
||||
const std::vector<nf7::File::Id>& shaders) noexcept;
|
||||
|
||||
void ApplyState() const noexcept;
|
||||
void RevertState() const noexcept;
|
||||
|
||||
std::optional<Depth> depth;
|
||||
};
|
||||
using Program = Obj<Obj_ProgramMeta>;
|
||||
using ProgramFactory = AsyncFactory<nf7::Mutex::Resource<std::shared_ptr<Program>>>;
|
||||
|
@ -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<nf7::File::Path> shaders;
|
||||
Program ret;
|
||||
for (const auto& shader : yaml["shaders"]) {
|
||||
shaders.push_back(
|
||||
ret.shaders_.push_back(
|
||||
nf7::File::Path::Parse(shader.as<std::string>()));
|
||||
}
|
||||
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<float>(),
|
||||
.far = yaml_depth["far"].as<float>(),
|
||||
.func = magic_enum::enum_cast<gl::TestFunc>(
|
||||
yaml_depth["func"].as<std::string>()).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<nf7::File::Path> shaders_;
|
||||
std::vector<nf7::File::Path> shaders_;
|
||||
std::optional<Product::Meta::Depth> depth_ = {{}};
|
||||
|
||||
|
||||
static void SetUniform(GLuint prog, const char* name, const nf7::Value& v) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user