Panda3D
Loading...
Searching...
No Matches
tagStateManager.cxx
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#include "tagStateManager.h"
29
30using std::endl;
31
32
33NotifyCategoryDef(tagstatemgr, "");
34
35/**
36 * @brief Constructs a new TagStateManager
37 * @details This constructs a new TagStateManager. The #main_cam_node should
38 * refer to the main scene camera, and will most likely be base.cam.
39 * It is necessary to pass the camera because the C++ code does not have
40 * access to the showbase.
41 *
42 * @param main_cam_node The main scene camera
43 */
45TagStateManager(NodePath main_cam_node) {
46 nassertv(!main_cam_node.is_empty());
47 nassertv(DCAST(Camera, main_cam_node.node()) != nullptr);
48 _main_cam_node = main_cam_node;
49
50 // Set default camera mask
51 DCAST(Camera, _main_cam_node.node())->set_camera_mask(BitMask32::bit(1));
52
53 // Init containers
54 _containers["shadow"] = StateContainer("Shadows", 2, false);
55 _containers["voxelize"] = StateContainer("Voxelize", 3, false);
56 _containers["envmap"] = StateContainer("Envmap", 4, true);
57 _containers["forward"] = StateContainer("Forward", 5, true);
58}
59
60/**
61 * @brief Destructs the TagStateManager
62 * @details This destructs the TagStateManager, and cleans up all resources used.
63 */
68
69/**
70 * @brief Applies a given state to a NodePath
71 * @details This applies a shader to the given NodePath which is used when the
72 * NodePath is rendered by any registered camera of the container.
73 *
74 * @param container The container which is used to store the state
75 * @param np The nodepath to apply the shader to
76 * @param shader A handle to the shader to apply
77 * @param name Name of the state, should be a unique identifier
78 * @param sort Changes the sort with which the shader will be applied.
79 */
81apply_state(StateContainer& container, NodePath np, Shader* shader,
82 const std::string &name, int sort) {
83 if (tagstatemgr_cat.is_spam()) {
84 tagstatemgr_cat.spam() << "Constructing new state " << name
85 << " with shader " << shader << endl;
86 }
87
88 // Construct the render state
89 CPT(RenderState) state = RenderState::make_empty();
90
91 // Disable color write for all stages except the environment container
92 if (!container.write_color) {
93 state = state->set_attrib(ColorWriteAttrib::make(ColorWriteAttrib::C_off), 10000);
94 }
95 state = state->set_attrib(ShaderAttrib::make(shader, sort), sort);
96
97 // Emit a warning if we override an existing state
98 if (container.tag_states.count(name) != 0) {
99 tagstatemgr_cat.warning() << "Overriding existing state " << name << endl;
100 }
101
102 // Store the state, this is required whenever we attach a new camera, so
103 // it can also track the existing states
104 container.tag_states[name] = state;
105
106 // Save the tag on the node path
107 np.set_tag(container.tag_name, name);
108
109 // Apply the state on all cameras which are attached so far
110 for (size_t i = 0; i < container.cameras.size(); ++i) {
111 container.cameras[i]->set_tag_state(name, state);
112 }
113}
114
115/**
116 * @brief Cleans up all registered states.
117 * @details This cleans up all states which were registered to the TagStateManager.
118 * It also calls Camera::clear_tag_states() on the main_cam_node and all attached
119 * cameras.
120 */
123 if (tagstatemgr_cat.is_info()) {
124 tagstatemgr_cat.info() << "cleaning up states" << endl;
125 }
126
127 // Clear all tag states of the main camera
128 DCAST(Camera, _main_cam_node.node())->clear_tag_states();
129
130 // Clear the containers
131 // XXX: Just iterate over the _container map
132 cleanup_container_states(_containers["shadow"]);
133 cleanup_container_states(_containers["voxelize"]);
134 cleanup_container_states(_containers["envmap"]);
135 cleanup_container_states(_containers["forward"]);
136}
137
138/**
139 * @brief Cleans up the states of a given container
140 * @details This cleans all tag states of the given container,
141 * and also calls Camera::clear_tag_states on every assigned camera.
142 *
143 * @param container Container to clear
144 */
145void TagStateManager::
146cleanup_container_states(StateContainer& container) {
147 for (size_t i = 0; i < container.cameras.size(); ++i) {
148 container.cameras[i]->clear_tag_states();
149 }
150 container.tag_states.clear();
151}
152
153/**
154 * @brief Registers a new camera to a given container
155 * @details This registers a new camera to a container, and sets its initial
156 * state as well as the camera mask.
157 *
158 * @param container The container to add the camera to
159 * @param source The camera to add
160 */
162register_camera(StateContainer& container, Camera* source) {
163 source->set_tag_state_key(container.tag_name);
164 source->set_camera_mask(container.mask);
165
166 // Construct an initial state which also disables color write, additionally
167 // to the ColorWriteAttrib on each unique state.
168 CPT(RenderState) state = RenderState::make_empty();
169
170 if (!container.write_color) {
171 state = state->set_attrib(ColorWriteAttrib::make(ColorWriteAttrib::C_off), 10000);
172 }
173 source->set_initial_state(state);
174
175 // Store the camera so we can keep track of it
176 container.cameras.push_back(source);
177}
178
179/**
180 * @brief Unregisters a camera from a container
181 * @details This unregisters a camera from the list of cameras of a given
182 * container. It also resets all tag states of the camera, and also its initial
183 * state.
184 *
185 * @param source Camera to unregister
186 */
188unregister_camera(StateContainer& container, Camera* source) {
189 CameraList& cameras = container.cameras;
190
191 // Make sure the camera was attached so far
192 if (std::find(cameras.begin(), cameras.end(), source) == cameras.end()) {
193 tagstatemgr_cat.error()
194 << "Called unregister_camera but camera was never registered!" << endl;
195 return;
196 }
197
198 // Remove the camera from the list of attached cameras
199 cameras.erase(std::remove(cameras.begin(), cameras.end(), source), cameras.end());
200
201 // Reset the camera
202 source->clear_tag_states();
203 source->set_initial_state(RenderState::make_empty());
204}
static BitMask< uint32_t, nbits > bit(int index)
Returns a BitMask with only the indicated bit on.
Definition bitMask.I:70
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
Definition camera.h:35
set_camera_mask
Changes the set of bits that represent the subset of the scene graph the camera will render.
Definition camera.h:63
set_initial_state
Sets the initial state which is applied to all nodes in the scene, as if it were set at the top of th...
Definition camera.h:79
void clear_tag_states()
Removes all associations established by previous calls to set_tag_state().
Definition camera.cxx:123
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition nodePath.h:159
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition nodePath.I:188
PandaNode * node() const
Returns the referenced node of the path.
Definition nodePath.I:227
void set_tag(const std::string &key, const std::string &value)
Associates a user-defined value with a user-defined key which is stored on the node.
Definition nodePath.I:1999
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition renderState.h:47
void register_camera(const std::string &state, Camera *source)
RenderPipeline.
~TagStateManager()
Destructs the TagStateManager.
void cleanup_states()
Cleans up all registered states.
void unregister_camera(const std::string &state, Camera *source)
Unregisters a camera from the list of shadow cameras.
TagStateManager(NodePath main_cam_node)
Constructs a new TagStateManager.
void apply_state(const std::string &state, NodePath np, Shader *shader, const std::string &name, int sort)
Applies a given state for a pass to a NodePath.