Panda3D
shadowManager.I
1 /**
2  *
3  * RenderPipeline
4  *
5  * Copyright (c) 2014-2016 tobspr <tobias.springer1@gmail.com>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  */
26 
27 
28 /**
29  * @brief Sets the maximum amount of updates per frame.
30  * @details This controls the maximum amount of updated ShadowSources per frame.
31  * The ShadowManager will take the first <max_updates> ShadowSources, and
32  * generate shadow maps for them every frame. If there are more ShadowSources
33  * waiting to get updated than available updates, the sources are sorted by
34  * priority, and the update of the less important sources is delayed to the
35  * next frame.
36  *
37  * If the update count is set too low, and there are a lot of ShadowSources
38  * waiting to get updated, artifacts will occur, and there might be ShadowSources
39  * which never get updated, due to low priority.
40  *
41  * If an update count of 0 is passed, no updates will happen. This also means
42  * that there are no shadows. This is not recommended.
43  *
44  * If an update count < 0 is passed, undefined behaviour occurs.
45  *
46  * This method has to get called before ShadowManager::init, otherwise an
47  * assertion will get triggered.
48  *
49  * @param max_updates Maximum amoumt of updates
50  */
51 inline void ShadowManager::set_max_updates(size_t max_updates) {
52  nassertv(max_updates >= 0);
53  nassertv(_atlas == nullptr); // ShadowManager was already initialized
54  if (max_updates == 0) {
55  shadowmanager_cat.warning() << "max_updates set to 0, no shadows will be updated." << std::endl;
56  }
57  _max_updates = max_updates;
58 }
59 
60 /**
61  * @brief Sets the shadow atlas size
62  * @details This sets the desired shadow atlas size. It should be big enough
63  * to store all important shadow sources, with some buffer, because the shadow
64  * maps usually won't be fitted perfectly, so gaps can occur.
65  *
66  * This has to get called before calling ShadowManager::init. When calling this
67  * method after initialization, an assertion will get triggered.
68  *
69  * @param atlas_size Size of the shadow atlas in pixels
70  */
71 inline void ShadowManager::set_atlas_size(size_t atlas_size) {
72  nassertv(atlas_size >= 16 && atlas_size <= 16384);
73  nassertv(_atlas == nullptr); // ShadowManager was already initialized
74  _atlas_size = atlas_size;
75 }
76 
77 /**
78  * @brief Returns the shadow atlas size.
79  * @details This returns the shadow atlas size previously set with
80  * ShadowManager::set_atlas_size.
81  * @return Shadow atlas size in pixels
82  */
83 inline size_t ShadowManager::get_atlas_size() const {
84  return _atlas_size;
85 }
86 
87 
88 /**
89  * @brief Returns a handle to the shadow atlas.
90  * @details This returns a handle to the internal shadow atlas instance. This
91  * is only valid after calling ShadowManager::init. Calling this earlier will
92  * trigger an assertion and undefined behaviour.
93  * @return The internal ShadowAtlas instance
94  */
95 inline ShadowAtlas* ShadowManager::get_atlas() const {
96  nassertr(_atlas != nullptr, nullptr); // Can't hurt to check
97  return _atlas;
98 }
99 
100 /**
101  * @brief Sets the target scene
102  * @details This sets the target scene for rendering shadows. All shadow cameras
103  * will be parented to this scene to render shadows.
104  *
105  * Usually the scene will be ShowBase.render. If the scene is an empty or
106  * invalid NodePath, an assertion will be triggered.
107  *
108  * This method has to get called before calling ShadowManager::init, or an
109  * assertion will get triggered.
110  *
111  * @param scene_parent The target scene
112  */
113 inline void ShadowManager::set_scene(NodePath scene_parent) {
114  nassertv(!scene_parent.is_empty());
115  nassertv(_atlas == nullptr); // ShadowManager was already initialized
116  _scene_parent = scene_parent;
117 }
118 
119 /**
120  * @brief Sets the handle to the TagStageManager.
121  * @details This sets the handle to the TagStateManager used by the pipeline.
122  * Usually this is RenderPipeline.get_tag_mgr().
123  *
124  * This has to get called before ShadowManager::init, otherwise an assertion
125  * will get triggered.
126  *
127  * @param tag_mgr [description]
128  */
130  nassertv(tag_mgr != nullptr);
131  nassertv(_atlas == nullptr); // ShadowManager was already initialized
132  _tag_state_mgr = tag_mgr;
133 }
134 
135 /**
136  * @brief Sets the handle to the Shadow targets output
137  * @details This sets the handle to the GraphicsOutput of the shadow atlas.
138  * Usually this is RenderTarget.get_internal_buffer(), whereas the RenderTarget
139  * is the target of the ShadowStage.
140  *
141  * This is used for creating display regions and attaching cameras to them,
142  * for performing shadow updates.
143  *
144  * This has to get called before ShadowManager::init, otherwise an assertion
145  * will be triggered.
146  *
147  * @param graphics_output [description]
148  */
150  nassertv(graphics_output != nullptr);
151  nassertv(_atlas == nullptr); // ShadowManager was already initialized
152  _atlas_graphics_output = graphics_output;
153 }
154 
155 
156 /**
157  * @brief Adds a new shadow update
158  * @details This adds a new update to the update queue. When the queue is already
159  * full, this method returns false, otherwise it returns true. The next time
160  * the manager is updated, the shadow source will recieve an update of its
161  * shadow map.
162  *
163  * @param source The shadow source to update
164  *
165  * @return Whether the shadow source udpate was sucessfully queued.
166  */
167 inline bool ShadowManager::add_update(const ShadowSource* source) {
168  nassertr(_atlas != nullptr, false); // ShadowManager::init not called yet.
169  nassertr(source != nullptr, false); // nullptr-Pointer passed
170 
171  if (_queued_updates.size() >= _max_updates) {
172  if (shadowmanager_cat.is_debug()) {
173  shadowmanager_cat.debug() << "cannot update source, out of update slots" << std::endl;
174  }
175  return false;
176  }
177 
178  // Add the update to the queue
179  _queued_updates.push_back(source);
180  return true;
181 }
182 
183 /**
184  * @brief Returns how many update slots are left.
185  * @details This returns how many update slots are left. You can assume the
186  * next n calls to add_update will succeed, whereas n is the value returned
187  * by this function.
188  * @return Number of update slots left.
189  */
190 inline size_t ShadowManager::get_num_update_slots_left() const {
191  return _max_updates - _queued_updates.size();
192 }
RenderPipeline.
Definition: shadowSource.h:51
This class handles all different tag states.
void set_atlas_graphics_output(GraphicsOutput *graphics_output)
Sets the handle to the Shadow targets output.
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
get_atlas_size
Returns the shadow atlas size.
Definition: shadowManager.h:58
void set_max_updates(size_t max_updates)
RenderPipeline.
Definition: shadowManager.I:51
void set_scene(NodePath scene_parent)
Sets the target scene.
void set_tag_state_manager(TagStateManager *tag_mgr)
Sets the handle to the TagStageManager.
bool add_update(const ShadowSource *source)
Adds a new shadow update.
get_atlas
Returns a handle to the shadow atlas.
Definition: shadowManager.h:64
This is a base class for the various different classes that represent the result of a frame of render...
Class which manages distributing shadow maps in an atlas.
Definition: shadowAtlas.h:41
set_atlas_size
Sets the shadow atlas size.
Definition: shadowManager.h:58
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161