Panda3D

lightLensNode.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file lightLensNode.cxx
10 * @author drose
11 * @date 2002-03-26
12 */
13
14 #include "lightLensNode.h"
15 #include "bamWriter.h"
16 #include "bamReader.h"
17 #include "datagram.h"
18 #include "datagramIterator.h"
19 #include "renderState.h"
20 #include "cullFaceAttrib.h"
21 #include "colorWriteAttrib.h"
22 #include "graphicsStateGuardianBase.h"
23
24 TypeHandle LightLensNode::_type_handle;
25
26 /**
27 *
28 */
29 LightLensNode::
30 LightLensNode(const std::string &name, Lens *lens) :
31 Camera(name, lens),
32 _has_specular_color(false),
33 _attrib_count(0),
34 _used_by_auto_shader(false)
35 {
36 set_active(false);
37 _shadow_caster = false;
38 _sb_size.set(512, 512);
39 _sb_sort = -10;
40 // set_initial_state(RenderState::make(ShaderAttrib::make_off(), 1000));
41 // Backface culling helps eliminating artifacts.
42 set_initial_state(RenderState::make(CullFaceAttrib::make_reverse(),
43 ColorWriteAttrib::make(ColorWriteAttrib::C_off)));
44 }
45
46 /**
47 *
48 */
49 LightLensNode::
50 ~LightLensNode() {
51 set_active(false);
52 clear_shadow_buffers();
53
54 // If this triggers, the number of attrib_ref() didn't match the number of
55 // attrib_unref() calls, probably indicating a bug in LightAttrib.
56 nassertv(AtomicAdjust::get(_attrib_count) == 0);
57 }
58
59 /**
60 *
61 */
62 LightLensNode::
63 LightLensNode(const LightLensNode &copy) :
64 Light(copy),
65 Camera(copy),
66 _shadow_caster(copy._shadow_caster),
67 _sb_size(copy._sb_size),
68 _sb_sort(-10),
69 _has_specular_color(copy._has_specular_color),
70 _attrib_count(0),
71 _used_by_auto_shader(false)
72 {
73 if (_shadow_caster) {
74 setup_shadow_map();
75 }
76 }
77
78 /**
79 * Sets the flag indicating whether this light should cast shadows or not.
80 * This is the variant without buffer size, meaning that the current buffer
81 * size will be kept (512x512 is the default). Note that enabling shadows will
82 * require the shader generator to be enabled on the scene.
83 */
84 void LightLensNode::
85 set_shadow_caster(bool caster) {
86 if (_shadow_caster && !caster) {
87 clear_shadow_buffers();
88 }
89 if (_shadow_caster != caster && _used_by_auto_shader) {
90 // Make sure any shaders using this light are regenerated.
91 GraphicsStateGuardianBase::mark_rehash_generated_shaders();
92 }
93 _shadow_caster = caster;
94 set_active(caster);
95 if (caster) {
96 setup_shadow_map();
97 }
98 }
99
100 /**
101 * Sets the flag indicating whether this light should cast shadows or not.
102 * The xsize and ysize parameters specify the size of the shadow buffer that
103 * will be set up, the sort parameter specifies the sort. Note that enabling
104 * shadows will require the shader generator to be enabled on the scene.
105 */
106 void LightLensNode::
107 set_shadow_caster(bool caster, int buffer_xsize, int buffer_ysize, int buffer_sort) {
108 if ((_shadow_caster && !caster) || buffer_xsize != _sb_size[0] || buffer_ysize != _sb_size[1]) {
109 clear_shadow_buffers();
110 }
111 if (_shadow_caster != caster && _used_by_auto_shader) {
112 // Make sure any shaders using this light are regenerated.
113 GraphicsStateGuardianBase::mark_rehash_generated_shaders();
114 }
115 _shadow_caster = caster;
116 _sb_size.set(buffer_xsize, buffer_ysize);
117
118 if (buffer_sort != _sb_sort) {
119 ShadowBuffers::iterator it;
120 for(it = _sbuffers.begin(); it != _sbuffers.end(); ++it) {
121 (*it).second->set_sort(buffer_sort);
122 }
123 _sb_sort = buffer_sort;
124 }
125 set_active(caster);
126 if (caster) {
127 setup_shadow_map();
128 }
129 }
130
131 /**
132 * Clears the shadow buffers, meaning they will be automatically recreated
133 * when the Shader Generator needs them.
134 */
135 void LightLensNode::
136 clear_shadow_buffers() {
137 if (_shadow_map) {
138 // Clear it to all ones, so that any shaders that might still be using
139 // it will see the shadows being disabled.
140 _shadow_map->clear_image();
141 }
142
143 ShadowBuffers::iterator it;
144 for(it = _sbuffers.begin(); it != _sbuffers.end(); ++it) {
145 (*it).first->remove_window((*it).second);
146 }
147 _sbuffers.clear();
148 }
149
150 /**
151 * Creates the shadow map texture. Can be overridden.
152 */
153 void LightLensNode::
154 setup_shadow_map() {
155 if (_shadow_map != nullptr &&
156 _shadow_map->get_x_size() == _sb_size[0] &&
157 _shadow_map->get_y_size() == _sb_size[1]) {
158 // Nothing to do.
159 return;
160 }
161
162 if (_shadow_map == nullptr) {
163 _shadow_map = new Texture(get_name());
164 }
165
166 _shadow_map->setup_2d_texture(_sb_size[0], _sb_size[1], Texture::T_unsigned_byte, Texture::F_depth_component);
167 _shadow_map->set_clear_color(LColor(1));
168 _shadow_map->set_wrap_u(SamplerState::WM_border_color);
169 _shadow_map->set_wrap_v(SamplerState::WM_border_color);
170 _shadow_map->set_border_color(LColor(1));
171 _shadow_map->set_minfilter(SamplerState::FT_shadow);
172 _shadow_map->set_magfilter(SamplerState::FT_shadow);
173 }
174
175 /**
176 * This is called when the light is added to a LightAttrib.
177 */
178 void LightLensNode::
179 attrib_ref() {
180 AtomicAdjust::inc(_attrib_count);
181 }
182
183 /**
184 * This is called when the light is removed from a LightAttrib.
185 */
186 void LightLensNode::
187 attrib_unref() {
188 // When it is removed from the last LightAttrib, destroy the shadow buffers.
189 // This is necessary to break the circular reference that the buffer holds
190 // on this node, via the display region's camera.
191 if (!AtomicAdjust::dec(_attrib_count)) {
192 clear_shadow_buffers();
193 }
194 }
195
196 /**
197 * Returns the Light object upcast to a PandaNode.
198 */
199 PandaNode *LightLensNode::
200 as_node() {
201 return this;
202 }
203
204 /**
205 * Cross-casts the node to a Light pointer, if it is one of the four kinds of
206 * Light nodes, or returns NULL if it is not.
207 */
208 Light *LightLensNode::
209 as_light() {
210 return this;
211 }
212
213 /**
214 *
215 */
216 void LightLensNode::
217 output(std::ostream &out) const {
218 LensNode::output(out);
219 }
220
221 /**
222 *
223 */
224 void LightLensNode::
225 write(std::ostream &out, int indent_level) const {
226 LensNode::write(out, indent_level);
227 }
228
229 /**
230 * Writes the contents of this object to the datagram for shipping out to a
231 * Bam file.
232 */
233 void LightLensNode::
234 write_datagram(BamWriter *manager, Datagram &dg) {
235 Camera::write_datagram(manager, dg);
236 Light::write_datagram(manager, dg);
237
238 dg.add_bool(_shadow_caster);
239 dg.add_int32(_sb_size[0]);
240 dg.add_int32(_sb_size[1]);
241 dg.add_int32(_sb_sort);
242 }
243
244 /**
245 * This internal function is called by make_from_bam to read in all of the
246 * relevant data from the BamFile for the new LightLensNode.
247 */
248 void LightLensNode::
249 fillin(DatagramIterator &scan, BamReader *manager) {
250 Camera::fillin(scan, manager);
251 Light::fillin(scan, manager);
252
253 bool shadow_caster = scan.get_bool();
254 int sb_xsize = scan.get_int32();
255 int sb_ysize = scan.get_int32();
256 int sb_sort = scan.get_int32();
257 set_shadow_caster(shadow_caster, sb_xsize, sb_ysize, sb_sort);
258 }
bamReader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bamWriter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
AtomicAdjustDummyImpl::dec
static bool dec(Integer &var)
Atomically decrements the indicated variable and returns true if the new value is nonzero,...
Definition: atomicAdjustDummyImpl.I:27
AtomicAdjustDummyImpl::inc
static void inc(Integer &var)
Atomically increments the indicated variable.
Definition: atomicAdjustDummyImpl.I:18
AtomicAdjustDummyImpl::get
static Integer get(const Integer &var)
Atomically retrieves the snapshot value of the indicated variable.
Definition: atomicAdjustDummyImpl.I:59
BamReader
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
BamWriter
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
Camera
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
Definition: camera.h:35
Camera::write_datagram
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: camera.cxx:271
Camera::set_active
set_active
Sets the active flag on the camera.
Definition: camera.h:50
DatagramIterator
A class to retrieve the individual data elements previously stored in a Datagram.
Definition: datagramIterator.h:27
DatagramIterator::get_bool
bool get_bool()
Extracts a boolean value.
Definition: datagramIterator.I:48
DatagramIterator::get_int32
int32_t get_int32()
Extracts a signed 32-bit integer.
Definition: datagramIterator.I:107
Datagram
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
Datagram::add_int32
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
Definition: datagram.I:67
Datagram::add_bool
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:34
Lens
A base class for any number of different kinds of lenses, linear and otherwise.
Definition: lens.h:41
LightLensNode
A derivative of Light and of Camera.
Definition: lightLensNode.h:33
LightLensNode::attrib_unref
virtual void attrib_unref()
This is called when the light is removed from a LightAttrib.
Definition: lightLensNode.cxx:187
LightLensNode::as_node
virtual PandaNode * as_node()
Returns the Light object upcast to a PandaNode.
Definition: lightLensNode.cxx:200
LightLensNode::write_datagram
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: lightLensNode.cxx:234
LightLensNode::as_light
virtual Light * as_light()
Cross-casts the node to a Light pointer, if it is one of the four kinds of Light nodes,...
Definition: lightLensNode.cxx:209
LightLensNode::attrib_ref
virtual void attrib_ref()
This is called when the light is added to a LightAttrib.
Definition: lightLensNode.cxx:179
LightLensNode::set_shadow_caster
void set_shadow_caster(bool caster)
Sets the flag indicating whether this light should cast shadows or not.
Definition: lightLensNode.cxx:85
Light
The abstract interface to all kinds of lights.
Definition: light.h:38
PandaNode
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
Texture
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:71
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
colorWriteAttrib.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
cullFaceAttrib.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
datagramIterator.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
datagram.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
graphicsStateGuardianBase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
lightLensNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
renderState.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.