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 */
129 inline void ShadowManager::set_tag_state_manager(TagStateManager* tag_mgr) {
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 */
149 inline void ShadowManager::set_atlas_graphics_output(GraphicsOutput* graphics_output) {
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 }
GraphicsOutput
This is a base class for the various different classes that represent the result of a frame of render...
Definition: graphicsOutput.h:63
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
NodePath::is_empty
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
ShadowAtlas
Class which manages distributing shadow maps in an atlas.
Definition: shadowAtlas.h:41
ShadowManager::add_update
bool add_update(const ShadowSource *source)
Adds a new shadow update.
Definition: shadowManager.I:167
ShadowManager::set_max_updates
void set_max_updates(size_t max_updates)
RenderPipeline.
Definition: shadowManager.I:51
ShadowManager::set_scene
void set_scene(NodePath scene_parent)
Sets the target scene.
Definition: shadowManager.I:113
ShadowManager::get_atlas_size
get_atlas_size
Returns the shadow atlas size.
Definition: shadowManager.h:58
ShadowManager::get_atlas
get_atlas
Returns a handle to the shadow atlas.
Definition: shadowManager.h:64
ShadowManager::set_atlas_size
set_atlas_size
Sets the shadow atlas size.
Definition: shadowManager.h:58
ShadowManager::get_num_update_slots_left
get_num_update_slots_left
Returns how many update slots are left.
Definition: shadowManager.h:61
ShadowManager::set_tag_state_manager
void set_tag_state_manager(TagStateManager *tag_mgr)
Sets the handle to the TagStageManager.
Definition: shadowManager.I:129
ShadowManager::set_atlas_graphics_output
void set_atlas_graphics_output(GraphicsOutput *graphics_output)
Sets the handle to the Shadow targets output.
Definition: shadowManager.I:149
ShadowSource
RenderPipeline.
Definition: shadowSource.h:51
TagStateManager
This class handles all different tag states.
Definition: tagStateManager.h:50