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

draw_view.hh « intern « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 94fb62508bb9155e99a298815ee917ca4e926fdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 2022 Blender Foundation. */

#pragma once

/** \file
 * \ingroup draw
 */

#include "DRW_gpu_wrapper.hh"
#include "DRW_render.h"

#include "draw_shader_shared.h"

namespace blender::draw {

class Manager;

/* TODO: de-duplicate. */
using ObjectBoundsBuf = StorageArrayBuffer<ObjectBounds, 128>;
/** \note Using uint4 for declaration but bound as uint. */
using VisibilityBuf = StorageArrayBuffer<uint4, 1, true>;

class View {
  friend Manager;

 private:
  UniformBuffer<ViewMatrices> data_;
  UniformBuffer<ViewCullingData> culling_;
  /** Frozen version of data_ used for debugging culling. */
  UniformBuffer<ViewMatrices> data_freeze_;
  UniformBuffer<ViewCullingData> culling_freeze_;
  /** Result of the visibility computation. 1 bit per resource ID. */
  VisibilityBuf visibility_buf_;

  const char *debug_name_;

  bool is_inverted_ = false;
  bool do_visibility_ = true;
  bool dirty_ = true;
  bool frozen_ = false;

 public:
  View(const char *name) : visibility_buf_(name), debug_name_(name){};
  /* For compatibility with old system. Will be removed at some point. */
  View(const char *name, const DRWView *view) : visibility_buf_(name), debug_name_(name)
  {
    float4x4 view_mat, win_mat;
    DRW_view_viewmat_get(view, view_mat.ptr(), false);
    DRW_view_winmat_get(view, win_mat.ptr(), false);
    this->sync(view_mat, win_mat);
  }

  void sync(const float4x4 &view_mat, const float4x4 &win_mat);

  bool is_persp() const
  {
    return data_.winmat[3][3] == 0.0f;
  }

  bool is_inverted() const
  {
    return is_inverted_;
  }

  float far_clip() const
  {
    if (is_persp()) {
      return -data_.winmat[3][2] / (data_.winmat[2][2] + 1.0f);
    }
    return -(data_.winmat[3][2] - 1.0f) / data_.winmat[2][2];
  }

  float near_clip() const
  {
    if (is_persp()) {
      return -data_.winmat[3][2] / (data_.winmat[2][2] - 1.0f);
    }
    return -(data_.winmat[3][2] + 1.0f) / data_.winmat[2][2];
  }

  const float4x4 &viewmat() const
  {
    return data_.viewmat;
  }

  const float4x4 &viewinv() const
  {
    return data_.viewinv;
  }

  const float4x4 &winmat() const
  {
    return data_.winmat;
  }

  const float4x4 &wininv() const
  {
    return data_.wininv;
  }

 private:
  /** Called from draw manager. */
  void bind();
  void compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool debug_freeze);

  void update_viewport_size();

  void frustum_boundbox_calc(BoundBox &bbox);
  void frustum_culling_planes_calc();
  void frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bsphere);
};

}  // namespace blender::draw