From 006bdb4f8660098fc524dcca80b24c943c65b249 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 25 Sep 2021 14:06:53 +0300 Subject: [PATCH] Make it possible to specify explicit clear values --- blender/io_mspgl/export_scene.py | 5 ++- extensions/msp_clear_buffer.glext | 1 + gl.msp.xml | 11 ++++++ source/builders/sequencebuilder.cpp | 6 ++++ source/builders/sequencetemplate.cpp | 30 ++++++++++++++++- source/builders/sequencetemplate.h | 17 ++++++++++ source/core/commands.cpp | 42 +++++++++++++++++++++-- source/core/commands.h | 2 +- source/core/framebuffer.h | 14 ++++++++ source/render/renderer.cpp | 9 ++--- source/render/renderer.h | 3 +- source/render/sequence.cpp | 50 ++++++++++++++++++++++++++-- source/render/sequence.h | 6 ++++ 13 files changed, 178 insertions(+), 18 deletions(-) create mode 100644 extensions/msp_clear_buffer.glext diff --git a/blender/io_mspgl/export_scene.py b/blender/io_mspgl/export_scene.py index 0f1d1935..0ad6769f 100644 --- a/blender/io_mspgl/export_scene.py +++ b/blender/io_mspgl/export_scene.py @@ -118,7 +118,10 @@ class SceneExporter: if scene.background_set: content = resources[scene.name+".wrapper.scene"] - seq_res.statements.append(Statement("clear")) + ss = Statement("clear") + ss.sub.append(Statement("color", 0.0, 0.0, 0.0, 0.0)) + ss.sub.append(Statement("depth", 1.0)) + seq_res.statements.append(ss) ss = Statement("step", "", "content") ss.sub.append(Statement("depth_test", Token("LEQUAL"))) diff --git a/extensions/msp_clear_buffer.glext b/extensions/msp_clear_buffer.glext new file mode 100644 index 00000000..fc4f1102 --- /dev/null +++ b/extensions/msp_clear_buffer.glext @@ -0,0 +1 @@ +extension MSP_clear_buffer diff --git a/gl.msp.xml b/gl.msp.xml index 7895a806..f406bc77 100644 --- a/gl.msp.xml +++ b/gl.msp.xml @@ -46,6 +46,17 @@ + + + + + + + + + + diff --git a/source/builders/sequencebuilder.cpp b/source/builders/sequencebuilder.cpp index 6e87081d..a614a836 100644 --- a/source/builders/sequencebuilder.cpp +++ b/source/builders/sequencebuilder.cpp @@ -50,6 +50,12 @@ void SequenceBuilder::build(Sequence &sequence) const #endif sequence.set_clear_enabled(tmpl.is_clear_enabled()); + if(tmpl.is_clear_enabled()) + { + sequence.set_clear_colors(tmpl.get_clear_colors()); + sequence.set_clear_depth(tmpl.get_clear_depth()); + sequence.set_clear_stencil(tmpl.get_clear_stencil()); + } for(const SequenceTemplate::Step &s: tmpl.get_steps()) { diff --git a/source/builders/sequencetemplate.cpp b/source/builders/sequencetemplate.cpp index 83c4b767..6e50c248 100644 --- a/source/builders/sequencetemplate.cpp +++ b/source/builders/sequencetemplate.cpp @@ -20,7 +20,9 @@ SequenceTemplate::SequenceTemplate(): alpha(false), required_multisample(0), max_multisample(0), - clear_enabled(false) + clear_enabled(false), + clear_depth(1.0f), + clear_stencil(0) { } SequenceTemplate::~SequenceTemplate() @@ -83,6 +85,8 @@ void SequenceTemplate::Loader::postprocessor_loaded() void SequenceTemplate::Loader::clear() { + ClearLoader ldr(obj); + load_sub_with(ldr); obj.clear_enabled = true; } @@ -131,6 +135,30 @@ void SequenceTemplate::Loader::step_with_slot(const string &tag, const string &r } +SequenceTemplate::ClearLoader::ClearLoader(SequenceTemplate &t): + ObjectLoader(t) +{ + add("color", &ClearLoader::color); + add("depth", &ClearLoader::depth); + add("stencil", &ClearLoader::stencil); +} + +void SequenceTemplate::ClearLoader::color(float r, float g, float b, float a) +{ + obj.clear_colors.push_back(Color(r, g, b, a)); +} + +void SequenceTemplate::ClearLoader::depth(float d) +{ + obj.clear_depth = d; +} + +void SequenceTemplate::ClearLoader::stencil(int s) +{ + obj.clear_stencil = s; +} + + SequenceTemplate::Step::Loader::Loader(Step &p): DataFile::CollectionObjectLoader(p, 0) { diff --git a/source/builders/sequencetemplate.h b/source/builders/sequencetemplate.h index 660a0432..81a130ef 100644 --- a/source/builders/sequencetemplate.h +++ b/source/builders/sequencetemplate.h @@ -110,6 +110,17 @@ public: }; private: + class ClearLoader: public DataFile::ObjectLoader + { + public: + ClearLoader(SequenceTemplate &); + + private: + void color(float, float, float, float); + void depth(float); + void stencil(int); + }; + typedef TypeRegistry PostProcessorRegistry; bool hdr; @@ -119,6 +130,9 @@ private: std::vector steps; std::vector postprocessors; bool clear_enabled; + std::vector clear_colors; + float clear_depth; + int clear_stencil; public: SequenceTemplate(); @@ -131,6 +145,9 @@ public: const std::vector &get_steps() const { return steps; } const std::vector &get_postprocessors() const { return postprocessors; } bool is_clear_enabled() const { return clear_enabled; } + const std::vector &get_clear_colors() const { return clear_colors; } + float get_clear_depth() const { return clear_depth; } + int get_clear_stencil() const { return clear_stencil; } template static void register_postprocessor(const std::string &); diff --git a/source/core/commands.cpp b/source/core/commands.cpp index 529cd392..2eb4659a 100644 --- a/source/core/commands.cpp +++ b/source/core/commands.cpp @@ -3,8 +3,10 @@ #include #include #include +#include #include "batch.h" #include "commands.h" +#include "error.h" #include "gl.h" #include "pipelinestate.h" @@ -22,10 +24,44 @@ void Commands::use_pipeline(const PipelineState &ps) pipeline_state = &ps; } -void Commands::clear(BufferBits buffers) +void Commands::clear(const ClearValue *values) { - pipeline_state->apply(); - glClear(buffers); + const Framebuffer *target = pipeline_state->get_framebuffer(); + if(!target) + throw invalid_operation("OpenGLCommands::clear"); + + if(!ARB_direct_state_access) + { + static Require _req(MSP_clear_buffer); + pipeline_state->apply(); + } + + unsigned i = 0; + for(FrameAttachment a: target->get_format()) + { + if(get_attach_point(a)==get_attach_point(DEPTH_ATTACHMENT)) + { + if(ARB_direct_state_access) + glClearNamedFramebufferfv(target->id, GL_DEPTH, 0, &values->depth_stencil.depth); + else + glClearBufferfv(GL_DEPTH, 0, &values->depth_stencil.depth); + } + else if(get_attach_point(a)==get_attach_point(STENCIL_ATTACHMENT)) + { + if(ARB_direct_state_access) + glClearNamedFramebufferiv(target->id, GL_STENCIL, 0, &values->depth_stencil.stencil); + else + glClearBufferiv(GL_STENCIL, 0, &values->depth_stencil.stencil); + } + else + { + if(ARB_direct_state_access) + glClearNamedFramebufferfv(target->id, GL_COLOR, i++, &values->color.r); + else + glClearBufferfv(GL_COLOR, i++, &values->color.r); + } + ++values; + } } void Commands::draw(const Batch &batch) diff --git a/source/core/commands.h b/source/core/commands.h index ec3281a0..08fdbffd 100644 --- a/source/core/commands.h +++ b/source/core/commands.h @@ -18,7 +18,7 @@ public: Commands(); void use_pipeline(const PipelineState &); - void clear(BufferBits); + void clear(const ClearValue *); void draw(const Batch &); void draw_instanced(const Batch &, unsigned); void resolve_multisample(Framebuffer &, BufferBits); diff --git a/source/core/framebuffer.h b/source/core/framebuffer.h index acb0d3ee..48888459 100644 --- a/source/core/framebuffer.h +++ b/source/core/framebuffer.h @@ -2,6 +2,7 @@ #define MSP_GL_FRAMEBUFFER_H_ #include +#include "color.h" #include "frameformat.h" #include "gl.h" #include "texturecube.h" @@ -128,6 +129,19 @@ public: static Framebuffer &system(); }; + +union ClearValue +{ + Color color; + struct + { + float depth; + int stencil; + } depth_stencil; + + ClearValue(): color(0.0f, 0.0f, 0.0f, 0.0f) { } +}; + inline BufferBits operator|(BufferBits a, BufferBits b) { return static_cast(static_cast(a)|static_cast(b)); } diff --git a/source/render/renderer.cpp b/source/render/renderer.cpp index 6f7e9cba..aa6c9b55 100644 --- a/source/render/renderer.cpp +++ b/source/render/renderer.cpp @@ -243,15 +243,10 @@ void Renderer::render(const Renderable &renderable, Tag tag) renderable.render(*this, tag); } -void Renderer::clear() -{ - clear(COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT|STENCIL_BUFFER_BIT); -} - -void Renderer::clear(BufferBits buffers) +void Renderer::clear(const ClearValue *values) { pipeline_state.set_framebuffer(state->framebuffer); - commands.clear(buffers); + commands.clear(values); } void Renderer::draw(const Batch &batch) diff --git a/source/render/renderer.h b/source/render/renderer.h index ff2c2a2f..8026f5ab 100644 --- a/source/render/renderer.h +++ b/source/render/renderer.h @@ -195,8 +195,7 @@ public: void exclude(const Renderable &); void include(const Renderable &); - void clear(); - void clear(BufferBits); + void clear(const ClearValue *); void render(const Renderable &, Tag = Tag()); void draw(const Batch &); diff --git a/source/render/sequence.cpp b/source/render/sequence.cpp index 254a6c46..7a964c87 100644 --- a/source/render/sequence.cpp +++ b/source/render/sequence.cpp @@ -18,7 +18,9 @@ Sequence::Sequence(): height(0), target{0, 0}, target_ms(0), - clear_enabled(false) + clear_enabled(false), + clear_depth(1.0f), + clear_stencil(0) { } Sequence::Sequence(unsigned w, unsigned h, const FrameFormat &f): @@ -26,7 +28,9 @@ Sequence::Sequence(unsigned w, unsigned h, const FrameFormat &f): height(h), target_format(f), target_ms(0), - clear_enabled(false) + clear_enabled(false), + clear_depth(1.0f), + clear_stencil(0) { if(target_format.empty()) throw invalid_argument("Sequence::Sequence"); @@ -55,6 +59,24 @@ void Sequence::set_clear_enabled(bool c) clear_enabled = c; } +void Sequence::set_clear_colors(const vector &c) +{ + clear_enabled = true; + clear_colors = c; +} + +void Sequence::set_clear_depth(float d) +{ + clear_enabled = true; + clear_depth = d; +} + +void Sequence::set_clear_stencil(int s) +{ + clear_enabled = true; + clear_stencil = s; +} + Sequence::Step &Sequence::add_step(Tag tag, Renderable &r) { steps.push_back(Step(tag, &r)); @@ -109,7 +131,29 @@ void Sequence::render(Renderer &renderer, Tag tag) const renderer.set_framebuffer(&(target_ms ? target_ms : target[0])->get_framebuffer()); if(clear_enabled) - renderer.clear(); + { + const Framebuffer *target_fbo = renderer.get_framebuffer(); + if(!target_fbo) + throw invalid_operation("Sequence::render"); + + const FrameFormat &format = target_fbo->get_format(); + ClearValue clear_values[7]; + unsigned i = 0; + Color default_color = (clear_colors.empty() ? Color(0.0f, 0.0f, 0.0f, 0.0f) : clear_colors.front()); + ClearValue *cv = clear_values; + for(FrameAttachment a: format) + { + if(get_attach_point(a)==get_attach_point(DEPTH_ATTACHMENT)) + cv->depth_stencil.depth = clear_depth; + else if(get_attach_point(a)==get_attach_point(STENCIL_ATTACHMENT)) + cv->depth_stencil.stencil = clear_stencil; + else + cv->color = (i clear_colors; + float clear_depth; + int clear_stencil; public: Sequence(); @@ -94,6 +97,9 @@ public: const FrameFormat &get_target_format() { return target_format; } void set_clear_enabled(bool); + void set_clear_colors(const std::vector &); + void set_clear_depth(float); + void set_clear_stencil(int); /** Adds a step to the sequence. It's permissible to add the same Renderable multiple times. */ -- 2.43.0