Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2022-08-30 14:06:22 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-08-30 14:06:22 +0300
commitfce7e485787c7ef7435873352fa0ccc678926386 (patch)
tree06c1914583cab9bc32d18b98f9ea948d7c3ee38a
parent2f6463517e6e8d0e789884f14ecd43d39a48939f (diff)
DRW: Add new pass type for transparent objects (PassSortable)
-rw-r--r--source/blender/draw/intern/draw_pass.hh59
-rw-r--r--source/blender/draw/tests/draw_pass_test.cc26
2 files changed, 85 insertions, 0 deletions
diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh
index 513e7580742..650fa30010c 100644
--- a/source/blender/draw/intern/draw_pass.hh
+++ b/source/blender/draw/intern/draw_pass.hh
@@ -364,6 +364,65 @@ template<typename DrawCommandBufType> class Pass : public detail::PassBase<DrawC
*/
// using PassMain = detail::Pass<DrawMultiBuf>;
+/**
+ * Special pass type for rendering transparent objects.
+ * The base level can only be composed of sub passes that will be ordered by a special value.
+ */
+class PassSortable : public PassMain {
+ private:
+ /** Sorting value associated with each sub pass. */
+ Vector<float> sorting_values_;
+
+ bool sorted_ = false;
+
+ public:
+ PassSortable(const char *name_) : PassMain(name_){};
+
+ void init()
+ {
+ sorting_values_.clear();
+ sorted_ = false;
+ PassMain::init();
+ }
+
+ PassMain::Sub &sub(const char *name, float sorting_value)
+ {
+ int64_t index = sub_passes_.append_and_get_index(
+ PassBase(name, draw_commands_buf_, sub_passes_, shader_));
+ headers_.append({Type::SubPass, static_cast<uint>(index)});
+ sorting_values_.append(sorting_value);
+ return sub_passes_[index];
+ }
+
+ std::string serialize(std::string line_prefix = "") const
+ {
+ if (sorted_ == false) {
+ const_cast<PassSortable *>(this)->sort();
+ }
+ return PassMain::serialize(line_prefix);
+ }
+
+ protected:
+ void sort()
+ {
+ std::sort(headers_.begin(), headers_.end(), [&](Header &a, Header &b) {
+ BLI_assert(a.type == Type::SubPass && b.type == Type::SubPass);
+ float a_val = sorting_values_[a.index];
+ float b_val = sorting_values_[b.index];
+ return a_val < b_val || (a_val == b_val && a.index < b.index);
+ });
+ sorted_ = true;
+ }
+
+ void submit(command::RecordingState &state) const
+ {
+ if (sorted_ == false) {
+ const_cast<PassSortable *>(this)->sort();
+ }
+ PassMain::submit(state);
+ }
+};
+
/** \} */
namespace detail {
diff --git a/source/blender/draw/tests/draw_pass_test.cc b/source/blender/draw/tests/draw_pass_test.cc
index ca32c4f1f29..5a8adaa866a 100644
--- a/source/blender/draw/tests/draw_pass_test.cc
+++ b/source/blender/draw/tests/draw_pass_test.cc
@@ -203,6 +203,32 @@ static void test_draw_pass_multi_draw()
}
DRAW_TEST(draw_pass_multi_draw)
+static void test_draw_pass_sortable()
+{
+ PassSortable pass = {"test.sortable"};
+ pass.init();
+
+ pass.sub("Sub3", 3.0f);
+ pass.sub("Sub2", 2.0f);
+ pass.sub("Sub5", 4.0f);
+ pass.sub("Sub4", 3.0f);
+ pass.sub("Sub1", 1.0f);
+
+ std::string result = pass.serialize();
+ std::stringstream expected;
+ expected << ".test.sortable" << std::endl;
+ expected << " .Sub1" << std::endl;
+ expected << " .Sub2" << std::endl;
+ expected << " .Sub3" << std::endl;
+ expected << " .Sub4" << std::endl;
+ expected << " .Sub5" << std::endl;
+
+ EXPECT_EQ(result, expected.str());
+
+ DRW_shape_cache_free();
+}
+DRAW_TEST(draw_pass_sortable)
+
static void test_draw_resource_id_gen()
{
float4x4 win_mat;